⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cursor.h

📁 最新版本!fastdb是高效的内存数据库系统
💻 H
📖 第 1 页 / 共 2 页
字号:
//-< 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 &gt; 0</code>) or previous (<code>n &lt; 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 + -