p align="left"> } }; Этот параметризированный класс на самом деле только переопределил сигнатуры методов более удобными и работающими с пользовательскими типами данных. База данных или объект окружения Этот объект фактически представляет собой абстракцию базы данных: является контейнером для индексируемых таблиц, отвечает за их открытие, доступ, а также проводит над ними служебные операции экспорта и т.п. На диаграмме это выглядит так: 57 Описание класса приведено ниже: class hbEnv { DbEnv *env; bool is_native_log; Log* LogObj; //! Путь к файлам char* path; //! Количество баз - ломает вектором писать - тогда дольше компилится int sz; //! Инишиалайзеры (в количестве равном sz) hbInit *dbinits; hbInit *idxinits; int idxsz; char* schemaid; // уже проверяется, при открытии из словаря чит. оригин. и сравнивается //! Мутекс для транзакций 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; 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;} // := public: 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],'']} | idxmod1 id '(' flist1 ')' '{*' rawcode '*}' {[0,$_[1],$_[2],$_[4],$_[7]]} | idxmod2 id '(' flist2 ')' {[1,$_[1],$_[2],$_[4],'']} | idxmod2 id '(' flist2 ')' '{*' rawcode '*}' {[1,$_[1],$_[2],$_[4],$_[7]]} ; idxmod1: '.!' | ':!' | '%!' ; idxmod2: '.' | ':' | '%' ; flist1: id {[[$_[1],'']]} | id ',' flist1 {unshift @{$_[3]},[$_[1],''];$_[3]} ; flist2: idxmod3 id {[[$_[2],$_[1]]]} | idxmod3 id ',' flist2 {unshift @{$_[4]},[$_[2],$_[1]];$_[4]} ; idxmod3: '+' | '-' | '^' ; #--------------------------------------------------------- codeblock: code 'decl' '{*' rawcode '*}' {tblproc::CodeBlockPrint('hh', \$_[4],0);} | code 'tab' '{*' rawcode '*}' {tblproc::CodeBlockPrint('tab', \$_[4],0);}
Страницы: 1, 2, 3, 4, 5, 6
|