hack up some persistance

This commit is contained in:
bienvenu%netscape.com 1999-02-25 04:04:43 +00:00
parent d2e486af10
commit bfefdb6288
5 changed files with 320 additions and 41 deletions

View File

@ -4,6 +4,9 @@
#define _MDB_ 1
#include "msgCore.h"
#include "nsFileSpec.h"
#include "nsFileStream.h"
// { %%%%% begin scalar typedefs %%%%%
typedef unsigned char mdb_bool; // unsigned byte with zero=false, nonzero=true
typedef unsigned long mdb_id; // unsigned object identity in a scope
@ -306,7 +309,7 @@ class nsIMdbHeap;
// { %%%%% begin temporary dummy base class for class hierarchy %%%%%
class mdbISupports { // msg db base class
public:
mdbISupports() {mRefCnt ;}
mdbISupports() {mRefCnt = 0;}
mdb_count Release(void) {if (mRefCnt > 0) -- mRefCnt; int saveRefCnt = mRefCnt; if (mRefCnt == 0) delete this; return saveRefCnt;}
mdb_count AddRef(void) {return ++mRefCnt;}
protected:
@ -467,6 +470,10 @@ public:
mdb_err CancelAndBreakThumb( // cancel pending operation
nsIMdbEnv* ev) ;
// } ===== end nsIMdbThumb methods =====
// mdbstubs hackery.
nsIMdbThumb() ;
nsFilePath m_backingFile;
nsIOFileStream *m_fileStream;
};
/*| nsIMdbEnv: a context parameter used when calling most abstract db methods.
@ -860,8 +867,15 @@ public:
nsIMdbPortTableCursor** acqCursor); // all such tables in the port
// } ----- end table methods -----
nsVoidArray m_tables;
// mdb stub hackery
nsIMdbPort() ;
nsVoidArray m_tables;
nsStringArray m_tokenStrings;
nsFilePath m_backingFile;
nsIOFileStream *m_fileStream;
// } ===== end nsIMdbPort methods =====
};
@ -1026,6 +1040,15 @@ public:
// } ----- end commit methods -----
// } ===== end nsIMdbStore methods =====
// mdbstubs hack
nsIMdbStore() {}
mdb_err WriteAll(nsIMdbEnv* ev, nsIMdbThumb** acqThumb);
mdb_err ReadTokenList();
mdb_err WriteTokenList();
mdb_err WriteTableList();
mdb_err ReadTableList();
};
/*| nsIMdbCursor: base cursor class for iterating row cells and table rows
@ -1204,14 +1227,15 @@ public:
mdb_err GetOid(nsIMdbEnv* ev,
const mdbOid* outOid) ; // read object identity
mdb_err BecomeContent(nsIMdbEnv* ev,
const mdbOid* inOid) ; // exchange content
const mdbOid* inOid) {m_Oid = *inOid; return 0;} // exchange content
// } ----- end ID methods -----
// { ----- begin activity dropping methods -----
mdb_err DropActivity( // tell collection usage no longer expected
nsIMdbEnv* ev) ;
// } ----- end activity dropping methods -----
mdbOid m_Oid;
nsIMdbCollection() {m_Oid.mOid_Id = 0;}
// } ===== end nsIMdbCollection methods =====
};
@ -1488,7 +1512,13 @@ public:
// } ----- end index methods -----
// ************************** mdbstubs hack
nsIMdbTable(nsIMdbPort*, mdb_kind kind);
mdb_err Write();
mdb_err Read();
nsVoidArray m_rows;
nsIMdbPort* m_owningPort;
mdb_kind m_kind;
// } ===== end nsIMdbTable methods =====
};
@ -1616,8 +1646,13 @@ public:
// } ----- end row methods -----
// } ===== end nsIMdbRow methods =====
// mdb stub hacks.
nsIMdbRow(nsIMdbTable *owningTable, nsIMdbStore *owningStore);
MDBCellArray m_cells;
mdbOid m_oid;
nsIMdbTable *m_owningTable;
nsIMdbStore *m_owningStore;
};

View File

@ -4,6 +4,9 @@
#define _MDB_ 1
#include "msgCore.h"
#include "nsFileSpec.h"
#include "nsFileStream.h"
// { %%%%% begin scalar typedefs %%%%%
typedef unsigned char mdb_bool; // unsigned byte with zero=false, nonzero=true
typedef unsigned long mdb_id; // unsigned object identity in a scope
@ -306,7 +309,7 @@ class nsIMdbHeap;
// { %%%%% begin temporary dummy base class for class hierarchy %%%%%
class mdbISupports { // msg db base class
public:
mdbISupports() {mRefCnt ;}
mdbISupports() {mRefCnt = 0;}
mdb_count Release(void) {if (mRefCnt > 0) -- mRefCnt; int saveRefCnt = mRefCnt; if (mRefCnt == 0) delete this; return saveRefCnt;}
mdb_count AddRef(void) {return ++mRefCnt;}
protected:
@ -467,6 +470,10 @@ public:
mdb_err CancelAndBreakThumb( // cancel pending operation
nsIMdbEnv* ev) ;
// } ===== end nsIMdbThumb methods =====
// mdbstubs hackery.
nsIMdbThumb() ;
nsFilePath m_backingFile;
nsIOFileStream *m_fileStream;
};
/*| nsIMdbEnv: a context parameter used when calling most abstract db methods.
@ -860,8 +867,15 @@ public:
nsIMdbPortTableCursor** acqCursor); // all such tables in the port
// } ----- end table methods -----
nsVoidArray m_tables;
// mdb stub hackery
nsIMdbPort() ;
nsVoidArray m_tables;
nsStringArray m_tokenStrings;
nsFilePath m_backingFile;
nsIOFileStream *m_fileStream;
// } ===== end nsIMdbPort methods =====
};
@ -1026,6 +1040,15 @@ public:
// } ----- end commit methods -----
// } ===== end nsIMdbStore methods =====
// mdbstubs hack
nsIMdbStore() {}
mdb_err WriteAll(nsIMdbEnv* ev, nsIMdbThumb** acqThumb);
mdb_err ReadTokenList();
mdb_err WriteTokenList();
mdb_err WriteTableList();
mdb_err ReadTableList();
};
/*| nsIMdbCursor: base cursor class for iterating row cells and table rows
@ -1204,14 +1227,15 @@ public:
mdb_err GetOid(nsIMdbEnv* ev,
const mdbOid* outOid) ; // read object identity
mdb_err BecomeContent(nsIMdbEnv* ev,
const mdbOid* inOid) ; // exchange content
const mdbOid* inOid) {m_Oid = *inOid; return 0;} // exchange content
// } ----- end ID methods -----
// { ----- begin activity dropping methods -----
mdb_err DropActivity( // tell collection usage no longer expected
nsIMdbEnv* ev) ;
// } ----- end activity dropping methods -----
mdbOid m_Oid;
nsIMdbCollection() {m_Oid.mOid_Id = 0;}
// } ===== end nsIMdbCollection methods =====
};
@ -1488,7 +1512,13 @@ public:
// } ----- end index methods -----
// ************************** mdbstubs hack
nsIMdbTable(nsIMdbPort*, mdb_kind kind);
mdb_err Write();
mdb_err Read();
nsVoidArray m_rows;
nsIMdbPort* m_owningPort;
mdb_kind m_kind;
// } ===== end nsIMdbTable methods =====
};
@ -1616,8 +1646,13 @@ public:
// } ----- end row methods -----
// } ===== end nsIMdbRow methods =====
// mdb stub hacks.
nsIMdbRow(nsIMdbTable *owningTable, nsIMdbStore *owningStore);
MDBCellArray m_cells;
mdbOid m_oid;
nsIMdbTable *m_owningTable;
nsIMdbStore *m_owningStore;
};

View File

@ -1,5 +1,7 @@
#include "mdb.h"
#include "stdio.h"
// for LINEBREAK
#include "fe_proto.h"
nsIMdbFactory *NS_NewIMdbFactory()
{
@ -11,22 +13,32 @@ nsIMdbFactory *NS_NewIMdbFactory()
nsIMdbEnv* ev, // context
nsIMdbThumb* ioThumb, // thumb from OpenFileStore() with done status
nsIMdbStore** acqStore) // acquire new db store object
{
*acqStore = new nsIMdbStore;
return 0;
}
{
nsIMdbStore *resultStore;
resultStore = new nsIMdbStore;
resultStore->m_fileStream = ioThumb->m_fileStream;
resultStore->m_backingFile = ioThumb->m_backingFile;
*acqStore = resultStore;
return 0;
}
mdb_err nsIMdbFactory::CreateNewFileStore( // create a new db with minimal content
nsIMdbEnv* ev, // context
nsIMdbHeap* ioHeap, // can be nil to cause ev's heap attribute to be used
const char* inFilePath, // name of file which should not yet exist
const mdbOpenPolicy* inOpenPolicy, // runtime policies for using db
nsIMdbStore** acqStore)
{
printf("new file store for %s\n", inFilePath);
*acqStore = new nsIMdbStore;
return 0;
}
{
printf("new file store for %s\n", inFilePath);
nsIMdbStore *resultStore;
resultStore = new nsIMdbStore;
resultStore->m_backingFile = inFilePath;
resultStore->m_fileStream = NULL;
*acqStore = resultStore;
return 0;
}
mdb_err nsIMdbStore::SmallCommit( // save minor changes if convenient and uncostly
nsIMdbEnv* ev)
@ -37,6 +49,7 @@ nsIMdbFactory *NS_NewIMdbFactory()
nsIMdbEnv* ev, // context
nsIMdbThumb** acqThumb)
{
WriteAll(ev, acqThumb);
return 0;
}
@ -44,6 +57,7 @@ nsIMdbFactory *NS_NewIMdbFactory()
nsIMdbEnv* ev, // context
nsIMdbThumb** acqThumb)
{
WriteAll(ev, acqThumb);
return 0;
}
@ -52,30 +66,149 @@ nsIMdbFactory *NS_NewIMdbFactory()
nsIMdbEnv* ev, // context
nsIMdbThumb** acqThumb)
{
WriteAll(ev, acqThumb);
return 0;
}
mdb_err
nsIMdbStore::WriteAll(nsIMdbEnv* ev, // context
nsIMdbThumb** acqThumb)
{
// nsVoidArray m_tables;
// nsStringArray m_tokenStrings;
m_fileStream = new nsIOFileStream(m_backingFile);
WriteTokenList();
WriteTableList();
m_fileStream->close();
delete m_fileStream;
m_fileStream = NULL;
return 0;
}
const char *kStartTokenList = "token list"LINEBREAK;
const char *kEndTokenList = "end token list"LINEBREAK;
mdb_err nsIMdbStore::WriteTokenList()
{
*m_fileStream << kStartTokenList;
PRInt32 i;
for (i = 0; i < m_tokenStrings.Count(); i++)
{
nsString outputNSString;
char *outputString;
m_tokenStrings.StringAt(i, outputNSString);
outputString = outputNSString.ToNewCString();
*m_fileStream << outputString;
delete [] outputString;
*m_fileStream << LINEBREAK;
}
*m_fileStream << kEndTokenList;
return 0;
}
mdb_err nsIMdbStore::ReadTokenList()
{
char readlineBuffer[100];
m_tokenStrings.Clear();
m_fileStream->readline(readlineBuffer, sizeof(readlineBuffer));
if (strcmp(readlineBuffer, kStartTokenList))
return -1;
while (TRUE)
{
if (m_fileStream->eof())
break;
m_fileStream->readline(readlineBuffer, sizeof(readlineBuffer));
if (!strcmp(readlineBuffer, kEndTokenList))
break;
nsString unicodeStr(readlineBuffer);
m_tokenStrings.AppendString(unicodeStr);
}
return 0;
}
const char *kStartTableList = "table list"LINEBREAK;
const char *kEndTableList = "end table list"LINEBREAK;
mdb_err nsIMdbStore::WriteTableList()
{
*m_fileStream << kStartTableList;
PRInt32 i;
for (i = 0; i < m_tables.Count(); i++)
{
nsIMdbTable *table = (nsIMdbTable *) m_tables.ElementAt(i);
table->Write();
}
*m_fileStream << kEndTableList;
return 0;
}
mdb_err nsIMdbStore::NewTable( // make one new table of specific type
nsIMdbEnv* ev, // context
mdb_scope inRowScope, // row scope for row ids
mdb_kind inTableKind, // the type of table to access
mdb_bool inMustBeUnique, // whether store can hold only one of these
nsIMdbTable** acqTable) ; // acquire scoped collection of rows
nsIMdbTable** acqTable) // acquire scoped collection of rows
mdb_err nsIMdbPort::GetTable( // access one table with specific oid
nsIMdbEnv* ev, // context
const mdbOid* inOid, // hypothetical table oid
nsIMdbTable** acqTable)
{
*acqTable = new nsIMdbTable;
*acqTable = new nsIMdbTable(this, inTableKind);
m_tables.AppendElement(*acqTable);
return 0;
}
nsIMdbPort::nsIMdbPort() : m_backingFile("")
{
}
mdb_err nsIMdbPort::GetTable( // access one table with specific oid
nsIMdbEnv* ev, // context
const mdbOid* inOid, // hypothetical table oid
nsIMdbTable** acqTable)
{
mdb_err result = -1;
nsIMdbTable *retTable = NULL;
*acqTable = NULL;
for (PRInt32 i = 0; i < m_tables.Count(); i++)
{
nsIMdbTable *table = (nsIMdbTable *) m_tables[i];
if (table->m_Oid.mOid_Id == inOid->mOid_Id)
{
retTable = table;
table->AddRef();
*acqTable = table;
result = 0;
break;
}
}
return result;
}
mdb_err nsIMdbPort::StringToToken ( nsIMdbEnv* ev, // context
const char* inTokenName, // Latin1 string to tokenize if possible
mdb_token* outToken)
{
*outToken = (mdb_token) inTokenName;
nsString unicodeStr(inTokenName);
PRInt32 tokenPos = m_tokenStrings.IndexOf(unicodeStr);
if (tokenPos >= 0)
{
*outToken = tokenPos;
}
else
{
m_tokenStrings.AppendString(unicodeStr);
*outToken = m_tokenStrings.Count() - 1;
}
// *outToken = (mdb_token) inTokenName;
return 0;
}
@ -87,10 +220,29 @@ mdb_err nsIMdbPort::GetTableKind (
mdb_bool* outMustBeUnique, // whether port can hold only one of these
nsIMdbTable** acqTable)
{
*acqTable = new nsIMdbTable;
nsIMdbTable *retTable = NULL;
for (PRInt32 i = 0; i < m_tables.Count(); i++)
{
nsIMdbTable *table = (nsIMdbTable *) m_tables[i];
if (table->m_kind == inTableKind)
{
retTable = table;
table->AddRef();
*acqTable = table;
break;
}
}
if (! retTable )
*acqTable = new nsIMdbTable (this, inTableKind);
return 0;
}
nsIMdbTable::nsIMdbTable(nsIMdbPort* owner, mdb_kind kind)
{
m_owningPort = owner;
m_kind = kind;
}
mdb_err nsIMdbTable::HasOid( // test for the table position of a row member
nsIMdbEnv* ev, // context
@ -123,6 +275,26 @@ mdb_err nsIMdbTable::HasOid( // test for the table position of a row member
return 0;
}
const char *kStartRowList = "start row list"LINEBREAK;
const char *kEndRowList = "end row list"LINEBREAK;
mdb_err nsIMdbTable::Write()
{
nsIOFileStream *stream = m_owningPort->m_fileStream;
*stream << m_kind;
*stream << kStartRowList;
PRInt32 i;
for (i = 0; i < m_rows.Count(); i++)
{
}
*stream << kEndRowList;
return 0;
}
mdb_err nsIMdbTableRowCursor::SetTable(nsIMdbEnv* ev, nsIMdbTable* ioTable)
{
m_table = ioTable;
@ -155,7 +327,7 @@ mdb_err nsIMdbStore::NewRowWithOid (nsIMdbEnv* ev, // new row w/ caller assigned
const mdbOid* inOid, // caller assigned oid
nsIMdbRow** acqRow)
{
*acqRow = new nsIMdbRow;
*acqRow = new nsIMdbRow (NULL, this);
(*acqRow)->m_oid = *inOid;
return 0;
}
@ -165,10 +337,15 @@ mdb_err nsIMdbTable::AddRow ( // make sure the row with inOid is a table member
nsIMdbRow* ioRow)
{
m_rows.AppendElement(ioRow);
ioRow->m_owningTable = this;
return 0;
}
nsIMdbRow::nsIMdbRow(nsIMdbTable *owningTable, nsIMdbStore *owningStore)
{
m_owningTable = owningTable;
m_owningStore = owningStore;
}
mdb_err nsIMdbRow::AddColumn( // make sure a particular column is inside row
nsIMdbEnv* ev, // context
@ -176,7 +353,18 @@ mdb_err nsIMdbRow::AddColumn( // make sure a particular column is inside row
const mdbYarn* inYarn)
{
// evilly, I happen to know the column token is a char * const str pointer.
printf("adding column %s : %s\n", inColumn, inYarn->mYarn_Buf);
char *columnName;
if (m_owningStore)
{
nsString columnStr;
m_owningStore->m_tokenStrings.StringAt(inColumn, columnStr);
columnName = columnStr.ToNewCString();
printf("adding column %s : %s\n", columnName, inYarn->mYarn_Buf);
delete [] columnName;
}
mdbCellImpl newCell;
nsIMdbCell *existingCell = NULL;
@ -255,6 +443,11 @@ mdb_err nsIMdbFactory::MakeEnv(nsIMdbHeap* ioHeap, nsIMdbEnv** acqEnv)
return 0;
}
nsIMdbThumb::nsIMdbThumb() : m_backingFile("")
{
m_fileStream = NULL;
}
mdb_err nsIMdbThumb::DoMore(nsIMdbEnv* ev,
mdb_count* outTotal, // total somethings to do in operation
mdb_count* outCurrent, // subportion of total completed so far
@ -270,12 +463,10 @@ mdb_err nsIMdbFactory::OpenFileStore(class nsIMdbEnv *, nsIMdbHeap* , char const
{
*retThumb = new nsIMdbThumb;
return 0;
}
nsFilePath filePath(fileName);
(*retThumb)->m_fileStream = new nsIOFileStream(filePath);
(*retThumb)->m_backingFile = fileName;
mdb_err nsIMdbStore::NewTable(class nsIMdbEnv *,unsigned long,unsigned long,unsigned char,class nsIMdbTable **retTable)
{
*retTable = new nsIMdbTable;
return 0;
}

View File

@ -60,7 +60,9 @@ nsMailDatabase::~nsMailDatabase()
if (stat ((const char *) summarySpec, &st) && create)
newFile = PR_TRUE;
mailDB = new nsMailDatabase(dbName);
nsFilePath dbPath(summarySpec);
mailDB = new nsMailDatabase(dbPath);
if (!mailDB)
return NS_ERROR_OUT_OF_MEMORY;
@ -68,9 +70,9 @@ nsMailDatabase::~nsMailDatabase()
// stat file before we open the db, because if we've latered
// any messages, handling latered will change time stamp on
// folder file.
statResult = stat ((const char *) dbName, &st);
statResult = stat ((const char *) dbPath, &st);
nsresult err = mailDB->OpenMDB(dbName, create);
nsresult err = mailDB->OpenMDB(dbPath, create);
if (NS_SUCCEEDED(err))
{

View File

@ -448,6 +448,7 @@ nsresult nsMsgDatabase::InitNewDB()
// create the unique table for the dbFolderInfo.
mdb_err err = store->NewTable(GetEnv(), m_hdrRowScopeToken,
m_hdrTableKindToken, PR_FALSE, &m_mdbAllMsgHeadersTable);
m_mdbAllMsgHeadersTable->BecomeContent(GetEnv(), &gAllMsgHdrsTableOID);
m_dbFolderInfo = dbFolderInfo;
}
@ -1369,7 +1370,7 @@ nsresult nsMsgDatabase::RowCellColumnToUInt32(nsIMdbRow *hdrRow, mdb_token colum
/* static */struct mdbYarn *nsMsgDatabase::UInt32ToYarn(struct mdbYarn *yarn, PRUint32 i)
{
PR_snprintf((char *) yarn->mYarn_Buf, yarn->mYarn_Size, "%uld", i);
PR_snprintf((char *) yarn->mYarn_Buf, yarn->mYarn_Size, "%lx", i);
yarn->mYarn_Fill = PL_strlen((const char *) yarn->mYarn_Buf) + 1;
yarn->mYarn_Form = 0; // what to do with this? Should be parsed out of the mime2 header?
return yarn;
@ -1380,10 +1381,25 @@ nsresult nsMsgDatabase::RowCellColumnToUInt32(nsIMdbRow *hdrRow, mdb_token colum
str->SetString((const char *) yarn->mYarn_Buf, yarn->mYarn_Fill);
}
/* static */void nsMsgDatabase::YarnToUInt32(struct mdbYarn *yarn, PRUint32 *i)
/* static */void nsMsgDatabase::YarnToUInt32(struct mdbYarn *yarn, PRUint32 *pResult)
{
char *endPtr;
*i = XP_STRTOUL((char *) yarn->mYarn_Buf, &endPtr, yarn->mYarn_Fill);
PRUint32 result;
char *p = (char *) yarn->mYarn_Buf;
PRInt32 numChars = min(8, yarn->mYarn_Fill);
PRInt32 i;
for (i=0, result = 0; i<numChars; i++, p++)
{
char C = *p;
PRInt8 unhex = ((C >= '0' && C <= '9') ? C - '0' :
((C >= 'A' && C <= 'F') ? C - 'A' + 10 :
((C >= 'a' && C <= 'f') ? C - 'a' + 10 : -1)));
if (unhex < 0)
break;
result = (result << 4) | unhex;
}
*pResult = result;
}
nsresult nsMsgDatabase::SetSummaryValid(PRBool valid /* = PR_TRUE */)