• Main Page
  • Classes
  • Files
  • File List

cursor.h

00001 //-< CURSOR.H >------------------------------------------------------*--------*
00002 // GigaBASE                  Version 1.0         (c) 1999  GARRET    *     ?  *
00003 // (Post Relational Database Management System)                      *   /\|  *
00004 //                                                                   *  /  \  *
00005 //                          Created:     20-Nov-98    K.A. Knizhnik  * / [] \ *
00006 //                          Last update: 10-Dec-98    K.A. Knizhnik  * GARRET *
00007 //-------------------------------------------------------------------*--------*
00008 // Table cursor
00009 //-------------------------------------------------------------------*--------*
00010 
00011 #ifndef __CURSOR_H__
00012 #define __CURSOR_H__
00013 
00014 #include "btree.h"
00015 #include "rtree.h"
00016 
00017 BEGIN_GIGABASE_NAMESPACE
00018 
00019 #include "selection.h"
00020 
00021 enum dbCursorType {
00022     dbCursorViewOnly,
00023     dbCursorForUpdate,
00027     dbCursorIncremental,
00036     dbCursorDetached
00037 };
00038 
00042 class dbTableIterator : public dbAbstractIterator {
00043     dbAnyCursor* cursor;
00044     dbExprNode*  filter;
00045     oid_t        curr;
00046 
00047   public:
00048     void init(dbAnyCursor* cursor, dbExprNode*  filter) {
00049         this->cursor = cursor;
00050         this->filter = filter;
00051         curr = 0;
00052     }
00053 
00054     virtual oid_t next();
00055     virtual oid_t prev();
00056     virtual oid_t first();
00057     virtual oid_t last();
00058 };
00059 
00060 
00061 
00065 class GIGABASE_DLL_ENTRY dbAnyCursor : public dbL2List {
00066     friend class dbDatabase;
00067     friend class dbHashTable;
00068     friend class dbRtreePage;
00069     friend class dbBtreePage;
00070     friend class dbRtreeIterator;
00071     friend class dbBtreeIterator;
00072     friend class dbTableIterator;
00073     friend class dbThickBtreePage;
00074     friend class dbSubSql;
00075     friend class dbStatement;
00076     friend class dbServer;
00077     friend class dbAnyContainer;
00078     friend class dbCLI;
00079     friend class JniResultSet;
00080   public:
00085     int getNumberOfRecords() const { return (int)selection.nRows; }
00086 
00090     void remove();
00091 
00096     bool isEmpty() const { 
00097         return currId == 0; 
00098     }
00099 
00100 
00105     oid_t getOid() {
00106         return currId;
00107     }
00108 
00113     bool isUpdateCursor() const { 
00114         return type == dbCursorForUpdate;
00115     }
00116 
00121     bool isLimitReached() const { 
00122         return selection.nRows >= limit || selection.nRows >= stmtLimitLen; 
00123     }
00124 
00135     int select(dbQuery& query, dbCursorType aType, void* paramStruct = NULL);
00136 
00144     oid_t* toArrayOfOid(oid_t* arr) const;
00145 
00152     int select(dbQuery& query, void* paramStruct = NULL) {
00153         return select(query, defaultType, paramStruct);
00154     }
00155 
00163     int select(char_t const* condition, dbCursorType aType, void* paramStruct = NULL) {
00164         dbQuery query(condition);
00165         return select(query, aType, paramStruct);
00166     }
00167 
00174     int select(char_t const* condition, void* paramStruct = NULL) {
00175         return select(condition, defaultType, paramStruct);
00176     }
00177 
00183     int select(dbCursorType aType) {
00184         type = aType;
00185         reset();
00186         db->select(this);
00187         if (gotoFirst() && prefetch) {
00188             fetch();
00189         }
00190         return (int)selection.nRows;
00191     }
00192 
00197     int select() {
00198         return select(defaultType);
00199     }
00200 
00207     int selectByKey(char_t const* key, void const* value);
00208 
00215     int selectByKey(dbFieldDescriptor* field, void const* value);
00216 
00225     int selectByKeyRange(char_t const* key, void const* minValue, void const* maxValue, bool ascent = true);
00226 
00235     int selectByKeyRange(dbFieldDescriptor* field, void const* minValue, void const* maxValue, bool ascent = true);
00236 
00242     bool update() {
00243         if (type != dbCursorForUpdate) {
00244             db->handleError(dbDatabase::CursorError, "Readonly cursor");
00245         }
00246         if (currId == 0) {
00247             db->handleError(dbDatabase::CursorError, "No current record");
00248         }
00249         return db->update(currId, table, record);
00250     }
00251 
00255     void removeAll() {
00256         assert(db != NULL);
00257         reset();
00258         db->deleteTable(table);
00259     }
00260 
00264     void removeAllSelected();
00265 
00269     void setSelectionLimit(size_t lim) { limit = lim; }
00270 
00274     void unsetSelectionLimit() { limit = dbDefaultSelectionLimit; }
00275 
00282     void setPrefetchMode(bool mode) { prefetch = mode; }
00283 
00294     bool isIncremental() { 
00295         return iterator != NULL;
00296     }
00297 
00302     bool hasIncrementalHint() { 
00303         return type == dbCursorIncremental;
00304     }
00305 
00310     void enableCheckForDuplicates(bool enabled) {
00311         checkForDuplicatedIsEnabled = enabled;
00312     }
00313  
00317     void reset();
00318 
00323     bool isLast() const; 
00324 
00329     bool isFirst() const; 
00330 
00336     void freeze();
00337 
00341     void unfreeze();
00342 
00350     bool skip(int n);
00351 
00357     int seek(oid_t oid);
00358 
00363     dbTableDescriptor* getTable() { return table; }
00364 
00365 
00370     bool isInSelection(oid_t oid);
00371 
00376     void fetch() {
00377         dbRecord* row = (type == dbCursorDetached) ? db->fetchRow(tie, currId) : db->getRow(tie, currId);
00378         table->columns->fetchRecordFields(record, (byte*)row);
00379     }
00380 
00384     bool hasNext() const;
00385 
00389     bool hasCurrent() const { 
00390         return currId != 0;
00391     }
00392 
00393   protected:
00394     dbDatabase*        db;
00395     dbTableDescriptor* table;
00396     dbCursorType       type;
00397     dbCursorType       defaultType;
00398     dbSelection        selection;
00399     bool               allRecords;
00400     oid_t              firstId;
00401     oid_t              lastId;
00402     oid_t              currId;
00403     byte*              record;
00404     size_t             limit;
00405     dbGetTie           tie;
00406     void*              paramBase;
00407 
00408     bool               eliminateDuplicates;
00409     bool               checkForDuplicatedIsEnabled;
00410     bool               prefetch;
00411     bool               removed; // current record was removed
00412     bool               lastRecordWasDeleted; //last record was deleted
00413 
00414     size_t             stmtLimitStart;
00415     size_t             stmtLimitLen;
00416     size_t             nSkipped;
00417 
00418     dbAbstractIterator*iterator;
00419     dbBtreeIterator    btreeIterator;
00420     dbRtreeIterator    rtreeIterator;
00421     dbTableIterator    tableIterator;
00422 
00423     void checkForDuplicates() { 
00424         if (!eliminateDuplicates && checkForDuplicatedIsEnabled && limit > 1) {
00425             eliminateDuplicates = true;
00426             selection.allocateBitmap(db);
00427         }
00428     }
00429 
00430     bool isMarked(oid_t oid) {
00431         return selection.bitmap != NULL && (selection.bitmap[(size_t)(oid >> 5)] & (1 << ((int)oid & 31))) != 0;
00432     }
00433     
00434     void deallocateBitmap() {
00435         selection.deallocateBitmap();
00436     }
00437 
00438     void mark(oid_t oid) {
00439         if (selection.bitmap != NULL) {
00440             selection.bitmap[(size_t)(oid >> 5)] |= 1 << ((int)oid & 31);
00441         }
00442     }
00443 
00444     void setStatementLimit(dbQuery const& q) { 
00445         stmtLimitStart = q.stmtLimitStartPtr != NULL ? (nat4)*q.stmtLimitStartPtr : q.stmtLimitStart;
00446         stmtLimitLen = q.stmtLimitLenPtr != NULL ? (nat4)*q.stmtLimitLenPtr : q.stmtLimitLen;
00447     }
00448 
00449     void truncateSelection() { 
00450         selection.truncate(stmtLimitStart, stmtLimitLen);
00451     }
00452 
00453     bool add(oid_t oid) {
00454         if (selection.nRows < limit && selection.nRows < stmtLimitLen) {
00455             if (nSkipped < stmtLimitStart) { 
00456                 nSkipped += 1;
00457                 return true;
00458             }
00459             if (eliminateDuplicates) {
00460                 if (selection.bitmap[(size_t)(oid >> 5)] & (1 << ((int)oid & 31))) {
00461                     return true;
00462                 }
00463                 selection.bitmap[oid >> 5] |= 1 << (oid & 31);
00464             }
00465             selection.add(oid);
00466             return selection.nRows < limit;
00467         }
00468         return false;
00469     }
00470     
00471     byte* fetchNext();
00472     byte* fetchPrev();
00473     byte* fetchFirst();
00474     byte* fetchLast();
00475 
00476     bool gotoNext();
00477     bool gotoPrev();
00478     bool gotoFirst();
00479     bool gotoLast();
00480 
00481     bool moveNext();
00482     bool movePrev();
00483 
00484     void setCurrent(dbAnyReference const& ref);
00485 
00486     void setTable(dbTableDescriptor* aTable) { 
00487         table = aTable;
00488         db = aTable->db;
00489     }
00490 
00491     void setRecord(void* rec) { 
00492         record = (byte*)rec;
00493     }
00494 
00495     dbAnyCursor(dbTableDescriptor& aTable, dbCursorType aType, byte* rec);
00496 
00497   public:
00498     dbAnyCursor(dbCursorType aType = dbCursorViewOnly);
00499     ~dbAnyCursor();
00500 };
00501 
00505 template<class T>
00506 class dbCursor : public dbAnyCursor {
00507   private:
00508     // Itis not possible to copy cursors
00509     dbCursor<T> operator = (dbCursor<T> const& src) { 
00510         return *this;
00511     } 
00512 
00513   protected:
00514     T record;
00515 
00516   public:
00521     dbCursor(dbCursorType type = dbCursorViewOnly)
00522         : dbAnyCursor(T::dbDescriptor, type, (byte*)&record) {}
00523 
00530     dbCursor(dbDatabase* aDb, dbCursorType type = dbCursorViewOnly)
00531         : dbAnyCursor(T::dbDescriptor, type, (byte*)&record) 
00532     {
00533         db = aDb;
00534         dbTableDescriptor* theTable = db->lookupTable(table);
00535         if (theTable != NULL) { 
00536             table = theTable;
00537         }
00538     }
00539 
00544     T* get() {
00545         return currId == 0 ? (T*)NULL : &record;
00546     }
00547 
00552     T* next() {
00553         return (T*)fetchNext();
00554     }
00555 
00560     T* prev() {
00561         return (T*)fetchPrev();
00562     }
00563 
00568     T* first() {
00569         return (T*)fetchFirst();
00570     }
00571 
00576     T* last() {
00577         return (T*)fetchLast();
00578     }
00579     
00585     int seek(dbReference<T> const& ref) { 
00586         return dbAnyCursor::seek(ref.getOid());
00587     }
00588 
00593     T* operator ->() {
00594         if (currId == 0) {
00595             db->handleError(dbDatabase::CursorError, "No current record");
00596         }
00597         return &record;
00598     }
00599 
00605     T* at(dbReference<T> const& ref) {
00606         setCurrent(ref);
00607         return &record;
00608     }
00609 
00614     dbReference<T> currentId() const {
00615         return dbReference<T>(currId);
00616     }
00617     
00622     void toArray(dbArray< dbReference<T> >& arr) const { 
00623         arr.resize(selection.nRows);
00624         toArrayOfOid((oid_t*)arr.base());
00625     }
00626 
00627     T* prevAvailable() { 
00628         if (!removed) { 
00629             return prev(); 
00630         } else {
00631             removed = false;
00632             return lastRecordWasDeleted ? get() : prev();
00633         }
00634     }
00635 
00640     bool isInSelection(dbReference<T>& ref) {
00641         return dbAnyCursor::isInSelection(ref.getOid());
00642     }
00643 };
00644 
00645 class dbParallelQueryContext {
00646   public:
00647     dbDatabase* const      db;
00648     dbCompiledQuery* const query;
00649     dbAnyCursor*           cursor;
00650     oid_t                  firstRow;
00651     dbTableDescriptor*     table;
00652     dbSelection            selection[dbMaxParallelSearchThreads];
00653 
00654     void search(int i);
00655 
00656     dbParallelQueryContext(dbDatabase* aDb, dbTableDescriptor* desc,
00657                            dbCompiledQuery* aQuery, dbAnyCursor* aCursor)
00658       : db(aDb), query(aQuery), cursor(aCursor), firstRow(desc->firstRow), table(desc) {}
00659 };
00660 
00661 END_GIGABASE_NAMESPACE
00662 
00663 #endif

Generated on Mon Aug 23 2010 00:04:01 for GigaBASE by  doxygen 1.7.1