This commit is contained in:
davidmc%netscape.com 1999-09-03 22:23:21 +00:00
Родитель 028f11d2bf
Коммит d230684a1a
64 изменённых файлов: 1542 добавлений и 1014 удалений

Двоичные данные
db/mork/macbuild/mork.mcp

Двоичный файл не отображается.

Просмотреть файл

@ -194,6 +194,8 @@ class morkRow;
class morkRowCellCursor;
class morkRowObject;
class morkRowSpace;
class morkSorting;
class morkSortingRowCursor;
class morkSpace;
class morkSpan;
class morkStore;

Просмотреть файл

@ -67,6 +67,9 @@ morkEnv::~morkEnv() /*i*/ // assert CloseEnv() executed earlier
MORK_ASSERT(mEnv_ErrorHook==0);
}
/* choose morkBool_kTrue or morkBool_kFalse for kBeVerbose: */
#define morkEnv_kBeVerbose morkBool_kFalse
/*public non-poly*/
morkEnv::morkEnv(const morkUsage& inUsage, nsIMdbHeap* ioHeap,
morkFactory* ioFactory, nsIMdbHeap* ioSlotHeap)
@ -86,7 +89,7 @@ morkEnv::morkEnv(const morkUsage& inUsage, nsIMdbHeap* ioHeap,
, mEnv_DoTrace( morkBool_kFalse )
, mEnv_AutoClear( morkAble_kDisabled )
, mEnv_ShouldAbort( morkBool_kFalse )
, mEnv_BeVerbose( morkBool_kFalse )
, mEnv_BeVerbose( morkEnv_kBeVerbose )
{
MORK_ASSERT(ioSlotHeap && ioFactory );
if ( ioSlotHeap )
@ -126,7 +129,7 @@ morkEnv::morkEnv(morkEnv* ev, /*i*/
, mEnv_DoTrace( morkBool_kFalse )
, mEnv_AutoClear( morkAble_kDisabled )
, mEnv_ShouldAbort( morkBool_kFalse )
, mEnv_BeVerbose( morkBool_kFalse )
, mEnv_BeVerbose( morkEnv_kBeVerbose )
{
// $$$ do we need to refcount the inSelfAsMdbEnv nsIMdbEnv??

Просмотреть файл

@ -36,9 +36,13 @@
#include "morkFile.h"
#endif
// #ifndef _ORKINFILE_
// #include "orkinFile.h"
// #endif
#define MORK_CONFIG_USE_ORKINFILE 1
#ifdef MORK_CONFIG_USE_ORKINFILE
#ifndef _ORKINFILE_
#include "orkinFile.h"
#endif
#endif /*MORK_CONFIG_USE_ORKINFILE*/
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789

Просмотреть файл

@ -173,19 +173,20 @@ void morkHandle::NewDownHandleError(morkEnv* ev) const
}
morkObject* morkHandle::GetGoodHandleObject(morkEnv* ev,
mork_bool inMutable, mork_magic inMagicType) const
mork_bool inMutable, mork_magic inMagicType, mork_bool inClosedOkay) const
{
morkObject* outObject = 0;
if ( this->IsHandle() && this->GoodHandleTag() && this->IsOpenNode() )
if ( this->IsHandle() && this->GoodHandleTag() &&
( inClosedOkay || this->IsOpenNode() ) )
{
if ( !inMagicType || mHandle_Magic == inMagicType )
{
morkObject* obj = this->mHandle_Object;
if ( obj )
if ( obj )
{
if ( obj->IsNode() )
{
if ( obj->IsOpenNode() )
if ( inClosedOkay || obj->IsOpenNode() )
{
if ( this->IsMutable() || !inMutable )
outObject = obj;
@ -198,7 +199,7 @@ morkObject* morkHandle::GetGoodHandleObject(morkEnv* ev,
else
this->NonNodeObjectError(ev);
}
else
else if ( !inClosedOkay )
this->NilHandleObjectError(ev);
}
else
@ -207,27 +208,28 @@ morkObject* morkHandle::GetGoodHandleObject(morkEnv* ev,
else
this->NewDownHandleError(ev);
MORK_ASSERT(outObject);
MORK_ASSERT(outObject || inClosedOkay);
return outObject;
}
morkEnv*
morkHandle::CanUseHandle(nsIMdbEnv* mev, mork_bool inMutable,
mdb_err* outErr) const
mork_bool inClosedOkay, mdb_err* outErr) const
{
morkEnv* outEnv = 0;
morkEnv* ev = morkEnv::FromMdbEnv(mev);
if ( ev )
{
morkObject* obj = this->GetGoodHandleObject(ev, inMutable, /*magic*/ 0);
morkObject* obj = this->GetGoodHandleObject(ev, inMutable,
/*magic*/ 0, inClosedOkay);
if ( obj )
{
outEnv = ev;
}
*outErr = ev->AsErr();
}
MORK_ASSERT(outEnv);
MORK_ASSERT(outEnv || inClosedOkay);
return outEnv;
}
@ -238,15 +240,20 @@ morkHandle::CanUseHandle(nsIMdbEnv* mev, mork_bool inMutable,
morkHandle::Handle_IsFrozenMdbObject(nsIMdbEnv* mev, mdb_bool* outIsReadonly)
{
mdb_err outErr = 0;
mdb_bool readOnly = mdbBool_kTrue;
morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse, &outErr);
morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse,
/*inClosedOkay*/ morkBool_kTrue, &outErr);
if ( ev )
{
MORK_ASSERT(outIsReadonly);
if ( outIsReadonly )
*outIsReadonly = mHandle_Object->IsFrozen();
readOnly = mHandle_Object->IsFrozen();
outErr = ev->AsErr();
}
MORK_ASSERT(outIsReadonly);
if ( outIsReadonly )
*outIsReadonly = readOnly;
return outErr;
}
// same as nsIMdbPort::GetIsPortReadonly() when this object is inside a port.
@ -257,23 +264,27 @@ morkHandle::Handle_IsFrozenMdbObject(nsIMdbEnv* mev, mdb_bool* outIsReadonly)
morkHandle::Handle_GetMdbFactory(nsIMdbEnv* mev, nsIMdbFactory** acqFactory)
{
mdb_err outErr = 0;
nsIMdbFactory* handle = 0;
morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse, &outErr);
morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse,
/*inClosedOkay*/ morkBool_kTrue, &outErr);
if ( ev )
{
morkFactory* factory = ev->mEnv_Factory;
if ( factory )
{
nsIMdbFactory* handle = factory->AcquireFactoryHandle(ev);
MORK_ASSERT(acqFactory);
if ( handle && acqFactory )
*acqFactory = handle;
handle = factory->AcquireFactoryHandle(ev);
}
else
this->NilFactoryError(ev);
outErr = ev->AsErr();
}
MORK_ASSERT(acqFactory);
if ( acqFactory )
*acqFactory = handle;
return outErr;
}
// } ----- end factory methods -----
@ -284,16 +295,19 @@ morkHandle::Handle_GetWeakRefCount(nsIMdbEnv* mev, // weak refs
mdb_count* outCount)
{
mdb_err outErr = 0;
mdb_count count = 0;
morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse, &outErr);
morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse,
/*inClosedOkay*/ morkBool_kTrue, &outErr);
if ( ev )
{
MORK_ASSERT(outCount);
if ( outCount )
*outCount = this->WeakRefsOnly();
count = this->WeakRefsOnly();
outErr = ev->AsErr();
}
MORK_ASSERT(outCount);
if ( outCount )
*outCount = count;
return outErr;
}
@ -302,16 +316,19 @@ morkHandle::Handle_GetStrongRefCount(nsIMdbEnv* mev, // strong refs
mdb_count* outCount)
{
mdb_err outErr = 0;
mdb_count count = 0;
morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse, &outErr);
morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse,
/*inClosedOkay*/ morkBool_kTrue, &outErr);
if ( ev )
{
MORK_ASSERT(outCount);
if ( outCount )
*outCount = this->StrongRefsOnly();
count = this->StrongRefsOnly();
outErr = ev->AsErr();
}
MORK_ASSERT(outCount);
if ( outCount )
*outCount = count;
return outErr;
}
@ -321,7 +338,8 @@ morkHandle::Handle_AddWeakRef(nsIMdbEnv* mev)
{
mdb_err outErr = 0;
morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse, &outErr);
morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse,
/*inClosedOkay*/ morkBool_kTrue, &outErr);
if ( ev )
{
this->AddWeakRef(ev);
@ -335,7 +353,8 @@ morkHandle::Handle_AddStrongRef(nsIMdbEnv* mev)
{
mdb_err outErr = 0;
morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse, &outErr);
morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse,
/*inClosedOkay*/ morkBool_kFalse, &outErr);
if ( ev )
{
this->AddStrongRef(ev);
@ -350,7 +369,8 @@ morkHandle::Handle_CutWeakRef(nsIMdbEnv* mev)
{
mdb_err outErr = 0;
morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse, &outErr);
morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse,
/*inClosedOkay*/ morkBool_kTrue, &outErr);
if ( ev )
{
this->CutWeakRef(ev);
@ -363,7 +383,8 @@ morkHandle::Handle_CutWeakRef(nsIMdbEnv* mev)
morkHandle::Handle_CutStrongRef(nsIMdbEnv* mev)
{
mdb_err outErr = 0;
morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse, &outErr);
morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse,
/*inClosedOkay*/ morkBool_kTrue, &outErr);
if ( ev )
{
this->CutStrongRef(ev);
@ -380,7 +401,8 @@ morkHandle::Handle_CloseMdbObject(nsIMdbEnv* mev)
if ( this->IsNode() && this->IsOpenNode() )
{
morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse, &outErr);
morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse,
/*inClosedOkay*/ morkBool_kTrue, &outErr);
if ( ev )
{
morkObject* object = mHandle_Object;

Просмотреть файл

@ -118,12 +118,12 @@ public: // other handle methods
void NonOpenObjectError(morkEnv* ev) const;
morkObject* GetGoodHandleObject(morkEnv* ev,
mork_bool inMutabl, mork_magic inMagicType) const;
mork_bool inMutable, mork_magic inMagicType, mork_bool inClosedOkay) const;
public: // interface supporting mdbObject methods
morkEnv* CanUseHandle(nsIMdbEnv* mev, mork_bool inMutable,
mdb_err* outErr) const;
mork_bool inClosedOkay, mdb_err* outErr) const;
// { ----- begin mdbObject style methods -----
mdb_err Handle_IsFrozenMdbObject(nsIMdbEnv* ev, mdb_bool* outIsReadonly);

Просмотреть файл

@ -342,6 +342,30 @@ morkNode::CloseNode(morkEnv* ev) // called by CloseMorkNode();
}
extern void // utility method very similar to morkNode::SlotStrongNode():
nsIMdbCompare_SlotStrongCompare(nsIMdbCompare* self, morkEnv* ev,
nsIMdbCompare** ioSlot)
// If *ioSlot is non-nil, that compare is released by CutStrongRef() and
// then zeroed out. Then if self is non-nil, this is acquired by
// calling AddStrongRef(), and if the return value shows success,
// then self is put into slot *ioSlot. Note self can be nil, so we take
// expression 'nsIMdbCompare_SlotStrongCompare(0, ev, &slot)'.
{
nsIMdbEnv* menv = ev->AsMdbEnv();
nsIMdbCompare* compare = *ioSlot;
if ( self != compare )
{
if ( compare )
{
*ioSlot = 0;
compare->CutStrongRef(menv);
}
if ( self && ev->Good() && (self->AddStrongRef(menv)==0) && ev->Good() )
*ioSlot = self;
}
}
extern void // utility method very similar to morkNode::SlotStrongNode():
nsIMdbFile_SlotStrongFile(nsIMdbFile* self, morkEnv* ev, nsIMdbFile** ioSlot)
// If *ioSlot is non-nil, that file is released by CutStrongRef() and
@ -352,13 +376,16 @@ nsIMdbFile_SlotStrongFile(nsIMdbFile* self, morkEnv* ev, nsIMdbFile** ioSlot)
{
nsIMdbEnv* menv = ev->AsMdbEnv();
nsIMdbFile* file = *ioSlot;
if ( file )
if ( self != file )
{
*ioSlot = 0;
file->CutStrongRef(menv);
if ( file )
{
*ioSlot = 0;
file->CutStrongRef(menv);
}
if ( self && ev->Good() && (self->AddStrongRef(menv)==0) && ev->Good() )
*ioSlot = self;
}
if ( self && ev->Good() && (self->AddStrongRef(menv)==0) && ev->Good() )
*ioSlot = self;
}
void // utility method very similar to morkNode::SlotStrongNode():
@ -371,13 +398,16 @@ nsIMdbHeap_SlotStrongHeap(nsIMdbHeap* self, morkEnv* ev, nsIMdbHeap** ioSlot)
{
nsIMdbEnv* menv = ev->AsMdbEnv();
nsIMdbHeap* heap = *ioSlot;
if ( heap )
if ( self != heap )
{
*ioSlot = 0;
heap->CutStrongRef(menv);
if ( heap )
{
*ioSlot = 0;
heap->CutStrongRef(menv);
}
if ( self && ev->Good() && (self->AddStrongRef(menv)==0) && ev->Good() )
*ioSlot = self;
}
if ( self && ev->Good() && (self->AddStrongRef(menv)==0) && ev->Good() )
*ioSlot = self;
}
/*public static*/ void

Просмотреть файл

@ -275,7 +275,16 @@ nsIMdbFile_SlotStrongFile(nsIMdbFile* self, morkEnv* ev, nsIMdbFile** ioSlot);
// then zeroed out. Then if self is non-nil, this is acquired by
// calling AddStrongRef(), and if the return value shows success,
// then self is put into slot *ioSlot. Note self can be nil, so we take
// expression 'nsIMdbHeap_SlotStrongFile(0, ev, &slot)'.
// expression 'nsIMdbFile_SlotStrongFile(0, ev, &slot)'.
extern void // utility method very similar to morkNode::SlotStrongNode():
nsIMdbCompare_SlotStrongCompare(nsIMdbCompare* self, morkEnv* ev,
nsIMdbCompare** ioSlot);
// If *ioSlot is non-nil, that compare is released by CutStrongRef() and
// then zeroed out. Then if self is non-nil, this is acquired by
// calling AddStrongRef(), and if the return value shows success,
// then self is put into slot *ioSlot. Note self can be nil, so we take
// expression 'nsIMdbCompare_SlotStrongCompare(0, ev, &slot)'.
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789

Просмотреть файл

@ -56,9 +56,9 @@
#include "morkNodeMap.h"
#endif
#ifndef _MORKFILE_
#include "morkFile.h"
#endif
// #ifndef _MORKFILE_
// #include "morkFile.h"
// #endif
#ifndef _MORKBUILDER_
#include "morkBuilder.h"
@ -246,9 +246,13 @@ morkStore::CloseStore(morkEnv* ev) // called by CloseMorkNode();
{
if ( this->IsNode() )
{
morkFile* file = mStore_File;
if ( file && file->IsOpenNode() )
file->CloseMorkNode(ev);
// morkFile* file = mStore_File;
// if ( file && file->IsOpenNode() )
// file->CloseMorkNode(ev);
nsIMdbFile* file = mStore_File;
if ( file )
file->CloseMdbObject(ev->AsMdbEnv());
morkAtomSpace::SlotStrongAtomSpace((morkAtomSpace*) 0, ev,
&mStore_OidAtomSpace);
@ -259,7 +263,11 @@ morkStore::CloseStore(morkEnv* ev) // called by CloseMorkNode();
mStore_RowSpaces.CloseMorkNode(ev);
mStore_AtomSpaces.CloseMorkNode(ev);
morkBuilder::SlotStrongBuilder((morkBuilder*) 0, ev, &mStore_Builder);
morkFile::SlotStrongFile((morkFile*) 0, ev, &mStore_File);
// morkFile::SlotStrongFile((morkFile*) 0, ev, &mStore_File);
nsIMdbFile_SlotStrongFile((nsIMdbFile*) 0, ev,
&mStore_File);
morkStream::SlotStrongStream((morkStream*) 0, ev, &mStore_InStream);
morkStream::SlotStrongStream((morkStream*) 0, ev, &mStore_OutStream);
@ -277,10 +285,27 @@ morkStore::CloseStore(morkEnv* ev) // called by CloseMorkNode();
// } ===== end morkNode methods =====
// ````` ````` ````` ````` `````
mork_bool morkStore::DoPreferLargeOverCompressCommit(morkEnv* ev)
// true when mStore_CanWriteIncremental && store has file large enough
{
nsIMdbFile* file = mStore_File;
nsIMdbEnv* menv = ev->AsMdbEnv();
if ( file && mStore_CanWriteIncremental )
{
mdb_pos fileEof = 0;
file->Eof(ev->AsMdbEnv(), &fileEof);
if ( ev->Good() && fileEof > 128 )
return morkBool_kTrue;
}
return morkBool_kFalse;
}
mork_percent morkStore::PercentOfStoreWasted(morkEnv* ev)
{
mork_percent outPercent = 0;
morkFile* file = mStore_File;
nsIMdbFile* file = mStore_File;
nsIMdbEnv* menv = ev->AsMdbEnv();
if ( file )
{
@ -291,7 +316,8 @@ mork_percent morkStore::PercentOfStoreWasted(morkEnv* ev)
if ( firstPos < 512 && secondPos > firstPos )
firstPos = secondPos; // better approximation of first commit
mork_pos fileLength = file->Length(ev); // end of file
mork_pos fileLength = 0;
file->Eof(ev->AsMdbEnv(), &fileLength); // end of file
if ( ev->Good() && fileLength > firstPos )
{
mork_size groupContent = fileLength - firstPos;
@ -501,7 +527,7 @@ morkStream* morkStore::LazyGetInStream(morkEnv* ev)
{
if ( !mStore_InStream )
{
morkFile* file = mStore_File;
nsIMdbFile* file = mStore_File;
if ( file )
{
morkStream* stream = new(*mPort_Heap, ev)
@ -523,7 +549,7 @@ morkStream* morkStore::LazyGetOutStream(morkEnv* ev)
{
if ( !mStore_OutStream )
{
morkFile* file = mStore_File;
nsIMdbFile* file = mStore_File;
if ( file )
{
morkStream* stream = new(*mPort_Heap, ev)
@ -643,43 +669,38 @@ morkStore::CannotAutoAssignAtomIdentityError(morkEnv* ev)
mork_bool
morkStore::OpenStoreFile(morkEnv* ev, mork_bool inFrozen,
const char* inFilePath, const mdbOpenPolicy* inOpenPolicy)
// const char* inFilePath,
nsIMdbFile* ioFile, // db abstract file interface
const mdbOpenPolicy* inOpenPolicy)
{
MORK_USED_1(inOpenPolicy);
morkFile::SlotStrongFile((morkFile*) 0, ev, &mStore_File);
if ( ev->Good() )
{
morkFile* file = morkFile::OpenOldFile(ev, mPort_Heap,
inFilePath, inFrozen);
if ( file )
{
if ( ev->Good() )
morkFile::SlotStrongFile(file, ev, &mStore_File);
else
file->CutStrongRef(ev);
}
}
MORK_USED_2(inOpenPolicy,inFrozen);
nsIMdbFile_SlotStrongFile(ioFile, ev, &mStore_File);
// if ( ev->Good() )
// {
// morkFile* file = morkFile::OpenOldFile(ev, mPort_Heap,
// inFilePath, inFrozen);
// if ( ioFile )
// {
// if ( ev->Good() )
// morkFile::SlotStrongFile(file, ev, &mStore_File);
// else
// file->CutStrongRef(ev);
//
// }
// }
return ev->Good();
}
mork_bool
morkStore::CreateStoreFile(morkEnv* ev,
const char* inFilePath, const mdbOpenPolicy* inOpenPolicy)
// const char* inFilePath,
nsIMdbFile* ioFile, // db abstract file interface
const mdbOpenPolicy* inOpenPolicy)
{
MORK_USED_1(inOpenPolicy);
morkFile::SlotStrongFile((morkFile*) 0, ev, &mStore_File);
if ( ev->Good() )
{
morkFile* file = morkFile::CreateNewFile(ev, mPort_Heap,
inFilePath);
if ( file )
{
if ( ev->Good() )
morkFile::SlotStrongFile(file, ev, &mStore_File);
else
file->CutStrongRef(ev);
}
}
nsIMdbFile_SlotStrongFile(ioFile, ev, &mStore_File);
return ev->Good();
}

Просмотреть файл

@ -155,7 +155,7 @@ public: // state is public because the entire Mork system is private
morkAtomSpace* mStore_GroundAtomSpace; // ground atom space for scopes
morkAtomSpace* mStore_GroundColumnSpace; // ground column space for scopes
morkFile* mStore_File; // the file containing Mork text
nsIMdbFile* mStore_File; // the file containing Mork text
morkStream* mStore_InStream; // stream using file used by the builder
morkBuilder* mStore_Builder; // to parse Mork text and build structures
@ -246,6 +246,11 @@ public: // building an atom inside mStore_BookAtom from a char* string
// inString. This method is the standard way to stage a string as an
// atom for searching or adding new atoms into an atom space hash table.
public: // determining whether incremental writing is a good use of time:
mork_bool DoPreferLargeOverCompressCommit(morkEnv* ev);
// true when mStore_CanWriteIncremental && store has file large enough
public: // lazy creation of members and nested row or atom spaces
morkAtomSpace* LazyGetOidAtomSpace(morkEnv* ev);
@ -304,11 +309,13 @@ public: // other store methods
mork_bool OpenStoreFile(morkEnv* ev, // return value equals ev->Good()
mork_bool inFrozen,
const char* inFilePath,
// const char* inFilePath,
nsIMdbFile* ioFile, // db abstract file interface
const mdbOpenPolicy* inOpenPolicy);
mork_bool CreateStoreFile(morkEnv* ev, // return value equals ev->Good()
const char* inFilePath,
// const char* inFilePath,
nsIMdbFile* ioFile, // db abstract file interface
const mdbOpenPolicy* inOpenPolicy);
morkAtom* CopyAtom(morkEnv* ev, const morkAtom* inAtom);

Просмотреть файл

@ -66,7 +66,7 @@ morkStream::~morkStream() // assert CloseStream() executed earlier
/*public non-poly*/
morkStream::morkStream(morkEnv* ev, const morkUsage& inUsage,
nsIMdbHeap* ioHeap,
morkFile* ioContentFile, mork_size inBufSize, mork_bool inFrozen)
nsIMdbFile* ioContentFile, mork_size inBufSize, mork_bool inFrozen)
: morkFile(ev, inUsage, ioHeap, ioHeap)
, mStream_At( 0 )
, mStream_ReadEnd( 0 )
@ -89,12 +89,10 @@ morkStream::morkStream(morkEnv* ev, const morkUsage& inUsage,
if ( ioContentFile && ioHeap )
{
if ( ioContentFile->FileFrozen() ) // forced to be readonly?
inFrozen = morkBool_kTrue; // override the input value
// if ( ioContentFile->FileFrozen() ) // forced to be readonly?
// inFrozen = morkBool_kTrue; // override the input value
mork_pos fileEnd = ioContentFile->Length(ev);
morkFile::SlotStrongFile(ioContentFile, ev, &mStream_ContentFile);
nsIMdbFile_SlotStrongFile(ioContentFile, ev, &mStream_ContentFile);
if ( ev->Good() )
{
mork_u1* buf = 0;
@ -138,7 +136,7 @@ morkStream::CloseStream(morkEnv* ev) // called by CloseMorkNode();
{
if ( this->IsNode() )
{
morkFile::SlotStrongFile((morkFile*) 0, ev, &mStream_ContentFile);
nsIMdbFile_SlotStrongFile((nsIMdbFile*) 0, ev, &mStream_ContentFile);
nsIMdbHeap* heap = mFile_SlotHeap;
mork_u1* buf = mStream_Buf;
mStream_Buf = 0;
@ -401,7 +399,7 @@ morkStream::AcquireBud(morkEnv* ev, nsIMdbHeap* ioHeap)
{
MORK_USED_1(ioHeap);
morkFile* outFile = 0;
morkFile* file = mStream_ContentFile;
nsIMdbFile* file = mStream_ContentFile;
if ( this->IsOpenAndActiveFile() && file )
{
// figure out how this interacts with buffering and mStream_WriteEnd:
@ -417,31 +415,35 @@ morkStream::Length(morkEnv* ev) const // eof
{
mork_pos outPos = 0;
morkFile* file = mStream_ContentFile;
nsIMdbFile* file = mStream_ContentFile;
if ( this->IsOpenAndActiveFile() && file )
{
mork_pos contentEof = file->Length(ev);
if ( mStream_WriteEnd ) // this stream supports writing?
mork_pos contentEof = 0;
nsIMdbEnv* menv = ev->AsMdbEnv();
file->Eof(menv, &contentEof);
if ( ev->Good() )
{
// the local buffer might have buffered content past content eof
if ( ev->Good() ) // no error happened during Length() above?
if ( mStream_WriteEnd ) // this stream supports writing?
{
mork_u1* at = mStream_At;
mork_u1* buf = mStream_Buf;
if ( at >= buf ) // expected cursor order?
// the local buffer might have buffered content past content eof
if ( ev->Good() ) // no error happened during Length() above?
{
mork_pos localContent = mStream_BufPos + (at - buf);
if ( localContent > contentEof ) // buffered past eof?
contentEof = localContent; // return new logical eof
mork_u1* at = mStream_At;
mork_u1* buf = mStream_Buf;
if ( at >= buf ) // expected cursor order?
{
mork_pos localContent = mStream_BufPos + (at - buf);
if ( localContent > contentEof ) // buffered past eof?
contentEof = localContent; // return new logical eof
outPos = contentEof;
outPos = contentEof;
}
else this->NewBadCursorOrderError(ev);
}
else this->NewBadCursorOrderError(ev);
}
else
outPos = contentEof; // frozen files get length from content file
}
else
outPos = contentEof; // frozen files get length from content file
}
else this->NewFileDownError(ev);
@ -471,7 +473,7 @@ morkStream::Tell(morkEnv* ev) const
{
mork_pos outPos = 0;
morkFile* file = mStream_ContentFile;
nsIMdbFile* file = mStream_ContentFile;
if ( this->IsOpenAndActiveFile() && file )
{
mork_u1* buf = mStream_Buf;
@ -512,7 +514,7 @@ morkStream::Read(morkEnv* ev, void* outBuf, mork_size inSize)
mork_pos outActual = 0;
morkFile* file = mStream_ContentFile;
nsIMdbFile* file = mStream_ContentFile;
if ( this->IsOpenAndActiveFile() && file )
{
mork_u1* end = mStream_ReadEnd; // byte after last buffered byte
@ -558,21 +560,24 @@ morkStream::Read(morkEnv* ev, void* outBuf, mork_size inSize)
mStream_At = mStream_ReadEnd = buf; // empty buffer
file->Seek(ev, mStream_BufPos); // set file pos
if ( ev->Good() ) // no seek error?
// file->Seek(ev, mStream_BufPos); // set file pos
// if ( ev->Good() ) // no seek error?
// {
// }
mork_num actual = 0;
nsIMdbEnv* menv = ev->AsMdbEnv();
file->Get(menv, sink, inSize, mStream_BufPos, &actual);
if ( ev->Good() ) // no read error?
{
mork_num actual = file->Read(ev, sink, inSize);
if ( ev->Good() ) // no read error?
if ( actual )
{
if ( actual )
{
outActual += actual;
mStream_BufPos += actual;
mStream_HitEof = morkBool_kFalse;
}
else if ( !outActual )
mStream_HitEof = morkBool_kTrue;
outActual += actual;
mStream_BufPos += actual;
mStream_HitEof = morkBool_kFalse;
}
else if ( !outActual )
mStream_HitEof = morkBool_kTrue;
}
}
}
@ -596,7 +601,7 @@ morkStream::Seek(morkEnv* ev, mork_pos inPos)
{
mork_pos outPos = 0;
morkFile* file = mStream_ContentFile;
nsIMdbFile* file = mStream_ContentFile;
if ( this->IsOpenOrClosingNode() && this->FileActive() && file )
{
mork_u1* at = mStream_At; // current position in buffer
@ -615,7 +620,9 @@ morkStream::Seek(morkEnv* ev, mork_pos inPos)
{
if ( mStream_BufPos != inPos ) // need to change pos?
{
mork_pos eof = file->Length(ev);
mork_pos eof = 0;
nsIMdbEnv* menv = ev->AsMdbEnv();
file->Eof(menv, &eof);
if ( ev->Good() ) // no errors getting length?
{
if ( inPos <= eof ) // acceptable new position?
@ -634,7 +641,9 @@ morkStream::Seek(morkEnv* ev, mork_pos inPos)
{
if ( at >= buf && at <= readEnd ) // expected cursor order?
{
mork_pos eof = file->Length(ev);
mork_pos eof = 0;
nsIMdbEnv* menv = ev->AsMdbEnv();
file->Eof(menv, &eof);
if ( ev->Good() ) // no errors getting length?
{
if ( inPos <= eof ) // acceptable new position?
@ -662,7 +671,7 @@ morkStream::Write(morkEnv* ev, const void* inBuf, mork_size inSize)
{
mork_num outActual = 0;
morkFile* file = mStream_ContentFile;
nsIMdbFile* file = mStream_ContentFile;
if ( this->IsOpenActiveAndMutableFile() && file )
{
mork_u1* end = mStream_WriteEnd; // byte after last buffered byte
@ -725,17 +734,18 @@ morkStream::Write(morkEnv* ev, const void* inBuf, mork_size inSize)
}
else // directly to content file instead
{
file->Seek(ev, mStream_BufPos); // set pos
if ( ev->Good() ) // no seek error?
// file->Seek(ev, mStream_BufPos); // set pos
// if ( ev->Good() ) // no seek error?
// {
// }
nsIMdbEnv* menv = ev->AsMdbEnv();
mork_num actual = 0;
file->Put(menv, source, inSize, mStream_BufPos, &actual);
if ( ev->Good() ) // no write error?
{
mork_num actual =
file->Write(ev, source, inSize);
if ( ev->Good() ) // no write error?
{
outActual += actual;
mStream_BufPos += actual;
}
outActual += actual;
mStream_BufPos += actual;
}
}
}
@ -759,12 +769,13 @@ morkStream::Write(morkEnv* ev, const void* inBuf, mork_size inSize)
/*public virtual*/ void
morkStream::Flush(morkEnv* ev)
{
morkFile* file = mStream_ContentFile;
nsIMdbFile* file = mStream_ContentFile;
if ( this->IsOpenOrClosingNode() && this->FileActive() && file )
{
if ( mStream_Dirty )
this->spill_buf(ev);
file->Flush(ev);
file->Flush(ev->AsMdbEnv());
}
else this->NewFileDownError(ev);
}
@ -777,7 +788,7 @@ morkStream::fill_getc(morkEnv* ev)
{
int c = EOF;
morkFile* file = mStream_ContentFile;
nsIMdbFile* file = mStream_ContentFile;
if ( this->IsOpenAndActiveFile() && file )
{
mork_u1* buf = mStream_Buf;
@ -789,25 +800,28 @@ morkStream::fill_getc(morkEnv* ev)
if ( ev->Good() ) // no errors yet?
{
file->Seek(ev, mStream_BufPos); // set file pos
if ( ev->Good() ) // no seek error?
// file->Seek(ev, mStream_BufPos); // set file pos
// if ( ev->Good() ) // no seek error?
// {
// }
nsIMdbEnv* menv = ev->AsMdbEnv();
mork_num actual = 0;
file->Get(menv, buf, mStream_BufSize, mStream_BufPos, &actual);
if ( ev->Good() ) // no read errors?
{
mork_num actual = file->Read(ev, buf, mStream_BufSize);
if ( ev->Good() ) // no read errors?
if ( actual > mStream_BufSize ) // more than asked for??
actual = mStream_BufSize;
mStream_At = buf;
mStream_ReadEnd = buf + actual;
if ( actual ) // any bytes actually read?
{
if ( actual > mStream_BufSize ) // more than asked for??
actual = mStream_BufSize;
mStream_At = buf;
mStream_ReadEnd = buf + actual;
if ( actual ) // any bytes actually read?
{
c = *mStream_At++; // return first byte from buffer
mStream_HitEof = morkBool_kFalse;
}
else
mStream_HitEof = morkBool_kTrue;
c = *mStream_At++; // return first byte from buffer
mStream_HitEof = morkBool_kFalse;
}
else
mStream_HitEof = morkBool_kTrue;
}
}
}
@ -827,7 +841,7 @@ morkStream::spill_putc(morkEnv* ev, int c)
void
morkStream::spill_buf(morkEnv* ev) // spill/flush from buffer to file
{
morkFile* file = mStream_ContentFile;
nsIMdbFile* file = mStream_ContentFile;
if ( this->IsOpenOrClosingNode() && this->FileActive() && file )
{
mork_u1* buf = mStream_Buf;
@ -847,16 +861,19 @@ morkStream::spill_buf(morkEnv* ev) // spill/flush from buffer to file
}
if ( ev->Good() )
{
file->Seek(ev, mStream_BufPos);
// file->Seek(ev, mStream_BufPos);
// if ( ev->Good() )
// {
// }
nsIMdbEnv* menv = ev->AsMdbEnv();
mork_num actual = 0;
file->Put(menv, buf, count, mStream_BufPos, &actual);
if ( ev->Good() )
{
file->Write(ev, buf, count);
if ( ev->Good() )
{
mStream_BufPos += count; // past bytes written
mStream_At = buf; // reset buffer cursor
mStream_Dirty = morkBool_kFalse;
}
mStream_BufPos += actual; // past bytes written
mStream_At = buf; // reset buffer cursor
mStream_Dirty = morkBool_kFalse;
}
}
}

Просмотреть файл

@ -83,7 +83,7 @@ protected: // protected morkStream members
mork_u1* mStream_ReadEnd; // null or one byte past last readable byte
mork_u1* mStream_WriteEnd; // null or mStream_Buf + mStream_BufSize
morkFile* mStream_ContentFile; // where content is read and written
nsIMdbFile* mStream_ContentFile; // where content is read and written
mork_u1* mStream_Buf; // dynamically allocated memory to buffer io
mork_size mStream_BufSize; // requested buf size (fixed by min and max)
@ -98,7 +98,7 @@ public: // morkNode virtual methods
public: // morkStream construction & destruction
morkStream(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioHeap,
morkFile* ioContentFile, mork_size inBufSize, mork_bool inFrozen);
nsIMdbFile* ioContentFile, mork_size inBufSize, mork_bool inFrozen);
void CloseStream(morkEnv* ev); // called by CloseMorkNode();
private: // copying is not allowed
@ -172,7 +172,7 @@ public: // public non-poly morkStream methods
void NewCantWriteSourceError(morkEnv* ev) const;
void NewPosBeyondEofError(morkEnv* ev) const;
morkFile* GetStreamContentFile() const { return mStream_ContentFile; }
nsIMdbFile* GetStreamContentFile() const { return mStream_ContentFile; }
mork_size GetStreamBufferSize() const { return mStream_BufSize; }
mork_size PutIndent(morkEnv* ev, mork_count inDepth);

Просмотреть файл

@ -129,6 +129,13 @@ morkTableRowCursor::NonTableRowCursorTypeError(morkEnv* ev)
ev->NewError("non morkTableRowCursor");
}
orkinTableRowCursor*
morkTableRowCursor::AcquireUniqueRowCursorHandle(morkEnv* ev)
{
return this->AcquireTableRowCursorHandle(ev);
}
orkinTableRowCursor*
morkTableRowCursor::AcquireTableRowCursorHandle(morkEnv* ev)
{
@ -154,6 +161,23 @@ morkTableRowCursor::NextRowOid(morkEnv* ev, mdbOid* outOid)
return outPos;
}
mork_bool
morkTableRowCursor::CanHaveDupRowMembers(morkEnv* ev)
{
return morkBool_kFalse; // false default is correct
}
mork_count
morkTableRowCursor::GetMemberCount(morkEnv* ev)
{
morkTable* table = mTableRowCursor_Table;
if ( table )
return table->mTable_RowArray.mArray_Fill;
else
return 0;
}
morkRow*
morkTableRowCursor::NextRow(morkEnv* ev, mdbOid* outOid, mdb_pos* outPos)
{

Просмотреть файл

@ -81,12 +81,20 @@ public: // dynamic type identification
public: // typing
static void NonTableRowCursorTypeError(morkEnv* ev);
public: // handle attachment
orkinTableRowCursor* AcquireTableRowCursorHandle(morkEnv* ev);
public: // oid only iteration
mdb_pos NextRowOid(morkEnv* ev, mdbOid* outOid);
public: // other table row cursor methods
orkinTableRowCursor* AcquireTableRowCursorHandle(morkEnv* ev);
virtual mork_bool CanHaveDupRowMembers(morkEnv* ev);
virtual mork_count GetMemberCount(morkEnv* ev);
virtual orkinTableRowCursor* AcquireUniqueRowCursorHandle(morkEnv* ev);
mdb_pos NextRowOid(morkEnv* ev, mdbOid* outOid);
morkRow* NextRow(morkEnv* ev, mdbOid* outOid, mdb_pos* outPos);
virtual morkRow* NextRow(morkEnv* ev, mdbOid* outOid, mdb_pos* outPos);
public: // typesafe refcounting inlines calling inherited morkNode methods
static void SlotWeakTableRowCursor(morkTableRowCursor* me,

Просмотреть файл

@ -44,9 +44,9 @@
#include "morkStore.h"
#endif
#ifndef _MORKFILE_
#include "morkFile.h"
#endif
// #ifndef _MORKFILE_
// #include "morkFile.h"
// #endif
#ifndef _MORKWRITER_
#include "morkWriter.h"
@ -60,10 +60,6 @@
#include "morkBuilder.h"
#endif
#ifndef _MORKFILE_
#include "morkFile.h"
#endif
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
// ````` ````` ````` ````` `````
@ -134,7 +130,7 @@ morkThumb::CloseThumb(morkEnv* ev) // called by CloseMorkNode();
morkBuilder::SlotStrongBuilder((morkBuilder*) 0, ev, &mThumb_Builder);
morkWriter::SlotStrongWriter((morkWriter*) 0, ev, &mThumb_Writer);
morkFile::SlotStrongFile((morkFile*) 0, ev, &mThumb_File);
nsIMdbFile_SlotStrongFile((nsIMdbFile*) 0, ev, &mThumb_File);
morkStore::SlotStrongStore((morkStore*) 0, ev, &mThumb_Store);
morkPort::SlotStrongPort((morkPort*) 0, ev, &mThumb_SourcePort);
this->MarkShut();
@ -208,10 +204,11 @@ morkThumb::Make_OpenFileStore(morkEnv* ev, nsIMdbHeap* ioHeap,
morkThumb* outThumb = 0;
if ( ioHeap && ioStore )
{
morkFile* file = ioStore->mStore_File;
nsIMdbFile* file = ioStore->mStore_File;
if ( file )
{
mork_pos fileEof = file->Length(ev);
mork_pos fileEof = 0;
file->Eof(ev->AsMdbEnv(), &fileEof);
if ( ev->Good() )
{
outThumb = new(*ioHeap, ev)
@ -248,7 +245,7 @@ morkThumb::Make_LargeCommit(morkEnv* ev,
morkThumb* outThumb = 0;
if ( ioHeap && ioStore )
{
morkFile* file = ioStore->mStore_File;
nsIMdbFile* file = ioStore->mStore_File;
if ( file )
{
outThumb = new(*ioHeap, ev)
@ -266,10 +263,10 @@ morkThumb::Make_LargeCommit(morkEnv* ev,
writer->mWriter_NeedDirtyAll = morkBool_kFalse;
outThumb->mThumb_DoCollect = morkBool_kFalse;
morkStore::SlotStrongStore(ioStore, ev, &outThumb->mThumb_Store);
morkFile::SlotStrongFile(file, ev, &outThumb->mThumb_File);
morkWriter::SlotStrongWriter(writer, ev, &outThumb->mThumb_Writer);
// writer no longer holds on to this.
writer->CutStrongRef(ev);
nsIMdbFile_SlotStrongFile(file, ev, &outThumb->mThumb_File);
outThumb->mThumb_Writer = writer; // pass writer ownership to thumb
}
}
}
@ -289,7 +286,7 @@ morkThumb::Make_CompressCommit(morkEnv* ev,
morkThumb* outThumb = 0;
if ( ioHeap && ioStore )
{
morkFile* file = ioStore->mStore_File;
nsIMdbFile* file = ioStore->mStore_File;
if ( file )
{
outThumb = new(*ioHeap, ev)
@ -305,7 +302,7 @@ morkThumb::Make_CompressCommit(morkEnv* ev,
writer->mWriter_NeedDirtyAll = morkBool_kTrue;
outThumb->mThumb_DoCollect = inDoCollect;
morkStore::SlotStrongStore(ioStore, ev, &outThumb->mThumb_Store);
morkFile::SlotStrongFile(file, ev, &outThumb->mThumb_File);
nsIMdbFile_SlotStrongFile(file, ev, &outThumb->mThumb_File);
morkWriter::SlotStrongWriter(writer, ev, &outThumb->mThumb_Writer);
// cope with fact that parsed transaction groups are going away:

Просмотреть файл

@ -82,7 +82,7 @@ public: // state is public because the entire Mork system is private
mork_u2 mThumb_Seed; // optional seed for u4 alignment padding
morkStore* mThumb_Store; // weak ref to created store
morkFile* mThumb_File; // strong ref to file (store, import, export)
nsIMdbFile* mThumb_File; // strong ref to file (store, import, export)
morkWriter* mThumb_Writer; // strong ref to writer (for commit)
morkBuilder* mThumb_Builder; // strong ref to builder (for store open)
morkPort* mThumb_SourcePort; // strong ref to port for import

Просмотреть файл

@ -40,9 +40,9 @@
#include "morkWriter.h"
#endif
#ifndef _MORKFILE_
#include "morkFile.h"
#endif
// #ifndef _MORKFILE_
// #include "morkFile.h"
// #endif
#ifndef _MORKSTREAM_
#include "morkStream.h"
@ -113,7 +113,7 @@ morkWriter::~morkWriter() // assert CloseTable() executed earlier
/*public non-poly*/
morkWriter::morkWriter(morkEnv* ev, const morkUsage& inUsage,
nsIMdbHeap* ioHeap, morkStore* ioStore, morkFile* ioFile,
nsIMdbHeap* ioHeap, morkStore* ioStore, nsIMdbFile* ioFile,
nsIMdbHeap* ioSlotHeap)
: morkNode(ev, inUsage, ioHeap)
, mWriter_Store( 0 )
@ -194,7 +194,7 @@ morkWriter::morkWriter(morkEnv* ev, const morkUsage& inUsage,
if ( ioSlotHeap && ioFile && ioStore )
{
morkStore::SlotWeakStore(ioStore, ev, &mWriter_Store);
morkFile::SlotStrongFile(ioFile, ev, &mWriter_File);
nsIMdbFile_SlotStrongFile(ioFile, ev, &mWriter_File);
nsIMdbHeap_SlotStrongHeap(ioSlotHeap, ev, &mWriter_SlotHeap);
if ( ev->Good() )
{
@ -228,7 +228,8 @@ morkWriter::MakeWriterStream(morkEnv* ev) // give writer a suitable stream
}
else // compress commit
{
morkFile* bud = mWriter_File->AcquireBud(ev, heap);
nsIMdbFile* bud = 0;
mWriter_File->AcquireBud(ev->AsMdbEnv(), heap, &bud);
if ( bud )
{
if ( ev->Good() )
@ -239,7 +240,7 @@ morkWriter::MakeWriterStream(morkEnv* ev) // give writer a suitable stream
morkWriter_kStreamBufSize, frozen);
}
else
bud->CutStrongRef(ev);
bud->CutStrongRef(ev->AsMdbEnv());
}
}
@ -264,8 +265,8 @@ morkWriter::CloseWriter(morkEnv* ev) // called by CloseMorkNode();
if ( this->IsNode() )
{
morkStore::SlotWeakStore((morkStore*) 0, ev, &mWriter_Store);
morkFile::SlotStrongFile((morkFile*) 0, ev, &mWriter_File);
morkFile::SlotStrongFile((morkFile*) 0, ev, &mWriter_Bud);
nsIMdbFile_SlotStrongFile((nsIMdbFile*) 0, ev, &mWriter_File);
nsIMdbFile_SlotStrongFile((nsIMdbFile*) 0, ev, &mWriter_Bud);
morkStream::SlotStrongStream((morkStream*) 0, ev, &mWriter_Stream);
nsIMdbHeap_SlotStrongHeap((nsIMdbHeap*) 0, ev, &mWriter_SlotHeap);
this->MarkShut();
@ -1195,12 +1196,12 @@ morkWriter::OnContentDone(morkEnv* ev)
}
stream->Flush(ev);
morkFile* bud = mWriter_Bud;
nsIMdbFile* bud = mWriter_Bud;
if ( bud )
{
bud->Flush(ev);
bud->BecomeTrunk(ev);
morkFile::SlotStrongFile((morkFile*) 0, ev, &mWriter_Bud);
bud->Flush(ev->AsMdbEnv());
bud->BecomeTrunk(ev->AsMdbEnv());
nsIMdbFile_SlotStrongFile((nsIMdbFile*) 0, ev, &mWriter_Bud);
}
else if ( !mWriter_Incremental ) // should have a bud?
this->NilWriterBudError(ev);

Просмотреть файл

@ -126,8 +126,8 @@ class morkWriter : public morkNode { // row iterator
public: // state is public because the entire Mork system is private
morkStore* mWriter_Store; // weak ref to committing store
morkFile* mWriter_File; // strong ref to store's file
morkFile* mWriter_Bud; // strong ref to bud of mWriter_File
nsIMdbFile* mWriter_File; // strong ref to store's file
nsIMdbFile* mWriter_Bud; // strong ref to bud of mWriter_File
morkStream* mWriter_Stream; // strong ref to stream on bud file
nsIMdbHeap* mWriter_SlotHeap; // strong ref to slot heap
@ -200,7 +200,7 @@ public: // morkNode virtual methods
public: // morkWriter construction & destruction
morkWriter(morkEnv* ev, const morkUsage& inUsage,
nsIMdbHeap* ioHeap, morkStore* ioStore, morkFile* ioFile,
nsIMdbHeap* ioHeap, morkStore* ioStore, nsIMdbFile* ioFile,
nsIMdbHeap* ioSlotHeap);
void CloseWriter(morkEnv* ev); // called by CloseMorkNode();

Просмотреть файл

@ -142,7 +142,8 @@ orkinCell::CanUseCell(nsIMdbEnv* mev, mork_bool inMutable,
if ( ev )
{
morkCellObject* cellObj = (morkCellObject*)
this->GetGoodHandleObject(ev, inMutable, morkMagic_kCell);
this->GetGoodHandleObject(ev, inMutable, morkMagic_kCell,
/*inClosedOkay*/ morkBool_kFalse);
if ( cellObj )
{
if ( cellObj->IsCellObject() )

Просмотреть файл

@ -80,6 +80,14 @@
#include "morkThumb.h"
#endif
#ifndef _ORKINHEAP_
#include "orkinHeap.h"
#endif
#ifndef _ORKINCOMPARE_
#include "orkinCompare.h"
#endif
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
/* public virtual*/
@ -144,7 +152,8 @@ orkinFactory::CanUseFactory(nsIMdbEnv* mev, mork_bool inMutable,
if ( ev )
{
morkFactory* factory = (morkFactory*)
this->GetGoodHandleObject(ev, inMutable, morkMagic_kFactory);
this->GetGoodHandleObject(ev, inMutable, morkMagic_kFactory,
/*inClosedOkay*/ morkBool_kFalse);
if ( factory )
{
if ( factory->IsFactory() )
@ -277,7 +286,8 @@ orkinFactory::IsOpenMdbObject(nsIMdbEnv* mev, mdb_bool* outOpen)
// { ----- begin file methods -----
/*virtual*/ mdb_err
orkinFactory::OpenOldFile(nsIMdbEnv* mev, nsIMdbHeap* ioHeap,
const char* inFilePath, mork_bool inFrozen, nsIMdbFile** acqFile)
const char* inFilePath,
mork_bool inFrozen, nsIMdbFile** acqFile)
// Choose some subclass of nsIMdbFile to instantiate, in order to read
// (and write if not frozen) the file known by inFilePath. The file
// returned should be open and ready for use, and presumably positioned
@ -413,6 +423,26 @@ orkinFactory::MakeHeap(nsIMdbEnv* mev, nsIMdbHeap** acqHeap)
}
// } ----- end heap methods -----
// { ----- begin compare methods -----
/*virtual*/ mdb_err
orkinFactory::MakeCompare(nsIMdbEnv* mev, nsIMdbCompare** acqCompare)
{
mdb_err outErr = 0;
nsIMdbCompare* outCompare = 0;
morkEnv* ev = this->CanUseFactory(mev,
/*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
outCompare = new orkinCompare();
if ( !outCompare )
ev->OutOfMemoryError();
}
if ( acqCompare )
*acqCompare = outCompare;
return outErr;
}
// } ----- end compare methods -----
// { ----- begin row methods -----
/*virtual*/ mdb_err
orkinFactory::MakeRow(nsIMdbEnv* mev, nsIMdbHeap* ioHeap,
@ -440,8 +470,9 @@ orkinFactory::MakeRow(nsIMdbEnv* mev, nsIMdbHeap* ioHeap,
/*virtual*/ mdb_err
orkinFactory::CanOpenFilePort(
nsIMdbEnv* mev, // context
const char* inFilePath, // the file to investigate
const mdbYarn* inFirst512Bytes,
// const char* inFilePath, // the file to investigate
// const mdbYarn* inFirst512Bytes,
nsIMdbFile* ioFile, // db abstract file interface
mdb_bool* outCanOpen, // whether OpenFilePort() might succeed
mdbYarn* outFormatVersion)
{
@ -455,9 +486,9 @@ orkinFactory::CanOpenFilePort(
/*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
if ( inFilePath && inFirst512Bytes && outCanOpen )
if ( ioFile && outCanOpen )
{
canOpenAsPort = this->CanOpenMorkTextFile(ev, inFirst512Bytes);
canOpenAsPort = this->CanOpenMorkTextFile(ev, ioFile);
}
else
ev->NilPointerError();
@ -475,7 +506,8 @@ orkinFactory::CanOpenFilePort(
orkinFactory::OpenFilePort(
nsIMdbEnv* mev, // context
nsIMdbHeap* ioHeap, // can be nil to cause ev's heap attribute to be used
const char* inFilePath, // the file to open for readonly import
// const char* inFilePath, // the file to open for readonly import
nsIMdbFile* ioFile, // db abstract file interface
const mdbOpenPolicy* inOpenPolicy, // runtime policies for using db
nsIMdbThumb** acqThumb)
{
@ -486,7 +518,7 @@ orkinFactory::OpenFilePort(
/*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
if ( inFilePath && inOpenPolicy && acqThumb )
if ( ioFile && inOpenPolicy && acqThumb )
{
}
else
@ -543,17 +575,39 @@ orkinFactory::ThumbToOpenPort( // redeeming a completed thumb from OpenFilePort(
mork_bool
orkinFactory::CanOpenMorkTextFile(morkEnv* ev,
const mdbYarn* inFirst512Bytes)
// const mdbYarn* inFirst512Bytes,
nsIMdbFile* ioFile)
{
MORK_USED_1(ev);
mork_bool outBool = morkBool_kFalse;
mork_size headSize = MORK_STRLEN(morkWriter_kFileHeader);
const mdbYarn* y = inFirst512Bytes;
if ( y && y->mYarn_Buf && y->mYarn_Fill >= headSize )
char localBuf[ 256 + 4 ]; // for extra for sloppy safety
mdbYarn localYarn;
mdbYarn* y = &localYarn;
y->mYarn_Buf = localBuf; // space to hold content
y->mYarn_Fill = 0; // no logical content yet
y->mYarn_Size = 256; // physical capacity is 256 bytes
y->mYarn_More = 0;
y->mYarn_Form = 0;
y->mYarn_Grow = 0;
if ( ioFile )
{
mork_u1* buf = (mork_u1*) y->mYarn_Buf;
outBool = ( MORK_MEMCMP(morkWriter_kFileHeader, buf, headSize) == 0 );
nsIMdbEnv* menv = ev->AsMdbEnv();
mdb_size actualSize = 0;
ioFile->Get(menv, y->mYarn_Buf, y->mYarn_Size, /*pos*/ 0, &actualSize);
y->mYarn_Fill = actualSize;
if ( y->mYarn_Buf && actualSize >= headSize && ev->Good() )
{
mork_u1* buf = (mork_u1*) y->mYarn_Buf;
outBool = ( MORK_MEMCMP(morkWriter_kFileHeader, buf, headSize) == 0 );
}
}
else
ev->NilPointerError();
return outBool;
}
@ -561,8 +615,9 @@ orkinFactory::CanOpenMorkTextFile(morkEnv* ev,
/*virtual*/ mdb_err
orkinFactory::CanOpenFileStore(
nsIMdbEnv* mev, // context
const char* inFilePath, // the file to investigate
const mdbYarn* inFirst512Bytes,
// const char* inFilePath, // the file to investigate
// const mdbYarn* inFirst512Bytes,
nsIMdbFile* ioFile, // db abstract file interface
mdb_bool* outCanOpenAsStore, // whether OpenFileStore() might succeed
mdb_bool* outCanOpenAsPort, // whether OpenFilePort() might succeed
mdbYarn* outFormatVersion)
@ -578,10 +633,10 @@ orkinFactory::CanOpenFileStore(
/*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
if ( inFilePath && inFirst512Bytes && outCanOpenAsStore )
if ( ioFile && outCanOpenAsStore )
{
// right now always say true; later we should look for magic patterns
canOpenAsStore = this->CanOpenMorkTextFile(ev, inFirst512Bytes);
canOpenAsStore = this->CanOpenMorkTextFile(ev, ioFile);
canOpenAsPort = canOpenAsStore;
}
else
@ -602,7 +657,8 @@ orkinFactory::CanOpenFileStore(
orkinFactory::OpenFileStore( // open an existing database
nsIMdbEnv* mev, // context
nsIMdbHeap* ioHeap, // can be nil to cause ev's heap attribute to be used
const char* inFilePath, // the file to open for general db usage
// const char* inFilePath, // the file to open for general db usage
nsIMdbFile* ioFile, // db abstract file interface
const mdbOpenPolicy* inOpenPolicy, // runtime policies for using db
nsIMdbThumb** acqThumb)
{
@ -615,7 +671,7 @@ orkinFactory::OpenFileStore( // open an existing database
if ( !ioHeap ) // need to use heap from env?
ioHeap = ev->mEnv_Heap;
if ( inFilePath && inOpenPolicy && acqThumb )
if ( ioFile && inOpenPolicy && acqThumb )
{
morkFactory* factory = (morkFactory*) this->mHandle_Object;
morkStore* store = new(*ioHeap, ev)
@ -624,7 +680,7 @@ orkinFactory::OpenFileStore( // open an existing database
if ( store )
{
mork_bool frozen = morkBool_kFalse; // open store mutable access
if ( store->OpenStoreFile(ev, frozen, inFilePath, inOpenPolicy) )
if ( store->OpenStoreFile(ev, frozen, ioFile, inOpenPolicy) )
{
morkThumb* thumb = morkThumb::Make_OpenFileStore(ev, ioHeap, store);
if ( thumb )
@ -691,7 +747,8 @@ orkinFactory::ThumbToOpenStore( // redeem completed thumb from OpenFileStore()
orkinFactory::CreateNewFileStore( // create a new db with minimal content
nsIMdbEnv* mev, // 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 char* inFilePath, // name of file which should not yet exist
nsIMdbFile* ioFile, // db abstract file interface
const mdbOpenPolicy* inOpenPolicy, // runtime policies for using db
nsIMdbStore** acqStore)
{
@ -704,7 +761,7 @@ orkinFactory::CreateNewFileStore( // create a new db with minimal content
if ( !ioHeap ) // need to use heap from env?
ioHeap = ev->mEnv_Heap;
if ( inFilePath && inOpenPolicy && acqStore && ioHeap )
if ( ioFile && inOpenPolicy && acqStore && ioHeap )
{
morkFactory* factory = (morkFactory*) this->mHandle_Object;
morkStore* store = new(*ioHeap, ev)
@ -716,7 +773,7 @@ orkinFactory::CreateNewFileStore( // create a new db with minimal content
store->mStore_CanDirty = morkBool_kTrue;
store->SetStoreAndAllSpacesCanDirty(ev, morkBool_kTrue);
if ( store->CreateStoreFile(ev, inFilePath, inOpenPolicy) )
if ( store->CreateStoreFile(ev, ioFile, inOpenPolicy) )
outStore = orkinStore::MakeStore(ev, store);
store->CutStrongRef(ev); // always cut ref (handle has its own ref)

Просмотреть файл

@ -93,7 +93,9 @@ public: // utilities:
morkEnv* GetInternalFactoryEnv(mdb_err* outErr);
mork_bool CanOpenMorkTextFile(morkEnv* ev, const mdbYarn* inFirst512Bytes);
mork_bool CanOpenMorkTextFile(morkEnv* ev,
// const mdbYarn* inFirst512Bytes,
nsIMdbFile* ioFile);
public: // type identification
mork_bool IsOrkinFactory() const
@ -142,7 +144,8 @@ public:
// { ----- begin file methods -----
virtual mdb_err OpenOldFile(nsIMdbEnv* ev, nsIMdbHeap* ioHeap,
const char* inFilePath, mdb_bool inFrozen, nsIMdbFile** acqFile);
const char* inFilePath,
mdb_bool inFrozen, nsIMdbFile** acqFile);
// Choose some subclass of nsIMdbFile to instantiate, in order to read
// (and write if not frozen) the file known by inFilePath. The file
// returned should be open and ready for use, and presumably positioned
@ -151,7 +154,8 @@ public:
// other portions or Mork source code don't want to know how it's done.
virtual mdb_err CreateNewFile(nsIMdbEnv* ev, nsIMdbHeap* ioHeap,
const char* inFilePath, nsIMdbFile** acqFile);
const char* inFilePath,
nsIMdbFile** acqFile);
// Choose some subclass of nsIMdbFile to instantiate, in order to read
// (and write if not frozen) the file known by inFilePath. The file
// returned should be created and ready for use, and presumably positioned
@ -169,6 +173,10 @@ public:
virtual mdb_err MakeHeap(nsIMdbEnv* ev, nsIMdbHeap** acqHeap); // new heap
// } ----- end heap methods -----
// { ----- begin compare methods -----
virtual mdb_err MakeCompare(nsIMdbEnv* ev, nsIMdbCompare** acqCompare); // ASCII
// } ----- end compare methods -----
// { ----- begin row methods -----
virtual mdb_err MakeRow(nsIMdbEnv* ev, nsIMdbHeap* ioHeap, nsIMdbRow** acqRow); // new row
// ioHeap can be nil, causing the heap associated with ev to be used
@ -177,15 +185,17 @@ public:
// { ----- begin port methods -----
virtual mdb_err CanOpenFilePort(
nsIMdbEnv* ev, // context
const char* inFilePath, // the file to investigate
const mdbYarn* inFirst512Bytes,
// const char* inFilePath, // the file to investigate
// const mdbYarn* inFirst512Bytes,
nsIMdbFile* ioFile, // db abstract file interface
mdb_bool* outCanOpen, // whether OpenFilePort() might succeed
mdbYarn* outFormatVersion); // informal file format description
virtual mdb_err OpenFilePort(
nsIMdbEnv* ev, // context
nsIMdbHeap* ioHeap, // can be nil to cause ev's heap attribute to be used
const char* inFilePath, // the file to open for readonly import
// const char* inFilePath, // the file to open for readonly import
nsIMdbFile* ioFile, // db abstract file interface
const mdbOpenPolicy* inOpenPolicy, // runtime policies for using db
nsIMdbThumb** acqThumb); // acquire thumb for incremental port open
// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
@ -200,8 +210,9 @@ public:
// { ----- begin store methods -----
virtual mdb_err CanOpenFileStore(
nsIMdbEnv* ev, // context
const char* inFilePath, // the file to investigate
const mdbYarn* inFirst512Bytes,
// const char* inFilePath, // the file to investigate
// const mdbYarn* inFirst512Bytes,
nsIMdbFile* ioFile, // db abstract file interface
mdb_bool* outCanOpenAsStore, // whether OpenFileStore() might succeed
mdb_bool* outCanOpenAsPort, // whether OpenFilePort() might succeed
mdbYarn* outFormatVersion); // informal file format description
@ -209,7 +220,8 @@ public:
virtual mdb_err OpenFileStore( // open an existing database
nsIMdbEnv* ev, // context
nsIMdbHeap* ioHeap, // can be nil to cause ev's heap attribute to be used
const char* inFilePath, // the file to open for general db usage
// const char* inFilePath, // the file to open for general db usage
nsIMdbFile* ioFile, // db abstract file interface
const mdbOpenPolicy* inOpenPolicy, // runtime policies for using db
nsIMdbThumb** acqThumb); // acquire thumb for incremental store open
// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
@ -224,7 +236,8 @@ public:
virtual mdb_err 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 char* inFilePath, // name of file which should not yet exist
nsIMdbFile* ioFile, // db abstract file interface
const mdbOpenPolicy* inOpenPolicy, // runtime policies for using db
nsIMdbStore** acqStore); // acquire new db store object
// } ----- end store methods -----

Просмотреть файл

@ -38,8 +38,8 @@ public:
virtual ~orkinHeap(); // does nothing
private: // copying is not allowed
orkinHeap(const morkHandle& other);
orkinHeap& operator=(const morkHandle& other);
orkinHeap(const orkinHeap& other);
orkinHeap& operator=(const orkinHeap& other);
public:

Просмотреть файл

@ -97,7 +97,8 @@ orkinPortTableCursor::CanUsePortTableCursor(nsIMdbEnv* mev,
if ( ev )
{
morkPortTableCursor* self = (morkPortTableCursor*)
this->GetGoodHandleObject(ev, inMutable, morkMagic_kPortTableCursor);
this->GetGoodHandleObject(ev, inMutable, morkMagic_kPortTableCursor,
/*inClosedOkay*/ morkBool_kFalse);
if ( self )
{
if ( self->IsPortTableCursor() )

Просмотреть файл

@ -120,7 +120,8 @@ orkinRow::CanUseRow(nsIMdbEnv* mev, mork_bool inMutable,
if ( ev )
{
morkRowObject* rowObj = (morkRowObject*)
this->GetGoodHandleObject(ev, inMutable, morkMagic_kRow);
this->GetGoodHandleObject(ev, inMutable, morkMagic_kRow,
/*inClosedOkay*/ morkBool_kFalse);
if ( rowObj )
{
if ( rowObj->IsRowObject() )

Просмотреть файл

@ -104,7 +104,8 @@ orkinRowCellCursor::CanUseRowCellCursor(nsIMdbEnv* mev, mork_bool inMutable,
if ( ev )
{
morkRowCellCursor* self = (morkRowCellCursor*)
this->GetGoodHandleObject(ev, inMutable, morkMagic_kRowCellCursor);
this->GetGoodHandleObject(ev, inMutable, morkMagic_kRowCellCursor,
/*inClosedOkay*/ morkBool_kFalse);
if ( self )
{
if ( self->IsRowCellCursor() )

Просмотреть файл

@ -68,9 +68,9 @@
#include "morkThumb.h"
#endif
#ifndef _MORKFILE_
#include "morkFile.h"
#endif
// #ifndef _MORKFILE_
// #include "morkFile.h"
// #endif
#ifndef _ORKINTHUMB_
#include "orkinThumb.h"
@ -119,7 +119,8 @@ orkinStore::CanUseStore(nsIMdbEnv* mev,
if ( ev )
{
morkStore* self = (morkStore*)
this->GetGoodHandleObject(ev, inMutable, morkMagic_kStore);
this->GetGoodHandleObject(ev, inMutable, morkMagic_kStore,
/*inClosedOkay*/ morkBool_kFalse);
if ( self )
{
if ( self->IsStore() )
@ -373,7 +374,46 @@ orkinStore::GetPortFilePath(
morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
ev->StubMethodOnlyError();
morkStore* store = (morkStore*) mHandle_Object;
nsIMdbFile* file = store->mStore_File;
if ( file )
file->Path(mev, outFilePath);
else
store->NilStoreFileError(ev);
outErr = ev->AsErr();
}
return outErr;
}
/*virtual*/ mdb_err
orkinStore::GetPortFile(
nsIMdbEnv* mev, // context
nsIMdbFile** acqFile) // acquire file used by port or store
{
mdb_err outErr = 0;
if ( acqFile )
*acqFile = 0;
morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
morkStore* store = (morkStore*) mHandle_Object;
nsIMdbFile* file = store->mStore_File;
if ( file )
{
if ( acqFile )
{
file->AddStrongRef(mev);
if ( ev->Good() )
*acqFile = file;
}
}
else
store->NilStoreFileError(ev);
outErr = ev->AsErr();
}
return outErr;
@ -421,19 +461,25 @@ orkinStore::CanExportToFormat( // can export content in given specific format?
/*virtual*/ mdb_err
orkinStore::ExportToFormat( // export content in given specific format
nsIMdbEnv* mev, // context
const char* inFilePath, // the file to receive exported content
// const char* inFilePath, // the file to receive exported content
nsIMdbFile* ioFile, // destination abstract file interface
const char* inFormatVersion, // file format description
nsIMdbThumb** acqThumb) // acquire thumb for incremental export
// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
// then the export will be finished.
{
MORK_USED_2(inFilePath,inFormatVersion);
mdb_err outErr = 0;
nsIMdbThumb* outThumb = 0;
morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
ev->StubMethodOnlyError();
if ( ioFile && inFormatVersion && acqThumb )
{
ev->StubMethodOnlyError();
}
else
ev->NilPointerError();
outErr = ev->AsErr();
}
if ( acqThumb )
@ -995,6 +1041,33 @@ orkinStore::ImportContent( // import content from port
*acqThumb = outThumb;
return outErr;
}
/*virtual*/ mdb_err
orkinStore::ImportFile( // import content from port
nsIMdbEnv* mev, // context
nsIMdbFile* ioFile, // the file with content to add to store
nsIMdbThumb** acqThumb) // acquire thumb for incremental import
// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
// then the import will be finished.
{
nsIMdbThumb* outThumb = 0;
mdb_err outErr = 0;
morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
if ( ioFile && acqThumb )
{
ev->StubMethodOnlyError();
}
else
ev->NilPointerError();
outErr = ev->AsErr();
}
if ( acqThumb )
*acqThumb = outThumb;
return outErr;
}
// } ----- end inport/export methods -----
// { ----- begin hinting methods -----
@ -1065,8 +1138,8 @@ orkinStore::LargeCommit( // save important changes if at all possible
nsIMdbHeap* heap = store->mPort_Heap;
morkThumb* thumb = 0;
morkFile* file = store->mStore_File;
if ( file && file->Length(ev) > 128 && store->mStore_CanWriteIncremental )
// morkFile* file = store->mStore_File;
if ( store->DoPreferLargeOverCompressCommit(ev) )
{
thumb = morkThumb::Make_LargeCommit(ev, heap, store);
}
@ -1107,8 +1180,7 @@ orkinStore::SessionCommit( // save all changes if large commits delayed
nsIMdbHeap* heap = store->mPort_Heap;
morkThumb* thumb = 0;
morkFile* file = store->mStore_File;
if ( file && file->Length(ev) > 128 && store->mStore_CanWriteIncremental )
if ( store->DoPreferLargeOverCompressCommit(ev) )
{
thumb = morkThumb::Make_LargeCommit(ev, heap, store);
}

Просмотреть файл

@ -163,6 +163,10 @@ public: // type identification
nsIMdbEnv* ev, // context
mdbYarn* outFilePath, // name of file holding port content
mdbYarn* outFormatVersion); // file format description
virtual mdb_err GetPortFile(
nsIMdbEnv* ev, // context
nsIMdbFile** acqFile); // acquire file used by port or store
// } ----- end filepath methods -----
// { ----- begin export methods -----
@ -178,7 +182,8 @@ public: // type identification
virtual mdb_err ExportToFormat( // export content in given specific format
nsIMdbEnv* ev, // context
const char* inFilePath, // the file to receive exported content
// const char* inFilePath, // the file to receive exported content
nsIMdbFile* ioFile, // destination abstract file interface
const char* inFormatVersion, // file format description
nsIMdbThumb** acqThumb); // acquire thumb for incremental export
// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
@ -424,6 +429,13 @@ public: // type identification
nsIMdbThumb** acqThumb); // acquire thumb for incremental import
// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
// then the import will be finished.
virtual mdb_err ImportFile( // import content from port
nsIMdbEnv* ev, // context
nsIMdbFile* ioFile, // the file with content to add to store
nsIMdbThumb** acqThumb); // acquire thumb for incremental import
// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
// then the import will be finished.
// } ----- end inport/export methods -----
// { ----- begin hinting methods -----

Просмотреть файл

@ -111,7 +111,8 @@ orkinTable::CanUseTable(nsIMdbEnv* mev,
if ( ev )
{
morkTable* self = (morkTable*)
this->GetGoodHandleObject(ev, inMutable, morkMagic_kTable);
this->GetGoodHandleObject(ev, inMutable, morkMagic_kTable,
/*inClosedOkay*/ morkBool_kFalse);
if ( self )
{
if ( self->IsTable() )
@ -557,7 +558,7 @@ orkinTable::GetTableRowCursor( // make a cursor, starting iteration at inRowPos
{
if ( ev->Good() )
{
cursor->mCursor_Seed = (mork_seed) inRowPos;
// cursor->mCursor_Seed = (mork_seed) inRowPos;
outCursor = cursor->AcquireTableRowCursorHandle(ev);
}
else
@ -845,15 +846,13 @@ orkinTable::CutAllRows( // remove all rows from the table
// { ----- begin searching methods -----
/*virtual*/ mdb_err
orkinTable::SearchOneSortedColumn( // search only currently sorted col
orkinTable::FindRowMatches( // search variable number of sorted cols
nsIMdbEnv* mev, // context
const mdbYarn* inPrefix, // content to find as prefix in row's column cell
mdbRange* outRange) // range of matching rows
nsIMdbTableRowCursor** acqCursor) // set of matching rows
{
MORK_USED_1(inPrefix);
mdbRange range;
range.mRange_FirstPos = -1;
range.mRange_LastPos = -1;
nsIMdbTableRowCursor* outCursor = 0;
mdb_err outErr = 0;
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
@ -861,23 +860,31 @@ orkinTable::SearchOneSortedColumn( // search only currently sorted col
ev->StubMethodOnlyError();
outErr = ev->AsErr();
}
if ( outRange )
*outRange = range;
if ( acqCursor )
*acqCursor = outCursor;
return outErr;
}
/*virtual*/ mdb_err
orkinTable::SearchManyColumns( // search variable number of sorted cols
orkinTable::GetSearchColumns( // query columns used by FindRowMatches()
nsIMdbEnv* mev, // context
const mdbYarn* inPrefix, // content to find as prefix in row's column cell
mdbSearch* ioSearch, // columns to search and resulting ranges
nsIMdbThumb** acqThumb) // acquire thumb for incremental search
// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
// then the search will be finished. Until that time, the ioSearch argument
// is assumed referenced and used by the thumb; one should not inspect any
// output results in ioSearch until after the thumb is finished with it.
mdb_count* outCount, // context
mdbColumnSet* outColSet) // caller supplied space to put columns
// GetSearchColumns() returns the columns actually searched when the
// FindRowMatches() method is called. No more than mColumnSet_Count
// slots of mColumnSet_Columns will be written, since mColumnSet_Count
// indicates how many slots are present in the column array. The
// actual number of search column used by the table is returned in
// the outCount parameter; if this number exceeds mColumnSet_Count,
// then a caller needs a bigger array to read the entire column set.
// The minimum of mColumnSet_Count and outCount is the number slots
// in mColumnSet_Columns that were actually written by this method.
//
// Callers are expected to change this set of columns by calls to
// nsIMdbTable::SearchColumnsHint() or SetSearchSorting(), or both.
{
MORK_USED_2(inPrefix,ioSearch);
MORK_USED_1(outColSet);
mdb_count count = 0;
mdb_err outErr = 0;
nsIMdbThumb* outThumb = 0;
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
@ -886,8 +893,8 @@ orkinTable::SearchManyColumns( // search variable number of sorted cols
ev->StubMethodOnlyError();
outErr = ev->AsErr();
}
if ( acqThumb )
*acqThumb = outThumb;
if ( outCount )
*outCount = count;
return outErr;
}
// } ----- end searching methods -----
@ -975,20 +982,18 @@ orkinTable::EndBatchChangeHint( // advise before many adds and cuts
// sort following the primary column sort, when table rows are sorted.
/*virtual*/ mdb_err
orkinTable::CanSortColumn( // query which col is currently used for sorting
orkinTable::CanSortColumn( // query which column is currently used for sorting
nsIMdbEnv* mev, // context
mdb_column inColumn, // column to query sorting potential
mdb_bool* outCanSort) // whether the column can be sorted
{
MORK_USED_1(inColumn);
mdb_bool canSort = morkBool_kFalse;
mdb_bool canSort = mdbBool_kFalse;
mdb_err outErr = 0;
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
if ( outCanSort )
*outCanSort = morkBool_kFalse;
// ev->StubMethodOnlyError();
outErr = ev->AsErr();
}
if ( outCanSort )
@ -997,121 +1002,70 @@ orkinTable::CanSortColumn( // query which col is currently used for sorting
}
/*virtual*/ mdb_err
orkinTable::NewSortColumn( // change col used for sorting in the table
orkinTable::GetSorting( // view same table in particular sorting
nsIMdbEnv* mev, // context
mdb_column inColumn, // requested new column for sorting table
mdb_column* outActualColumn, // column actually used for sorting
nsIMdbThumb** acqThumb) // acquire thumb for incremental table resort
nsIMdbSorting** acqSorting) // acquire sorting for column
{
MORK_USED_1(inColumn);
mdb_column actualColumn = 0;
nsIMdbSorting* outSorting = 0;
mdb_err outErr = 0;
nsIMdbThumb* outThumb = 0;
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
ev->StubMethodOnlyError();
outErr = ev->AsErr();
}
if ( outActualColumn )
*outActualColumn = actualColumn;
if ( acqThumb )
*acqThumb = outThumb;
return outErr;
}
// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
// then the sort will be finished.
/*virtual*/ mdb_err
orkinTable::NewSortColumnWithCompare( // change sort col w/ explicit compare
nsIMdbEnv* mev, // context
nsIMdbCompare* ioCompare, // explicit interface for yarn comparison
mdb_column inColumn, // requested new column for sorting table
mdb_column* outActualColumn, // column actually used for sorting
nsIMdbThumb** acqThumb) // acquire thumb for incremental table resort
{
MORK_USED_2(inColumn,ioCompare);
mdb_column actualColumn = 0;
mdb_err outErr = 0;
nsIMdbThumb* outThumb = 0;
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
ev->StubMethodOnlyError();
outErr = ev->AsErr();
}
if ( outActualColumn )
*outActualColumn = actualColumn;
if ( acqThumb )
*acqThumb = outThumb;
return outErr;
}
// Note the table will hold a reference to inCompare if this object is used
// to sort the table. Until the table closes, callers can only force release
// of the compare object by changing the sort (by say, changing to unsorted).
// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
// then the sort will be finished.
/*virtual*/ mdb_err
orkinTable::GetSortColumn( // query which col is currently sorted
nsIMdbEnv* mev, // context
mdb_column* outColumn) // col the table uses for sorting (or zero)
{
mdb_err outErr = 0;
mdb_column col = 0;
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
ev->StubMethodOnlyError();
outErr = ev->AsErr();
}
if ( outColumn )
*outColumn = col;
if ( acqSorting )
*acqSorting = outSorting;
return outErr;
}
/*virtual*/ mdb_err
orkinTable::CloneSortColumn( // view same table with a different sort
orkinTable::SetSearchSorting( // use this sorting in FindRowMatches()
nsIMdbEnv* mev, // context
mdb_column inColumn, // requested new column for sorting table
nsIMdbThumb** acqThumb) // acquire thumb for incremental table clone
mdb_column inColumn, // often same as nsIMdbSorting::GetSortColumn()
nsIMdbSorting* ioSorting) // requested sorting for some column
// SetSearchSorting() attempts to inform the table that ioSorting
// should be used during calls to FindRowMatches() for searching
// the column which is actually sorted by ioSorting. This method
// is most useful in conjunction with nsIMdbSorting::SetCompare(),
// because otherwise a caller would not be able to override the
// comparison ordering method used during searchs. Note that some
// database implementations might be unable to use an arbitrarily
// specified sort order, either due to schema or runtime interface
// constraints, in which case ioSorting might not actually be used.
// Presumably ioSorting is an instance that was returned from some
// earlier call to nsIMdbTable::GetSorting(). A caller can also
// use nsIMdbTable::SearchColumnsHint() to specify desired change
// in which columns are sorted and searched by FindRowMatches().
//
// A caller can pass a nil pointer for ioSorting to request that
// column inColumn no longer be used at all by FindRowMatches().
// But when ioSorting is non-nil, then inColumn should match the
// column actually sorted by ioSorting; when these do not agree,
// implementations are instructed to give precedence to the column
// specified by ioSorting (so this means callers might just pass
// zero for inColumn when ioSorting is also provided, since then
// inColumn is both redundant and ignored).
{
MORK_USED_1(inColumn);
mdb_err outErr = 0;
nsIMdbThumb* outThumb = 0;
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
ev->StubMethodOnlyError();
if ( ioSorting )
{
ev->StubMethodOnlyError();
}
else
ev->NilPointerError();
outErr = ev->AsErr();
}
if ( acqThumb )
*acqThumb = outThumb;
return outErr;
}
// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
// then call nsIMdbTable::ThumbToCloneSortTable() to get the table instance.
/*virtual*/ mdb_err
orkinTable::ThumbToCloneSortTable( // redeem complete CloneSortColumn() thumb
nsIMdbEnv* mev, // context
nsIMdbThumb* ioThumb, // thumb from CloneSortColumn() with done status
nsIMdbTable** acqTable) // new table instance (or old if sort unchanged)
{
MORK_USED_1(ioThumb);
mdb_err outErr = 0;
nsIMdbTable* outTable = 0;
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
ev->StubMethodOnlyError();
outErr = ev->AsErr();
}
if ( acqTable )
*acqTable = outTable;
return outErr;
}
// } ----- end sorting methods -----
// { ----- begin moving methods -----

Просмотреть файл

@ -60,8 +60,8 @@ protected: // construction is protected (use the static Make() method)
// void CloseHandle(morkEnv* ev); // don't need to specialize closing
private: // copying is not allowed
orkinTable(const morkHandle& other);
orkinTable& operator=(const morkHandle& other);
orkinTable(const orkinTable& other);
orkinTable& operator=(const orkinTable& other);
// public: // dynamic type identification
// mork_bool IsHandle() const //
@ -273,23 +273,6 @@ public: // type identification
nsIMdbEnv* ev); // context
// } ----- end row set methods -----
// { ----- begin searching methods -----
virtual mdb_err SearchOneSortedColumn( // search only currently sorted col
nsIMdbEnv* ev, // context
const mdbYarn* inPrefix, // content to find as prefix in row's column cell
mdbRange* outRange); // range of matching rows
virtual mdb_err SearchManyColumns( // search variable number of sorted cols
nsIMdbEnv* ev, // context
const mdbYarn* inPrefix, // content to find as prefix in row's column cell
mdbSearch* ioSearch, // columns to search and resulting ranges
nsIMdbThumb** acqThumb); // acquire thumb for incremental search
// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
// then the search will be finished. Until that time, the ioSearch argument
// is assumed referenced and used by the thumb; one should not inspect any
// output results in ioSearch until after the thumb is finished with it.
// } ----- end searching methods -----
// { ----- begin hinting methods -----
virtual mdb_err SearchColumnsHint( // advise re future expected search cols
nsIMdbEnv* ev, // context
@ -319,6 +302,30 @@ public: // type identification
// a surprise request occurs for row position during batch changes.
// } ----- end hinting methods -----
// { ----- begin searching methods -----
virtual mdb_err FindRowMatches( // search variable number of sorted cols
nsIMdbEnv* ev, // context
const mdbYarn* inPrefix, // content to find as prefix in row's column cell
nsIMdbTableRowCursor** acqCursor); // set of matching rows
virtual mdb_err GetSearchColumns( // query columns used by FindRowMatches()
nsIMdbEnv* ev, // context
mdb_count* outCount, // context
mdbColumnSet* outColSet); // caller supplied space to put columns
// GetSearchColumns() returns the columns actually searched when the
// FindRowMatches() method is called. No more than mColumnSet_Count
// slots of mColumnSet_Columns will be written, since mColumnSet_Count
// indicates how many slots are present in the column array. The
// actual number of search column used by the table is returned in
// the outCount parameter; if this number exceeds mColumnSet_Count,
// then a caller needs a bigger array to read the entire column set.
// The minimum of mColumnSet_Count and outCount is the number slots
// in mColumnSet_Columns that were actually written by this method.
//
// Callers are expected to change this set of columns by calls to
// nsIMdbTable::SearchColumnsHint() or SetSearchSorting(), or both.
// } ----- end searching methods -----
// { ----- begin sorting methods -----
// sorting: note all rows are assumed sorted by row ID as a secondary
// sort following the primary column sort, when table rows are sorted.
@ -328,46 +335,38 @@ public: // type identification
nsIMdbEnv* ev, // context
mdb_column inColumn, // column to query sorting potential
mdb_bool* outCanSort); // whether the column can be sorted
virtual mdb_err
NewSortColumn( // change the column used for sorting in the table
nsIMdbEnv* ev, // context
mdb_column inColumn, // requested new column for sorting table
mdb_column* outActualColumn, // column actually used for sorting
nsIMdbThumb** acqThumb); // acquire thumb for incremental table resort
// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
// then the sort will be finished.
virtual mdb_err
NewSortColumnWithCompare( // change sort column with explicit compare
nsIMdbEnv* ev, // context
nsIMdbCompare* ioCompare, // explicit interface for yarn comparison
mdb_column inColumn, // requested new column for sorting table
mdb_column* outActualColumn, // column actually used for sorting
nsIMdbThumb** acqThumb); // acquire thumb for incremental table resort
// Note the table will hold a reference to inCompare if this object is used
// to sort the table. Until the table closes, callers can only force release
// of the compare object by changing the sort (by say, changing to unsorted).
// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
// then the sort will be finished.
virtual mdb_err GetSortColumn( // query which col is currently sorted
nsIMdbEnv* ev, // context
mdb_column* outColumn); // col the table uses for sorting (or zero)
virtual mdb_err CloneSortColumn( // view same table with a different sort
nsIMdbEnv* ev, // context
mdb_column inColumn, // requested new column for sorting table
nsIMdbThumb** acqThumb); // acquire thumb for incremental table clone
// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
// then call nsIMdbTable::ThumbToCloneSortTable() to get the table instance.
virtual mdb_err
ThumbToCloneSortTable( // redeem complete CloneSortColumn() thumb
virtual mdb_err GetSorting( // view same table in particular sorting
nsIMdbEnv* ev, // context
nsIMdbThumb* ioThumb, // thumb from CloneSortColumn() with done status
nsIMdbTable** acqTable); // new table instance (or old if sort unchanged)
mdb_column inColumn, // requested new column for sorting table
nsIMdbSorting** acqSorting); // acquire sorting for column
virtual mdb_err SetSearchSorting( // use this sorting in FindRowMatches()
nsIMdbEnv* ev, // context
mdb_column inColumn, // often same as nsIMdbSorting::GetSortColumn()
nsIMdbSorting* ioSorting); // requested sorting for some column
// SetSearchSorting() attempts to inform the table that ioSorting
// should be used during calls to FindRowMatches() for searching
// the column which is actually sorted by ioSorting. This method
// is most useful in conjunction with nsIMdbSorting::SetCompare(),
// because otherwise a caller would not be able to override the
// comparison ordering method used during searchs. Note that some
// database implementations might be unable to use an arbitrarily
// specified sort order, either due to schema or runtime interface
// constraints, in which case ioSorting might not actually be used.
// Presumably ioSorting is an instance that was returned from some
// earlier call to nsIMdbTable::GetSorting(). A caller can also
// use nsIMdbTable::SearchColumnsHint() to specify desired change
// in which columns are sorted and searched by FindRowMatches().
//
// A caller can pass a nil pointer for ioSorting to request that
// column inColumn no longer be used at all by FindRowMatches().
// But when ioSorting is non-nil, then inColumn should match the
// column actually sorted by ioSorting; when these do not agree,
// implementations are instructed to give precedence to the column
// specified by ioSorting (so this means callers might just pass
// zero for inColumn when ioSorting is also provided, since then
// inColumn is both redundant and ignored).
// } ----- end sorting methods -----
// { ----- begin moving methods -----

Просмотреть файл

@ -109,7 +109,8 @@ orkinTableRowCursor::CanUseTableRowCursor(nsIMdbEnv* mev,
if ( ev )
{
morkTableRowCursor* self = (morkTableRowCursor*)
this->GetGoodHandleObject(ev, inMutable, morkMagic_kTableRowCursor);
this->GetGoodHandleObject(ev, inMutable, morkMagic_kTableRowCursor,
/*inClosedOkay*/ morkBool_kFalse);
if ( self )
{
if ( self->IsTableRowCursor() )
@ -235,8 +236,7 @@ orkinTableRowCursor::GetCount(nsIMdbEnv* mev, mdb_count* outCount)
if ( ev )
{
morkTableRowCursor* cursor = (morkTableRowCursor*) mHandle_Object;
morkTable* table = cursor->mTableRowCursor_Table;
count = table->mTable_RowArray.mArray_Fill;
count = cursor->GetMemberCount(ev);
outErr = ev->AsErr();
}
if ( outCount )
@ -303,7 +303,8 @@ orkinTableRowCursor::SetDoFailOnSeedOutOfSync(nsIMdbEnv* mev, mdb_bool inFail)
this->CanUseTableRowCursor(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
ev->StubMethodOnlyError();
morkTableRowCursor* cursor = (morkTableRowCursor*) mHandle_Object;
cursor->mCursor_DoFailOnSeedOutOfSync = inFail;
outErr = ev->AsErr();
}
return outErr;
@ -318,7 +319,8 @@ orkinTableRowCursor::GetDoFailOnSeedOutOfSync(nsIMdbEnv* mev, mdb_bool* outFail)
this->CanUseTableRowCursor(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
ev->StubMethodOnlyError();
morkTableRowCursor* cursor = (morkTableRowCursor*) mHandle_Object;
fail = cursor->mCursor_DoFailOnSeedOutOfSync;
outErr = ev->AsErr();
}
if ( outFail )
@ -333,20 +335,6 @@ orkinTableRowCursor::GetDoFailOnSeedOutOfSync(nsIMdbEnv* mev, mdb_bool* outFail)
// { ===== begin nsIMdbTableRowCursor methods =====
// { ----- begin attribute methods -----
/*virtual*/ mdb_err
orkinTableRowCursor::SetTable(nsIMdbEnv* mev, nsIMdbTable* ioTable)
{
MORK_USED_1(ioTable);
mdb_err outErr = 0;
morkEnv* ev =
this->CanUseTableRowCursor(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
ev->StubMethodOnlyError();
outErr = ev->AsErr();
}
return outErr;
}
/*virtual*/ mdb_err
orkinTableRowCursor::GetTable(nsIMdbEnv* mev, nsIMdbTable** acqTable)
@ -428,67 +416,71 @@ orkinTableRowCursor::NextRow( // get row cells from table for cells already in r
}
// } ----- end row iteration methods -----
// { ----- begin copy iteration methods -----
// { ----- begin duplicate row removal methods -----
/*virtual*/ mdb_err
orkinTableRowCursor::NextRowCopy( // put row cells into sink only when already in sink
nsIMdbEnv* mev, // context
nsIMdbRow* ioSinkRow, // sink for row cells read from next row
mdbOid* outOid, // out row oid
mdb_pos* outRowPos)
orkinTableRowCursor::CanHaveDupRowMembers(nsIMdbEnv* mev, // cursor might hold dups?
mdb_bool* outCanHaveDups)
{
MORK_USED_1(ioSinkRow);
mdbOid oid;
oid.mOid_Scope = 0;
oid.mOid_Id = (mork_id) -1;
mdb_pos rowPos = -1;
mdb_err outErr = 0;
mdb_bool canHaveDups = mdbBool_kFalse;
morkEnv* ev =
this->CanUseTableRowCursor(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
if ( outOid )
{
ev->StubMethodOnlyError();
}
else
ev->NilPointerError();
morkTableRowCursor* cursor = (morkTableRowCursor*) mHandle_Object;
canHaveDups = cursor->CanHaveDupRowMembers(ev);
outErr = ev->AsErr();
}
if ( outRowPos )
*outRowPos = rowPos;
if ( outOid )
*outOid = oid;
if ( outCanHaveDups )
*outCanHaveDups = canHaveDups;
return outErr;
}
/*virtual*/ mdb_err
orkinTableRowCursor::NextRowCopyAll( // put all row cells into sink, adding to sink
orkinTableRowCursor::MakeUniqueCursor( // clone cursor, removing duplicate rows
nsIMdbEnv* mev, // context
nsIMdbRow* ioSinkRow, // sink for row cells read from next row
mdbOid* outOid, // out row oid
mdb_pos* outRowPos)
nsIMdbTableRowCursor** acqCursor) // acquire clone with no dups
// Note that MakeUniqueCursor() is never necessary for a cursor which was
// created by table method nsIMdbTable::GetTableRowCursor(), because a table
// never contains the same row as a member more than once. However, a cursor
// created by table method nsIMdbTable::FindRowMatches() might contain the
// same row more than once, because the same row can generate a hit by more
// than one column with a matching string prefix. Note this method can
// return the very same cursor instance with just an incremented refcount,
// when the original cursor could not contain any duplicate rows (calling
// CanHaveDupRowMembers() shows this case on a false return). Otherwise
// this method returns a different cursor instance. Callers should not use
// this MakeUniqueCursor() method lightly, because it tends to defeat the
// purpose of lazy programming techniques, since it can force creation of
// an explicit row collection in a new cursor's representation, in order to
// inspect the row membership and remove any duplicates; this can have big
// impact if a collection holds tens of thousands of rows or more, when
// the original cursor with dups simply referenced rows indirectly by row
// position ranges, without using an explicit row set representation.
// Callers are encouraged to use nsIMdbCursor::GetCount() to determine
// whether the row collection is very large (tens of thousands), and to
// delay calling MakeUniqueCursor() when possible, until a user interface
// element actually demands the creation of an explicit set representation.
{
MORK_USED_1(ioSinkRow);
mdbOid oid;
oid.mOid_Scope = 0;
oid.mOid_Id = (mork_id) -1;
mdb_pos rowPos = -1;
mdb_err outErr = 0;
nsIMdbTableRowCursor* outCursor = 0;
morkEnv* ev =
this->CanUseTableRowCursor(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
ev->StubMethodOnlyError();
if ( this->Handle_AddStrongRef(mev) == 0 )
outCursor = this;
outErr = ev->AsErr();
}
if ( outRowPos )
*outRowPos = rowPos;
if ( outOid )
*outOid = oid;
if ( acqCursor )
*acqCursor = outCursor;
return outErr;
} // nonzero if child, and a row child
// } ----- end copy iteration methods -----
}
// } ----- end duplicate row removal methods -----
// } ===== end nsIMdbTableRowCursor methods =====

Просмотреть файл

@ -150,7 +150,6 @@ public: // type identification
// { ===== begin nsIMdbTableRowCursor methods =====
// { ----- begin attribute methods -----
virtual mdb_err SetTable(nsIMdbEnv* ev, nsIMdbTable* ioTable); // sets pos to -1
virtual mdb_err GetTable(nsIMdbEnv* ev, nsIMdbTable** acqTable);
// } ----- end attribute methods -----
@ -168,19 +167,35 @@ public: // type identification
mdb_pos* outRowPos); // zero-based position of the row in table
// } ----- end row iteration methods -----
// { ----- begin copy iteration methods -----
virtual mdb_err NextRowCopy( // put row cells into sink only when already in sink
// { ----- begin duplicate row removal methods -----
virtual mdb_err CanHaveDupRowMembers(nsIMdbEnv* ev, // cursor might hold dups?
mdb_bool* outCanHaveDups);
virtual mdb_err MakeUniqueCursor( // clone cursor, removing duplicate rows
nsIMdbEnv* ev, // context
nsIMdbRow* ioSinkRow, // sink for row cells read from next row
mdbOid* outOid, // out row oid
mdb_pos* outRowPos); // zero-based position of the row in table
virtual mdb_err NextRowCopyAll( // put all row cells into sink, adding to sink
nsIMdbEnv* ev, // context
nsIMdbRow* ioSinkRow, // sink for row cells read from next row
mdbOid* outOid, // out row oid
mdb_pos* outRowPos); // zero-based position of the row in table
// } ----- end copy iteration methods -----
nsIMdbTableRowCursor** acqCursor); // acquire clone with no dups
// Note that MakeUniqueCursor() is never necessary for a cursor which was
// created by table method nsIMdbTable::GetTableRowCursor(), because a table
// never contains the same row as a member more than once. However, a cursor
// created by table method nsIMdbTable::FindRowMatches() might contain the
// same row more than once, because the same row can generate a hit by more
// than one column with a matching string prefix. Note this method can
// return the very same cursor instance with just an incremented refcount,
// when the original cursor could not contain any duplicate rows (calling
// CanHaveDupRowMembers() shows this case on a false return). Otherwise
// this method returns a different cursor instance. Callers should not use
// this MakeUniqueCursor() method lightly, because it tends to defeat the
// purpose of lazy programming techniques, since it can force creation of
// an explicit row collection in a new cursor's representation, in order to
// inspect the row membership and remove any duplicates; this can have big
// impact if a collection holds tens of thousands of rows or more, when
// the original cursor with dups simply referenced rows indirectly by row
// position ranges, without using an explicit row set representation.
// Callers are encouraged to use nsIMdbCursor::GetCount() to determine
// whether the row collection is very large (tens of thousands), and to
// delay calling MakeUniqueCursor() when possible, until a user interface
// element actually demands the creation of an explicit set representation.
// } ----- end duplicate row removal methods -----
// } ===== end nsIMdbTableRowCursor methods =====
};

Просмотреть файл

@ -87,7 +87,8 @@ orkinThumb::CanUseThumb(nsIMdbEnv* mev,
if ( ev )
{
morkThumb* self = (morkThumb*)
this->GetGoodHandleObject(ev, inMutable, morkMagic_kThumb);
this->GetGoodHandleObject(ev, inMutable, morkMagic_kThumb,
/*inClosedOkay*/ morkBool_kFalse);
if ( self )
{
if ( self->IsThumb() )

Двоичные данные
mailnews/db/mork/macbuild/mork.mcp

Двоичный файл не отображается.

Просмотреть файл

@ -194,6 +194,8 @@ class morkRow;
class morkRowCellCursor;
class morkRowObject;
class morkRowSpace;
class morkSorting;
class morkSortingRowCursor;
class morkSpace;
class morkSpan;
class morkStore;

Просмотреть файл

@ -67,6 +67,9 @@ morkEnv::~morkEnv() /*i*/ // assert CloseEnv() executed earlier
MORK_ASSERT(mEnv_ErrorHook==0);
}
/* choose morkBool_kTrue or morkBool_kFalse for kBeVerbose: */
#define morkEnv_kBeVerbose morkBool_kFalse
/*public non-poly*/
morkEnv::morkEnv(const morkUsage& inUsage, nsIMdbHeap* ioHeap,
morkFactory* ioFactory, nsIMdbHeap* ioSlotHeap)
@ -86,7 +89,7 @@ morkEnv::morkEnv(const morkUsage& inUsage, nsIMdbHeap* ioHeap,
, mEnv_DoTrace( morkBool_kFalse )
, mEnv_AutoClear( morkAble_kDisabled )
, mEnv_ShouldAbort( morkBool_kFalse )
, mEnv_BeVerbose( morkBool_kFalse )
, mEnv_BeVerbose( morkEnv_kBeVerbose )
{
MORK_ASSERT(ioSlotHeap && ioFactory );
if ( ioSlotHeap )
@ -126,7 +129,7 @@ morkEnv::morkEnv(morkEnv* ev, /*i*/
, mEnv_DoTrace( morkBool_kFalse )
, mEnv_AutoClear( morkAble_kDisabled )
, mEnv_ShouldAbort( morkBool_kFalse )
, mEnv_BeVerbose( morkBool_kFalse )
, mEnv_BeVerbose( morkEnv_kBeVerbose )
{
// $$$ do we need to refcount the inSelfAsMdbEnv nsIMdbEnv??

Просмотреть файл

@ -36,9 +36,13 @@
#include "morkFile.h"
#endif
// #ifndef _ORKINFILE_
// #include "orkinFile.h"
// #endif
#define MORK_CONFIG_USE_ORKINFILE 1
#ifdef MORK_CONFIG_USE_ORKINFILE
#ifndef _ORKINFILE_
#include "orkinFile.h"
#endif
#endif /*MORK_CONFIG_USE_ORKINFILE*/
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789

Просмотреть файл

@ -173,19 +173,20 @@ void morkHandle::NewDownHandleError(morkEnv* ev) const
}
morkObject* morkHandle::GetGoodHandleObject(morkEnv* ev,
mork_bool inMutable, mork_magic inMagicType) const
mork_bool inMutable, mork_magic inMagicType, mork_bool inClosedOkay) const
{
morkObject* outObject = 0;
if ( this->IsHandle() && this->GoodHandleTag() && this->IsOpenNode() )
if ( this->IsHandle() && this->GoodHandleTag() &&
( inClosedOkay || this->IsOpenNode() ) )
{
if ( !inMagicType || mHandle_Magic == inMagicType )
{
morkObject* obj = this->mHandle_Object;
if ( obj )
if ( obj )
{
if ( obj->IsNode() )
{
if ( obj->IsOpenNode() )
if ( inClosedOkay || obj->IsOpenNode() )
{
if ( this->IsMutable() || !inMutable )
outObject = obj;
@ -198,7 +199,7 @@ morkObject* morkHandle::GetGoodHandleObject(morkEnv* ev,
else
this->NonNodeObjectError(ev);
}
else
else if ( !inClosedOkay )
this->NilHandleObjectError(ev);
}
else
@ -207,27 +208,28 @@ morkObject* morkHandle::GetGoodHandleObject(morkEnv* ev,
else
this->NewDownHandleError(ev);
MORK_ASSERT(outObject);
MORK_ASSERT(outObject || inClosedOkay);
return outObject;
}
morkEnv*
morkHandle::CanUseHandle(nsIMdbEnv* mev, mork_bool inMutable,
mdb_err* outErr) const
mork_bool inClosedOkay, mdb_err* outErr) const
{
morkEnv* outEnv = 0;
morkEnv* ev = morkEnv::FromMdbEnv(mev);
if ( ev )
{
morkObject* obj = this->GetGoodHandleObject(ev, inMutable, /*magic*/ 0);
morkObject* obj = this->GetGoodHandleObject(ev, inMutable,
/*magic*/ 0, inClosedOkay);
if ( obj )
{
outEnv = ev;
}
*outErr = ev->AsErr();
}
MORK_ASSERT(outEnv);
MORK_ASSERT(outEnv || inClosedOkay);
return outEnv;
}
@ -238,15 +240,20 @@ morkHandle::CanUseHandle(nsIMdbEnv* mev, mork_bool inMutable,
morkHandle::Handle_IsFrozenMdbObject(nsIMdbEnv* mev, mdb_bool* outIsReadonly)
{
mdb_err outErr = 0;
mdb_bool readOnly = mdbBool_kTrue;
morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse, &outErr);
morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse,
/*inClosedOkay*/ morkBool_kTrue, &outErr);
if ( ev )
{
MORK_ASSERT(outIsReadonly);
if ( outIsReadonly )
*outIsReadonly = mHandle_Object->IsFrozen();
readOnly = mHandle_Object->IsFrozen();
outErr = ev->AsErr();
}
MORK_ASSERT(outIsReadonly);
if ( outIsReadonly )
*outIsReadonly = readOnly;
return outErr;
}
// same as nsIMdbPort::GetIsPortReadonly() when this object is inside a port.
@ -257,23 +264,27 @@ morkHandle::Handle_IsFrozenMdbObject(nsIMdbEnv* mev, mdb_bool* outIsReadonly)
morkHandle::Handle_GetMdbFactory(nsIMdbEnv* mev, nsIMdbFactory** acqFactory)
{
mdb_err outErr = 0;
nsIMdbFactory* handle = 0;
morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse, &outErr);
morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse,
/*inClosedOkay*/ morkBool_kTrue, &outErr);
if ( ev )
{
morkFactory* factory = ev->mEnv_Factory;
if ( factory )
{
nsIMdbFactory* handle = factory->AcquireFactoryHandle(ev);
MORK_ASSERT(acqFactory);
if ( handle && acqFactory )
*acqFactory = handle;
handle = factory->AcquireFactoryHandle(ev);
}
else
this->NilFactoryError(ev);
outErr = ev->AsErr();
}
MORK_ASSERT(acqFactory);
if ( acqFactory )
*acqFactory = handle;
return outErr;
}
// } ----- end factory methods -----
@ -284,16 +295,19 @@ morkHandle::Handle_GetWeakRefCount(nsIMdbEnv* mev, // weak refs
mdb_count* outCount)
{
mdb_err outErr = 0;
mdb_count count = 0;
morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse, &outErr);
morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse,
/*inClosedOkay*/ morkBool_kTrue, &outErr);
if ( ev )
{
MORK_ASSERT(outCount);
if ( outCount )
*outCount = this->WeakRefsOnly();
count = this->WeakRefsOnly();
outErr = ev->AsErr();
}
MORK_ASSERT(outCount);
if ( outCount )
*outCount = count;
return outErr;
}
@ -302,16 +316,19 @@ morkHandle::Handle_GetStrongRefCount(nsIMdbEnv* mev, // strong refs
mdb_count* outCount)
{
mdb_err outErr = 0;
mdb_count count = 0;
morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse, &outErr);
morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse,
/*inClosedOkay*/ morkBool_kTrue, &outErr);
if ( ev )
{
MORK_ASSERT(outCount);
if ( outCount )
*outCount = this->StrongRefsOnly();
count = this->StrongRefsOnly();
outErr = ev->AsErr();
}
MORK_ASSERT(outCount);
if ( outCount )
*outCount = count;
return outErr;
}
@ -321,7 +338,8 @@ morkHandle::Handle_AddWeakRef(nsIMdbEnv* mev)
{
mdb_err outErr = 0;
morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse, &outErr);
morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse,
/*inClosedOkay*/ morkBool_kTrue, &outErr);
if ( ev )
{
this->AddWeakRef(ev);
@ -335,7 +353,8 @@ morkHandle::Handle_AddStrongRef(nsIMdbEnv* mev)
{
mdb_err outErr = 0;
morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse, &outErr);
morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse,
/*inClosedOkay*/ morkBool_kFalse, &outErr);
if ( ev )
{
this->AddStrongRef(ev);
@ -350,7 +369,8 @@ morkHandle::Handle_CutWeakRef(nsIMdbEnv* mev)
{
mdb_err outErr = 0;
morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse, &outErr);
morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse,
/*inClosedOkay*/ morkBool_kTrue, &outErr);
if ( ev )
{
this->CutWeakRef(ev);
@ -363,7 +383,8 @@ morkHandle::Handle_CutWeakRef(nsIMdbEnv* mev)
morkHandle::Handle_CutStrongRef(nsIMdbEnv* mev)
{
mdb_err outErr = 0;
morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse, &outErr);
morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse,
/*inClosedOkay*/ morkBool_kTrue, &outErr);
if ( ev )
{
this->CutStrongRef(ev);
@ -380,7 +401,8 @@ morkHandle::Handle_CloseMdbObject(nsIMdbEnv* mev)
if ( this->IsNode() && this->IsOpenNode() )
{
morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse, &outErr);
morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse,
/*inClosedOkay*/ morkBool_kTrue, &outErr);
if ( ev )
{
morkObject* object = mHandle_Object;

Просмотреть файл

@ -118,12 +118,12 @@ public: // other handle methods
void NonOpenObjectError(morkEnv* ev) const;
morkObject* GetGoodHandleObject(morkEnv* ev,
mork_bool inMutabl, mork_magic inMagicType) const;
mork_bool inMutable, mork_magic inMagicType, mork_bool inClosedOkay) const;
public: // interface supporting mdbObject methods
morkEnv* CanUseHandle(nsIMdbEnv* mev, mork_bool inMutable,
mdb_err* outErr) const;
mork_bool inClosedOkay, mdb_err* outErr) const;
// { ----- begin mdbObject style methods -----
mdb_err Handle_IsFrozenMdbObject(nsIMdbEnv* ev, mdb_bool* outIsReadonly);

Просмотреть файл

@ -342,6 +342,30 @@ morkNode::CloseNode(morkEnv* ev) // called by CloseMorkNode();
}
extern void // utility method very similar to morkNode::SlotStrongNode():
nsIMdbCompare_SlotStrongCompare(nsIMdbCompare* self, morkEnv* ev,
nsIMdbCompare** ioSlot)
// If *ioSlot is non-nil, that compare is released by CutStrongRef() and
// then zeroed out. Then if self is non-nil, this is acquired by
// calling AddStrongRef(), and if the return value shows success,
// then self is put into slot *ioSlot. Note self can be nil, so we take
// expression 'nsIMdbCompare_SlotStrongCompare(0, ev, &slot)'.
{
nsIMdbEnv* menv = ev->AsMdbEnv();
nsIMdbCompare* compare = *ioSlot;
if ( self != compare )
{
if ( compare )
{
*ioSlot = 0;
compare->CutStrongRef(menv);
}
if ( self && ev->Good() && (self->AddStrongRef(menv)==0) && ev->Good() )
*ioSlot = self;
}
}
extern void // utility method very similar to morkNode::SlotStrongNode():
nsIMdbFile_SlotStrongFile(nsIMdbFile* self, morkEnv* ev, nsIMdbFile** ioSlot)
// If *ioSlot is non-nil, that file is released by CutStrongRef() and
@ -352,13 +376,16 @@ nsIMdbFile_SlotStrongFile(nsIMdbFile* self, morkEnv* ev, nsIMdbFile** ioSlot)
{
nsIMdbEnv* menv = ev->AsMdbEnv();
nsIMdbFile* file = *ioSlot;
if ( file )
if ( self != file )
{
*ioSlot = 0;
file->CutStrongRef(menv);
if ( file )
{
*ioSlot = 0;
file->CutStrongRef(menv);
}
if ( self && ev->Good() && (self->AddStrongRef(menv)==0) && ev->Good() )
*ioSlot = self;
}
if ( self && ev->Good() && (self->AddStrongRef(menv)==0) && ev->Good() )
*ioSlot = self;
}
void // utility method very similar to morkNode::SlotStrongNode():
@ -371,13 +398,16 @@ nsIMdbHeap_SlotStrongHeap(nsIMdbHeap* self, morkEnv* ev, nsIMdbHeap** ioSlot)
{
nsIMdbEnv* menv = ev->AsMdbEnv();
nsIMdbHeap* heap = *ioSlot;
if ( heap )
if ( self != heap )
{
*ioSlot = 0;
heap->CutStrongRef(menv);
if ( heap )
{
*ioSlot = 0;
heap->CutStrongRef(menv);
}
if ( self && ev->Good() && (self->AddStrongRef(menv)==0) && ev->Good() )
*ioSlot = self;
}
if ( self && ev->Good() && (self->AddStrongRef(menv)==0) && ev->Good() )
*ioSlot = self;
}
/*public static*/ void

Просмотреть файл

@ -275,7 +275,16 @@ nsIMdbFile_SlotStrongFile(nsIMdbFile* self, morkEnv* ev, nsIMdbFile** ioSlot);
// then zeroed out. Then if self is non-nil, this is acquired by
// calling AddStrongRef(), and if the return value shows success,
// then self is put into slot *ioSlot. Note self can be nil, so we take
// expression 'nsIMdbHeap_SlotStrongFile(0, ev, &slot)'.
// expression 'nsIMdbFile_SlotStrongFile(0, ev, &slot)'.
extern void // utility method very similar to morkNode::SlotStrongNode():
nsIMdbCompare_SlotStrongCompare(nsIMdbCompare* self, morkEnv* ev,
nsIMdbCompare** ioSlot);
// If *ioSlot is non-nil, that compare is released by CutStrongRef() and
// then zeroed out. Then if self is non-nil, this is acquired by
// calling AddStrongRef(), and if the return value shows success,
// then self is put into slot *ioSlot. Note self can be nil, so we take
// expression 'nsIMdbCompare_SlotStrongCompare(0, ev, &slot)'.
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789

Просмотреть файл

@ -56,9 +56,9 @@
#include "morkNodeMap.h"
#endif
#ifndef _MORKFILE_
#include "morkFile.h"
#endif
// #ifndef _MORKFILE_
// #include "morkFile.h"
// #endif
#ifndef _MORKBUILDER_
#include "morkBuilder.h"
@ -246,9 +246,13 @@ morkStore::CloseStore(morkEnv* ev) // called by CloseMorkNode();
{
if ( this->IsNode() )
{
morkFile* file = mStore_File;
if ( file && file->IsOpenNode() )
file->CloseMorkNode(ev);
// morkFile* file = mStore_File;
// if ( file && file->IsOpenNode() )
// file->CloseMorkNode(ev);
nsIMdbFile* file = mStore_File;
if ( file )
file->CloseMdbObject(ev->AsMdbEnv());
morkAtomSpace::SlotStrongAtomSpace((morkAtomSpace*) 0, ev,
&mStore_OidAtomSpace);
@ -259,7 +263,11 @@ morkStore::CloseStore(morkEnv* ev) // called by CloseMorkNode();
mStore_RowSpaces.CloseMorkNode(ev);
mStore_AtomSpaces.CloseMorkNode(ev);
morkBuilder::SlotStrongBuilder((morkBuilder*) 0, ev, &mStore_Builder);
morkFile::SlotStrongFile((morkFile*) 0, ev, &mStore_File);
// morkFile::SlotStrongFile((morkFile*) 0, ev, &mStore_File);
nsIMdbFile_SlotStrongFile((nsIMdbFile*) 0, ev,
&mStore_File);
morkStream::SlotStrongStream((morkStream*) 0, ev, &mStore_InStream);
morkStream::SlotStrongStream((morkStream*) 0, ev, &mStore_OutStream);
@ -277,10 +285,27 @@ morkStore::CloseStore(morkEnv* ev) // called by CloseMorkNode();
// } ===== end morkNode methods =====
// ````` ````` ````` ````` `````
mork_bool morkStore::DoPreferLargeOverCompressCommit(morkEnv* ev)
// true when mStore_CanWriteIncremental && store has file large enough
{
nsIMdbFile* file = mStore_File;
nsIMdbEnv* menv = ev->AsMdbEnv();
if ( file && mStore_CanWriteIncremental )
{
mdb_pos fileEof = 0;
file->Eof(ev->AsMdbEnv(), &fileEof);
if ( ev->Good() && fileEof > 128 )
return morkBool_kTrue;
}
return morkBool_kFalse;
}
mork_percent morkStore::PercentOfStoreWasted(morkEnv* ev)
{
mork_percent outPercent = 0;
morkFile* file = mStore_File;
nsIMdbFile* file = mStore_File;
nsIMdbEnv* menv = ev->AsMdbEnv();
if ( file )
{
@ -291,7 +316,8 @@ mork_percent morkStore::PercentOfStoreWasted(morkEnv* ev)
if ( firstPos < 512 && secondPos > firstPos )
firstPos = secondPos; // better approximation of first commit
mork_pos fileLength = file->Length(ev); // end of file
mork_pos fileLength = 0;
file->Eof(ev->AsMdbEnv(), &fileLength); // end of file
if ( ev->Good() && fileLength > firstPos )
{
mork_size groupContent = fileLength - firstPos;
@ -501,7 +527,7 @@ morkStream* morkStore::LazyGetInStream(morkEnv* ev)
{
if ( !mStore_InStream )
{
morkFile* file = mStore_File;
nsIMdbFile* file = mStore_File;
if ( file )
{
morkStream* stream = new(*mPort_Heap, ev)
@ -523,7 +549,7 @@ morkStream* morkStore::LazyGetOutStream(morkEnv* ev)
{
if ( !mStore_OutStream )
{
morkFile* file = mStore_File;
nsIMdbFile* file = mStore_File;
if ( file )
{
morkStream* stream = new(*mPort_Heap, ev)
@ -643,43 +669,38 @@ morkStore::CannotAutoAssignAtomIdentityError(morkEnv* ev)
mork_bool
morkStore::OpenStoreFile(morkEnv* ev, mork_bool inFrozen,
const char* inFilePath, const mdbOpenPolicy* inOpenPolicy)
// const char* inFilePath,
nsIMdbFile* ioFile, // db abstract file interface
const mdbOpenPolicy* inOpenPolicy)
{
MORK_USED_1(inOpenPolicy);
morkFile::SlotStrongFile((morkFile*) 0, ev, &mStore_File);
if ( ev->Good() )
{
morkFile* file = morkFile::OpenOldFile(ev, mPort_Heap,
inFilePath, inFrozen);
if ( file )
{
if ( ev->Good() )
morkFile::SlotStrongFile(file, ev, &mStore_File);
else
file->CutStrongRef(ev);
}
}
MORK_USED_2(inOpenPolicy,inFrozen);
nsIMdbFile_SlotStrongFile(ioFile, ev, &mStore_File);
// if ( ev->Good() )
// {
// morkFile* file = morkFile::OpenOldFile(ev, mPort_Heap,
// inFilePath, inFrozen);
// if ( ioFile )
// {
// if ( ev->Good() )
// morkFile::SlotStrongFile(file, ev, &mStore_File);
// else
// file->CutStrongRef(ev);
//
// }
// }
return ev->Good();
}
mork_bool
morkStore::CreateStoreFile(morkEnv* ev,
const char* inFilePath, const mdbOpenPolicy* inOpenPolicy)
// const char* inFilePath,
nsIMdbFile* ioFile, // db abstract file interface
const mdbOpenPolicy* inOpenPolicy)
{
MORK_USED_1(inOpenPolicy);
morkFile::SlotStrongFile((morkFile*) 0, ev, &mStore_File);
if ( ev->Good() )
{
morkFile* file = morkFile::CreateNewFile(ev, mPort_Heap,
inFilePath);
if ( file )
{
if ( ev->Good() )
morkFile::SlotStrongFile(file, ev, &mStore_File);
else
file->CutStrongRef(ev);
}
}
nsIMdbFile_SlotStrongFile(ioFile, ev, &mStore_File);
return ev->Good();
}

Просмотреть файл

@ -155,7 +155,7 @@ public: // state is public because the entire Mork system is private
morkAtomSpace* mStore_GroundAtomSpace; // ground atom space for scopes
morkAtomSpace* mStore_GroundColumnSpace; // ground column space for scopes
morkFile* mStore_File; // the file containing Mork text
nsIMdbFile* mStore_File; // the file containing Mork text
morkStream* mStore_InStream; // stream using file used by the builder
morkBuilder* mStore_Builder; // to parse Mork text and build structures
@ -246,6 +246,11 @@ public: // building an atom inside mStore_BookAtom from a char* string
// inString. This method is the standard way to stage a string as an
// atom for searching or adding new atoms into an atom space hash table.
public: // determining whether incremental writing is a good use of time:
mork_bool DoPreferLargeOverCompressCommit(morkEnv* ev);
// true when mStore_CanWriteIncremental && store has file large enough
public: // lazy creation of members and nested row or atom spaces
morkAtomSpace* LazyGetOidAtomSpace(morkEnv* ev);
@ -304,11 +309,13 @@ public: // other store methods
mork_bool OpenStoreFile(morkEnv* ev, // return value equals ev->Good()
mork_bool inFrozen,
const char* inFilePath,
// const char* inFilePath,
nsIMdbFile* ioFile, // db abstract file interface
const mdbOpenPolicy* inOpenPolicy);
mork_bool CreateStoreFile(morkEnv* ev, // return value equals ev->Good()
const char* inFilePath,
// const char* inFilePath,
nsIMdbFile* ioFile, // db abstract file interface
const mdbOpenPolicy* inOpenPolicy);
morkAtom* CopyAtom(morkEnv* ev, const morkAtom* inAtom);

Просмотреть файл

@ -66,7 +66,7 @@ morkStream::~morkStream() // assert CloseStream() executed earlier
/*public non-poly*/
morkStream::morkStream(morkEnv* ev, const morkUsage& inUsage,
nsIMdbHeap* ioHeap,
morkFile* ioContentFile, mork_size inBufSize, mork_bool inFrozen)
nsIMdbFile* ioContentFile, mork_size inBufSize, mork_bool inFrozen)
: morkFile(ev, inUsage, ioHeap, ioHeap)
, mStream_At( 0 )
, mStream_ReadEnd( 0 )
@ -89,12 +89,10 @@ morkStream::morkStream(morkEnv* ev, const morkUsage& inUsage,
if ( ioContentFile && ioHeap )
{
if ( ioContentFile->FileFrozen() ) // forced to be readonly?
inFrozen = morkBool_kTrue; // override the input value
// if ( ioContentFile->FileFrozen() ) // forced to be readonly?
// inFrozen = morkBool_kTrue; // override the input value
mork_pos fileEnd = ioContentFile->Length(ev);
morkFile::SlotStrongFile(ioContentFile, ev, &mStream_ContentFile);
nsIMdbFile_SlotStrongFile(ioContentFile, ev, &mStream_ContentFile);
if ( ev->Good() )
{
mork_u1* buf = 0;
@ -138,7 +136,7 @@ morkStream::CloseStream(morkEnv* ev) // called by CloseMorkNode();
{
if ( this->IsNode() )
{
morkFile::SlotStrongFile((morkFile*) 0, ev, &mStream_ContentFile);
nsIMdbFile_SlotStrongFile((nsIMdbFile*) 0, ev, &mStream_ContentFile);
nsIMdbHeap* heap = mFile_SlotHeap;
mork_u1* buf = mStream_Buf;
mStream_Buf = 0;
@ -401,7 +399,7 @@ morkStream::AcquireBud(morkEnv* ev, nsIMdbHeap* ioHeap)
{
MORK_USED_1(ioHeap);
morkFile* outFile = 0;
morkFile* file = mStream_ContentFile;
nsIMdbFile* file = mStream_ContentFile;
if ( this->IsOpenAndActiveFile() && file )
{
// figure out how this interacts with buffering and mStream_WriteEnd:
@ -417,31 +415,35 @@ morkStream::Length(morkEnv* ev) const // eof
{
mork_pos outPos = 0;
morkFile* file = mStream_ContentFile;
nsIMdbFile* file = mStream_ContentFile;
if ( this->IsOpenAndActiveFile() && file )
{
mork_pos contentEof = file->Length(ev);
if ( mStream_WriteEnd ) // this stream supports writing?
mork_pos contentEof = 0;
nsIMdbEnv* menv = ev->AsMdbEnv();
file->Eof(menv, &contentEof);
if ( ev->Good() )
{
// the local buffer might have buffered content past content eof
if ( ev->Good() ) // no error happened during Length() above?
if ( mStream_WriteEnd ) // this stream supports writing?
{
mork_u1* at = mStream_At;
mork_u1* buf = mStream_Buf;
if ( at >= buf ) // expected cursor order?
// the local buffer might have buffered content past content eof
if ( ev->Good() ) // no error happened during Length() above?
{
mork_pos localContent = mStream_BufPos + (at - buf);
if ( localContent > contentEof ) // buffered past eof?
contentEof = localContent; // return new logical eof
mork_u1* at = mStream_At;
mork_u1* buf = mStream_Buf;
if ( at >= buf ) // expected cursor order?
{
mork_pos localContent = mStream_BufPos + (at - buf);
if ( localContent > contentEof ) // buffered past eof?
contentEof = localContent; // return new logical eof
outPos = contentEof;
outPos = contentEof;
}
else this->NewBadCursorOrderError(ev);
}
else this->NewBadCursorOrderError(ev);
}
else
outPos = contentEof; // frozen files get length from content file
}
else
outPos = contentEof; // frozen files get length from content file
}
else this->NewFileDownError(ev);
@ -471,7 +473,7 @@ morkStream::Tell(morkEnv* ev) const
{
mork_pos outPos = 0;
morkFile* file = mStream_ContentFile;
nsIMdbFile* file = mStream_ContentFile;
if ( this->IsOpenAndActiveFile() && file )
{
mork_u1* buf = mStream_Buf;
@ -512,7 +514,7 @@ morkStream::Read(morkEnv* ev, void* outBuf, mork_size inSize)
mork_pos outActual = 0;
morkFile* file = mStream_ContentFile;
nsIMdbFile* file = mStream_ContentFile;
if ( this->IsOpenAndActiveFile() && file )
{
mork_u1* end = mStream_ReadEnd; // byte after last buffered byte
@ -558,21 +560,24 @@ morkStream::Read(morkEnv* ev, void* outBuf, mork_size inSize)
mStream_At = mStream_ReadEnd = buf; // empty buffer
file->Seek(ev, mStream_BufPos); // set file pos
if ( ev->Good() ) // no seek error?
// file->Seek(ev, mStream_BufPos); // set file pos
// if ( ev->Good() ) // no seek error?
// {
// }
mork_num actual = 0;
nsIMdbEnv* menv = ev->AsMdbEnv();
file->Get(menv, sink, inSize, mStream_BufPos, &actual);
if ( ev->Good() ) // no read error?
{
mork_num actual = file->Read(ev, sink, inSize);
if ( ev->Good() ) // no read error?
if ( actual )
{
if ( actual )
{
outActual += actual;
mStream_BufPos += actual;
mStream_HitEof = morkBool_kFalse;
}
else if ( !outActual )
mStream_HitEof = morkBool_kTrue;
outActual += actual;
mStream_BufPos += actual;
mStream_HitEof = morkBool_kFalse;
}
else if ( !outActual )
mStream_HitEof = morkBool_kTrue;
}
}
}
@ -596,7 +601,7 @@ morkStream::Seek(morkEnv* ev, mork_pos inPos)
{
mork_pos outPos = 0;
morkFile* file = mStream_ContentFile;
nsIMdbFile* file = mStream_ContentFile;
if ( this->IsOpenOrClosingNode() && this->FileActive() && file )
{
mork_u1* at = mStream_At; // current position in buffer
@ -615,7 +620,9 @@ morkStream::Seek(morkEnv* ev, mork_pos inPos)
{
if ( mStream_BufPos != inPos ) // need to change pos?
{
mork_pos eof = file->Length(ev);
mork_pos eof = 0;
nsIMdbEnv* menv = ev->AsMdbEnv();
file->Eof(menv, &eof);
if ( ev->Good() ) // no errors getting length?
{
if ( inPos <= eof ) // acceptable new position?
@ -634,7 +641,9 @@ morkStream::Seek(morkEnv* ev, mork_pos inPos)
{
if ( at >= buf && at <= readEnd ) // expected cursor order?
{
mork_pos eof = file->Length(ev);
mork_pos eof = 0;
nsIMdbEnv* menv = ev->AsMdbEnv();
file->Eof(menv, &eof);
if ( ev->Good() ) // no errors getting length?
{
if ( inPos <= eof ) // acceptable new position?
@ -662,7 +671,7 @@ morkStream::Write(morkEnv* ev, const void* inBuf, mork_size inSize)
{
mork_num outActual = 0;
morkFile* file = mStream_ContentFile;
nsIMdbFile* file = mStream_ContentFile;
if ( this->IsOpenActiveAndMutableFile() && file )
{
mork_u1* end = mStream_WriteEnd; // byte after last buffered byte
@ -725,17 +734,18 @@ morkStream::Write(morkEnv* ev, const void* inBuf, mork_size inSize)
}
else // directly to content file instead
{
file->Seek(ev, mStream_BufPos); // set pos
if ( ev->Good() ) // no seek error?
// file->Seek(ev, mStream_BufPos); // set pos
// if ( ev->Good() ) // no seek error?
// {
// }
nsIMdbEnv* menv = ev->AsMdbEnv();
mork_num actual = 0;
file->Put(menv, source, inSize, mStream_BufPos, &actual);
if ( ev->Good() ) // no write error?
{
mork_num actual =
file->Write(ev, source, inSize);
if ( ev->Good() ) // no write error?
{
outActual += actual;
mStream_BufPos += actual;
}
outActual += actual;
mStream_BufPos += actual;
}
}
}
@ -759,12 +769,13 @@ morkStream::Write(morkEnv* ev, const void* inBuf, mork_size inSize)
/*public virtual*/ void
morkStream::Flush(morkEnv* ev)
{
morkFile* file = mStream_ContentFile;
nsIMdbFile* file = mStream_ContentFile;
if ( this->IsOpenOrClosingNode() && this->FileActive() && file )
{
if ( mStream_Dirty )
this->spill_buf(ev);
file->Flush(ev);
file->Flush(ev->AsMdbEnv());
}
else this->NewFileDownError(ev);
}
@ -777,7 +788,7 @@ morkStream::fill_getc(morkEnv* ev)
{
int c = EOF;
morkFile* file = mStream_ContentFile;
nsIMdbFile* file = mStream_ContentFile;
if ( this->IsOpenAndActiveFile() && file )
{
mork_u1* buf = mStream_Buf;
@ -789,25 +800,28 @@ morkStream::fill_getc(morkEnv* ev)
if ( ev->Good() ) // no errors yet?
{
file->Seek(ev, mStream_BufPos); // set file pos
if ( ev->Good() ) // no seek error?
// file->Seek(ev, mStream_BufPos); // set file pos
// if ( ev->Good() ) // no seek error?
// {
// }
nsIMdbEnv* menv = ev->AsMdbEnv();
mork_num actual = 0;
file->Get(menv, buf, mStream_BufSize, mStream_BufPos, &actual);
if ( ev->Good() ) // no read errors?
{
mork_num actual = file->Read(ev, buf, mStream_BufSize);
if ( ev->Good() ) // no read errors?
if ( actual > mStream_BufSize ) // more than asked for??
actual = mStream_BufSize;
mStream_At = buf;
mStream_ReadEnd = buf + actual;
if ( actual ) // any bytes actually read?
{
if ( actual > mStream_BufSize ) // more than asked for??
actual = mStream_BufSize;
mStream_At = buf;
mStream_ReadEnd = buf + actual;
if ( actual ) // any bytes actually read?
{
c = *mStream_At++; // return first byte from buffer
mStream_HitEof = morkBool_kFalse;
}
else
mStream_HitEof = morkBool_kTrue;
c = *mStream_At++; // return first byte from buffer
mStream_HitEof = morkBool_kFalse;
}
else
mStream_HitEof = morkBool_kTrue;
}
}
}
@ -827,7 +841,7 @@ morkStream::spill_putc(morkEnv* ev, int c)
void
morkStream::spill_buf(morkEnv* ev) // spill/flush from buffer to file
{
morkFile* file = mStream_ContentFile;
nsIMdbFile* file = mStream_ContentFile;
if ( this->IsOpenOrClosingNode() && this->FileActive() && file )
{
mork_u1* buf = mStream_Buf;
@ -847,16 +861,19 @@ morkStream::spill_buf(morkEnv* ev) // spill/flush from buffer to file
}
if ( ev->Good() )
{
file->Seek(ev, mStream_BufPos);
// file->Seek(ev, mStream_BufPos);
// if ( ev->Good() )
// {
// }
nsIMdbEnv* menv = ev->AsMdbEnv();
mork_num actual = 0;
file->Put(menv, buf, count, mStream_BufPos, &actual);
if ( ev->Good() )
{
file->Write(ev, buf, count);
if ( ev->Good() )
{
mStream_BufPos += count; // past bytes written
mStream_At = buf; // reset buffer cursor
mStream_Dirty = morkBool_kFalse;
}
mStream_BufPos += actual; // past bytes written
mStream_At = buf; // reset buffer cursor
mStream_Dirty = morkBool_kFalse;
}
}
}

Просмотреть файл

@ -83,7 +83,7 @@ protected: // protected morkStream members
mork_u1* mStream_ReadEnd; // null or one byte past last readable byte
mork_u1* mStream_WriteEnd; // null or mStream_Buf + mStream_BufSize
morkFile* mStream_ContentFile; // where content is read and written
nsIMdbFile* mStream_ContentFile; // where content is read and written
mork_u1* mStream_Buf; // dynamically allocated memory to buffer io
mork_size mStream_BufSize; // requested buf size (fixed by min and max)
@ -98,7 +98,7 @@ public: // morkNode virtual methods
public: // morkStream construction & destruction
morkStream(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioHeap,
morkFile* ioContentFile, mork_size inBufSize, mork_bool inFrozen);
nsIMdbFile* ioContentFile, mork_size inBufSize, mork_bool inFrozen);
void CloseStream(morkEnv* ev); // called by CloseMorkNode();
private: // copying is not allowed
@ -172,7 +172,7 @@ public: // public non-poly morkStream methods
void NewCantWriteSourceError(morkEnv* ev) const;
void NewPosBeyondEofError(morkEnv* ev) const;
morkFile* GetStreamContentFile() const { return mStream_ContentFile; }
nsIMdbFile* GetStreamContentFile() const { return mStream_ContentFile; }
mork_size GetStreamBufferSize() const { return mStream_BufSize; }
mork_size PutIndent(morkEnv* ev, mork_count inDepth);

Просмотреть файл

@ -129,6 +129,13 @@ morkTableRowCursor::NonTableRowCursorTypeError(morkEnv* ev)
ev->NewError("non morkTableRowCursor");
}
orkinTableRowCursor*
morkTableRowCursor::AcquireUniqueRowCursorHandle(morkEnv* ev)
{
return this->AcquireTableRowCursorHandle(ev);
}
orkinTableRowCursor*
morkTableRowCursor::AcquireTableRowCursorHandle(morkEnv* ev)
{
@ -154,6 +161,23 @@ morkTableRowCursor::NextRowOid(morkEnv* ev, mdbOid* outOid)
return outPos;
}
mork_bool
morkTableRowCursor::CanHaveDupRowMembers(morkEnv* ev)
{
return morkBool_kFalse; // false default is correct
}
mork_count
morkTableRowCursor::GetMemberCount(morkEnv* ev)
{
morkTable* table = mTableRowCursor_Table;
if ( table )
return table->mTable_RowArray.mArray_Fill;
else
return 0;
}
morkRow*
morkTableRowCursor::NextRow(morkEnv* ev, mdbOid* outOid, mdb_pos* outPos)
{

Просмотреть файл

@ -81,12 +81,20 @@ public: // dynamic type identification
public: // typing
static void NonTableRowCursorTypeError(morkEnv* ev);
public: // handle attachment
orkinTableRowCursor* AcquireTableRowCursorHandle(morkEnv* ev);
public: // oid only iteration
mdb_pos NextRowOid(morkEnv* ev, mdbOid* outOid);
public: // other table row cursor methods
orkinTableRowCursor* AcquireTableRowCursorHandle(morkEnv* ev);
virtual mork_bool CanHaveDupRowMembers(morkEnv* ev);
virtual mork_count GetMemberCount(morkEnv* ev);
virtual orkinTableRowCursor* AcquireUniqueRowCursorHandle(morkEnv* ev);
mdb_pos NextRowOid(morkEnv* ev, mdbOid* outOid);
morkRow* NextRow(morkEnv* ev, mdbOid* outOid, mdb_pos* outPos);
virtual morkRow* NextRow(morkEnv* ev, mdbOid* outOid, mdb_pos* outPos);
public: // typesafe refcounting inlines calling inherited morkNode methods
static void SlotWeakTableRowCursor(morkTableRowCursor* me,

Просмотреть файл

@ -44,9 +44,9 @@
#include "morkStore.h"
#endif
#ifndef _MORKFILE_
#include "morkFile.h"
#endif
// #ifndef _MORKFILE_
// #include "morkFile.h"
// #endif
#ifndef _MORKWRITER_
#include "morkWriter.h"
@ -60,10 +60,6 @@
#include "morkBuilder.h"
#endif
#ifndef _MORKFILE_
#include "morkFile.h"
#endif
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
// ````` ````` ````` ````` `````
@ -134,7 +130,7 @@ morkThumb::CloseThumb(morkEnv* ev) // called by CloseMorkNode();
morkBuilder::SlotStrongBuilder((morkBuilder*) 0, ev, &mThumb_Builder);
morkWriter::SlotStrongWriter((morkWriter*) 0, ev, &mThumb_Writer);
morkFile::SlotStrongFile((morkFile*) 0, ev, &mThumb_File);
nsIMdbFile_SlotStrongFile((nsIMdbFile*) 0, ev, &mThumb_File);
morkStore::SlotStrongStore((morkStore*) 0, ev, &mThumb_Store);
morkPort::SlotStrongPort((morkPort*) 0, ev, &mThumb_SourcePort);
this->MarkShut();
@ -208,10 +204,11 @@ morkThumb::Make_OpenFileStore(morkEnv* ev, nsIMdbHeap* ioHeap,
morkThumb* outThumb = 0;
if ( ioHeap && ioStore )
{
morkFile* file = ioStore->mStore_File;
nsIMdbFile* file = ioStore->mStore_File;
if ( file )
{
mork_pos fileEof = file->Length(ev);
mork_pos fileEof = 0;
file->Eof(ev->AsMdbEnv(), &fileEof);
if ( ev->Good() )
{
outThumb = new(*ioHeap, ev)
@ -248,7 +245,7 @@ morkThumb::Make_LargeCommit(morkEnv* ev,
morkThumb* outThumb = 0;
if ( ioHeap && ioStore )
{
morkFile* file = ioStore->mStore_File;
nsIMdbFile* file = ioStore->mStore_File;
if ( file )
{
outThumb = new(*ioHeap, ev)
@ -266,10 +263,10 @@ morkThumb::Make_LargeCommit(morkEnv* ev,
writer->mWriter_NeedDirtyAll = morkBool_kFalse;
outThumb->mThumb_DoCollect = morkBool_kFalse;
morkStore::SlotStrongStore(ioStore, ev, &outThumb->mThumb_Store);
morkFile::SlotStrongFile(file, ev, &outThumb->mThumb_File);
morkWriter::SlotStrongWriter(writer, ev, &outThumb->mThumb_Writer);
// writer no longer holds on to this.
writer->CutStrongRef(ev);
nsIMdbFile_SlotStrongFile(file, ev, &outThumb->mThumb_File);
outThumb->mThumb_Writer = writer; // pass writer ownership to thumb
}
}
}
@ -289,7 +286,7 @@ morkThumb::Make_CompressCommit(morkEnv* ev,
morkThumb* outThumb = 0;
if ( ioHeap && ioStore )
{
morkFile* file = ioStore->mStore_File;
nsIMdbFile* file = ioStore->mStore_File;
if ( file )
{
outThumb = new(*ioHeap, ev)
@ -305,7 +302,7 @@ morkThumb::Make_CompressCommit(morkEnv* ev,
writer->mWriter_NeedDirtyAll = morkBool_kTrue;
outThumb->mThumb_DoCollect = inDoCollect;
morkStore::SlotStrongStore(ioStore, ev, &outThumb->mThumb_Store);
morkFile::SlotStrongFile(file, ev, &outThumb->mThumb_File);
nsIMdbFile_SlotStrongFile(file, ev, &outThumb->mThumb_File);
morkWriter::SlotStrongWriter(writer, ev, &outThumb->mThumb_Writer);
// cope with fact that parsed transaction groups are going away:

Просмотреть файл

@ -82,7 +82,7 @@ public: // state is public because the entire Mork system is private
mork_u2 mThumb_Seed; // optional seed for u4 alignment padding
morkStore* mThumb_Store; // weak ref to created store
morkFile* mThumb_File; // strong ref to file (store, import, export)
nsIMdbFile* mThumb_File; // strong ref to file (store, import, export)
morkWriter* mThumb_Writer; // strong ref to writer (for commit)
morkBuilder* mThumb_Builder; // strong ref to builder (for store open)
morkPort* mThumb_SourcePort; // strong ref to port for import

Просмотреть файл

@ -40,9 +40,9 @@
#include "morkWriter.h"
#endif
#ifndef _MORKFILE_
#include "morkFile.h"
#endif
// #ifndef _MORKFILE_
// #include "morkFile.h"
// #endif
#ifndef _MORKSTREAM_
#include "morkStream.h"
@ -113,7 +113,7 @@ morkWriter::~morkWriter() // assert CloseTable() executed earlier
/*public non-poly*/
morkWriter::morkWriter(morkEnv* ev, const morkUsage& inUsage,
nsIMdbHeap* ioHeap, morkStore* ioStore, morkFile* ioFile,
nsIMdbHeap* ioHeap, morkStore* ioStore, nsIMdbFile* ioFile,
nsIMdbHeap* ioSlotHeap)
: morkNode(ev, inUsage, ioHeap)
, mWriter_Store( 0 )
@ -194,7 +194,7 @@ morkWriter::morkWriter(morkEnv* ev, const morkUsage& inUsage,
if ( ioSlotHeap && ioFile && ioStore )
{
morkStore::SlotWeakStore(ioStore, ev, &mWriter_Store);
morkFile::SlotStrongFile(ioFile, ev, &mWriter_File);
nsIMdbFile_SlotStrongFile(ioFile, ev, &mWriter_File);
nsIMdbHeap_SlotStrongHeap(ioSlotHeap, ev, &mWriter_SlotHeap);
if ( ev->Good() )
{
@ -228,7 +228,8 @@ morkWriter::MakeWriterStream(morkEnv* ev) // give writer a suitable stream
}
else // compress commit
{
morkFile* bud = mWriter_File->AcquireBud(ev, heap);
nsIMdbFile* bud = 0;
mWriter_File->AcquireBud(ev->AsMdbEnv(), heap, &bud);
if ( bud )
{
if ( ev->Good() )
@ -239,7 +240,7 @@ morkWriter::MakeWriterStream(morkEnv* ev) // give writer a suitable stream
morkWriter_kStreamBufSize, frozen);
}
else
bud->CutStrongRef(ev);
bud->CutStrongRef(ev->AsMdbEnv());
}
}
@ -264,8 +265,8 @@ morkWriter::CloseWriter(morkEnv* ev) // called by CloseMorkNode();
if ( this->IsNode() )
{
morkStore::SlotWeakStore((morkStore*) 0, ev, &mWriter_Store);
morkFile::SlotStrongFile((morkFile*) 0, ev, &mWriter_File);
morkFile::SlotStrongFile((morkFile*) 0, ev, &mWriter_Bud);
nsIMdbFile_SlotStrongFile((nsIMdbFile*) 0, ev, &mWriter_File);
nsIMdbFile_SlotStrongFile((nsIMdbFile*) 0, ev, &mWriter_Bud);
morkStream::SlotStrongStream((morkStream*) 0, ev, &mWriter_Stream);
nsIMdbHeap_SlotStrongHeap((nsIMdbHeap*) 0, ev, &mWriter_SlotHeap);
this->MarkShut();
@ -1195,12 +1196,12 @@ morkWriter::OnContentDone(morkEnv* ev)
}
stream->Flush(ev);
morkFile* bud = mWriter_Bud;
nsIMdbFile* bud = mWriter_Bud;
if ( bud )
{
bud->Flush(ev);
bud->BecomeTrunk(ev);
morkFile::SlotStrongFile((morkFile*) 0, ev, &mWriter_Bud);
bud->Flush(ev->AsMdbEnv());
bud->BecomeTrunk(ev->AsMdbEnv());
nsIMdbFile_SlotStrongFile((nsIMdbFile*) 0, ev, &mWriter_Bud);
}
else if ( !mWriter_Incremental ) // should have a bud?
this->NilWriterBudError(ev);

Просмотреть файл

@ -126,8 +126,8 @@ class morkWriter : public morkNode { // row iterator
public: // state is public because the entire Mork system is private
morkStore* mWriter_Store; // weak ref to committing store
morkFile* mWriter_File; // strong ref to store's file
morkFile* mWriter_Bud; // strong ref to bud of mWriter_File
nsIMdbFile* mWriter_File; // strong ref to store's file
nsIMdbFile* mWriter_Bud; // strong ref to bud of mWriter_File
morkStream* mWriter_Stream; // strong ref to stream on bud file
nsIMdbHeap* mWriter_SlotHeap; // strong ref to slot heap
@ -200,7 +200,7 @@ public: // morkNode virtual methods
public: // morkWriter construction & destruction
morkWriter(morkEnv* ev, const morkUsage& inUsage,
nsIMdbHeap* ioHeap, morkStore* ioStore, morkFile* ioFile,
nsIMdbHeap* ioHeap, morkStore* ioStore, nsIMdbFile* ioFile,
nsIMdbHeap* ioSlotHeap);
void CloseWriter(morkEnv* ev); // called by CloseMorkNode();

Просмотреть файл

@ -142,7 +142,8 @@ orkinCell::CanUseCell(nsIMdbEnv* mev, mork_bool inMutable,
if ( ev )
{
morkCellObject* cellObj = (morkCellObject*)
this->GetGoodHandleObject(ev, inMutable, morkMagic_kCell);
this->GetGoodHandleObject(ev, inMutable, morkMagic_kCell,
/*inClosedOkay*/ morkBool_kFalse);
if ( cellObj )
{
if ( cellObj->IsCellObject() )

Просмотреть файл

@ -80,6 +80,14 @@
#include "morkThumb.h"
#endif
#ifndef _ORKINHEAP_
#include "orkinHeap.h"
#endif
#ifndef _ORKINCOMPARE_
#include "orkinCompare.h"
#endif
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
/* public virtual*/
@ -144,7 +152,8 @@ orkinFactory::CanUseFactory(nsIMdbEnv* mev, mork_bool inMutable,
if ( ev )
{
morkFactory* factory = (morkFactory*)
this->GetGoodHandleObject(ev, inMutable, morkMagic_kFactory);
this->GetGoodHandleObject(ev, inMutable, morkMagic_kFactory,
/*inClosedOkay*/ morkBool_kFalse);
if ( factory )
{
if ( factory->IsFactory() )
@ -277,7 +286,8 @@ orkinFactory::IsOpenMdbObject(nsIMdbEnv* mev, mdb_bool* outOpen)
// { ----- begin file methods -----
/*virtual*/ mdb_err
orkinFactory::OpenOldFile(nsIMdbEnv* mev, nsIMdbHeap* ioHeap,
const char* inFilePath, mork_bool inFrozen, nsIMdbFile** acqFile)
const char* inFilePath,
mork_bool inFrozen, nsIMdbFile** acqFile)
// Choose some subclass of nsIMdbFile to instantiate, in order to read
// (and write if not frozen) the file known by inFilePath. The file
// returned should be open and ready for use, and presumably positioned
@ -413,6 +423,26 @@ orkinFactory::MakeHeap(nsIMdbEnv* mev, nsIMdbHeap** acqHeap)
}
// } ----- end heap methods -----
// { ----- begin compare methods -----
/*virtual*/ mdb_err
orkinFactory::MakeCompare(nsIMdbEnv* mev, nsIMdbCompare** acqCompare)
{
mdb_err outErr = 0;
nsIMdbCompare* outCompare = 0;
morkEnv* ev = this->CanUseFactory(mev,
/*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
outCompare = new orkinCompare();
if ( !outCompare )
ev->OutOfMemoryError();
}
if ( acqCompare )
*acqCompare = outCompare;
return outErr;
}
// } ----- end compare methods -----
// { ----- begin row methods -----
/*virtual*/ mdb_err
orkinFactory::MakeRow(nsIMdbEnv* mev, nsIMdbHeap* ioHeap,
@ -440,8 +470,9 @@ orkinFactory::MakeRow(nsIMdbEnv* mev, nsIMdbHeap* ioHeap,
/*virtual*/ mdb_err
orkinFactory::CanOpenFilePort(
nsIMdbEnv* mev, // context
const char* inFilePath, // the file to investigate
const mdbYarn* inFirst512Bytes,
// const char* inFilePath, // the file to investigate
// const mdbYarn* inFirst512Bytes,
nsIMdbFile* ioFile, // db abstract file interface
mdb_bool* outCanOpen, // whether OpenFilePort() might succeed
mdbYarn* outFormatVersion)
{
@ -455,9 +486,9 @@ orkinFactory::CanOpenFilePort(
/*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
if ( inFilePath && inFirst512Bytes && outCanOpen )
if ( ioFile && outCanOpen )
{
canOpenAsPort = this->CanOpenMorkTextFile(ev, inFirst512Bytes);
canOpenAsPort = this->CanOpenMorkTextFile(ev, ioFile);
}
else
ev->NilPointerError();
@ -475,7 +506,8 @@ orkinFactory::CanOpenFilePort(
orkinFactory::OpenFilePort(
nsIMdbEnv* mev, // context
nsIMdbHeap* ioHeap, // can be nil to cause ev's heap attribute to be used
const char* inFilePath, // the file to open for readonly import
// const char* inFilePath, // the file to open for readonly import
nsIMdbFile* ioFile, // db abstract file interface
const mdbOpenPolicy* inOpenPolicy, // runtime policies for using db
nsIMdbThumb** acqThumb)
{
@ -486,7 +518,7 @@ orkinFactory::OpenFilePort(
/*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
if ( inFilePath && inOpenPolicy && acqThumb )
if ( ioFile && inOpenPolicy && acqThumb )
{
}
else
@ -543,17 +575,39 @@ orkinFactory::ThumbToOpenPort( // redeeming a completed thumb from OpenFilePort(
mork_bool
orkinFactory::CanOpenMorkTextFile(morkEnv* ev,
const mdbYarn* inFirst512Bytes)
// const mdbYarn* inFirst512Bytes,
nsIMdbFile* ioFile)
{
MORK_USED_1(ev);
mork_bool outBool = morkBool_kFalse;
mork_size headSize = MORK_STRLEN(morkWriter_kFileHeader);
const mdbYarn* y = inFirst512Bytes;
if ( y && y->mYarn_Buf && y->mYarn_Fill >= headSize )
char localBuf[ 256 + 4 ]; // for extra for sloppy safety
mdbYarn localYarn;
mdbYarn* y = &localYarn;
y->mYarn_Buf = localBuf; // space to hold content
y->mYarn_Fill = 0; // no logical content yet
y->mYarn_Size = 256; // physical capacity is 256 bytes
y->mYarn_More = 0;
y->mYarn_Form = 0;
y->mYarn_Grow = 0;
if ( ioFile )
{
mork_u1* buf = (mork_u1*) y->mYarn_Buf;
outBool = ( MORK_MEMCMP(morkWriter_kFileHeader, buf, headSize) == 0 );
nsIMdbEnv* menv = ev->AsMdbEnv();
mdb_size actualSize = 0;
ioFile->Get(menv, y->mYarn_Buf, y->mYarn_Size, /*pos*/ 0, &actualSize);
y->mYarn_Fill = actualSize;
if ( y->mYarn_Buf && actualSize >= headSize && ev->Good() )
{
mork_u1* buf = (mork_u1*) y->mYarn_Buf;
outBool = ( MORK_MEMCMP(morkWriter_kFileHeader, buf, headSize) == 0 );
}
}
else
ev->NilPointerError();
return outBool;
}
@ -561,8 +615,9 @@ orkinFactory::CanOpenMorkTextFile(morkEnv* ev,
/*virtual*/ mdb_err
orkinFactory::CanOpenFileStore(
nsIMdbEnv* mev, // context
const char* inFilePath, // the file to investigate
const mdbYarn* inFirst512Bytes,
// const char* inFilePath, // the file to investigate
// const mdbYarn* inFirst512Bytes,
nsIMdbFile* ioFile, // db abstract file interface
mdb_bool* outCanOpenAsStore, // whether OpenFileStore() might succeed
mdb_bool* outCanOpenAsPort, // whether OpenFilePort() might succeed
mdbYarn* outFormatVersion)
@ -578,10 +633,10 @@ orkinFactory::CanOpenFileStore(
/*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
if ( inFilePath && inFirst512Bytes && outCanOpenAsStore )
if ( ioFile && outCanOpenAsStore )
{
// right now always say true; later we should look for magic patterns
canOpenAsStore = this->CanOpenMorkTextFile(ev, inFirst512Bytes);
canOpenAsStore = this->CanOpenMorkTextFile(ev, ioFile);
canOpenAsPort = canOpenAsStore;
}
else
@ -602,7 +657,8 @@ orkinFactory::CanOpenFileStore(
orkinFactory::OpenFileStore( // open an existing database
nsIMdbEnv* mev, // context
nsIMdbHeap* ioHeap, // can be nil to cause ev's heap attribute to be used
const char* inFilePath, // the file to open for general db usage
// const char* inFilePath, // the file to open for general db usage
nsIMdbFile* ioFile, // db abstract file interface
const mdbOpenPolicy* inOpenPolicy, // runtime policies for using db
nsIMdbThumb** acqThumb)
{
@ -615,7 +671,7 @@ orkinFactory::OpenFileStore( // open an existing database
if ( !ioHeap ) // need to use heap from env?
ioHeap = ev->mEnv_Heap;
if ( inFilePath && inOpenPolicy && acqThumb )
if ( ioFile && inOpenPolicy && acqThumb )
{
morkFactory* factory = (morkFactory*) this->mHandle_Object;
morkStore* store = new(*ioHeap, ev)
@ -624,7 +680,7 @@ orkinFactory::OpenFileStore( // open an existing database
if ( store )
{
mork_bool frozen = morkBool_kFalse; // open store mutable access
if ( store->OpenStoreFile(ev, frozen, inFilePath, inOpenPolicy) )
if ( store->OpenStoreFile(ev, frozen, ioFile, inOpenPolicy) )
{
morkThumb* thumb = morkThumb::Make_OpenFileStore(ev, ioHeap, store);
if ( thumb )
@ -691,7 +747,8 @@ orkinFactory::ThumbToOpenStore( // redeem completed thumb from OpenFileStore()
orkinFactory::CreateNewFileStore( // create a new db with minimal content
nsIMdbEnv* mev, // 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 char* inFilePath, // name of file which should not yet exist
nsIMdbFile* ioFile, // db abstract file interface
const mdbOpenPolicy* inOpenPolicy, // runtime policies for using db
nsIMdbStore** acqStore)
{
@ -704,7 +761,7 @@ orkinFactory::CreateNewFileStore( // create a new db with minimal content
if ( !ioHeap ) // need to use heap from env?
ioHeap = ev->mEnv_Heap;
if ( inFilePath && inOpenPolicy && acqStore && ioHeap )
if ( ioFile && inOpenPolicy && acqStore && ioHeap )
{
morkFactory* factory = (morkFactory*) this->mHandle_Object;
morkStore* store = new(*ioHeap, ev)
@ -716,7 +773,7 @@ orkinFactory::CreateNewFileStore( // create a new db with minimal content
store->mStore_CanDirty = morkBool_kTrue;
store->SetStoreAndAllSpacesCanDirty(ev, morkBool_kTrue);
if ( store->CreateStoreFile(ev, inFilePath, inOpenPolicy) )
if ( store->CreateStoreFile(ev, ioFile, inOpenPolicy) )
outStore = orkinStore::MakeStore(ev, store);
store->CutStrongRef(ev); // always cut ref (handle has its own ref)

Просмотреть файл

@ -93,7 +93,9 @@ public: // utilities:
morkEnv* GetInternalFactoryEnv(mdb_err* outErr);
mork_bool CanOpenMorkTextFile(morkEnv* ev, const mdbYarn* inFirst512Bytes);
mork_bool CanOpenMorkTextFile(morkEnv* ev,
// const mdbYarn* inFirst512Bytes,
nsIMdbFile* ioFile);
public: // type identification
mork_bool IsOrkinFactory() const
@ -142,7 +144,8 @@ public:
// { ----- begin file methods -----
virtual mdb_err OpenOldFile(nsIMdbEnv* ev, nsIMdbHeap* ioHeap,
const char* inFilePath, mdb_bool inFrozen, nsIMdbFile** acqFile);
const char* inFilePath,
mdb_bool inFrozen, nsIMdbFile** acqFile);
// Choose some subclass of nsIMdbFile to instantiate, in order to read
// (and write if not frozen) the file known by inFilePath. The file
// returned should be open and ready for use, and presumably positioned
@ -151,7 +154,8 @@ public:
// other portions or Mork source code don't want to know how it's done.
virtual mdb_err CreateNewFile(nsIMdbEnv* ev, nsIMdbHeap* ioHeap,
const char* inFilePath, nsIMdbFile** acqFile);
const char* inFilePath,
nsIMdbFile** acqFile);
// Choose some subclass of nsIMdbFile to instantiate, in order to read
// (and write if not frozen) the file known by inFilePath. The file
// returned should be created and ready for use, and presumably positioned
@ -169,6 +173,10 @@ public:
virtual mdb_err MakeHeap(nsIMdbEnv* ev, nsIMdbHeap** acqHeap); // new heap
// } ----- end heap methods -----
// { ----- begin compare methods -----
virtual mdb_err MakeCompare(nsIMdbEnv* ev, nsIMdbCompare** acqCompare); // ASCII
// } ----- end compare methods -----
// { ----- begin row methods -----
virtual mdb_err MakeRow(nsIMdbEnv* ev, nsIMdbHeap* ioHeap, nsIMdbRow** acqRow); // new row
// ioHeap can be nil, causing the heap associated with ev to be used
@ -177,15 +185,17 @@ public:
// { ----- begin port methods -----
virtual mdb_err CanOpenFilePort(
nsIMdbEnv* ev, // context
const char* inFilePath, // the file to investigate
const mdbYarn* inFirst512Bytes,
// const char* inFilePath, // the file to investigate
// const mdbYarn* inFirst512Bytes,
nsIMdbFile* ioFile, // db abstract file interface
mdb_bool* outCanOpen, // whether OpenFilePort() might succeed
mdbYarn* outFormatVersion); // informal file format description
virtual mdb_err OpenFilePort(
nsIMdbEnv* ev, // context
nsIMdbHeap* ioHeap, // can be nil to cause ev's heap attribute to be used
const char* inFilePath, // the file to open for readonly import
// const char* inFilePath, // the file to open for readonly import
nsIMdbFile* ioFile, // db abstract file interface
const mdbOpenPolicy* inOpenPolicy, // runtime policies for using db
nsIMdbThumb** acqThumb); // acquire thumb for incremental port open
// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
@ -200,8 +210,9 @@ public:
// { ----- begin store methods -----
virtual mdb_err CanOpenFileStore(
nsIMdbEnv* ev, // context
const char* inFilePath, // the file to investigate
const mdbYarn* inFirst512Bytes,
// const char* inFilePath, // the file to investigate
// const mdbYarn* inFirst512Bytes,
nsIMdbFile* ioFile, // db abstract file interface
mdb_bool* outCanOpenAsStore, // whether OpenFileStore() might succeed
mdb_bool* outCanOpenAsPort, // whether OpenFilePort() might succeed
mdbYarn* outFormatVersion); // informal file format description
@ -209,7 +220,8 @@ public:
virtual mdb_err OpenFileStore( // open an existing database
nsIMdbEnv* ev, // context
nsIMdbHeap* ioHeap, // can be nil to cause ev's heap attribute to be used
const char* inFilePath, // the file to open for general db usage
// const char* inFilePath, // the file to open for general db usage
nsIMdbFile* ioFile, // db abstract file interface
const mdbOpenPolicy* inOpenPolicy, // runtime policies for using db
nsIMdbThumb** acqThumb); // acquire thumb for incremental store open
// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
@ -224,7 +236,8 @@ public:
virtual mdb_err 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 char* inFilePath, // name of file which should not yet exist
nsIMdbFile* ioFile, // db abstract file interface
const mdbOpenPolicy* inOpenPolicy, // runtime policies for using db
nsIMdbStore** acqStore); // acquire new db store object
// } ----- end store methods -----

Просмотреть файл

@ -38,8 +38,8 @@ public:
virtual ~orkinHeap(); // does nothing
private: // copying is not allowed
orkinHeap(const morkHandle& other);
orkinHeap& operator=(const morkHandle& other);
orkinHeap(const orkinHeap& other);
orkinHeap& operator=(const orkinHeap& other);
public:

Просмотреть файл

@ -97,7 +97,8 @@ orkinPortTableCursor::CanUsePortTableCursor(nsIMdbEnv* mev,
if ( ev )
{
morkPortTableCursor* self = (morkPortTableCursor*)
this->GetGoodHandleObject(ev, inMutable, morkMagic_kPortTableCursor);
this->GetGoodHandleObject(ev, inMutable, morkMagic_kPortTableCursor,
/*inClosedOkay*/ morkBool_kFalse);
if ( self )
{
if ( self->IsPortTableCursor() )

Просмотреть файл

@ -120,7 +120,8 @@ orkinRow::CanUseRow(nsIMdbEnv* mev, mork_bool inMutable,
if ( ev )
{
morkRowObject* rowObj = (morkRowObject*)
this->GetGoodHandleObject(ev, inMutable, morkMagic_kRow);
this->GetGoodHandleObject(ev, inMutable, morkMagic_kRow,
/*inClosedOkay*/ morkBool_kFalse);
if ( rowObj )
{
if ( rowObj->IsRowObject() )

Просмотреть файл

@ -104,7 +104,8 @@ orkinRowCellCursor::CanUseRowCellCursor(nsIMdbEnv* mev, mork_bool inMutable,
if ( ev )
{
morkRowCellCursor* self = (morkRowCellCursor*)
this->GetGoodHandleObject(ev, inMutable, morkMagic_kRowCellCursor);
this->GetGoodHandleObject(ev, inMutable, morkMagic_kRowCellCursor,
/*inClosedOkay*/ morkBool_kFalse);
if ( self )
{
if ( self->IsRowCellCursor() )

Просмотреть файл

@ -68,9 +68,9 @@
#include "morkThumb.h"
#endif
#ifndef _MORKFILE_
#include "morkFile.h"
#endif
// #ifndef _MORKFILE_
// #include "morkFile.h"
// #endif
#ifndef _ORKINTHUMB_
#include "orkinThumb.h"
@ -119,7 +119,8 @@ orkinStore::CanUseStore(nsIMdbEnv* mev,
if ( ev )
{
morkStore* self = (morkStore*)
this->GetGoodHandleObject(ev, inMutable, morkMagic_kStore);
this->GetGoodHandleObject(ev, inMutable, morkMagic_kStore,
/*inClosedOkay*/ morkBool_kFalse);
if ( self )
{
if ( self->IsStore() )
@ -373,7 +374,46 @@ orkinStore::GetPortFilePath(
morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
ev->StubMethodOnlyError();
morkStore* store = (morkStore*) mHandle_Object;
nsIMdbFile* file = store->mStore_File;
if ( file )
file->Path(mev, outFilePath);
else
store->NilStoreFileError(ev);
outErr = ev->AsErr();
}
return outErr;
}
/*virtual*/ mdb_err
orkinStore::GetPortFile(
nsIMdbEnv* mev, // context
nsIMdbFile** acqFile) // acquire file used by port or store
{
mdb_err outErr = 0;
if ( acqFile )
*acqFile = 0;
morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
morkStore* store = (morkStore*) mHandle_Object;
nsIMdbFile* file = store->mStore_File;
if ( file )
{
if ( acqFile )
{
file->AddStrongRef(mev);
if ( ev->Good() )
*acqFile = file;
}
}
else
store->NilStoreFileError(ev);
outErr = ev->AsErr();
}
return outErr;
@ -421,19 +461,25 @@ orkinStore::CanExportToFormat( // can export content in given specific format?
/*virtual*/ mdb_err
orkinStore::ExportToFormat( // export content in given specific format
nsIMdbEnv* mev, // context
const char* inFilePath, // the file to receive exported content
// const char* inFilePath, // the file to receive exported content
nsIMdbFile* ioFile, // destination abstract file interface
const char* inFormatVersion, // file format description
nsIMdbThumb** acqThumb) // acquire thumb for incremental export
// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
// then the export will be finished.
{
MORK_USED_2(inFilePath,inFormatVersion);
mdb_err outErr = 0;
nsIMdbThumb* outThumb = 0;
morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
ev->StubMethodOnlyError();
if ( ioFile && inFormatVersion && acqThumb )
{
ev->StubMethodOnlyError();
}
else
ev->NilPointerError();
outErr = ev->AsErr();
}
if ( acqThumb )
@ -995,6 +1041,33 @@ orkinStore::ImportContent( // import content from port
*acqThumb = outThumb;
return outErr;
}
/*virtual*/ mdb_err
orkinStore::ImportFile( // import content from port
nsIMdbEnv* mev, // context
nsIMdbFile* ioFile, // the file with content to add to store
nsIMdbThumb** acqThumb) // acquire thumb for incremental import
// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
// then the import will be finished.
{
nsIMdbThumb* outThumb = 0;
mdb_err outErr = 0;
morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
if ( ioFile && acqThumb )
{
ev->StubMethodOnlyError();
}
else
ev->NilPointerError();
outErr = ev->AsErr();
}
if ( acqThumb )
*acqThumb = outThumb;
return outErr;
}
// } ----- end inport/export methods -----
// { ----- begin hinting methods -----
@ -1065,8 +1138,8 @@ orkinStore::LargeCommit( // save important changes if at all possible
nsIMdbHeap* heap = store->mPort_Heap;
morkThumb* thumb = 0;
morkFile* file = store->mStore_File;
if ( file && file->Length(ev) > 128 && store->mStore_CanWriteIncremental )
// morkFile* file = store->mStore_File;
if ( store->DoPreferLargeOverCompressCommit(ev) )
{
thumb = morkThumb::Make_LargeCommit(ev, heap, store);
}
@ -1107,8 +1180,7 @@ orkinStore::SessionCommit( // save all changes if large commits delayed
nsIMdbHeap* heap = store->mPort_Heap;
morkThumb* thumb = 0;
morkFile* file = store->mStore_File;
if ( file && file->Length(ev) > 128 && store->mStore_CanWriteIncremental )
if ( store->DoPreferLargeOverCompressCommit(ev) )
{
thumb = morkThumb::Make_LargeCommit(ev, heap, store);
}

Просмотреть файл

@ -163,6 +163,10 @@ public: // type identification
nsIMdbEnv* ev, // context
mdbYarn* outFilePath, // name of file holding port content
mdbYarn* outFormatVersion); // file format description
virtual mdb_err GetPortFile(
nsIMdbEnv* ev, // context
nsIMdbFile** acqFile); // acquire file used by port or store
// } ----- end filepath methods -----
// { ----- begin export methods -----
@ -178,7 +182,8 @@ public: // type identification
virtual mdb_err ExportToFormat( // export content in given specific format
nsIMdbEnv* ev, // context
const char* inFilePath, // the file to receive exported content
// const char* inFilePath, // the file to receive exported content
nsIMdbFile* ioFile, // destination abstract file interface
const char* inFormatVersion, // file format description
nsIMdbThumb** acqThumb); // acquire thumb for incremental export
// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
@ -424,6 +429,13 @@ public: // type identification
nsIMdbThumb** acqThumb); // acquire thumb for incremental import
// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
// then the import will be finished.
virtual mdb_err ImportFile( // import content from port
nsIMdbEnv* ev, // context
nsIMdbFile* ioFile, // the file with content to add to store
nsIMdbThumb** acqThumb); // acquire thumb for incremental import
// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
// then the import will be finished.
// } ----- end inport/export methods -----
// { ----- begin hinting methods -----

Просмотреть файл

@ -111,7 +111,8 @@ orkinTable::CanUseTable(nsIMdbEnv* mev,
if ( ev )
{
morkTable* self = (morkTable*)
this->GetGoodHandleObject(ev, inMutable, morkMagic_kTable);
this->GetGoodHandleObject(ev, inMutable, morkMagic_kTable,
/*inClosedOkay*/ morkBool_kFalse);
if ( self )
{
if ( self->IsTable() )
@ -557,7 +558,7 @@ orkinTable::GetTableRowCursor( // make a cursor, starting iteration at inRowPos
{
if ( ev->Good() )
{
cursor->mCursor_Seed = (mork_seed) inRowPos;
// cursor->mCursor_Seed = (mork_seed) inRowPos;
outCursor = cursor->AcquireTableRowCursorHandle(ev);
}
else
@ -845,15 +846,13 @@ orkinTable::CutAllRows( // remove all rows from the table
// { ----- begin searching methods -----
/*virtual*/ mdb_err
orkinTable::SearchOneSortedColumn( // search only currently sorted col
orkinTable::FindRowMatches( // search variable number of sorted cols
nsIMdbEnv* mev, // context
const mdbYarn* inPrefix, // content to find as prefix in row's column cell
mdbRange* outRange) // range of matching rows
nsIMdbTableRowCursor** acqCursor) // set of matching rows
{
MORK_USED_1(inPrefix);
mdbRange range;
range.mRange_FirstPos = -1;
range.mRange_LastPos = -1;
nsIMdbTableRowCursor* outCursor = 0;
mdb_err outErr = 0;
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
@ -861,23 +860,31 @@ orkinTable::SearchOneSortedColumn( // search only currently sorted col
ev->StubMethodOnlyError();
outErr = ev->AsErr();
}
if ( outRange )
*outRange = range;
if ( acqCursor )
*acqCursor = outCursor;
return outErr;
}
/*virtual*/ mdb_err
orkinTable::SearchManyColumns( // search variable number of sorted cols
orkinTable::GetSearchColumns( // query columns used by FindRowMatches()
nsIMdbEnv* mev, // context
const mdbYarn* inPrefix, // content to find as prefix in row's column cell
mdbSearch* ioSearch, // columns to search and resulting ranges
nsIMdbThumb** acqThumb) // acquire thumb for incremental search
// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
// then the search will be finished. Until that time, the ioSearch argument
// is assumed referenced and used by the thumb; one should not inspect any
// output results in ioSearch until after the thumb is finished with it.
mdb_count* outCount, // context
mdbColumnSet* outColSet) // caller supplied space to put columns
// GetSearchColumns() returns the columns actually searched when the
// FindRowMatches() method is called. No more than mColumnSet_Count
// slots of mColumnSet_Columns will be written, since mColumnSet_Count
// indicates how many slots are present in the column array. The
// actual number of search column used by the table is returned in
// the outCount parameter; if this number exceeds mColumnSet_Count,
// then a caller needs a bigger array to read the entire column set.
// The minimum of mColumnSet_Count and outCount is the number slots
// in mColumnSet_Columns that were actually written by this method.
//
// Callers are expected to change this set of columns by calls to
// nsIMdbTable::SearchColumnsHint() or SetSearchSorting(), or both.
{
MORK_USED_2(inPrefix,ioSearch);
MORK_USED_1(outColSet);
mdb_count count = 0;
mdb_err outErr = 0;
nsIMdbThumb* outThumb = 0;
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
@ -886,8 +893,8 @@ orkinTable::SearchManyColumns( // search variable number of sorted cols
ev->StubMethodOnlyError();
outErr = ev->AsErr();
}
if ( acqThumb )
*acqThumb = outThumb;
if ( outCount )
*outCount = count;
return outErr;
}
// } ----- end searching methods -----
@ -975,20 +982,18 @@ orkinTable::EndBatchChangeHint( // advise before many adds and cuts
// sort following the primary column sort, when table rows are sorted.
/*virtual*/ mdb_err
orkinTable::CanSortColumn( // query which col is currently used for sorting
orkinTable::CanSortColumn( // query which column is currently used for sorting
nsIMdbEnv* mev, // context
mdb_column inColumn, // column to query sorting potential
mdb_bool* outCanSort) // whether the column can be sorted
{
MORK_USED_1(inColumn);
mdb_bool canSort = morkBool_kFalse;
mdb_bool canSort = mdbBool_kFalse;
mdb_err outErr = 0;
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
if ( outCanSort )
*outCanSort = morkBool_kFalse;
// ev->StubMethodOnlyError();
outErr = ev->AsErr();
}
if ( outCanSort )
@ -997,121 +1002,70 @@ orkinTable::CanSortColumn( // query which col is currently used for sorting
}
/*virtual*/ mdb_err
orkinTable::NewSortColumn( // change col used for sorting in the table
orkinTable::GetSorting( // view same table in particular sorting
nsIMdbEnv* mev, // context
mdb_column inColumn, // requested new column for sorting table
mdb_column* outActualColumn, // column actually used for sorting
nsIMdbThumb** acqThumb) // acquire thumb for incremental table resort
nsIMdbSorting** acqSorting) // acquire sorting for column
{
MORK_USED_1(inColumn);
mdb_column actualColumn = 0;
nsIMdbSorting* outSorting = 0;
mdb_err outErr = 0;
nsIMdbThumb* outThumb = 0;
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
ev->StubMethodOnlyError();
outErr = ev->AsErr();
}
if ( outActualColumn )
*outActualColumn = actualColumn;
if ( acqThumb )
*acqThumb = outThumb;
return outErr;
}
// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
// then the sort will be finished.
/*virtual*/ mdb_err
orkinTable::NewSortColumnWithCompare( // change sort col w/ explicit compare
nsIMdbEnv* mev, // context
nsIMdbCompare* ioCompare, // explicit interface for yarn comparison
mdb_column inColumn, // requested new column for sorting table
mdb_column* outActualColumn, // column actually used for sorting
nsIMdbThumb** acqThumb) // acquire thumb for incremental table resort
{
MORK_USED_2(inColumn,ioCompare);
mdb_column actualColumn = 0;
mdb_err outErr = 0;
nsIMdbThumb* outThumb = 0;
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
ev->StubMethodOnlyError();
outErr = ev->AsErr();
}
if ( outActualColumn )
*outActualColumn = actualColumn;
if ( acqThumb )
*acqThumb = outThumb;
return outErr;
}
// Note the table will hold a reference to inCompare if this object is used
// to sort the table. Until the table closes, callers can only force release
// of the compare object by changing the sort (by say, changing to unsorted).
// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
// then the sort will be finished.
/*virtual*/ mdb_err
orkinTable::GetSortColumn( // query which col is currently sorted
nsIMdbEnv* mev, // context
mdb_column* outColumn) // col the table uses for sorting (or zero)
{
mdb_err outErr = 0;
mdb_column col = 0;
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
ev->StubMethodOnlyError();
outErr = ev->AsErr();
}
if ( outColumn )
*outColumn = col;
if ( acqSorting )
*acqSorting = outSorting;
return outErr;
}
/*virtual*/ mdb_err
orkinTable::CloneSortColumn( // view same table with a different sort
orkinTable::SetSearchSorting( // use this sorting in FindRowMatches()
nsIMdbEnv* mev, // context
mdb_column inColumn, // requested new column for sorting table
nsIMdbThumb** acqThumb) // acquire thumb for incremental table clone
mdb_column inColumn, // often same as nsIMdbSorting::GetSortColumn()
nsIMdbSorting* ioSorting) // requested sorting for some column
// SetSearchSorting() attempts to inform the table that ioSorting
// should be used during calls to FindRowMatches() for searching
// the column which is actually sorted by ioSorting. This method
// is most useful in conjunction with nsIMdbSorting::SetCompare(),
// because otherwise a caller would not be able to override the
// comparison ordering method used during searchs. Note that some
// database implementations might be unable to use an arbitrarily
// specified sort order, either due to schema or runtime interface
// constraints, in which case ioSorting might not actually be used.
// Presumably ioSorting is an instance that was returned from some
// earlier call to nsIMdbTable::GetSorting(). A caller can also
// use nsIMdbTable::SearchColumnsHint() to specify desired change
// in which columns are sorted and searched by FindRowMatches().
//
// A caller can pass a nil pointer for ioSorting to request that
// column inColumn no longer be used at all by FindRowMatches().
// But when ioSorting is non-nil, then inColumn should match the
// column actually sorted by ioSorting; when these do not agree,
// implementations are instructed to give precedence to the column
// specified by ioSorting (so this means callers might just pass
// zero for inColumn when ioSorting is also provided, since then
// inColumn is both redundant and ignored).
{
MORK_USED_1(inColumn);
mdb_err outErr = 0;
nsIMdbThumb* outThumb = 0;
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
ev->StubMethodOnlyError();
if ( ioSorting )
{
ev->StubMethodOnlyError();
}
else
ev->NilPointerError();
outErr = ev->AsErr();
}
if ( acqThumb )
*acqThumb = outThumb;
return outErr;
}
// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
// then call nsIMdbTable::ThumbToCloneSortTable() to get the table instance.
/*virtual*/ mdb_err
orkinTable::ThumbToCloneSortTable( // redeem complete CloneSortColumn() thumb
nsIMdbEnv* mev, // context
nsIMdbThumb* ioThumb, // thumb from CloneSortColumn() with done status
nsIMdbTable** acqTable) // new table instance (or old if sort unchanged)
{
MORK_USED_1(ioThumb);
mdb_err outErr = 0;
nsIMdbTable* outTable = 0;
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
ev->StubMethodOnlyError();
outErr = ev->AsErr();
}
if ( acqTable )
*acqTable = outTable;
return outErr;
}
// } ----- end sorting methods -----
// { ----- begin moving methods -----

Просмотреть файл

@ -60,8 +60,8 @@ protected: // construction is protected (use the static Make() method)
// void CloseHandle(morkEnv* ev); // don't need to specialize closing
private: // copying is not allowed
orkinTable(const morkHandle& other);
orkinTable& operator=(const morkHandle& other);
orkinTable(const orkinTable& other);
orkinTable& operator=(const orkinTable& other);
// public: // dynamic type identification
// mork_bool IsHandle() const //
@ -273,23 +273,6 @@ public: // type identification
nsIMdbEnv* ev); // context
// } ----- end row set methods -----
// { ----- begin searching methods -----
virtual mdb_err SearchOneSortedColumn( // search only currently sorted col
nsIMdbEnv* ev, // context
const mdbYarn* inPrefix, // content to find as prefix in row's column cell
mdbRange* outRange); // range of matching rows
virtual mdb_err SearchManyColumns( // search variable number of sorted cols
nsIMdbEnv* ev, // context
const mdbYarn* inPrefix, // content to find as prefix in row's column cell
mdbSearch* ioSearch, // columns to search and resulting ranges
nsIMdbThumb** acqThumb); // acquire thumb for incremental search
// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
// then the search will be finished. Until that time, the ioSearch argument
// is assumed referenced and used by the thumb; one should not inspect any
// output results in ioSearch until after the thumb is finished with it.
// } ----- end searching methods -----
// { ----- begin hinting methods -----
virtual mdb_err SearchColumnsHint( // advise re future expected search cols
nsIMdbEnv* ev, // context
@ -319,6 +302,30 @@ public: // type identification
// a surprise request occurs for row position during batch changes.
// } ----- end hinting methods -----
// { ----- begin searching methods -----
virtual mdb_err FindRowMatches( // search variable number of sorted cols
nsIMdbEnv* ev, // context
const mdbYarn* inPrefix, // content to find as prefix in row's column cell
nsIMdbTableRowCursor** acqCursor); // set of matching rows
virtual mdb_err GetSearchColumns( // query columns used by FindRowMatches()
nsIMdbEnv* ev, // context
mdb_count* outCount, // context
mdbColumnSet* outColSet); // caller supplied space to put columns
// GetSearchColumns() returns the columns actually searched when the
// FindRowMatches() method is called. No more than mColumnSet_Count
// slots of mColumnSet_Columns will be written, since mColumnSet_Count
// indicates how many slots are present in the column array. The
// actual number of search column used by the table is returned in
// the outCount parameter; if this number exceeds mColumnSet_Count,
// then a caller needs a bigger array to read the entire column set.
// The minimum of mColumnSet_Count and outCount is the number slots
// in mColumnSet_Columns that were actually written by this method.
//
// Callers are expected to change this set of columns by calls to
// nsIMdbTable::SearchColumnsHint() or SetSearchSorting(), or both.
// } ----- end searching methods -----
// { ----- begin sorting methods -----
// sorting: note all rows are assumed sorted by row ID as a secondary
// sort following the primary column sort, when table rows are sorted.
@ -328,46 +335,38 @@ public: // type identification
nsIMdbEnv* ev, // context
mdb_column inColumn, // column to query sorting potential
mdb_bool* outCanSort); // whether the column can be sorted
virtual mdb_err
NewSortColumn( // change the column used for sorting in the table
nsIMdbEnv* ev, // context
mdb_column inColumn, // requested new column for sorting table
mdb_column* outActualColumn, // column actually used for sorting
nsIMdbThumb** acqThumb); // acquire thumb for incremental table resort
// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
// then the sort will be finished.
virtual mdb_err
NewSortColumnWithCompare( // change sort column with explicit compare
nsIMdbEnv* ev, // context
nsIMdbCompare* ioCompare, // explicit interface for yarn comparison
mdb_column inColumn, // requested new column for sorting table
mdb_column* outActualColumn, // column actually used for sorting
nsIMdbThumb** acqThumb); // acquire thumb for incremental table resort
// Note the table will hold a reference to inCompare if this object is used
// to sort the table. Until the table closes, callers can only force release
// of the compare object by changing the sort (by say, changing to unsorted).
// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
// then the sort will be finished.
virtual mdb_err GetSortColumn( // query which col is currently sorted
nsIMdbEnv* ev, // context
mdb_column* outColumn); // col the table uses for sorting (or zero)
virtual mdb_err CloneSortColumn( // view same table with a different sort
nsIMdbEnv* ev, // context
mdb_column inColumn, // requested new column for sorting table
nsIMdbThumb** acqThumb); // acquire thumb for incremental table clone
// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
// then call nsIMdbTable::ThumbToCloneSortTable() to get the table instance.
virtual mdb_err
ThumbToCloneSortTable( // redeem complete CloneSortColumn() thumb
virtual mdb_err GetSorting( // view same table in particular sorting
nsIMdbEnv* ev, // context
nsIMdbThumb* ioThumb, // thumb from CloneSortColumn() with done status
nsIMdbTable** acqTable); // new table instance (or old if sort unchanged)
mdb_column inColumn, // requested new column for sorting table
nsIMdbSorting** acqSorting); // acquire sorting for column
virtual mdb_err SetSearchSorting( // use this sorting in FindRowMatches()
nsIMdbEnv* ev, // context
mdb_column inColumn, // often same as nsIMdbSorting::GetSortColumn()
nsIMdbSorting* ioSorting); // requested sorting for some column
// SetSearchSorting() attempts to inform the table that ioSorting
// should be used during calls to FindRowMatches() for searching
// the column which is actually sorted by ioSorting. This method
// is most useful in conjunction with nsIMdbSorting::SetCompare(),
// because otherwise a caller would not be able to override the
// comparison ordering method used during searchs. Note that some
// database implementations might be unable to use an arbitrarily
// specified sort order, either due to schema or runtime interface
// constraints, in which case ioSorting might not actually be used.
// Presumably ioSorting is an instance that was returned from some
// earlier call to nsIMdbTable::GetSorting(). A caller can also
// use nsIMdbTable::SearchColumnsHint() to specify desired change
// in which columns are sorted and searched by FindRowMatches().
//
// A caller can pass a nil pointer for ioSorting to request that
// column inColumn no longer be used at all by FindRowMatches().
// But when ioSorting is non-nil, then inColumn should match the
// column actually sorted by ioSorting; when these do not agree,
// implementations are instructed to give precedence to the column
// specified by ioSorting (so this means callers might just pass
// zero for inColumn when ioSorting is also provided, since then
// inColumn is both redundant and ignored).
// } ----- end sorting methods -----
// { ----- begin moving methods -----

Просмотреть файл

@ -109,7 +109,8 @@ orkinTableRowCursor::CanUseTableRowCursor(nsIMdbEnv* mev,
if ( ev )
{
morkTableRowCursor* self = (morkTableRowCursor*)
this->GetGoodHandleObject(ev, inMutable, morkMagic_kTableRowCursor);
this->GetGoodHandleObject(ev, inMutable, morkMagic_kTableRowCursor,
/*inClosedOkay*/ morkBool_kFalse);
if ( self )
{
if ( self->IsTableRowCursor() )
@ -235,8 +236,7 @@ orkinTableRowCursor::GetCount(nsIMdbEnv* mev, mdb_count* outCount)
if ( ev )
{
morkTableRowCursor* cursor = (morkTableRowCursor*) mHandle_Object;
morkTable* table = cursor->mTableRowCursor_Table;
count = table->mTable_RowArray.mArray_Fill;
count = cursor->GetMemberCount(ev);
outErr = ev->AsErr();
}
if ( outCount )
@ -303,7 +303,8 @@ orkinTableRowCursor::SetDoFailOnSeedOutOfSync(nsIMdbEnv* mev, mdb_bool inFail)
this->CanUseTableRowCursor(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
ev->StubMethodOnlyError();
morkTableRowCursor* cursor = (morkTableRowCursor*) mHandle_Object;
cursor->mCursor_DoFailOnSeedOutOfSync = inFail;
outErr = ev->AsErr();
}
return outErr;
@ -318,7 +319,8 @@ orkinTableRowCursor::GetDoFailOnSeedOutOfSync(nsIMdbEnv* mev, mdb_bool* outFail)
this->CanUseTableRowCursor(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
ev->StubMethodOnlyError();
morkTableRowCursor* cursor = (morkTableRowCursor*) mHandle_Object;
fail = cursor->mCursor_DoFailOnSeedOutOfSync;
outErr = ev->AsErr();
}
if ( outFail )
@ -333,20 +335,6 @@ orkinTableRowCursor::GetDoFailOnSeedOutOfSync(nsIMdbEnv* mev, mdb_bool* outFail)
// { ===== begin nsIMdbTableRowCursor methods =====
// { ----- begin attribute methods -----
/*virtual*/ mdb_err
orkinTableRowCursor::SetTable(nsIMdbEnv* mev, nsIMdbTable* ioTable)
{
MORK_USED_1(ioTable);
mdb_err outErr = 0;
morkEnv* ev =
this->CanUseTableRowCursor(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
ev->StubMethodOnlyError();
outErr = ev->AsErr();
}
return outErr;
}
/*virtual*/ mdb_err
orkinTableRowCursor::GetTable(nsIMdbEnv* mev, nsIMdbTable** acqTable)
@ -428,67 +416,71 @@ orkinTableRowCursor::NextRow( // get row cells from table for cells already in r
}
// } ----- end row iteration methods -----
// { ----- begin copy iteration methods -----
// { ----- begin duplicate row removal methods -----
/*virtual*/ mdb_err
orkinTableRowCursor::NextRowCopy( // put row cells into sink only when already in sink
nsIMdbEnv* mev, // context
nsIMdbRow* ioSinkRow, // sink for row cells read from next row
mdbOid* outOid, // out row oid
mdb_pos* outRowPos)
orkinTableRowCursor::CanHaveDupRowMembers(nsIMdbEnv* mev, // cursor might hold dups?
mdb_bool* outCanHaveDups)
{
MORK_USED_1(ioSinkRow);
mdbOid oid;
oid.mOid_Scope = 0;
oid.mOid_Id = (mork_id) -1;
mdb_pos rowPos = -1;
mdb_err outErr = 0;
mdb_bool canHaveDups = mdbBool_kFalse;
morkEnv* ev =
this->CanUseTableRowCursor(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
if ( outOid )
{
ev->StubMethodOnlyError();
}
else
ev->NilPointerError();
morkTableRowCursor* cursor = (morkTableRowCursor*) mHandle_Object;
canHaveDups = cursor->CanHaveDupRowMembers(ev);
outErr = ev->AsErr();
}
if ( outRowPos )
*outRowPos = rowPos;
if ( outOid )
*outOid = oid;
if ( outCanHaveDups )
*outCanHaveDups = canHaveDups;
return outErr;
}
/*virtual*/ mdb_err
orkinTableRowCursor::NextRowCopyAll( // put all row cells into sink, adding to sink
orkinTableRowCursor::MakeUniqueCursor( // clone cursor, removing duplicate rows
nsIMdbEnv* mev, // context
nsIMdbRow* ioSinkRow, // sink for row cells read from next row
mdbOid* outOid, // out row oid
mdb_pos* outRowPos)
nsIMdbTableRowCursor** acqCursor) // acquire clone with no dups
// Note that MakeUniqueCursor() is never necessary for a cursor which was
// created by table method nsIMdbTable::GetTableRowCursor(), because a table
// never contains the same row as a member more than once. However, a cursor
// created by table method nsIMdbTable::FindRowMatches() might contain the
// same row more than once, because the same row can generate a hit by more
// than one column with a matching string prefix. Note this method can
// return the very same cursor instance with just an incremented refcount,
// when the original cursor could not contain any duplicate rows (calling
// CanHaveDupRowMembers() shows this case on a false return). Otherwise
// this method returns a different cursor instance. Callers should not use
// this MakeUniqueCursor() method lightly, because it tends to defeat the
// purpose of lazy programming techniques, since it can force creation of
// an explicit row collection in a new cursor's representation, in order to
// inspect the row membership and remove any duplicates; this can have big
// impact if a collection holds tens of thousands of rows or more, when
// the original cursor with dups simply referenced rows indirectly by row
// position ranges, without using an explicit row set representation.
// Callers are encouraged to use nsIMdbCursor::GetCount() to determine
// whether the row collection is very large (tens of thousands), and to
// delay calling MakeUniqueCursor() when possible, until a user interface
// element actually demands the creation of an explicit set representation.
{
MORK_USED_1(ioSinkRow);
mdbOid oid;
oid.mOid_Scope = 0;
oid.mOid_Id = (mork_id) -1;
mdb_pos rowPos = -1;
mdb_err outErr = 0;
nsIMdbTableRowCursor* outCursor = 0;
morkEnv* ev =
this->CanUseTableRowCursor(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
ev->StubMethodOnlyError();
if ( this->Handle_AddStrongRef(mev) == 0 )
outCursor = this;
outErr = ev->AsErr();
}
if ( outRowPos )
*outRowPos = rowPos;
if ( outOid )
*outOid = oid;
if ( acqCursor )
*acqCursor = outCursor;
return outErr;
} // nonzero if child, and a row child
// } ----- end copy iteration methods -----
}
// } ----- end duplicate row removal methods -----
// } ===== end nsIMdbTableRowCursor methods =====

Просмотреть файл

@ -150,7 +150,6 @@ public: // type identification
// { ===== begin nsIMdbTableRowCursor methods =====
// { ----- begin attribute methods -----
virtual mdb_err SetTable(nsIMdbEnv* ev, nsIMdbTable* ioTable); // sets pos to -1
virtual mdb_err GetTable(nsIMdbEnv* ev, nsIMdbTable** acqTable);
// } ----- end attribute methods -----
@ -168,19 +167,35 @@ public: // type identification
mdb_pos* outRowPos); // zero-based position of the row in table
// } ----- end row iteration methods -----
// { ----- begin copy iteration methods -----
virtual mdb_err NextRowCopy( // put row cells into sink only when already in sink
// { ----- begin duplicate row removal methods -----
virtual mdb_err CanHaveDupRowMembers(nsIMdbEnv* ev, // cursor might hold dups?
mdb_bool* outCanHaveDups);
virtual mdb_err MakeUniqueCursor( // clone cursor, removing duplicate rows
nsIMdbEnv* ev, // context
nsIMdbRow* ioSinkRow, // sink for row cells read from next row
mdbOid* outOid, // out row oid
mdb_pos* outRowPos); // zero-based position of the row in table
virtual mdb_err NextRowCopyAll( // put all row cells into sink, adding to sink
nsIMdbEnv* ev, // context
nsIMdbRow* ioSinkRow, // sink for row cells read from next row
mdbOid* outOid, // out row oid
mdb_pos* outRowPos); // zero-based position of the row in table
// } ----- end copy iteration methods -----
nsIMdbTableRowCursor** acqCursor); // acquire clone with no dups
// Note that MakeUniqueCursor() is never necessary for a cursor which was
// created by table method nsIMdbTable::GetTableRowCursor(), because a table
// never contains the same row as a member more than once. However, a cursor
// created by table method nsIMdbTable::FindRowMatches() might contain the
// same row more than once, because the same row can generate a hit by more
// than one column with a matching string prefix. Note this method can
// return the very same cursor instance with just an incremented refcount,
// when the original cursor could not contain any duplicate rows (calling
// CanHaveDupRowMembers() shows this case on a false return). Otherwise
// this method returns a different cursor instance. Callers should not use
// this MakeUniqueCursor() method lightly, because it tends to defeat the
// purpose of lazy programming techniques, since it can force creation of
// an explicit row collection in a new cursor's representation, in order to
// inspect the row membership and remove any duplicates; this can have big
// impact if a collection holds tens of thousands of rows or more, when
// the original cursor with dups simply referenced rows indirectly by row
// position ranges, without using an explicit row set representation.
// Callers are encouraged to use nsIMdbCursor::GetCount() to determine
// whether the row collection is very large (tens of thousands), and to
// delay calling MakeUniqueCursor() when possible, until a user interface
// element actually demands the creation of an explicit set representation.
// } ----- end duplicate row removal methods -----
// } ===== end nsIMdbTableRowCursor methods =====
};

Просмотреть файл

@ -87,7 +87,8 @@ orkinThumb::CanUseThumb(nsIMdbEnv* mev,
if ( ev )
{
morkThumb* self = (morkThumb*)
this->GetGoodHandleObject(ev, inMutable, morkMagic_kThumb);
this->GetGoodHandleObject(ev, inMutable, morkMagic_kThumb,
/*inClosedOkay*/ morkBool_kFalse);
if ( self )
{
if ( self->IsThumb() )