//----------------------------------------------------------------------------- // Copyright (c) 1994,1995 Southeastern Universities Research Association, // Continuous Electron Beam Accelerator Facility // // This software was developed under a United States Government license // described in the NOTICE file included as part of this distribution. // //----------------------------------------------------------------------------- // // Description: // RSVC database interface to db library (Thread Safe) // // Author: Jie Chen // // // // #ifndef _RSVC_DATABASE_H #define _RSVC_DATABASE_H #include #include #include #include #include #include #include #include #include #include #include #if defined (_RSVC_USE_THREAD) && defined (_REENTRANT) #include #endif // comparision function definition typedef int (*rsvcCompFunc) (const DBT* key1, const DBT* key2); // this class will handle interface to btree based database implementation. // data/key are rsvcData/undefined. When caller insert a rsvc, the // rsvcData must have a key in this data with tag name 'key'. // when caller tries to get rsvcData, caller has to specify the key // which is in a rsvcData with tag name 'key' // This interface will not provide two iterators at the same time. // This is the limitation by low level database library // All pointers to key must be the memory location provided by callers class rsvcDatabaseLocker; class rsvcDatabase : public rsvcVirtualDbase { public: // constructor // default constructor, users have to call open explicitly rsvcDatabase (void); // constructor: name is a file name, flags are the same flags as // standard open routine. // data_size is estimate of each data stored in the database rsvcDatabase (char* name, int flags, int keyType = RSVC_STRING, size_t data_size = 496, size_t cache_size = 0, size_t page_size = 0, int mode = 0666); // destructor ~rsvcDatabase (void); // operation // open a database int open (char* name, int flags, int keyType = RSVC_STRING, size_t cache_size = 0, int mode = 0666); // create a database int create (char* name, int flags, int keyType = RSVC_STRING, size_t data_size = 496, size_t cache_size = 0, size_t page_size = 0, int mode = 0666); // close connection to the database int close (void); // get a rsvcData. int get (rsvcData& data, rsvcData& key); // insert a rsvcData which must have a key inside int put (rsvcData& data, rsvcData& key); // delete a data object pointed by key value int del (rsvcData& key); // flush all internal buffer to disk int flush (void); // return database name char* database (void) const; // return file descriptor for the opened database int fd (void); // check to see the database is open or not int opened (void) const; // iterator for sequential access to database int cursorInit (void); // set cursor to the position pointed by key 'key', // and return data 'data' if successful int cursorSet (rsvcData& data, rsvcData& key); // move cursor to the next position. // return CDEV_SUCCESS on success, CDEV_ERROR: check errno // return CDEV_INVALIDOBJ: no more int cursorNext (rsvcData& data, rsvcData& key); // move cursor to the previous position // return CDEV_SUCCESS on success, CDEV_ERROR: check errno // return CDEV_INVALIDOBJ: no more int cursorPrev (rsvcData& data, rsvcData& key); // merge current value pointed by cursor: // this routine can only used to update the data with the same // or smaller size than the exisiting data // If you like to update arbitrary size of data, use del and put int cursorUpdate (rsvcData& data); // move cursor to the beginning of the database // no need to provide key int cursorFirst (rsvcData& data, rsvcData& key); // move cursor to the end of the database // no need to provide key int cursorLast (rsvcData& data, rsvcData& key); // close cursor operation int cursorFinish (void); const char* className (void) const {return "rsvcDatabase";} protected: // convert a DBT to rsvcData (database --> back to memory) static int convertData (rsvcData& data, const DBT* res); // convert rsvcData to rsvcDBT (memory --> to database ) static int convertData (rsvcDBT* out, rsvcData& data); // convert rsvcData to DBT and a key (memory --> to database) static int convertData (rsvcDBT* out, rsvcDBT* key, rsvcData & data, rsvcData& tkey, int keyType); // find key size static size_t keySize (rsvcData& key, void* tkey, int keyType); // convert key from regular rsvcData to DBT format // using convertion buffer keybuf // used when convert memory -->to database static int convertKey (rsvcDBT* key, rsvcData& tkey, int keyType, char* keybuf); // copy key data from database back to memory static int copyKeyData (rsvcData& key, DBT* data, int keyType); private: #if defined (_RSVC_USE_THREAD) && defined (_REENTRANT) cpMutex mutex_; #endif // database access option: different site can change option DB_INFO b_; // internal DB pointer DB* dbp_; // Database cursor pointer DBC* dbc_; // keep track of size of data that have been written to a database int wsize_; // static buffer for key char keybuf_[RSVC_MAX_KEY_LEN]; // Function pointers to all comparision functions static rsvcCompFunc compFuncs_[]; // deny access to copy and assignment operator rsvcDatabase (const rsvcDatabase& dbase); rsvcDatabase& operator = (const rsvcDatabase& dbase); // friend class friend class rsvcDatabaseLocker; }; class rsvcDatabaseLocker { public: // constructor and destructor rsvcDatabaseLocker (rsvcDatabase* dbase); ~rsvcDatabaseLocker (void); private: rsvcDatabase* dbase_; // deny access to assignment and copy operations rsvcDatabaseLocker (const rsvcDatabaseLocker& ); rsvcDatabaseLocker& operator = (const rsvcDatabaseLocker& ); }; #endif