📄 cursor.h
字号:
table->columns->fetchRecordFields(record, (byte*)db->getRow(currId)); } /** * Check if there is more records in the selection */ bool hasNext() const; 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 lastRecordWasDeleted; //last record was deleted size_t stmtLimitStart; size_t stmtLimitLen; size_t nSkipped; void* paramBase; void checkForDuplicates(); bool isMarked(oid_t oid) { return bitmap != NULL && (bitmap[oid >> 5] & (1 << (oid & 31))) != 0; } void setStatementLimit(dbQuery const& q) { stmtLimitStart = q.stmtLimitStartPtr != NULL ? (nat4)*q.stmtLimitStartPtr : q.stmtLimitStart; stmtLimitLen = q.stmtLimitLenPtr != NULL ? (nat4)*q.stmtLimitLenPtr : q.stmtLimitLen; } void truncateSelection() { selection.truncate(stmtLimitStart, stmtLimitLen); } void mark(oid_t oid) { if (bitmap != NULL) { bitmap[oid >> 5] |= 1 << (oid & 31); } } bool add(oid_t oid) { if (selection.nRows < limit && selection.nRows < stmtLimitLen) { if (nSkipped < stmtLimitStart) { nSkipped += 1; return true; } 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(); bool moveNext(); bool movePrev(); void setCurrent(dbAnyReference const& ref); void adjustReferences(size_t base, size_t size, long shift) { if (currId != 0 && record != NULL) { table->columns->adjustReferences(record, base, size, shift); } } dbAnyCursor(dbTableDescriptor& aTable, dbCursorType aType, byte* rec) : table(&aTable),type(aType),defaultType(aType), allRecords(false),currId(0),record(rec) { db = aTable.db; limit = dbDefaultSelectionLimit; prefetch = rec != NULL; removed = false; bitmap = NULL; bitmapSize = 0; eliminateDuplicates = false; paramBase = NULL; stmtLimitLen = dbDefaultSelectionLimit; stmtLimitStart = 0; nSkipped = 0; } public: dbAnyCursor() : table(NULL),type(dbCursorViewOnly),defaultType(dbCursorViewOnly), allRecords(false),currId(0),record(NULL) { limit = dbDefaultSelectionLimit; prefetch = false; removed = false; bitmap = NULL; bitmapSize = 0; eliminateDuplicates = false; db = NULL; paramBase = NULL; stmtLimitLen = dbDefaultSelectionLimit; stmtLimitStart = 0; nSkipped = 0; } ~dbAnyCursor();};/** * Cursor template parameterized by table class */template<class T>class dbCursor : public dbAnyCursor { private: // Itis not possible to copy cursors dbCursor<T> operator = (dbCursor<T> const& src) { return *this; } 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 lookup 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; } /** * Position cursor on the record with the specified OID * @param ref reference to the object * @return poistion of the record in the selection or -1 if record with such OID is not in selection */ int seek(dbReference<T> const& ref) { return dbAnyCursor::seek(ref.getOid()); } /** * 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) const { arr.resize(selection.nRows); toArrayOfOid((oid_t*)arr.base()); } /** * Get current object idenitifer * @return reference to the current record */ dbReference<T> currentId() const { 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 lastRecordWasDeleted ? NULL : get(); } } /** * Method prevAvailable allows to iterate through the records in uniform way even when some records * are removed. For example: * <PRE> * if (cursor.select(q) > 0) { * cursor.last(); * do { * if (x) { * cursor.remove(); * } else { * cursor.update(); * } * } while (cursor.prevAvaiable()); * } *</PRE> * @return pointer to the current record */ T* prevAvailable() { if (!removed) { return prev(); } else { removed = false; return lastRecordWasDeleted ? get() : prev(); } } /** * Check if record with specified OID is in selection * @return <code>true</code> if record with such OID was selected */ bool isInSelection(dbReference<T>& ref) { return dbAnyCursor::isInSelection(ref.getOid()); }};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);END_FASTDB_NAMESPACE#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -