База данных или объект окружения

Этот объект фактически представляет  собой абстракцию базы данных: является контейнером для индексируемых таблиц, отвечает за их открытие, доступ, а также проводит над ними служебные операции экспорта и т.п. На диаграмме это выглядит так:

Описание класса приведено ниже:

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);}

       | code 'def' '{*' rawcode '*}'

                      {tblproc::CodeBlockPrint('cc', \$_[4],0);}

       | code 'def' 'top' '{*' rawcode '*}'

               {tblproc::CodeBlockPrint('cc', \$_[5],1);}

       | code '{*' rawcode '*}' 

                           {tblproc::CodeBlockPrint('all', \$_[3],0);}

;

 

#---------------------------------------------------------

enumblock: 'enum' id '{' enumlist '}' ';' 

                   {tblproc::EnumBlockPrint($_[2],$_[4]);}

       | 'enum' id ';'

                                     {tblproc::EnumBlockPrint($_[2],[]);}

;

enumlist:  enumitem                                           {[$_[1]]}

       | enumitem ',' enumlist                              {unshift @{$_[3]}, $_[1]; $_[3]}

;

enumitem:  id                                                 {[$_[1],'']}

       | id '=' num                                         {[$_[1],$_[3]]}

;

 

#---------------------------------------------------------

 

structblock: 'struct' id '{' structlist '}' ';'

               {tblproc::StructBlockPrint($_[2],$_[4]);}

;

 

structlist: structitem                                         {[$_[1]]}

       | structitem structlist                              {unshift @{$_[2]}, $_[1]; $_[2]}

;

 

structitem: id pnlistid ';'   

                               {[$_[1],@{$_[2]}[0],@{$_[2]}[1]]}

;

 

#---------------------------------------------------------

tableblock: tableforward  

                  {tblproc::TableBlockPrint(@{$_[1]}[0],'',[],[]);}

       | tablehead ';' 

                            {tblproc::TableBlockPrint(@{$_[1]}[0],@{$_[1]}[1],@{$_[1]}[2], []);}

       | tablehead tail ';' 

                               {tblproc::TableBlockPrint(@{$_[1]}[0],@{$_[1]}[1],@{$_[1]}[2], $_[2]);}

;

 

tail:      idxtailitem                                        {$_[1]}

       | idxtailitem tail                                {unshift @{$_[2]},$_[1];$_[2]}

       | optiontailitem

       | optiontailitem tail

;

 

tableforward: 'table' id ';'                                     {[$_[2]]}

;

 

tablehead: 'table' memmodifid '{' memberlist '}'

             {[@{$_[2]}[0],@{$_[2]}[1],$_[4]]}

;

 

memmodifid: id                                                 {[$_[1],'']}

       | memmodificator id                                  {[$_[2],'$']}

;

 

memberlist: memberitem                                         {[$_[1]]}

       | memberitem memberlist                              {unshift @{$_[2]}, $_[1]; $_[2]}

;

memberitem: id pnlistid ';' 

                                 {[$_[1],@{$_[2]}[0],@{$_[2]}[1],[]]}

       | id pnlistid modificator1 ';' 

                    {[$_[1],@{$_[2]}[0],@{$_[2]}[1],$_[3]]}

;

 

modificator1: idxmodificator                                     {[$_[1], '']}

#      | idxmodificator memmodificator                      {[$_[1], '$','']}

       | idxmodificator '{*' rawcode '*}'                   {[$_[1], $_[3]]}

#      | idxmodificator memmodificator '{*' rawcode '*}'    {[$_[1], '$', $_[4]]}

;

 

pnlistid:  pnlist id                                          {[$_[1], $_[2]]}

       | id                                                 {[[], $_[1]]}

;

 

pnlist:    pointer                                            {[$_[1],'']}

       | pointer array                                      {[$_[1],$_[2]]}

       | array                                              {['',$_[1]]}

;

 

pointer:   '+'

       | '-'

       | '*'

;

 

array:     '[' id ']'                                         {$_[2]}

       | '[' num ']'                                        {$_[2]}

;

 

idxmodificator: '.!'

       | ':!'

       | '%!'

       | '.+'

       | ':+'

       | '%+'

       | '.-'

       | ':-'

       | '%-'

       | '.^'

       | ':^'

       | '%^'

;

 

memmodificator: '$'

;

 

idxtailitem: 'idx' idxitem                                      {[$_[2]]}

       | 'idx' '{' idxitemlist '}'                          {$_[3]}

;

 

optiontailitem: 'option' '{' oplist '}'

       | 'option' opitem

;

#---------------------------------------------------------

%%

use tblproc;

 

 

Основными компонентами этой грамматики являются:

· option   – элемент языка, определяющий настройки к конкретной таблице.

· Idx блок – это блок, определяющий параметры индексной таблицы.

· Table блок - блок, определяющий таблицу, ее записи и индексы.

· Struct блок - блок, аналогичен table, с той разницей, генерирует только определения структур записей без определения самой таблицы.

· Enum блок – определение С++ енумераторов, используемых в определении таблицы.

· Code блок – блок сырого С++ кода встраимого непосредственного в результирующий файл.

Транслятор состоит из 3 основных частей лексики, семантики и пускового модуля, написанных на языке Perl.

Лексический анализатор создан с учетом этой грамматики и имеет следующий интерфейс.

Prepare(array of lines); // normal result ==0

token Next();

Он поддерживает также препроцессирование на уровне вложений include.

Семантический анализатор состоит из API, вызываемых как обработчики событий (для интерфейса yapp указываются в определении грамматики).

Пусковой модуль является оболочкой для запуска синтаксического анализатора, с разбором входных параметров

Формат:

   1)HibaseCompiler.pl [-f имя файла] [-p путь к hibase] [-d каталог, куда помещ. сген стаб]

   2)program | HibaseCompiler.pl [-p путь к hibase] [-d каталог,куда помещ. сген стаб].

 


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: