Scimore Embedded database

 
Àâòîð: Ãîëîâêî Ãåîðãèé
 
Îïóáëèêîâàíî:
Èñïðàâëåíî:

ÏËÀÍ:

Äëÿ êîãî ïðåäíàçíà÷åíà ýòà ñòàòüÿ

Ïðåèìóùåñòâà ÁÄ Scimore

Ðàáîòà ñ ÁÄ

Øàã 1. Ñîçäàåì ÁÄ

Øàã 2. Óñòàíàâëèâàåì ñîåäèíåíèå ñ ÁÄ

Øàã 3. Âûïîëíÿåì çàïðîñ ê ÑÓÁÄ

Øàã 4. Ïîëó÷àåì äàííûå èç ÑÓÁÄ

Øàã 5. Âíîñèì èçìåíåíèÿ â ÁÄ

Øàã 6. Ïðîèçâîäèì ïîèñê äàííûõ â ÁÄ

Øàã 7. Çàâåðøåíèå ðàáîòû

 

Äåìîíñòðàöèîííàÿ ïðîãðàììà (Èñõîäíûå òåêñòû)

 

Äëÿ êîãî ïðåäíàçíà÷åíà ýòà ñòàòüÿ

 

Åñëè âû õîòèòå óçíàòü âñå ïðåèìóùåñòâà è âîçìîæíîñòè ÑÓÁÄ Scimore à òàêæå êàê ïðîãðàììíî óïðàâëÿòü äàííûìè â óêàçàííîé ÑÓÁÄ, òî ýòà ñòàòüÿ äëÿ âàñ.

 

Ïðåèìóùåñòâà ÁÄ Scimore

 

 

 

Ðàáîòà ñ ÁÄ

Ñíà÷àëà â îáùèõ ÷åðòàõ.

§                Ñîçäàòü ÁÄ

§                Óñòàíîâèòü ñîåäèíåíèå ñ ÁÄ

§                Âûïîëíèòü çàïðîñ

§                Ïîëó÷èòü äàííûå

§                Âíåñòè èçìåíåíèÿ â ÁÄ (åñëè íåîáõîäèìî)

§                Ïðîèçâåñòè ïîèñê äàííûõ â ÁÄ (åñëè íåîáõîäèìî)

§                Çàêðûòü ñîåäèíåíèå

Òåïåðü ïîäðîáíåå.

 

Øàã 1. Ñîçäàåì ÁÄ

 

Äëÿ ñîçäàíèÿ ÁÄ â ïåðâóþ î÷åðåäü íåîáõîäèìî, ÷òîáû â äèðåêòîðèè èñïîëíÿåìîãî ìîäóëÿ íàõîäèëèñü ôàéëû Scimore.Data.dll è scimoredb.dll – äèíàìè÷åñêèå áèáëèîòåêè äëÿ ïîääåðæêè è âçàèìîäåéñòâèÿ ñ ÁÄ, à òàêæå â íàñòðîéêàõ ïðîåêòà ïðîïèñàòü ïóòü ê *.h – ôàéëàì èç äèðåêòîðèè sdk è ê áèáëèîòåêå scdriver.lib èç äèðåêòîðèè mtlib. Ýòî íåîáõîäèìî, ÷òîáû èìåòü äîñòóï ê ïðîñòðàíñòâó èìåí scdriver, êîòîðîå è ïðåäîñòàâëÿåò âîçìîæíîñòè ïî âçàèìîäåéñòâèþ ñ ÁÄ. Äàëåå íåîáõîäèìî ñîçäàòü è çàïóñòèòü ÁÄ. Äëÿ ýòîãî ñîçäàäèì ýêçåìïëÿð êëàññà c_scimore_db â êëàññå ïðåäñòàâëåíèÿ:

 

public:

      c_scimore_db db;

 

Òåïåðü ìîæíî ñîçäàòü è çàïóñòèòü ÁÄ, äëÿ ýòîãî ïðîïèøåì ñëåäóþùèé êîä:

 

void CEmbadedDBView::OpenDB(BOOL &DB)

{

      // Åñëè ÁÄ íå ñóùåñòâóåò, òî óñòàíîâèòü è îòêðûòü åå

      if (!IsDBInstalled())

      {

            try

            {

                  db.install(DB);

                  db.close();

                  db.start(DB);

 

                  db.create_schema(DB);

            }

            // Îáðàáîòêà èñêëþ÷èòåëüíîé ñèòóàöèè

            catch (node_exception)

            {

            }

      }

      // Åñëè ÁÄ ñóùåñòâóåò îòêðûòü åå

      else

            db.start(DB);

}

 

Ôóíêöèÿ IsDBInstalled() èùåò â äèðåêòîðèè èñïîëíÿåìîãî ôàéëà ïàïêó scimoreDB. Åñëè îíà ñóùåñòâóåò, ýòî çíà÷èò, ÷òî ÁÄ óñòàíîâëåíà, è îíà áóäåò òîëüêî îòêðûòà, â ïðîòèâíîì ñëó÷àå áóäåò ïðîèçâåäåíà åå óñòàíîâêà.

Ðàññìîòðèì ïîäðîáíåå ôóíêöèè êëàññà c_scimore_db:

1. Óñòàíîâêà:

 


      void install(BOOL &IsDB)

      {

            char path[MAX_PATH];

 

            if(GetModuleFileNameA(NULL,path,MAX_PATH))

            {

                  _TINT  ch     = TEXT('\\');

                  char *pfirst = strrchr(path, ch);

                  char *pnext  = NULL;

                 

                  // Search backward and replaces the dll name with the hook one

                  while(pfirst)

                  {

                        if(!(pnext = strrchr(pfirst + 1, ch)))

                        {

                             strcpy(&path[pfirst-path],"");

                             break;

                        }

                        else

                             pfirst = strrchr(path, ch);

                  }

                 

                  // install embedded database

                  installDB(path, IsDB);

            }

      };

 

 

      void installDB(const char *path, BOOL &IsDB)

      {

            char *net_conn = "-net/maxconn=8";

#ifdef SCIMORE_PROTO_TCP

            char *net_edpn = "-net/endpoint=127.0.0.1:998";

            char *net_prot = "-net/protocol=1";

#elif SCIMORE_PROTO_INPROC

            char *net_edpn = "-net/endpoint=EmbadedDB";

            char *net_prot = "-net/protocol=2";

#endif

            char *tran_lock= "-tran/maxlocks=512";

            char *tran_log = "-tran/logblocks=1";

            char dllpath[MAX_PATH];

            char db_sys1[MAX_PATH];

            char db_sys2[MAX_PATH];

            char db_sys3[MAX_PATH];

            char *db_sys4  = "-db/cachepages=256";

 

            sprintf(dllpath,"%s\\%s",path,"scimoreDB");

 

            CreateDirectoryA(dllpath,0);

           

            sprintf(db_sys1,"-db/systables=%s\\scimoredb",path);

            sprintf(db_sys2,"-db/syslog=%s\\scimoredb",path);

            sprintf(db_sys3,"-db/data=%s\\scimoredb",path);

            sprintf(dllpath,"%s\\%s",path,"scimoreDB.dll");

           

            char *param[9] = {net_conn,net_edpn,net_prot,tran_lock,tran_log,db_sys1,db_sys2,db_sys3,db_sys4};

 

            // install embedded DB

            SCIMORE_DB *dbInstall = 0;

 

            //Load the dll and keep the handle to it

            dllHandle = LoadLibraryA(dllpath);

 

            // If the handle is valid, try to get the function address.

            if (NULL != dllHandle)

            {

                  //Get pointer to our function using GetProcAddress:

                  dbInstall = (SCIMORE_DB*)GetProcAddress(dllHandle, "DBInstall");

                  (*dbInstall)(9,param);

            }

            else IsDB = FALSE;

      };

 

2. Çàïóñê:

 

      bool start(BOOL &IsDB)

      {

            static bool started = false;

 

            if(!started)

            {

                  char path[MAX_PATH];

 

                  if(GetModuleFileNameA(NULL,path,MAX_PATH))

                  {

                        _TINT  ch     = TEXT('\\');

                        char *pfirst = strrchr(path, ch);

                        char *pnext  = NULL;

                       

                        // Search backward and replaces the dll name with the hook one

                        while(pfirst)

                        {

                             if(!(pnext = strrchr(pfirst + 1, ch)))

                             {

                                   strcpy(&path[pfirst-path],(""));

                                   break;

                             }

                             else

                                   pfirst = strrchr(path, ch);

                        }

                        if(!startDB(path, IsDB))

                             return false;

 

                        started = true;

                  }

            }

 

            return true;

      };

 

 

 

      bool startDB(const char *path, BOOL &IsDB)

      {

            char *net_conn = "-net/maxconn=8";

            char *net_mode = "-net/mode=1";

#ifdef SCIMORE_PROTO_TCP

            char *net_edpn = "-net/endpoint=127.0.0.1:998";

            char *net_prot = "-net/protocol=1";

#elif SCIMORE_PROTO_INPROC

            char *net_edpn = "-net/endpoint=EmbadedDB";

            char *net_prot = "-net/protocol=2";

#endif

            char *tran_lock= "-tran/maxlocks=512";

            char *tran_log = "-tran/logblocks=1";

            char *tran_chk = "-tran/LogCheckpoint=1";

           

            char dllpath[MAX_PATH];

            char db_sys1[MAX_PATH];

            char db_sys2[MAX_PATH];

            char db_sys3[MAX_PATH];

            char *db_sys4  = "-db/cachepages=4096";

           

            sprintf(db_sys1,"-db/systables=%s\\scimoredb",path);

            sprintf(db_sys2,"-db/syslog=%s\\scimoredb",path);

            sprintf(db_sys3,"-db/data=%s\\scimoredb",path);

 

            sprintf(dllpath,"%s\\%s",path,"scimoreDB.dll");

 

            char *param[11] = {net_conn,net_mode,net_edpn,net_prot,tran_lock,tran_log,tran_chk,db_sys1,db_sys2,db_sys3,db_sys4};

 

            // install embedded DB

            SCIMORE_DB *dbStart = 0;

 

            //Load the dll and keep the handle to it

            dllHandle = LoadLibraryA(dllpath);

 

            // If the handle is valid, try to get the function address.

            if (NULL != dllHandle)

            {

                  //Get pointer to our function using GetProcAddress:

                  dbStart = (SCIMORE_DB*)GetProcAddress(dllHandle, "DBStart");

                  (*dbStart)(11,param);

                 

                  // set in_process default protocol

#ifdef SCIMORE_PROTO_TCP

                  set_default_prot(1);

#elif SCIMORE_PROTO_INPROC

                  set_default_prot(2);

#endif

                  return true;

            }

           

            IsDB = FALSE;

            return false;

      };

 

3. Ñîçäàíèå êîíöåïòóàëüíîé ñõåìû:

 

      void create_schema(BOOL &IsDB)

      {

#ifdef SCIMORE_PROTO_TCP

            char* host = "localhost";

#elif SCIMORE_PROTO_INPROC

            char* host = "EmbadedDB";

#endif

            CConnection conn;

            try

            {

                  conn.Connect(host, 998);

            }

            catch (node_exception& e)

            {

                  MessageBoxA(0, e.msg, "Attention", MB_OK | MB_ICONERROR);

            }

 

            try

            {

                  // Ñîçäàäèì ÁÄ

                  conn.Execute("CREATE DATABASE IF NOT EXISTS SALES");

                  conn.GetCompletionStatus();

                  conn.Execute("USE SALES");

                  conn.GetCompletionStatus();

 

                  // Ñîçäàäèì òàáëèöó ó÷åòà Ïðîäóêòîâ

                  conn.Execute("CREATE TABLE IF NOT EXISTS PRODUCT("

                        "ID BIGINT NOT NULL PRIMARY KEY, "

                        "NAME VARCHAR(255) NOT NULL, "

                        "PRICE DOUBLE NOT NULL, "

                        "FIRM VARCHAR(255) NOT NULL, "

                        "SLIFE VARCHAR(32))");

                  conn.GetCompletionStatus();

                  // Ñîçäàäèì òàáëèöó ó÷åòà Ïîêóïàòåëåé

                  conn.Execute("CREATE TABLE IF NOT EXISTS CUSTOMER("

                        "ID BIGINT NOT NULL PRIMARY KEY, "

                        "FNAME VARCHAR(255) NOT NULL, "

                        "LNAME VARCHAR(255), "

                        "ADDRESS VARCHAR(255) NOT NULL, "

                        "YBORN DATETIME)");

                  conn.GetCompletionStatus();

                  // Ñîçäàäèì òàáëèöó ó÷åòà Ïðîäàæ

                  conn.Execute("CREATE TABLE IF NOT EXISTS SALE("

                        "ID BIGINT NOT NULL PRIMARY KEY, "

                        "PID BIGINT NOT NULL, "

                        "CID BIGINT NOT NULL, "

                        "DATE DATETIME NOT NULL, "

                        "TSUM DOUBLE NOT NULL, "

                        "CONSTRAINT FKP FOREIGN KEY (PID) REFERENCES PRODUCT(ID), "

                        "CONSTRAINT FKC FOREIGN KEY (CID) REFERENCES CUSTOMER(ID))");

                  conn.GetCompletionStatus();

                  conn.Close();

            }

            catch (node_exception& e)

            {

                  MessageBoxA(0, e.msg, "Attention", MB_OK | MB_ICONERROR);

                  IsDB = FALSE;

            }

      };

 

Øàã 2. Óñòàíàâëèâàåì ñîåäèíåíèå ñ ÁÄ

 

Ïðåæäå ÷åì íà÷àòü ðàáîòàòü, íàì íåîáõîäèìî óñòàíîâèòü ñîåäèíåíèå ñ ÁÄ. Äëÿ ýòèõ öåëåé ñëóæèò ïðîñòðàíñòâî èìåí scdriver, îáúÿâëåíèå è èíòåðôåéñ êîòîðîãî íàõîäèòñÿ â ôàéëå scdriver.h èç äèðåêòîðèè sdk. À èìåííî, âîñïîëüçóåìñÿ ñðåäñòâàìè êëàññà CConnection, ïîñðåäñòâîì êîòîðîãî ìû è áóäåì óñòàíàâëèâàòü ñîåäèíåíèå è óïðàâëåíèå çàïèñÿìè â ÁÄ. Äëÿ ïðèìåðà âîçüìåì ñîçäàíèå êîíöåïòóàëüíîé ñõåìû èç ïðåäûäóùåãî øàãà.

×òîáû ïðîãðàììíî îáðàùàòüñÿ ê ÁÄ, íåîáõîäèìî â äèðåêòèâàõ ïðåïðîöåññîðà íàñòðîåê ïðîåêòà îïðåäåëèòü îäíî èç ìàêðîîïðåäåëåíèé: SCIMORE_PROTO_TCP – äëÿ îáðàùåíèÿ ïîñðåäñòâîì ïðîòîêîëà TCP èëè SCIMORE_PROTO_INPROC – äëÿ îáðàùåíèÿ ÷åðåç àëèàñ.

Òåïåðü, â çàâèñèìîñòè îò îáúÿâëåííîãî ìàêðîîïðåäåëåíèÿ, ìû ìîæåì ôîðìèðîâàòü àäðåñ óçëà è ïîðò, ïîñðåäñòâîì êîòîðûõ áóäåò ïðîèñõîäèòü îáðàùåíèå ê ÁÄ:

 

#ifdef SCIMORE_PROTO_TCP

            char* host = "localhost";

#elif SCIMORE_PROTO_INPROC

            char* host = "EmbadedDB";

#endif

 

Òåïåðü ìîæíî ñîçäàòü ýêçåìïëÿð êëàññà CConnection:

 

CConnection conn;

 

È óñòàíîâèòü ñîåäèíåíèå:

 

try

{

      conn.Connect(host, 998);

}

catch (node_exception& e)

{

      MessageBoxA(0, e.msg, "Attention", MB_OK | MB_ICONERROR);

}

 

Ïîñëå âûïîëíåíèÿ íåîáõîäèìûõ äåéñòâèé, ñîåäèíåíèå ñ ÁÄ íåîáõîäèìî çàâåðøèòü. Äëÿ ýòîãî âûïîëíèì ñëåäóþùèé êîä:

 

conn.Close();

 

Øàã 3. Âûïîëíÿåì çàïðîñ ê ÑÓÁÄ

 

Âûïîëíèì çàïðîñ ê ñîçäàííîé ðàíåå ÁÄ (ñì. Øàã 1 – Ñîçäàíèå êîíöåïòóàëüíîé ñõåìû). Ðàññìîòðèì çàïðîñ íà ïðèìåðå ïîëó÷åíèÿ äàííûõ èç ÁÄ è âûâîäà èõ íà ýêðàí â òàáëèöó. Äëÿ ýòîãî íàì íåîáõîäèìî ñîçäàòü ýêçåìïëÿð êëàññà CConnection:

 

CConnection conn;

 

Òåïåðü íåîáõîäèìî âûïîëíèòü ïîäêëþ÷åíèå ê ÁÄ. Äëÿ ýòîãî âûïîëíèì ñëåäóþùèé êîä:

 

int CMyTable::Connect(CConnection* conn)

{

#ifdef SCIMORE_PROTO_TCP

            char* host = "localhost";

#elif SCIMORE_PROTO_INPROC

            char* host = "EmbadedDB";

#endif

     

      try

      {

            // Ïîäêëþ÷åíèå ê óçëó ïî óêàçàííîìó ïîðòó

            conn->Connect(host, 998);

            // Èñïîëüçîâàíèå ÁÄ SALES

            conn->Execute("USE SALES");

            conn->GetCompletionStatus();

      }

      // Îáðàáîòêà èñêëþ÷èòåëüíîé ñèòóàöèè

      catch(node_exception& e)

      {

            MessageBoxA(0, e.msg, "Attention", MB_OK | MB_ICONERROR);

            return 0;

      }

      return 1;

}

 

Ãäå âõîäíîé ïàðàìåòð CConnection* conn ÿâëÿåòñÿ óêàçàòåëåì íà ðàíåå îáúÿâëåííûé îáúåêò êëàññà CConnection. Ìû èñïîëüçóåì êîíñòðóêöèþ try