00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef __DATABASE_H__
00012 #define __DATABASE_H__
00013
00014 #include "class.h"
00015 #include "reference.h"
00016 #include "file.h"
00017 #include "pagepool.h"
00018
00019 BEGIN_GIGABASE_NAMESPACE
00020
00021 #ifdef _WINCE
00022
00025 const size_t dbDefaultInitIndexSize = 10*1024;
00026
00030 const size_t dbDefaultExtensionQuantum = 1*512*1024;
00031 #else
00032
00035 const size_t dbDefaultInitIndexSize = 512*1024;
00036
00040 const size_t dbDefaultExtensionQuantum = 4*1024*1024;
00041 #endif
00042
00046 const unsigned dbMaxParallelSearchThreads = 64;
00047
00051 enum dbHandleFlags {
00052 dbPageObjectFlag = 0x1,
00053 dbModifiedFlag = 0x2,
00054 dbFreeHandleFlag = 0x4,
00055 dbFlagsMask = 0x7,
00056 dbFlagsBits = 3
00057 };
00058
00059 const size_t dbAllocationQuantumBits = 6;
00060 const size_t dbAllocationQuantum = 1 << dbAllocationQuantumBits;
00061 const size_t dbPageBits = 13;
00062 const size_t dbPageSize = 1 << dbPageBits;
00063 const size_t dbIdsPerPage = dbPageSize / sizeof(oid_t);
00064 const size_t dbHandlesPerPage = dbPageSize / sizeof(offs_t);
00065 const size_t dbHandleBits = 1 + sizeof(offs_t)/4;
00066 const size_t dbBitmapSegmentBits = dbPageBits + 3 + dbAllocationQuantumBits;
00067 const size_t dbBitmapSegmentSize = 1 << dbBitmapSegmentBits;
00068 const size_t dbBitmapPages = 1 << (dbDatabaseOffsetBits-dbBitmapSegmentBits);
00069 const size_t dbDirtyPageBitmapSize = 1 << (dbDatabaseOidBits-dbPageBits+dbHandleBits-3);
00070 const size_t dbDefaultSelectionLimit = 2000000000;
00075 const int dbBMsearchThreshold = 512;
00079 const size_t dbIndexedMergeThreshold = 100;
00080
00081
00082 const char_t dbMatchAnyOneChar = '_';
00083 const char_t dbMatchAnySubstring = '%';
00084
00085 const int dbMaxFileSegments = 64;
00086
00090 enum dbPredefinedIds {
00091 dbInvalidId,
00092 dbMetaTableId,
00093 dbBitmapId,
00094 dbFirstUserId = dbBitmapId + dbBitmapPages
00095 };
00096
00100 enum dbLockType {
00101 dbNoLock,
00102 dbSharedLock,
00103 dbUpdateLock,
00104 dbExclusiveLock
00105 };
00106
00110 class dbHeader {
00111 public:
00112 int4 curr;
00113 int4 dirty;
00114 int4 initialized;
00115 #if dbDatabaseOffsetBits > 32 && defined(ALIGN_HEADER)
00116 int4 pad1;
00117 #endif
00118 struct {
00119 offs_t size;
00120 offs_t index;
00121 offs_t shadowIndex;
00122 oid_t indexSize;
00123 oid_t shadowIndexSize;
00124 oid_t indexUsed;
00125 oid_t freeList;
00126 oid_t bitmapEnd;
00127 #ifdef DO_NOT_REUSE_OID_WITHIN_SESSION
00128 struct {
00129 oid_t head;
00130 oid_t tail;
00131 } sessionFreeList;
00132 #endif
00133 #if dbDatabaseOffsetBits > 32 && dbDatabaseOidBits <= 32 && defined(ALIGN_HEADER)
00134 oid_t pad2;
00135 #endif
00136 } root[2];
00137
00138 int4 versionMajor;
00139 int4 versionMinor;
00140 int4 transactionId;
00141 int4 mode;
00142
00143 enum {
00144 MODE_ALIGN_HEADER = 0x01,
00145 MODE_OID_64 = 0x02,
00146 MODE_OFFS_64 = 0x04,
00147 MODE_UNICODE = 0x08,
00148 MODE_AUTOINCREMENT = 0x10,
00149 MODE_RECTANGLE_DIM = 0x20,
00150 MODE_DO_NOT_REUSE_OID = 0x40
00151 };
00152
00153 int getVersion() {
00154 return versionMajor*100 + versionMinor;
00155 }
00156
00157 bool isCompatible();
00158 static int getCurrentMode();
00159
00160 bool isInitialized() {
00161 return initialized == 1
00162 && (dirty == 1 || dirty == 0)
00163 && (curr == 1 || curr == 0)
00164 && root[curr].size > root[curr].index
00165 && root[curr].size > root[curr].shadowIndex
00166 && root[curr].size > root[curr].indexSize*sizeof(offs_t)
00167 + root[curr].shadowIndexSize*sizeof(offs_t)
00168 && root[curr].indexSize >= root[curr].indexUsed
00169 && root[curr].indexUsed >= dbFirstUserId
00170 && root[curr].bitmapEnd > dbBitmapId;
00171 }
00172 };
00173
00174 class dbSynthesizedAttribute;
00175 class dbInheritedAttribute;
00176 class dbDatabaseThreadContext;
00177
00178 struct dbMemoryStatistic {
00179 offs_t used;
00180 offs_t free;
00181 offs_t nHoles;
00182 offs_t minHoleSize;
00183 offs_t maxHoleSize;
00184 size_t nHolesOfSize[dbDatabaseOffsetBits];
00185 };
00186
00187 class dbMonitor {
00188 public:
00189 dbLockType accLock;
00190
00191 dbDatabaseThreadContext* firstPending;
00192 dbDatabaseThreadContext* lastPending;
00193
00194 int nLockUpgrades;
00195
00196 int nReaders;
00197 int nWriters;
00198 int backupInProgress;
00199
00200 void wait(dbLockType type, dbMutex& mutex, dbDatabaseThreadContext* ctx);
00201
00202 dbMonitor() {
00203 firstPending = lastPending = NULL;
00204 accLock = dbNoLock;
00205 backupInProgress = 0;
00206 nReaders = nWriters = 0;
00207 nLockUpgrades = 0;
00208 }
00209 };
00210
00211
00212
00213 class dbAnyCursor;
00214 class dbQuery;
00215 class dbExprNode;
00216 class dbSearchContext;
00217
00218
00219 class dbVisitedObject {
00220 public:
00221 dbVisitedObject* next;
00222 oid_t oid;
00223
00224 dbVisitedObject(oid_t oid, dbVisitedObject* chain) {
00225 this->oid = oid;
00226 next = chain;
00227 }
00228 };
00229
00233 class GIGABASE_DLL_ENTRY dbDatabase {
00234 friend class dbSelection;
00235 friend class dbAnyCursor;
00236 friend class dbHashTable;
00237 friend class dbQuery;
00238 friend class dbRtree;
00239 friend class dbRtreePage;
00240 friend class dbBtree;
00241 friend class dbBtreePage;
00242 friend class dbThickBtreePage;
00243 friend class dbInheritedAttribute;
00244 friend class dbParallelQueryContext;
00245 friend class dbServer;
00246 friend class dbPagePool;
00247
00248 friend class dbBlob;
00249 friend class dbBlobIterator;
00250 friend class dbBlobReadIterator;
00251 friend class dbBlobWriteIterator;
00252 friend class dbAnyContainer;
00253
00254 friend class dbGetTie;
00255 friend class dbPutTie;
00256
00257 friend class dbUserFunctionArgument;
00258
00259 friend class dbCLI;
00260 friend class GiSTdb;
00261
00262 friend class dbBtreeIterator;
00263 friend class dbRtreeIterator;
00264 friend class dbTableIterator;
00265 public:
00273 bool open(char_t const* databaseName, time_t transactionCommitDelay = 0, int openAttr = 0);
00274
00282 bool open(dbFile* file, time_t transactionCommitDelay = 0, bool deleteFileOnClose = false);
00283
00284 enum dbAccessType {
00285 dbReadOnly,
00286 dbAllAccess,
00287 dbMulticlientReadOnly,
00288 dbMulticlientReadWrite
00289 };
00290
00294 struct OpenParameters {
00298 char_t const* databaseName;
00299
00303 int openAttr;
00304
00308 dbFile* file;
00309
00313 time_t transactionCommitDelay;
00314
00318 bool deleteFileOnClose;
00319
00329 bool doNotReuseOidAfterClose;
00330
00334 dbAccessType accessType;
00335
00342 size_t poolSize;
00343
00347 size_t extensionQuantum;
00348
00352 size_t initIndexSize;
00353
00357 int nThreads;
00358
00359
00364 offs_t freeSpaceReuseThreshold;
00365
00366 OpenParameters() {
00367 databaseName = NULL;
00368 openAttr = 0;
00369 file = NULL;
00370 transactionCommitDelay = 0;
00371 deleteFileOnClose = false;
00372 accessType = dbAllAccess;
00373 poolSize = 0;
00374 extensionQuantum = dbDefaultExtensionQuantum;
00375 initIndexSize = dbDefaultInitIndexSize;
00376 nThreads = 1;
00377 freeSpaceReuseThreshold = dbDefaultExtensionQuantum;
00378 doNotReuseOidAfterClose = false;
00379 }
00380 };
00381
00382
00388 bool open(OpenParameters& params);
00389
00390
00394 virtual void close();
00395
00399 void commit();
00400
00404 void executeBatch();
00405
00410 void precommit();
00411
00415 void rollback();
00416
00421 void attach();
00422
00428 void attach(dbDatabaseThreadContext* ctx);
00429
00430 enum DetachFlags {
00431 COMMIT = 1,
00432 DESTROY_CONTEXT = 2
00433 };
00438 void detach(int flags = COMMIT|DESTROY_CONTEXT);
00439
00444 void lock(dbLockType type = dbExclusiveLock) { beginTransaction(type); }
00445
00454 bool backup(char_t const* backupFileName, bool compactify);
00455
00465 bool backup(dbOSFile* file, bool compactify);
00466
00473 bool restore(char_t const* backupFileName, char_t const* databaseFileName);
00474
00478 int getVersion();
00479
00484 void assign(dbTableDescriptor& desc) {
00485 assert(((void)"Table is not yet assigned to the database",
00486 desc.tableId == 0));
00487 desc.db = this;
00488 desc.fixedDatabase = true;
00489 }
00490
00497 dbTableDescriptor* lookupTable(dbTableDescriptor* desc);
00498
00503 void getMemoryStatistic(dbMemoryStatistic& stat);
00504
00512 void setConcurrency(unsigned nThreads);
00513
00518 offs_t getAllocatedSize() { return allocatedSize; }
00519
00527 void allowColumnsDeletion(bool enabled = true) {
00528 confirmDeleteColumns = enabled;
00529 }
00530
00534 void disableOidReuseOnClose(bool disabled = true) {
00535 doNotReuseOidAfterClose = disabled;
00536 }
00537
00538
00546 bool prepareQuery(dbAnyCursor* cursor, dbQuery& query);
00547
00551 enum dbErrorClass {
00552 NoError,
00553 QueryError,
00554 ArithmeticError,
00555 IndexOutOfRangeError,
00556 DatabaseOpenError,
00557 FileError,
00558 OutOfMemoryError,
00559 Deadlock,
00560 NullReferenceError,
00561 FileLimitExeeded,
00562 DatabaseReadOnly
00563 };
00564 static char const* const errorMessage[];
00565 typedef void (*dbErrorHandler)(int error, char const* msg, int msgarg, void* context);
00566
00573 dbErrorHandler setErrorHandler(dbErrorHandler newHandler, void* errorHandlerContext = NULL);
00574
00575
00582 virtual void scheduleBackup(char_t const* fileName, time_t periodSec);
00583
00584
00592 virtual void handleError(dbErrorClass error, char const* msg = NULL,
00593 int arg = 0);
00594
00595 dbAccessType accessType;
00596 size_t extensionQuantum;
00597 size_t initIndexSize;
00598 offs_t freeSpaceReuseThreshold;
00599
00600 static unsigned dbParallelScanThreshold;
00601
00610 void insertRecord(dbTableDescriptor* table, dbAnyReference* ref,
00611 void const* record, bool batch);
00616 offs_t used();
00617
00621 bool isOpen() const { return opened; }
00622
00629 offs_t getDatabaseSize() {
00630 return header->root[1-curr].size;
00631 }
00632
00639 void setFileExtensionQuantum(offs_t quantum) {
00640 dbFileExtensionQuantum = quantum;
00641 }
00642
00647 void setFileSizeLimit(offs_t limit) {
00648 dbFileSizeLimit = limit;
00649 }
00650
00662 void createCluster(offs_t size);
00663
00664
00665 #ifndef NO_MEMBER_TEMPLATES
00666
00671 template<class T>
00672 dbReference<T> insert(T const& record) {
00673 dbReference<T> ref;
00674 insertRecord(lookupTable(&T::dbDescriptor), &ref, &record, false);
00675 return ref;
00676 }
00683 template<class T>
00684 dbReference<T> batchInsert(T const& record) {
00685 dbReference<T> ref;
00686 insertRecord(lookupTable(&T::dbDescriptor), &ref, &record, true);
00687 return ref;
00688 }
00689 #endif
00690
00703 dbDatabase(dbAccessType type = dbAllAccess,
00704 size_t poolSize = 0,
00705 size_t dbExtensionQuantum = dbDefaultExtensionQuantum,
00706 size_t dbInitIndexSize = dbDefaultInitIndexSize,
00707 int nThreads = 1
00708
00709
00710
00711
00712 #ifdef NO_PTHREADS
00713 , bool usePthreads = false
00714 #endif
00715 );
00716
00720 virtual ~dbDatabase();
00721
00722 protected:
00723 dbThreadContext<dbDatabaseThreadContext> threadContext;
00724
00725 dbThreadPool threadPool;
00726
00727 dbHeader* header;
00728 int4* dirtyPagesMap;
00729 unsigned parThreads;
00730 bool modified;
00731
00732 int curr;
00733
00734
00735 int transactionId;
00736
00737 bool uncommittedChanges;
00738
00739 offs_t dbFileExtensionQuantum;
00740 offs_t dbFileSizeLimit;
00741
00742
00743 volatile int commitInProgress;
00744 volatile int concurrentTransId;
00745
00746 oid_t currRBitmapPage;
00747 size_t currRBitmapOffs;
00748
00749 oid_t currPBitmapPage;
00750 size_t currPBitmapOffs;
00751
00752
00753 struct dbLocation {
00754 offs_t pos;
00755 offs_t size;
00756 dbLocation* next;
00757 };
00758 dbLocation* reservedChain;
00759
00760 oid_t committedIndexSize;
00761 oid_t currIndexSize;
00762
00763 oid_t updatedRecordId;
00764
00765 dbFile* file;
00766 dbMutex mutex;
00767 dbSemaphore writeSem;
00768 dbSemaphore readSem;
00769 dbSemaphore upgradeSem;
00770 dbEvent backupCompletedEvent;
00771 dbMonitor monitor;
00772 dbPagePool pool;
00773 dbTableDescriptor* tables;
00774
00775 int* bitmapPageAvailableSpace;
00776 bool opened;
00777
00778 offs_t allocatedSize;
00779 offs_t deallocatedSize;
00780
00781 int forceCommitCount;
00782 time_t commitDelay;
00783 time_t commitTimeout;
00784 time_t commitTimerStarted;
00785
00786 dbMutex commitThreadSyncMutex;
00787 dbMutex delayedCommitStartTimerMutex;
00788 dbMutex delayedCommitStopTimerMutex;
00789 dbEvent commitThreadSyncEvent;
00790
00791 dbEvent delayedCommitStartTimerEvent;
00792
00793 dbEvent delayedCommitStopTimerEvent;
00794 dbDatabaseThreadContext* delayedCommitContext;
00795
00796 dbMutex backupMutex;
00797 dbEvent backupInitEvent;
00798 char_t* backupFileName;
00799 time_t backupPeriod;
00800
00801 dbThread backupThread;
00802 dbThread commitThread;
00803
00804 dbTableDescriptor* batchList;
00805
00806 int accessCount;
00807
00808 dbL2List threadContextList;
00809 dbMutex threadContextListMutex;
00810
00811 dbErrorHandler errorHandler;
00812 void* errorHandlerContext;
00813
00814 bool confirmDeleteColumns;
00815 int schemeVersion;
00816 dbVisitedObject* visitedChain;
00817
00818 int* btreeBuf;
00819 bool deleteFile;
00820 bool doNotReuseOidAfterClose;
00821
00827 dbTableDescriptor* loadMetaTable();
00828
00829 void releaseFile();
00830
00834 virtual void replicatePage(offs_t pageOffs, void* pageData);
00835
00839 void delayedCommit();
00840
00844 void backupScheduler();
00845
00846 static void thread_proc delayedCommitProc(void* arg) {
00847 ((dbDatabase*)arg)->delayedCommit();
00848 }
00849
00850 static void thread_proc backupSchedulerProc(void* arg) {
00851 ((dbDatabase*)arg)->backupScheduler();
00852 }
00853
00858 void commit(dbDatabaseThreadContext* ctx);
00859
00865 offs_t getPos(oid_t oid) {
00866 byte* p = pool.get(header->root[1-curr].index
00867 + (offs_t)(oid / dbHandlesPerPage) * dbPageSize);
00868 offs_t pos = *((offs_t*)p + oid % dbHandlesPerPage);
00869 pool.unfix(p);
00870 return pos;
00871 }
00872
00878 void setPos(oid_t oid, offs_t pos) {
00879 byte* p = pool.put(header->root[1-curr].index
00880 + (offs_t)(oid / dbHandlesPerPage) * dbPageSize);
00881 *((offs_t*)p + oid % dbHandlesPerPage) = pos;
00882 pool.unfix(p);
00883 }
00884
00890 bool isValidOid(oid_t oid) {
00891 if (oid < dbFirstUserId || oid >= currIndexSize) {
00892 return false;
00893 }
00894 offs_t pos = getPos(oid);
00895 return !(pos & (dbFreeHandleFlag|dbPageObjectFlag));
00896 }
00897
00904 dbRecord* getRow(dbGetTie& tie, oid_t oid) {
00905 offs_t pos = getPos(oid);
00906 assert(!(pos & (dbFreeHandleFlag|dbPageObjectFlag)));
00907 tie.set(pool, pos & ~dbFlagsMask);
00908 return (dbRecord*)tie.get();
00909 }
00910
00917 dbRecord* fetchRow(dbGetTie& tie, oid_t oid) {
00918 offs_t pos = getPos(oid);
00919 assert(!(pos & (dbFreeHandleFlag|dbPageObjectFlag)));
00920 tie.fetch(pool, pos & ~dbFlagsMask);
00921 return (dbRecord*)tie.get();
00922 }
00923
00929 void getHeader(dbRecord& rec, oid_t oid) {
00930 offs_t pos = getPos(oid);
00931 int offs = (int)pos & (dbPageSize-1);
00932 byte* p = pool.get(pos - offs);
00933 rec = *(dbRecord*)(p + (offs & ~dbFlagsMask));
00934 pool.unfix(p);
00935 }
00936
00942 byte* put(oid_t oid) {
00943 offs_t pos = getPos(oid);
00944 int offs = (int)pos & (dbPageSize-1);
00945 return pool.put(pos-offs) + (offs & ~dbFlagsMask);
00946 }
00947
00953 byte* get(oid_t oid) {
00954 offs_t pos = getPos(oid);
00955 int offs = (int)pos & (dbPageSize-1);
00956 return pool.get(pos-offs) + (offs & ~dbFlagsMask);
00957 }
00958
00966 dbRecord* putRow(dbPutTie& tie, oid_t oid, size_t newSize);
00967
00974 dbRecord* putRow(dbPutTie& tie, oid_t oid);
00975
00982 byte* put(dbPutTie& tie, oid_t oid);
00983
00988 void restoreTablesConsistency();
00989
00995 void applyIndex(dbFieldDescriptor* field, dbSearchContext& sc);
00996
01013 bool isIndexApplicable(dbAnyCursor* cursor, dbExprNode* expr, dbQuery& query,
01014 dbFieldDescriptor* &indexedField, bool& truncate, bool ascent, bool forAll);
01015
01023 bool isIndexApplicableToExpr(dbSearchContext& sc, dbExprNode* expr);
01024
01028 bool followInverseReference(dbExprNode* expr, dbExprNode* andExpr,
01029 dbAnyCursor* cursor, oid_t iref);
01030
01038 bool existsInverseReference(dbExprNode* expr, int nExistsClauses);
01039
01046 static void _fastcall execute(dbExprNode* expr,
01047 dbInheritedAttribute& iattr,
01048 dbSynthesizedAttribute& sattr);
01057 bool evaluateBoolean(dbExprNode* expr, oid_t oid, dbTableDescriptor* table, dbAnyCursor* cursor);
01058
01068 size_t evaluateString(dbExprNode* expr, oid_t oid, dbTableDescriptor* table, char_t* buf, size_t bufSize);
01069
01077 void evaluate(dbExprNode* expr, oid_t oid, dbTableDescriptor* table, dbSynthesizedAttribute& result);
01078
01083 void select(dbAnyCursor* cursor);
01084
01090 void select(dbAnyCursor* cursor, dbQuery& query);
01091
01097 void traverse(dbAnyCursor* cursor, dbQuery& query);
01098
01105 void update(oid_t oid, dbTableDescriptor* table, void const* record);
01106
01112 void remove(dbTableDescriptor* table, oid_t oid);
01113
01121 offs_t allocate(offs_t size, oid_t oid = 0);
01122
01128 void free(offs_t pos, offs_t size);
01129
01134 void extend(offs_t size);
01135
01142 void cloneBitmap(offs_t pos, offs_t size);
01143
01148 oid_t allocateId();
01149
01154 void freeId(oid_t oid);
01155
01162 void updateCursors(oid_t oid, bool removed = false);
01163
01168 oid_t allocatePage() {
01169 oid_t oid = allocateId();
01170 setPos(oid, allocate(dbPageSize) | dbPageObjectFlag | dbModifiedFlag);
01171 return oid;
01172 }
01173
01178 void freePage(oid_t oid);
01179
01187 oid_t allocateRow(oid_t tableId, size_t size,
01188 dbTableDescriptor* desc = NULL)
01189 {
01190 oid_t oid = allocateId();
01191 allocateRow(tableId, oid, size, desc);
01192 return oid;
01193 }
01194
01203 void allocateRow(oid_t tableId, oid_t oid, size_t size, dbTableDescriptor* desc);
01204
01211 void freeRow(oid_t tableId, oid_t oid, dbTableDescriptor* desc = NULL);
01212
01217 static void deleteCompiledQuery(dbExprNode* tree);
01218
01223 void beginTransaction(dbLockType type);
01228 void endTransaction(dbDatabaseThreadContext* ctx);
01229
01233 void initializeMetaTable();
01234
01241 bool loadScheme();
01242
01248 bool completeDescriptorsInitialization();
01249
01255 void reformatTable(oid_t tableId, dbTableDescriptor* desc);
01256
01262 void addIndices(dbTableDescriptor* desc);
01263
01269 oid_t addNewTable(dbTableDescriptor* desc);
01270
01277 void updateTableDescriptor(dbTableDescriptor* desc,
01278 oid_t tableId, dbTable* table);
01279
01280
01286 void removeInverseReferences(dbTableDescriptor* desc, oid_t oid);
01287
01288
01297 void insertInverseReference(dbFieldDescriptor* desc, oid_t reverseId,
01298 oid_t targetId);
01299
01308 void removeInverseReference(dbFieldDescriptor* desc,
01309 oid_t reverseId, oid_t targetId);
01310
01311
01316 void deleteTable(dbTableDescriptor* desc);
01317
01322 void dropTable(dbTableDescriptor* desc);
01323
01328 void createIndex(dbFieldDescriptor* fd);
01329
01334 void createHashTable(dbFieldDescriptor* fd);
01335
01340 void dropIndex(dbFieldDescriptor* fd);
01341
01346 void dropHashTable(dbFieldDescriptor* fd);
01347
01353 void linkTable(dbTableDescriptor* table, oid_t tableId);
01354
01359 void unlinkTable(dbTableDescriptor* table);
01360
01361
01368 bool wasReserved(offs_t pos, offs_t size);
01369
01378 void reserveLocation(dbLocation& location, offs_t pos, offs_t size);
01379
01384 void commitLocation();
01385
01391 dbTableDescriptor* findTable(char_t const* name);
01392
01399 dbTableDescriptor* findTableByName(char_t const* name);
01400
01401
01406 dbTableDescriptor* getTables() {
01407 return tables;
01408 }
01409
01410
01415 void cleanupOnOpenError();
01416
01420 void setDirty();
01421
01425 void refreshTable(dbTableDescriptor* desc);
01426 };
01427
01428 template<class T>
01429 dbReference<T> insert(T const& record) {
01430 dbReference<T> ref;
01431 T::dbDescriptor.getDatabase()->insertRecord(&T::dbDescriptor, &ref, &record, false);
01432 return ref;
01433 }
01434
01435 template<class T>
01436 dbReference<T> batchInsert(T const& record) {
01437 dbReference<T> ref;
01438 T::dbDescriptor.getDatabase()->insertRecord(&T::dbDescriptor, &ref, &record, true);
01439 return ref;
01440 }
01441
01442 #ifdef NO_MEMBER_TEMPLATES
01443 template<class T>
01444 dbReference<T> insert(dbDatabase& db, T const& record) {
01445 dbReference<T> ref;
01446 db.insertRecord(db.lookupTable(&T::dbDescriptor), &ref, &record, false);
01447 return ref;
01448 }
01449 template<class T>
01450 dbReference<T> batchInsert(dbDatabase& db, T const& record) {
01451 dbReference<T> ref;
01452 db.insertRecord(db.lookupTable(&T::dbDescriptor), &ref, &record, true);
01453 return ref;
01454 }
01455 #endif
01456
01457 class dbSearchContext {
01458 public:
01459 dbDatabase* db;
01460 dbExprNode* condition;
01461 dbAnyCursor* cursor;
01462 char_t* firstKey;
01463 int firstKeyInclusion;
01464 char_t* lastKey;
01465 int lastKeyInclusion;
01466 int prefixLength;
01467 int offs;
01468 int probes;
01469 bool ascent;
01470 bool tmpKeys;
01471 bool spatialSearch;
01472 bool arraySearch;
01473
01474 void operator = (dbSearchContext const& sc);
01475
01476 union {
01477 bool b;
01478 int1 i1;
01479 int2 i2;
01480 int4 i4;
01481 db_int8 i8;
01482 real4 f4;
01483 real8 f8;
01484 oid_t oid;
01485 void* raw;
01486 rectangle* rect;
01487 char_t* s;
01488 dbAnyArray* a;
01489 } literal[2];
01490 };
01491
01492 END_GIGABASE_NAMESPACE
01493
01494 #endif
01495