Äëÿ êîãî ïðåäíàçíà÷åíà ýòà ñòàòüÿ
Ïðåèìóùåñòâà ÁÄ Scimore
Ðàáîòà ñ ÁÄ
Øàã
1. Ñîçäàåì ÁÄ
Øàã
2. Óñòàíàâëèâàåì ñîåäèíåíèå ñ ÁÄ
Øàã
3. Âûïîëíÿåì çàïðîñ ê ÑÓÁÄ
Øàã
4. Ïîëó÷àåì äàííûå èç ÑÓÁÄ
Øàã
5. Âíîñèì èçìåíåíèÿ â ÁÄ
Øàã
6. Ïðîèçâîäèì ïîèñê äàííûõ â ÁÄ
Øàã
7. Çàâåðøåíèå ðàáîòû
Äåìîíñòðàöèîííàÿ ïðîãðàììà
(Èñõîäíûå òåêñòû)
Åñëè âû õîòèòå óçíàòü âñå
ïðåèìóùåñòâà è âîçìîæíîñòè ÑÓÁÄ Scimore à
òàêæå êàê ïðîãðàììíî óïðàâëÿòü äàííûìè â óêàçàííîé ÑÓÁÄ, òî ýòà ñòàòüÿ äëÿ âàñ.
Ñíà÷àëà â îáùèõ ÷åðòàõ.
§
Ñîçäàòü ÁÄ
§
Óñòàíîâèòü ñîåäèíåíèå
ñ ÁÄ
§
Âûïîëíèòü çàïðîñ
§
Ïîëó÷èòü äàííûå
§
Âíåñòè èçìåíåíèÿ â ÁÄ
(åñëè íåîáõîäèìî)
§
Ïðîèçâåñòè ïîèñê
äàííûõ â ÁÄ (åñëè íåîáõîäèìî)
§
Çàêðûòü ñîåäèíåíèå
Òåïåðü ïîäðîáíåå.
Äëÿ ñîçäàíèÿ ÁÄ â ïåðâóþ
î÷åðåäü íåîáõîäèìî, ÷òîáû â äèðåêòîðèè èñïîëíÿåìîãî ìîäóëÿ íàõîäèëèñü ôàéëû 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 "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; } }; |
Ïðåæäå ÷åì íà÷àòü ðàáîòàòü, íàì íåîáõîäèìî óñòàíîâèòü ñîåäèíåíèå ñ ÁÄ. Äëÿ ýòèõ öåëåé ñëóæèò ïðîñòðàíñòâî èìåí 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(); |
Âûïîëíèì çàïðîñ ê ñîçäàííîé ðàíåå ÁÄ (ñì. Øàã 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