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

📄 cursor.h

📁 用于嵌入式环境的数据库
💻 H
📖 第 1 页 / 共 2 页
字号:

    /**
     * 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)));
        table->columns->fetchRecordFields(record, 
                                          (byte*)db->getRow(currId));
    }


  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

    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 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;
        prefetch = rec != NULL;
        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;
        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) 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 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 + -