//! Мутекс для транзакций
pthread_mutex_t mx;
uint dltype;
//! in secs interval for checkpoints and logarchs
ulong dldelay,bdbchkpoint,bdblogrem;
static void* thf_deadrs(void*);
static void* thf_chkpnt(void*);
static void* thf_logarc(void*);
pthread_t pth_deadrs,pth_chkpnt,pth_logarc;
ushort stflags;
bool IsOpenflag;
ushort state;
TDictionary dict;
//char* ConfFile; //имя конф. файла может переопределятся в потомках/ но зачем
FILE* OpenOutputStream(const char* fn,const char* mode);
void CloseOutputStream(FILE* f);
// удаляет все __db.00x файлы т.к там хранится хэш, из-за которого может неверно сработать проверка индексов
protected:
//! Сами тейблы, индексов здесь нет, они в самих тейблах
hbPTable **dbs;
void SetSchemaid(const char* File) {if(schemaid)free(schemaid);schemaid = strdup(File);}
// тэйблы будут создаваться в конструкторе потомка ,и вноситься в dbs
int Close(int);
virtual void UsrClose();
public:
Log* GetLog() {return LogObj;}
operator DbEnv*() {return env;};
DbEnv* operator ->() {return env;}
//DbEnv& GetDbEnv(){ return env;}
const char* GetSchemaId()const {return schemaid;}
const char* GetUuid(const bexcp&, hbTxn *tx);
const char* GetPath()const {return path;}
bool IsOpen() {return state;}
hbEnv(const char *p,envInit& e,ushort flt = LL_DEBUG, Log* LogObj1 = 0);
virtual ~hbEnv();
//st_flags помещ. в DbEnv::set_flags (DB_TXN_NOSYNC)
//op_flags помещ. в Db::open (DB_PRIVATE/DB_THREAD - by default)
// если режим CDS то эти флаги игнорируются за исключением op_flags = DB_PRIVATE!!
void OpenTDSMode(const bexcp& excp, u_int32_t st_flags = 0, u_int32_t op_flags = (DB_THREAD | DB_RECOVER) ) //DB_THREAD | DB_RECOVER_FATAL
{DBOpen(excp, OPEN_TDS,true,st_flags, op_flags);}
void OpenCDSMode(const bexcp& excp, bool opentables = true,u_int32_t op_flags = 0/*только для DB_PRIVATE*/)
{DBOpen(excp, OPEN_CDS,opentables,0,op_flags);}
void Close(const bexcp& excp);
void Close();
// полная инициализация&создание базы с нуля (предварительное удаление БД)
void Init(const bexcp& excp, u_int32_t op_flags=DB_THREAD);
// Проверка индексов и если надо их корректировка база должна быть в offline
void CheckForIdx(const bexcp& excp, uint bulk_ret_buffer_size = (5 * 1024 * 1024),bool fix = false);
void CheckForRef(const bexcp& excp, uint bulk_ret_buffer_size = (5 * 1024 * 1024));
//! экспорт базы даных
void ExportDB(const bexcp& excp, const char* fn,uint bulk_ret_buffer_size = (5 * 1024 * 1024));
//! импорт базы даных
void ImportDB(const bexcp& excp, const char* fn);
void printf(ushort level,const char* fmt,...); // обвертка под Log::printf
};
Этот класс инкапсулирует работу со словарем, где может храниться информация, полезная для программиста.
Транзакции
Класс транзакций имеет следующий вид:
class hbTxn{
hbEnv& Env;
bexcp excp1;
hbTxn* parent;
DbTxn* Txn;
void SetFlags(){}
hbTxn(const hbTxn& Txn1):Env(Txn1.Env){} //copy constr
hbTxn& operator=(const hbTxn&){return *this;} // :=
operator DbTxn*() {return Txn;};
hbTxn(const bexcp& excp, hbEnv& env1,ullong flags = 0,hbTxn* parent1 = 0); // младшие 32 бита это //обычн. беркл. флаги 33 бит отвечает за немедленный старт транзакции сразу же после создания
hbTxn(const bexcp& excp, hbTxn* parent1,ullong flags = 0);
// --- " ---
~hbTxn();
bool HaveParentTxn() {return parent!=0;}
void Start(const bexcp& excp, ulong flags = 0);
void Commit(const bexcp& excp, ulong flags = 0);
void RollBack(const bexcp& excp);
//void RollBack();
Его особенностью является то, что созданный объект транзакции нельзя копировать или создавать копированием. А также такой объект должен создаваться автоматически, то есть как стековая переменная:
try
{
hbTxn tx(excp, parent_tx);
// операции с базой
tx.Commit();
}
catch(…){}Как видим, первое - не надо заботиться об удалении объекта транзакции (при любой ситуации), второе - в случае исключения Rollback() вызовется автоматически в деструкторе этого объекта.
Транслятор
Как уже говорилось, задача транслятора состоит в том, чтобы создать по желанию пользователя максимально удобную оболочку для библиотеки в соответствии с его определениями основных элементов базы.
Файл грамматики приведен ниже:
%%
#-------------------------------------------------------
#------ COMMENTS --------------------------------------
#id идентификатор
#string строковый литерал или идентификатор
#num чиловой литерал
#float литерал числа с плавающей точкой
#char символьный литерал
#rawcode ::= любая последователность кода между '{*' и '*}'
file: 'end' {tblproc::Finish();}
| filetext 'end' {tblproc::Finish();}
;
filetext: item
| item filetext
item: optionblock
| idxblock
| structblock
| enumblock
| codeblock
| tableblock
literal: string {[$_[1],0]}
| num {[$_[1],1]}
| float {[$_[1],2]}
| char {[$_[1],3]}
#---------------------------------------------------------
optionblock: 'option' '{' oplist '}' ';'
{tblproc::OptBlockPrint('',$_[3]);}
| 'option' opitem ';'
{tblproc::OptBlockPrint('',[$_[2]]);}
| 'option' id '{' oplist '}' ';'
{tblproc::OptBlockPrint($_[2],$_[4]);}
| 'option' id opitem ';'
{tblproc::OptBlockPrint($_[2],[$_[3]]);}
oplist:
opitem ';' {[$_[1]]}
| opitem ';' oplist {push @{$_[3]}, $_[1]; $_[3]}
opitem: id '=' literal
{[$_[1],@{$_[3]}[0],0,@{$_[3]}[1]]}
| id '=' id {[$_[1],$_[3] ,1,'']}
idxblock: 'idx' id idxitem ';'
{tblproc::IdxBlockPrint($_[2],[$_[3]]);}
| 'idx' id '{' idxitemlist '}' ';'
{tblproc::IdxBlockPrint($_[2],$_[4]);}
idxitemlist: idxitem ';' {[$_[1]]}
| idxitem ';' idxitemlist {unshift @{$_[3]},$_[1]; $_[3]}
idxitem: idxmod1 id '(' flist1 ')'
{[0,$_[1],$_[2],$_[4],'']}
Страницы: 1, 2, 3, 4, 5, 6, 7