📄 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_NAMESPACE
class 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; }
/**
* Enable or disable duplicates checking (if programmer knows that disjuncts in query do not intersect, then
* he can disable duplicate checking and avoid bitmap allocation
*/
void enableCheckForDuplicates(bool enabled) {
checkForDuplicatedIsEnabled = enabled;
}
/**
* 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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -