📄 cursor.h
字号:
//-< CURSOR.H >------------------------------------------------------*--------*// FastDB Version 1.0 (c) 1999 GARRET * ? *// (Main Memory Database Management System) * /\| *// * / \ *// Created: 20-Nov-98 K.A. Knizhnik * / [] \ *// Last update: 10-Dec-98 K.A. Knizhnik * GARRET *//-------------------------------------------------------------------*--------*// Table cursor//-------------------------------------------------------------------*--------*#ifndef __CURSOR_H__#define __CURSOR_H__BEGIN_FASTDB_NAMESPACEclass dbOrderByNode;class FASTDB_DLL_ENTRY dbSelection { public: enum { quantum = 1024 }; class segment { public: segment* prev; segment* next; size_t nRows; oid_t rows[quantum]; segment(segment* after) { prev = after; next = NULL; nRows = 0; } }; segment* first; segment* last; segment* curr; size_t nRows; size_t pos; segment* createNewSegment(segment* after); void add(oid_t oid) { if (last == NULL) { first = last = createNewSegment(NULL); } else if (last->nRows == quantum) { last = last->next = createNewSegment(last); } last->rows[last->nRows++] = oid; nRows += 1; } void sort(dbDatabase* db, dbOrderByNode* order); static int compare(oid_t a, oid_t b, dbOrderByNode* order); void toArray(oid_t* oids) const; void truncate(size_t from, size_t length); dbSelection() { nRows = 0; pos = 0; first = curr = last = NULL; } void reverse(); void reset();};enum dbCursorType { dbCursorViewOnly, dbCursorForUpdate};/** * Base class for all cursors */class FASTDB_DLL_ENTRY dbAnyCursor : public dbL2List { friend class dbAnyContainer; friend class dbDatabase; friend class dbHashTable; friend class dbTtreeNode; friend class dbRtreePage; friend class dbSubSql; friend class dbStatement; friend class dbServer; friend class dbCLI; friend class JniResultSet; public: /** * Get number of selected records * @return number of selected records */ int getNumberOfRecords() const { return (int)selection.nRows; } /** * Remove current record */ void remove(); /** * Checks whether selection is empty * @return true if there is no current record */ bool isEmpty() const { return currId == 0; } /** * Check whether this cursor can be used for update * @return true if it is update cursor */ bool isUpdateCursor() const { return type == dbCursorForUpdate; } /** * Checks whether limit for number of selected reacord is reached * @return true if limit is reached */ bool isLimitReached() const { return selection.nRows >= limit || selection.nRows >= stmtLimitLen; } /** * Extract OIDs of selected recrods in array * @param arr if <code>arr</code> is not null, then this array is used as destination (it should * be at least selection.nRows long)<BR> * If <code>arr</code> is null, then new array is created by new oid_t[] and returned by this method * @return if <code>arr</code> is not null, then <code>arr</code>, otherwise array created by this method */ oid_t* toArrayOfOid(oid_t* arr) const; /** * Execute query. * @param query selection criteria * @param aType cursor type: <code>dbCursorForUpdate, dbCursorViewOnly</code> * @param paramStruct pointer to structure with parameters. If you want to create reentrant precompiled query, i.e. * query which can be used concurrently by different threadsm you should avoid to use static variables in * such query, and instead of it place paramters into some structure, specify in query relative offsets to the parameters, * fill local structure and pass pointer to it to select method. * @return number of selected records */ int select(dbQuery& query, dbCursorType aType, void* paramStruct = NULL) { type = aType; reset(); paramBase = paramStruct; db->select(this, query); paramBase = NULL; if (gotoFirst() && prefetch) { fetch(); } return (int)selection.nRows; } /** * Execute query with default cursor type. * @param query selection criteria * @param paramStruct pointer to structure with parameters. * @return number of selected records */ int select(dbQuery& query, void* paramStruct = NULL) { return select(query, defaultType, paramStruct); } /** * Execute query. * @param condition selection criteria * @param aType cursor type: <code>dbCursorForUpdate, dbCursorViewOnly</code> * @param paramStruct pointer to structure with parameters. * @return number of selected records */ int select(char const* condition, dbCursorType aType, void* paramStruct = NULL) { dbQuery query(condition); return select(query, aType, paramStruct); } /** * Execute query with default cursor type. * @param condition selection criteria * @param paramStruct pointer to structure with parameters. * @return number of selected records */ int select(char const* condition, void* paramStruct = NULL) { return select(condition, defaultType, paramStruct); } /** * Select all records from the table * @param aType cursor type: <code>dbCursorForUpdate, dbCursorViewOnly</code> * @return number of selected records */ int select(dbCursorType aType) { type = aType; reset(); db->select(this); if (gotoFirst() && prefetch) { fetch(); } return (int)selection.nRows; } /** * Select all records from the table with default cursor type * @return number of selected records */ int select() { return select(defaultType); } /** * Select all records from the table with specfied value of the key * @param key name of the key field * @param value searched value of the key * @return number of selected records */ int selectByKey(char const* key, void const* value); /** * Select all records from the table with specfied range of the key values * @param key name of the key field * @param minValue inclusive low bound for key values, if <code>NULL</code> then there is no low bound * @param maxValue inclusive high bound for key values, if <code>NULL</code> then there is no high bound * @return number of selected records */ int selectByKeyRange(char const* key, void const* minValue, void const* maxValue); /** * Update current record. You should changed value of current record before and then call * update method to save changes to the database */ void update() { assert(type == dbCursorForUpdate && currId != 0); db->update(currId, table, record); } /** * Remove all records in the table */ void removeAll() { assert(db != NULL); db->deleteTable(table); reset(); } /** * Remove all selected records */ void removeAllSelected(); /** * Specify maximal number of records to be selected */ void setSelectionLimit(size_t lim) { limit = lim; } /** * Remove selection limit */ void unsetSelectionLimit() { limit = dbDefaultSelectionLimit; } /** * Set prefetch mode. By default, current record is fetch as soon as it is becomes current. * But sometimesyou need only OIDs of selected records. In this case setting prefetchMode to false can help. * @param mode if <code>false</code> then current record is not fetched. You should explicitly call <code>fetch</code> * method if you want to fetch it. */ void setPrefetchMode(bool mode) { prefetch = mode; } /** * Reset cursor */ void reset(); /** * Check whether current record is the last one in the selection * @return true if next() method will return <code>NULL</code> */ bool isLast() const; /** * Check whether current record is the first one in the selection * @return true if prev() method will return <code>NULL</code> */ bool isFirst() const; /** * Freeze cursor. This method makes it possible to save current state of cursor, close transaction to allow * other threads to proceed, and then later restore state of the cursor using unfreeze method and continue * traversal through selected records. */ void freeze(); /** * Unfreeze cursor. This method starts new transaction and restore state of the cursor */ void unfreeze(); /** * Skip specified number of records * @param n if positive then skip <code>n</code> records forward, if negative then skip <code>-n</code> * records backward * @return <code>true</code> if specified number of records was successfully skipped, <code>false</code> if * there is no next (<code>n > 0</code>) or previous (<code>n < 0</code>) record in the selction. */ bool skip(int n); /** * Position cursor on the record with the specified OID * @param oid object identifier of record * @return poistion of the record in the selection or -1 if record with such OID is not in selection */ int seek(oid_t oid); /** * Get table for which cursor is opened */ dbTableDescriptor* getTable() { return table; } /** * Set table for the cursor * @param aTable table which records will be iterated */ void setTable(dbTableDescriptor* aTable) { table = aTable; db = aTable->db; } /** * Set destination for selected record * rec - buffer to which fields of current record will be fetched */ void setRecord(void* rec) { record = (byte*)rec; } /** * Get pointer to the location where fields of the current record are fetched * @return pointer to the memory location set by cursor constructor or setRecord method */ void* getRecord() { return record; } /** * Check if record with specified OID is in selection * @return <code>true</code> if record with such OID was selected */ bool isInSelection(oid_t oid); /** * Fetch current record. * You should use this method only if prefetch mode is disabled */ void fetch() { assert(!(db->currIndex[currId] & (dbInternalObjectMarker|dbFreeHandleMarker)));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -