📄 cursor.h
字号:
{
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);
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);
}
}
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 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)
{
arr.resize(selection.nRows);
toArrayOfOid((oid_t*)arr.base());
}
/**
* Get current object idenitifer
* @return 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
();
}
}
/**
* 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);
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -