Пример работы программы

 

В качестве примера  расмотрим следующее определение базы данных

Tables.def

code def top

{*

#include <stdio.h>

#include <stdlib.h>

#include <pthread.h>

#include <db_cxx.h>

 

#include "../hblib/consts.hh"

#include "../hblib/ll.hh"

#include "../hblib/utils.hh"

#include "../hblib/hdb.hh"

 

#include "tbmain.hh"

#include "dbmain.hh"

*}

 

option

{

file = "main";

namespace = "hb";

};

 

 table supplier

 {

char [12]name.!; // key uh; //unq,hash

char [40]desc;

 };

 

 table thing

 {

    supplier+ tsupplier;                    // внешняя ссылка

char [12]name.!; // key uh; //unq,hash

char [40]desc;

 };

end

 

В результате работы транслятора  получаем 3 файла: файл описания структур записей таблиц, файл определения самих таблиц и базы и файл ее реализации:

Hbmain.hh

 

namespace hb{

using namespace hb;

class mainEnv;

 

struct supplierKey

{

   db_recno_t key;

 

inline void Export(FILE* f);

inline void Import(char*,uint);

supplierKey(const db_recno_t& key_temp);

supplierKey(){}

}__attribute__ ((packed));

struct supplierVal

{

   char name[12];

   char desc[40];

 

inline void Export(FILE* f);

inline void Import(char*,uint);

supplierVal(char* name_temp,char* desc_temp);

supplierVal(){}

}__attribute__ ((packed));

class qsupplier: public hbTable<supplierKey,supplierVal>{

mainEnv& menv;

public:

qsupplier(mainEnv&);

inline void RefInit();

static void GetRef_supplier(uint, char*,char*, db_recno_t*&, uint&);

    static int qsupplier::idx_name(Db *db,const Dbt* pk,const Dbt* pv,Dbt* fv);

};

struct isupplier_name

{

   char name[12];

    char* Getname(){return name;}

   isupplier_name(char* name_temp);

}__attribute__ ((packed));

 

//------------------------------------------------------------------------------

 

struct thingKey

{

   db_recno_t key;

 

inline void Export(FILE* f);

inline void Import(char*,uint);

thingKey(const db_recno_t& key_temp);

thingKey(){}

}__attribute__ ((packed));

struct thingVal

{

   db_recno_t tsupplier;

   char name[12];

   char desc[40];

 

inline void Export(FILE* f);

inline void Import(char*,uint);

thingVal(const db_recno_t& tsupplier_temp,char* name_temp,char* desc_temp);

thingVal(){}

}__attribute__ ((packed));

 

 

class qthing: public hbTable<thingKey,thingVal>{

mainEnv& menv;

public:

qthing(mainEnv&);

inline void RefInit();

static void GetRef_thing(uint, char*,char*, db_recno_t*&, uint&);

    static int qthing::idx_name(Db *db,const Dbt* pk,const Dbt* pv,Dbt* fv);

};

struct ithing_name

{

   char name[12];

    char* Getname(){return name;}

   ithing_name(char* name_temp);

}__attribute__ ((packed));

 

//------------------------------------------------------------------------------

};

 

Dbmain.hh

 

namespace hb{

using namespace hb;

enum idxNames{

   dbn_supplier_name = 0, dbn_thing_name = 0};

class mainEnv;

class mainEnv:public hbEnv{

public:

   mainEnv(const char*,ushort flt = LL_DEBUG, Log* LogObj1 = 0);

   qsupplier&         tsupplier;

   qthing&    tthing;

};

};

 

Dbmain.cc

 

#include <stdio.h>

#include <stdlib.h>

#include <pthread.h>

#include <db_cxx.h>

 

#include "../hblib/consts.hh"

#include "../hblib/ll.hh"

#include "../hblib/utils.hh"

#include "../hblib/hdb.hh"

 

#include "tbmain.hh"

#include "dbmain.hh"

 

//#include <stdio.h>

//#include <stdlib.h>

//#include <time.h>

//#include <string.h>

//#include <stdarg.h>

//#include <pthread.h>

//#include <unistd.h>

//#include <dirent.h>

//#include <ctype.h>

//#include <sys/types.h>

 

//#include "../hibase/consts.hh"

//#include "../hibase/ll.hh"

 

//#include "../hibase/hdb.hh"

 

//#include "myconst.hh"

//#include "dbmain.hh"

namespace hb{};

using namespace hb;

namespace hb{};

using namespace hb;

#define NUMDB 2

enum maindbNames{

dbnsupplier = 0,dbnthing};

static hbInit tblIndexes[]={

{ "supplier::name","supplier.i","name",DB_HASH,0,0,0,&qsupplier::idx_name, 0, 0 },

{ "thing::name","thing.i","name",DB_HASH,0,0,0,&qthing::idx_name, 0, 0 }

};

static hbInit tblInits[]={

{"supplier","supplier.q",0,DB_QUEUE,0,1, tblIndexes + 0, 0, &qsupplier::GetRef_supplier, 0},

{"thing","thing.q",0,DB_QUEUE,0,1, tblIndexes + 1, 0, &qthing::GetRef_thing, 1}

};

envInit mainEnvInit={

NUMDB,

 "$Id: tblproc.pm,v 1.35 2004/01/10 23:57:48 bora Exp $"

};

 

 

qsupplier::qsupplier(mainEnv& env): hbTable<supplierKey,supplierVal>(env,tblInits[dbnsupplier]), menv(env)

{}

 

void qsupplier::RefInit()

{

 

}

 

void qsupplier::GetRef_supplier(uint num, char* key,char* val, db_recno_t*& refs, uint& ref_count)

{

   supplierKey *key1 = (supplierKey*)key;

   supplierVal *val1 = (supplierVal*)val;

 

}

void supplierKey::Export(FILE* f)

{

   fprintf(f,"%d",key);

}

void supplierKey::Import(char* buf, uint len)

{

   int j,num, i = 0;

   char temp;

   {j = i;for(;i<len;i++)if(buf[i]==',' || buf[i]=='}')break;}

           temp = buf[i];buf[i] = '\0';sscanf(buf+j,"%d",&key);

           buf[i] = temp;

   i++;

}

supplierKey::supplierKey(const db_recno_t& key_temp)

{

   memset(this,0,sizeof(*this));

   key = key_temp;

}

void supplierVal::Export(FILE* f)

{

   fprintf(f,"{");

   CharArrInToStr(f,name,12);

   fprintf(f,"}");

   fprintf(f,",");

   fprintf(f,"{");

   CharArrInToStr(f,desc,40);

   fprintf(f,"}");

}

void supplierVal::Import(char* buf, uint len)

{

   int j,num, i = 0;

   char temp;

 

if(buf[i++]!='{')

   throw hbExcp(3,LL_CRITICAL,0,"Ошибка импорта: +указатель на таблицу = 0.");

j = i;

for(;i<len;i++)

{

   if (buf[i] == '}' && buf[i-1]!='\\')

       break;

}

   StrToCharArr(buf+j,i-j,name,12);

   i+= 2;

 

if(buf[i++]!='{')

   throw hbExcp(3,LL_CRITICAL,0,"Ошибка импорта: +указатель на таблицу = 0.");

j = i;

for(;i<len;i++)

{

   if (buf[i] == '}' && buf[i-1]!='\\')

       break;

}

   StrToCharArr(buf+j,i-j,desc,40);

   i+= 2;

}

supplierVal::supplierVal(char* name_temp,char* desc_temp)

{

   memset(this,0,sizeof(*this));

   strncpy(name,name_temp, sizeof(name));

   strncpy(desc,desc_temp, sizeof(desc));

}

 

 

isupplier_name::isupplier_name(char* name_temp)

{

   memcpy(name,name_temp,sizeof(name));

}

 

int qsupplier::idx_name(Db *db,const Dbt* pk,const Dbt* pv,Dbt* fv)

{

   supplierVal *v= (supplierVal*)(pv->get_data());

 

fv->set_data(v->name);

fv->set_size(sizeof(isupplier_name));

return 0;

}

 

//------------------------------------------------------------------------------

 

qthing::qthing(mainEnv& env): hbTable<thingKey,thingVal>(env,tblInits[dbnthing]), menv(env)

{}

 

void qthing::RefInit()

{

   ref.reftables[0].type      = '+';

   ref.reftables[0].reftable  = &menv.tsupplier;

 

}

 

void qthing::GetRef_thing(uint num, char* key,char* val, db_recno_t*& refs, uint& ref_count)

{

   thingKey *key1 = (thingKey*)key;

   thingVal *val1 = (thingVal*)val;

   if(num==0)

   {

           refs = &val1->tsupplier; ref_count = 1;

   }

 

}

void thingKey::Export(FILE* f)

{

   fprintf(f,"%d",key);

}

void thingKey::Import(char* buf, uint len)

{

   int j,num, i = 0;

   char temp;

   {j = i;for(;i<len;i++)if(buf[i]==',' || buf[i]=='}')break;}

           temp = buf[i];buf[i] = '\0';sscanf(buf+j,"%d",&key);

           buf[i] = temp;

   i++;

}

thingKey::thingKey(const db_recno_t& key_temp)

{

   memset(this,0,sizeof(*this));

   key = key_temp;

}

void thingVal::Export(FILE* f)

{

   fprintf(f,"%d",tsupplier);

   fprintf(f,",");

   fprintf(f,"{");

   CharArrInToStr(f,name,12);

   fprintf(f,"}");

   fprintf(f,",");

   fprintf(f,"{");

   CharArrInToStr(f,desc,40);

   fprintf(f,"}");

}

void thingVal::Import(char* buf, uint len)

{

   int j,num, i = 0;

   char temp;

   {j = i;for(;i<len;i++)if(buf[i]==',' || buf[i]=='}')break;}

           temp = buf[i];buf[i] = '\0';sscanf(buf+j,"%d",&tsupplier);

           buf[i] = temp;

   if(tsupplier == 0) throw hbExcp(3,LL_CRITICAL,0," Ошибка импорта: +указатель на таблицу = 0. ");

   i++;

 

if(buf[i++]!='{')

   throw hbExcp(3,LL_CRITICAL,0," Ошибка импорта: не могу распарсить строку.");

j = i;

for(;i<len;i++)

{

   if (buf[i] == '}' && buf[i-1]!='\\')

       break;

}

   StrToCharArr(buf+j,i-j,name,12);

   i+= 2;

 

if(buf[i++]!='{')

   throw hbExcp(3,LL_CRITICAL,0," Ошибка импорта: не могу распарсить строку. ");

j = i;

for(;i<len;i++)

{

   if (buf[i] == '}' && buf[i-1]!='\\')

       break;

}

   StrToCharArr(buf+j,i-j,desc,40);

   i+= 2;

}

thingVal::thingVal(const db_recno_t& tsupplier_temp,char* name_temp,char* desc_temp)

{

   memset(this,0,sizeof(*this));

   tsupplier = tsupplier_temp;

   strncpy(name,name_temp, sizeof(name));

   strncpy(desc,desc_temp, sizeof(desc));

}

 

ithing_name::ithing_name(char* name_temp)

{

   memcpy(name,name_temp,sizeof(name));

}

 

int qthing::idx_name(Db *db,const Dbt* pk,const Dbt* pv,Dbt* fv)

{

   thingVal *v= (thingVal*)(pv->get_data());

 

fv->set_data(v->name);

fv->set_size(sizeof(ithing_name));

return 0;

}

 

//------------------------------------------------------------------------------

mainEnv::mainEnv(const char *path,ushort flt, Log* LogObj1):hbEnv(path,mainEnvInit,flt,LogObj1),

tsupplier(* (new qsupplier(*this))),

tthing(* (new qthing(*this)))

{

   dbs[dbnsupplier]            = &tsupplier;tsupplier.RefInit();

   dbs[dbnthing]       = &tthing;tthing.RefInit();

 

}

 

Файл пример описан так

int main(void)

{

mainEnv env ("./DataBase/");

//создаем базу, то есть формируем необходимые файлы для всех таблиц

env.Init(bexcp(16,"main","example.cc",3,LL_DEBUG));

env.Close(bexcp(16,"main","example.cc",3,LL_DEBUG));

env.ImportDB(bexcp(16,"main","example.cc",3,LL_DEBUG),"./Export1.ex");

env.ExportDB(bexcp(16,"main","example.cc",3,LL_DEBUG),"./Export.ex");

// проверяем на индексную целостность

env.CheckForIdx(bexcp(16,"main","example.cc",3,LL_DEBUG));

// проверяем на ссылочную целостность

env.CheckForRef(bexcp(16,"main","example.cc",3,LL_DEBUG));

env.OpenTDSMode(); //открываем ее в нормальном транзакционном режиме

try

{

hbTxn tx(env);

tx.Start();

supplierKey key = {1};

supplierVal val = {"Boris","Boss"};

env.tsupplier.Put(&tx,&key,&val);

thingKey key = {1};

thingVal val = {1,"Computer","best"};

env.tthing.Put(&tx,&key,&val);

tx.commit();

    }

    catch(hbExcp& excp)

    {

              cout<<excp.what();

}

env.Close(); 

return 0;

}

 

Заключение

 

На сегодняшний день навигационно-сетевые базы вновь приобрели свою актуальность. Это обуславливается, главным образом, их очень высокой скоростью работы, даже, несмотря на сложность понимания для неквалифицированного специалиста. Чтобы облегчить работу программисту с такой базой средствами BerkeleyDB к ней был введен генератор объектно-ориентированного интерфейса. Это позволило качественно улучшить скорость разработки на С++ и повысить уровень абстракции работы с ней.


8.Список используемой литературы:

1) http://www.sleepycat.com – официальный сайт компании –разработчика BerkeleyDB

2) The Object Data Standard ODMG 3.0. New York, MK, 2002.

3) Gamma E., Helm R., Johnson R., Vlissides J. Design Patterns: Elements of reusable object-oriented software, Reading, MA: Addison-Westley, 1995.

4) Герберт Шилдт. Полный справочник по С. М., Вильямс, 2002.



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



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