Files
2022-12-13 12:44:04 +01:00

206 lines
6.1 KiB
C++

//-----------------------------------------------------------------------------
// 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/param.h>
#include <fcntl.h>
#include <sys/types.h>
#include <db.h>
#include <rsvcData.h>
#include <rsvcDBT.h>
#include <rsvcServerConfig.h>
#include <rsvcVirtualDbase.h>
#if defined (_RSVC_USE_THREAD) && defined (_REENTRANT)
#include <cpSynch.h>
#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