cursor.h

来自「一个功能强大的内存数据库源代码,c++编写,有详细的注释」· C头文件 代码 · 共 576 行 · 第 1/2 页

H
576
字号
    /**     * Get table for which cursor is opened     */    dbTableDescriptor* getTable() { return table; }  protected:     dbDatabase*        db;    dbTableDescriptor* table;    dbCursorType       type;    dbCursorType       defaultType;    dbSelection        selection;    bool               allRecords;    oid_t              firstId;    oid_t              lastId;    oid_t              currId;    byte*              record;    size_t             limit;    int4*              bitmap; // bitmap to avoid duplicates    size_t             bitmapSize;    bool               eliminateDuplicates;    bool               prefetch;    bool               removed; // current record was removed    bool               updateInProgress;    void*              paramBase;        void checkForDuplicates();    bool isMarked(oid_t oid) { 	return bitmap != NULL && (bitmap[oid >> 5] & (1 << (oid & 31))) != 0;    }    void mark(oid_t oid) { 	if (bitmap != NULL) { 	    bitmap[oid >> 5] |= 1 << (oid & 31);	}    }        bool add(oid_t oid) { 	if (selection.nRows < limit) { 	    if (eliminateDuplicates) { 		if (bitmap[oid >> 5] & (1 << (oid & 31))) { 		    return true;		}		bitmap[oid >> 5] |= 1 << (oid & 31);	    } 	    selection.add(oid);	    return selection.nRows < limit;	} 	return false;    }    bool gotoNext();    bool gotoPrev();     bool gotoFirst();    bool gotoLast();        void setCurrent(dbAnyReference const& ref);    void fetch() { 	assert(!(db->currIndex[currId] 		 & (dbInternalObjectMarker|dbFreeHandleMarker)));	table->columns->fetchRecordFields(record, 					  (byte*)db->getRow(currId));    }    void adjustReferences(size_t base, size_t size, long shift) { 	if (currId != 0) { 	    table->columns->adjustReferences(record, base, size, shift);	}    }    void setTable(dbTableDescriptor* aTable) { 	table = aTable;	db = aTable->db;    }    void setRecord(byte* rec) { 	record = rec;    }    dbAnyCursor(dbTableDescriptor& aTable, dbCursorType aType, byte* rec)    : table(&aTable),type(aType),defaultType(aType),      allRecords(false),currId(0),record(rec)    {	db = aTable.db;	limit = dbDefaultSelectionLimit;	updateInProgress = false;	prefetch = true;	removed = false;	bitmap = NULL; 	bitmapSize = 0;	eliminateDuplicates = false;	paramBase = NULL;    }  public:    dbAnyCursor()     : table(NULL),type(dbCursorViewOnly),defaultType(dbCursorViewOnly),	  allRecords(false),currId(0),record(NULL)    {	limit = dbDefaultSelectionLimit;	updateInProgress = false;	prefetch = false;	removed = false;	bitmap = NULL;	bitmapSize = 0;	eliminateDuplicates = false;	db = NULL;	paramBase = NULL;    }    ~dbAnyCursor();};/** * Cursor template parameterized by table class */template<class T>class dbCursor : public dbAnyCursor {   protected:    T record;      public:    /**     * Cursor constructor     * @param type cursor type (dbCursorViewOnly by default)     */    dbCursor(dbCursorType type = dbCursorViewOnly)         : dbAnyCursor(T::dbDescriptor, type, (byte*)&record) {}    /**     * Cursor constructor with explicit specification of database.     * This cursor should be used for unassigned tables.      * @param aDB database in which table lokkup is performed     * @param type cursor type (dbCursorViewOnly by default)     */    dbCursor(dbDatabase* aDb, dbCursorType type = dbCursorViewOnly)	: dbAnyCursor(T::dbDescriptor, type, (byte*)&record)    {	db = aDb;	dbTableDescriptor* theTable = db->lookupTable(table);	if (theTable != NULL) { 	    table = theTable;	}    }    /**     * Get pointer to the current record     * @return pointer to the current record or <code>NULL</code> if there is no current record     */    T* get() { 	return currId == 0 ? (T*)NULL : &record;     }        /**     * Get next record     * @return pointer to the next record or <code>NULL</code> if there is no next record     */         T* next() { 	if (gotoNext()) { 	    fetch();	    return &record;	}	return NULL;    }    /**     * Get previous record     * @return pointer to the previous record or <code>NULL</code> if there is no previous record     */         T* prev() {		if (gotoPrev()) { 	    fetch();	    return &record;	}	return NULL;    }    /**     * Get pointer to the first record     * @return pointer to the first record or <code>NULL</code> if no records were selected     */    T* first() { 	if (gotoFirst()) {	    fetch();	    return &record;	}	return NULL;    }    /**     * Get pointer to the last record     * @return pointer to the last record or <code>NULL</code> if no records were selected     */    T* last() { 	if (gotoLast()) {	    fetch();	    return &record;	}	return NULL;    }            /**     * Overloaded operator for accessing components of the current record     * @return pointer to the current record     */    T* operator ->() { 	assert(currId != 0);	return &record;    }    /**     * Select record by reference     * @param ref reference to the record     * @return pointer to the referenced record     */    T* at(dbReference<T> const& ref) { 	setCurrent(ref);	return &record;    }        /**     * Convert selection to array of reference     * @param arr [OUT] array of refeences in which references to selected recrods will be placed     */    void toArray(dbArray< dbReference<T> >& arr) { 	arr.resize(selection.nRows);	toArrayOfOid((oid_t*)arr.base());    }    /**     * Get current object idenitifer     * @param reference to the current record     */    dbReference<T> currentId() { 	return dbReference<T>(currId);    }    /**     * Method nextAvailable allows to iterate through the records in uniform way even when some records      * are removed. For example:     * <PRE>     * if (cursor.select(q) > 0) {      *     do {      *         if (x) {      *             cursor.remove();     *         } else {      *             cursor.update();     *         }     *     } while (cursor.nextAvaiable());     *  }     *</PRE>     * @return pointer to the current record     */         T* nextAvailable() { 	if (!removed) { 	    return next(); 	} else { 	    removed = false;	    return get();	}    }};class dbParallelQueryContext {   public:    dbDatabase* const      db;    dbCompiledQuery* const query;    oid_t                  firstRow;    dbTable*               table;    dbAnyCursor*           cursor;    dbSelection            selection[dbMaxParallelSearchThreads];    void search(int i);     dbParallelQueryContext(dbDatabase* aDb, dbTable* aTable, 			   dbCompiledQuery* aQuery, dbAnyCursor* aCursor)      : db(aDb), query(aQuery), firstRow(aTable->firstRow), table(aTable), cursor(aCursor) {}};extern char* strupper(char* s);extern char* strlower(char* s);#endif

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?