home *** CD-ROM | disk | FTP | other *** search
- #ifndef H_OOFctreeX
- #define H_OOFctreeX
-
- // OOFILE c-tree Plus backend implementation
- // IMPLEMENTATION header
-
- #include "oofctree.hpp"
- #include "oof2.hpp"
- #include "ooflist.hpp"
- #ifdef __CW55__
- // conflicts with defs in string.h if extern "C" these
- #include "ctdecl.h"
- #include "cterrc.h"
- #include "ctaerr.h"
- #else
- extern "C" {
- #include "ctdecl.h"
- #include "cterrc.h"
-
- #ifdef _Windows
- #define CTPERM
- #include "ctstrc.h"
- #include "ctgvar.h"
- #else
- #include "ctaerr.h"
- #endif
- }
- #endif
-
-
- // locking macros
-
- #define WITH_LOCK_WAIT do {
-
- #define IF_NON_LOCK_ERR if (filErr && (filErr!=DLOK_ERR) && (filErr!=ITIM_ERR))
-
- #define END_LOCK_WAIT(filErr) \
- if ((filErr==DLOK_ERR) || (filErr==ITIM_ERR)) { \
- LockCollisionWait(); \
- continue; \
- } \
- } while ((filErr==DLOK_ERR) || (filErr==ITIM_ERR));
-
-
- #ifdef _Macintosh
- const char kDirSeparator = ':';
- #else
- #ifdef _Windows
- const char kDirSeparator = '\\';
- #else
- #ifdef _DOS
- const char kDirSeparator = '\\';
- #else
- const char kDirSeparator = '/';
- #endif
- #endif
- #endif
-
- class OOF_Context_ctree : public OOF_Context
- {
- public:
- virtual ~OOF_Context_ctree();
-
- protected:
- OOF_Context_ctree(LONG off=0) :
- mCurrLoadedRecOffset(off),
- mBuffer(0),
- mRecordState(off>0 ? eLoaded : eUnloaded),
- mBlobFieldBodies(0)
- {};
- OOF_Context_ctree(const OOF_Context_ctree* rhs) :
- mCurrLoadedRecOffset(rhs->mCurrLoadedRecOffset),
- mBuffer(rhs->mBuffer),
- mRecordState(rhs->mRecordState),
- mBlobFieldBodies(rhs->mBlobFieldBodies ?
- new OOF_ExpandableLongArray(*(rhs->mBlobFieldBodies)) :
- 0)
- {};
-
- void SetOffset(LONG);
- // data storage
- enum ERecordState {eNew, eLoaded, eUnloaded};
- LONG mCurrLoadedRecOffset;
- char *mBuffer; // owned
- ERecordState mRecordState;
- OOF_ExpandableLongArray* mBlobFieldBodies;
-
- friend class OOF_tableBackend_ctree;
- };
-
-
-
-
- class OOF_ctreeSelection; // forward
-
- class OOF_ctreeSelectionRep : public OOF_ExpandableLongArray, public OOF_mixRefCount {
- private:
- // construction
- OOF_ctreeSelectionRep(unsigned long numSlots=0, unsigned int expandBySlots=10) :
- OOF_ExpandableLongArray(0, numSlots, expandBySlots)
- {};
-
- unsigned long* ExposeArray();
- void MarkAsUsed(unsigned long);
-
- friend class OOF_ctreeSelection;
- };
-
-
- class OOF_ctreeSelection {
- // a Handle class for OOF_ctreeSelectionRep
-
- // default constructor, or passing in zero items skips allocating storage
- public:
- enum selectionState {empty, oneRec, someRecs, allRecs};
- enum {kDefExpansionChunk=10};
-
- OOF_ctreeSelection() ;
- OOF_ctreeSelection(unsigned long numSlots);
- OOF_ctreeSelection(const selectionState, unsigned long numSlots);
- OOF_ctreeSelection(unsigned long numSlots, unsigned int expansionChunk);
- OOF_ctreeSelection(const OOF_ctreeSelection&);
- ~OOF_ctreeSelection();
-
- unsigned long* allocSelection(unsigned long numSlots);
- unsigned long* allocConsumedSelection(unsigned long numSlots);
- void adopt(OOF_ctreeSelection&);
- void copyContents(const OOF_ctreeSelection&);
-
- // combinatorial operators
- void difference_with(const OOF_ctreeSelection& rhs, OOF_tableBackend_ctree* caller);
- void intersection_with(const OOF_ctreeSelection& rhs);
- void union_with(const OOF_ctreeSelection& rhs);
-
- // reflective operators
- selectionState state() const;
- LONG oneRecOffset() const;
- bool isEmpty() const;
-
- // change state
- void selectNone();
- void selectOneRec(LONG);
- void selectAll();
-
- // access operators
- unsigned long& operator[](unsigned long);
- unsigned long& operator[](long);
- unsigned long& operator()();
- unsigned long value(unsigned long) const;
- void append(unsigned long);
- LONG appendNewRecord();
- void deleteEntry(unsigned long itemIndex);
- unsigned long& currentItem(); // same as operator() but easier to call internally
-
- // iterator protocol
- void start();
- bool more() const;
- void next();
- unsigned long count() const;
-
- // boolean operators
- bool isMember(unsigned long item) const;
-
- // other protocol
-
- OOF_ctreeSelection& operator=(const OOF_ctreeSelection&);
-
- private:
- void DropSelection();
-
- // data storage
- private:
- selectionState mState;
- OOF_ctreeSelectionRep *mRep; // owned
- unsigned long mInternalIter;
- LONG mCurrSingleRecOffset, mNextFakeNewRecOffset;
- };
-
-
- class OOF_ctreeFieldExtra { // should really be a nested class
- private:
- OOF_ctreeFieldExtra() :
- mKeyLength(0)
- {};
- // data storage
- VRLEN mOffset, mLength, mKeyLength;
- COUNT mIndexNo, mDODAfieldNo;
-
- friend class OOF_tableBackend_ctree;
- };
-
-
- // VERY simplistic class for now
- // later issues include recording masking only part of a field, this one assumes
- // each segment is the complete field
- class OOF_ctreeIndexSegList : public dbClass{ // should really be a nested class
- private:
- OOF_ctreeIndexSegList(COUNT indexFileNo, const dbCompoundField* indexField);
- virtual ~OOF_ctreeIndexSegList();
-
- public:
- // data access
- void appendFieldNo(fieldNumT);
- fieldNumT fieldNo(unsigned short segmentNo) const;
- bool startsWith(fieldNumT) const;
- bool startsWith(unsigned long pairOfFieldNos) const;
- COUNT indexFileNo() const;
- const dbCompoundField* indexField() const;
-
- private:
- // data storage
- fieldNumT *mSegmentFieldNos; // owned
- const COUNT mIndexFileNo;
- const dbCompoundField* mIndexField;
-
- friend class OOF_tableBackend_ctree; // can create us
- };
-
-
- class OOF_ctreeIndexDictionary : public OOF_Dictionary {
- private:
- OOF_ctreeIndexDictionary();
- virtual ~OOF_ctreeIndexDictionary() {};
-
- // data access
- COUNT indexStartingWithField(fieldNumT) const;
- const dbCompoundField* fieldMatchingPair(unsigned long) const;
-
- friend class OOF_tableBackend_ctree; // can create & use us
- };
-
-
- extern "C" {
- #ifdef NO_PROTOTYPE
- typedef LONG (ctDECL *ctComparativeKeySearch) (...);
- #else
- typedef LONG (ctDECL *ctComparativeKeySearch) (COUNT,pVOID,pVOID);
- #endif
- }
-
-
- class OOF_tableBackend_ctree : public OOF_tableBackend, private OOF_Context_ctree {
- private:
- // constructors
- OOF_tableBackend_ctree(const OOF_Dictionary& tablesfields, const OOF_String& tableName, dbConnect_ctree* connection):
- OOF_tableBackend(tablesfields, tableName),
- mConnection(connection),
- mFieldBufMap(0),
- mRecordCache(0)
- {};
- OOF_tableBackend_ctree(const OOF_tableBackend_ctree&, bool selectionNotCopied, const OOF_Dictionary& tablesFields);
- void operator=(const OOF_tableBackend_ctree&) {assert(0);};
-
- public:
- virtual ~OOF_tableBackend_ctree();
-
- virtual OOF_tableBackend* clone(bool selectionNotCopied, const OOF_Dictionary&) const;
- virtual void buildSchema();
- virtual void createTableInConnection(const dbConnect*);
- virtual void openTableInConnection(const dbConnect*);
- virtual unsigned int numIndexes() const;
- virtual unsigned int numFiles() const;
-
- virtual void setBlobLength(fieldNumT, unsigned long len);
-
- // public search functions
- virtual bool gotoRecord(unsigned long);
- virtual bool gotoRelativeRecord(unsigned long);
- virtual void selectAll();
- virtual void selectNone();
- virtual bool search(const dbQueryClause* qClause);
- virtual bool searchSelection(const dbQueryClause*);
- virtual bool searchEqual(const dbField*, const char*, bool matchEntireKey=true);
- virtual bool searchEqual(const dbField*, const VOID*);
- virtual void difference_with(const OOF_tableBackend*);
- virtual void intersection_with(const OOF_tableBackend*);
- virtual void invert();
- virtual void union_with(const OOF_tableBackend*);
- virtual bool loadRelatedContextJoiningFromTo(const dbField*, const dbField*);
-
- enum {kDataExtendSize=0, kIndexExtendSize=0};
- enum {kCtreeKeySeqenceAddonLength=4};
-
-
- // recordwise access
- virtual void start();
- virtual void next();
- virtual void prev();
- virtual bool more() const;
- virtual bool atFirst() const;
- virtual bool atLast() const;
-
- virtual void sortBy(fieldNumT);
- virtual unsigned long count() const;
- virtual unsigned long countAll() const;
-
- // data access
- virtual void newRecord();
- virtual void deleteRecord();
- virtual void saveRecord();
- virtual void unloadRecord();
- virtual bool isRecordLoaded() const;
- virtual unsigned long recordNumber() const;
-
- virtual void *getFieldWriteDest(fieldNumT);
- virtual void *getFieldReadFrom(fieldNumT);
- virtual void loadBlob(dbBLOB*);
-
- // reflective operators
- virtual unsigned long fieldDataLen(const dbField*) const;
- virtual unsigned long blobPointerReferenceSize() const;
- virtual long sequenceNumber() const;
-
- // current record context management
- virtual bool contextChangedFrom(const OOF_Context*) const;
- virtual void updateContext(OOF_Context*) const;
- virtual OOF_Context* createContext() const;
- virtual void returnToContext(OOF_Context*);
-
- protected:
- virtual void CacheDirtyBuffer();
-
- private:
- COUNT MapFieldTypeToCtreeKeyType(const OOF_fieldTypes, bool caseSensitive) const;
- COUNT MapFieldTypeToCtreeDODAType(const OOF_fieldTypes) const;
- VRLEN BlobLenFromBuffer(const dbField*, const char* theirBuffer) const;
- LONG BlobPosFromBuffer(const dbField* fld, const char* theirBuffer) const;
- VRLEN BlobLenFromBuffer(fieldNumT, const char* theirBuffer) const;
- LONG BlobPosFromBuffer(fieldNumT, const char* theirBuffer) const;
- void SetBlobLenInBuffer(fieldNumT, VRLEN len, const char* theirBuffer) const;
- void SetBlobPosInBuffer(fieldNumT, LONG pos, const char* theirBuffer) const;
- void ResetBlobsFromCache(OOF_ExpandableLongArray*, const char* theirBuffer);
- void LoadRecordAtOffset(LONG offset);
- void CompleteLoadFromOffset(LONG offset);
- void CompleteMoveToRecForAllRecs(COUNT err, const char* caller);
- bool MaybeLoadRecordFromCache(LONG offset);
- void SetISAMtoContext(const OOF_Context_ctree*);
- void SaveContext(OOF_Context_ctree*);
- void EnsureOurContextMatchesISAM();
-
- void AllocBuffer();
- void AdoptBlobs();
- void CompleteIIDX(const dbField *fld, IIDX& ix);
- void BuildBackendtables();
- DATOBJ* BuildDODA(UCOUNT& numDODAfields);
- unsigned long PadFieldWidthForAlignment(const dbField* fld) const;
- unsigned int FieldAlignsTo(const dbField*) const;
- void ResetBlobs();
- void BuildKey(COUNT keyIndexNo, char* target, const char* keyStr, COUNT keyStrLen, VRLEN keyLen) const;
- void BuildKey(COUNT keyIndexNo, char* target, const char* keyStr, COUNT keyStrLen, VRLEN keyLen, LONG suffix) const;
- void BuildKey(COUNT keyIndexNo, char* target, const VOID* binKey, VRLEN keyLen) const;
- void BuildKey(COUNT keyIndexNo, char* target, const VOID* binKey, VRLEN keyLen, LONG suffix) const;
-
- bool SearchBinaryFieldToLiteral(const dbQueryBinary*);
- bool SearchTrinaryFieldToLiterals(const dbQueryTrinary*);
- bool SearchCombineSubclauses(const dbQueryBinaryCombo*);
- void LockCollisionWait();
-
- bool SearchComparative(const dbField*, const char*, ctComparativeKeySearch, ctComparativeKeySearch, LONG possibleSuffix);
- bool SearchComparative(const dbField*, const VOID*, ctComparativeKeySearch, ctComparativeKeySearch, LONG possibleSuffix);
- bool SearchBetween(const dbField*, const char*, const char*);
- bool SearchBetween(const dbField*, const VOID*, const VOID*);
-
- // data storage
- enum {kOverheadLeadingBytes = 2};
- dbConnect_ctree* mConnection;
- OOF_ctreeSelection mSelection;
- OOF_ctreeFieldExtra *mFieldBufMap; // owned semi-static member passed onto sub-collections
- unsigned int* mFieldBufMapRefCount; // owned semi-static member passed onto sub-collections
- unsigned long mRecBufLen;
- unsigned short mNumFiles, mNumIndexes, mOverheadLeadingBytes;
- unsigned long mInternalIter; // mainly used for All recs
-
-
- COUNT mBlobFilNo, mISAMdatno, mSortIndexNo; // c-tree file number handling
- bool mUnsorted;
- OOF_ExpandableLongArray* mBlobFieldNums; // owned
- OOF_ExpandableLongArray* mRecordCache; // owned (used as pointers)
- IFIL mIFIL;
- OOF_ctreeIndexDictionary mIndexDictionary;
-
- static COUNT sNextFileNo;
-
- static void ResetCtreeFileNoForStartOfConnection(COUNT nextFileNo);
-
- public:
- static COUNT sFileMode;
-
- friend void dbConnect_ctree::SetupConnection(const OOF_String& connectionName);
- friend OOF_tableBackend *dbConnect_ctree::MakeTableBackend(const OOF_Dictionary& tablesfields, const OOF_String& tableName);
- friend void dbTable::ContextChange();
- };
-
-
- // include inline definitions
- #include "oofctrex.inl"
-
- #endif