|
VDBE 的機(jī)器語言由圍繞于數(shù)據(jù)庫管理 128 個操作碼(opcode)組成。對于打開表,查詢索引、存儲和刪除記錄和很多其他數(shù)據(jù)庫操作都有對應(yīng)的操作碼。在VDBE里的每條指令由1個操作碼和3個操作數(shù)(operand)組成。一些指令使用全部(3個)操作數(shù);也有些可能一個也未使用。這完全取決于指令的性質(zhì)。例如Open指令,用于打開一個表的指針,使用了全部(3個)操作數(shù):第1個操作數(shù)(P1)包含指針的ID號。第2操作數(shù)(P2)指出表的根位置(或者表的首頁位置);而第3個操作數(shù)則是表的名字。對于Rollback指令則根本不需要操作數(shù)。為了進(jìn)行一次Rollback VDBE,僅需知道是否要做Rollback\[1\]。 3.2SQLite開發(fā)技術(shù) SQLite的API極其易于使用,只需要三個用來執(zhí)行SQL和獲得數(shù)據(jù)的函數(shù)。它還是可以擴(kuò)展的,允許程序員自定義函數(shù)然后以callback的形式集合進(jìn)去。C語言API是腳本接口的基礎(chǔ),如已經(jīng)發(fā)布的(Tcl接口)。開放源碼團(tuán)體已經(jīng)擴(kuò)展了眾多的客戶接口、適配器、驅(qū)動等,這就使得其他語言對SQLite的使用也成為可能。 使用C語言API只需要三步。首先,要提供文件名和訪問模式用來調(diào)用sqlite _open()連接數(shù)據(jù)庫。然后,執(zhí)行一個callback函數(shù),SQLite通過對每個記錄執(zhí)行callback函數(shù)獲得從數(shù)據(jù)庫那里得到的結(jié)果。最后,如果想執(zhí)行一個SQL查詢并獲得一個callback函數(shù)的指針,可以調(diào)用sqlite_exec()。除此之外還需要錯誤代碼檢查。SQLite可以通過對一個主鍵聲明它為INTEGER PRIMARY KEY成為能夠自動增加的主鍵,實(shí)現(xiàn)自增字段。 SQLite還提供了存取二進(jìn)制大對象(BLOBs)的方法,在線程安全、數(shù)據(jù)庫管理、API的擴(kuò)展等方面也都提供了強(qiáng)大方便的技術(shù)支持。 4SQLite在ARMLinux平臺上的實(shí)現(xiàn) SQLite嵌入式數(shù)據(jù)庫提供了以源碼發(fā)布的方式,要在眾多的硬件平臺進(jìn)行移植,可以根據(jù)不同平臺對源碼進(jìn)行交叉編譯來實(shí)現(xiàn)。編譯主要有以下幾個步驟\[2\]: ① 到http://www.sqlite.org/的cvs中下載最新的源代碼包,解壓后將生成sqlite目錄,另外新建并轉(zhuǎn)到一個與sqlite目錄平行的同級目錄,如make目錄。 ② 用“echo $PATH”命令查看PATH中是否已經(jīng)包含交叉編譯工具armlinuxgcc。 ③ 為了在ARMLinux下能正常運(yùn)行sqlite,需要對sqlite/src/sqliteInt.h作一定的修改,以確保btree(B樹)有正確的變量大小,如“ptr”和“char*”。不同體系結(jié)構(gòu)的Linux,如x86和ARM,會有些差別。對于ARMLinux可以找到如下部分:# ifndef INTPTR_TYPE # if SQLITE_PTR_SZ==4 # define INTPTR_TYPE int # else # define INTPTR_TYPE long long # endif 在上面的代碼前加上一句#define SQLITE_PTR_SZ 4 這樣后面的“typedef INTPTR_TYPE ptr;”就是定義的“int”類型,而不是“l(fā)ong long”。 ④ 使用configure進(jìn)行一些配置。修改sqlite目錄下的configure,讓configure不去檢查交叉編譯環(huán)境。由于篇幅有限不再詳述。 ⑤ 修改Makefile文件。將代碼行 BCC = armlinuxgccgO2改成BCC = gccgO2。另外,一般是以靜態(tài)鏈接的形式將sqlite放到ARMLinux的硬件板上運(yùn)行的,所以繼續(xù)修改Makefile,找到標(biāo)記為sqlite:的代碼段,將其中的libsqlite.la改成.libs/libsqlite.a。做完上述修改,用make生成sqlite、libsqlite.a、libsqlite.so。為了減小執(zhí)行文件大小可以用strip處理,去掉其中的調(diào)試信息。 ⑥ 在ARM板上運(yùn)行sqlite。將sqlite拷貝到ARM板上,方法很多,需要根據(jù)具體的情況來選擇。如ftp、cmdftp、wget等。將sqlite下載到ARM板的/tmp目錄,因?yàn)榇四夸浭强蓪懙。修改?quán)限并運(yùn)行:chmod +wx sqlite ./sqlite test.sqlite 會出現(xiàn)sqlite> 如果一切正常,現(xiàn)在sqlite已經(jīng)在ARMLinux下跑了起來,然后就可以基于此進(jìn)行進(jìn)一步的應(yīng)用開發(fā)了。 5SQLite的應(yīng)用開發(fā) 家庭網(wǎng)絡(luò)中央控制器以ARM微處理器為中心建立硬件平臺,對外通過寬帶Ethernet、Modem與Internet連接,對內(nèi)將家用電器通過內(nèi)部無線局域網(wǎng)連接成一體,通過遠(yuǎn)程Web瀏覽器、本地觸摸屏以及電話語音三種方式實(shí)現(xiàn)對家用電器的狀態(tài)查詢和控制。多樣化的數(shù)據(jù)存儲與管理需要有一個后臺數(shù)據(jù)庫來支撐,SQLite無疑是一個合適的選擇。下面就其應(yīng)用程序的編寫方式作一個簡單的介紹。 為了講解方便,下面例程通過程序代碼生成了數(shù)據(jù)庫sysdb及其中的一個表格user,也可以用sqlite命令行或者sqlitebrowse等圖形化工具建立數(shù)據(jù)庫。#include <string.h> #include "sqlite.h" int callback( void *p_data, int num_fields, char **p_fields, char **p_col_names); main(){ FILE *inp_fp; int ret; int nrecs = 0; char *errmsg; sqlite *p_db; unsigned char *sqlcommand; unsigned char * sqlcreatedb; sqlcommand="select * from user ;" ; sqlcreatedb="create table user(id numeric, name text);"; /*建立數(shù)據(jù)庫*/ if ((inp_fp = fopen("./sysdb", "r"))==NULL) { printf("Cannot find database file !\\n"); printf("Recover the database file ...\\n"); p_db=sqlite_open("./sysdb",0777,0); sqlite_exec(p_db,sqlcreatedb,0,0,0); printf("The database file have been recorvered!\\n"); sqlite_close(p_db); } /*打開數(shù)據(jù)庫*/ sqlite* p_db=sqlite_open("./sysdb", 0777, 0); /*選擇 user表中的所有記錄. */ ret=sqlite_exec(p_db,sqlcommand,callback, &nrecs, errmsg); if(ret!=SQLITE_OK){ printf("Error on SELECT: %s.\\n", errmsg); } else{ printf("Retrieved %i records.\\n", nrecs); } /* 關(guān)閉數(shù)據(jù)庫*/ sqlite_close(p_db); } int callback( void *p_data, int num_fields, char**p_fields, char **p_col_names){ int i; int *p_rn = (int*)p_data; (*p_rn)++; for(i=0; i < num_fields; i++){ printf("%s " p_fields\[i\]); } return 0; }然后利用sqlite.h、libsqlite.a、libsqlite.so,根據(jù)需要進(jìn)行交叉編譯即可。 上例僅是一個簡單的程序段,可以根據(jù)需要構(gòu)造自己的數(shù)據(jù)庫和callback函數(shù),用來實(shí)現(xiàn)具體的功能。支持SQLite的第三方極多,在項(xiàng)目實(shí)際開發(fā)中還針對QT利用qtsqliteplugin插件開發(fā)了圖形程序,用以實(shí)現(xiàn)通過觸摸屏的本地交互界面,利用移植的Web服務(wù)器編寫了CGI程序,實(shí)現(xiàn)了B/S模式的遠(yuǎn)程訪問。 6總結(jié) 在經(jīng)過大量的分析對比之后,針對嵌入式系統(tǒng)開發(fā)的特點(diǎn),從眾多數(shù)據(jù)庫發(fā)行版中選出非常適用的嵌入式數(shù)據(jù)庫SQLite。在ARMLinux下完成了對SQLite的編譯,并基于此在項(xiàng)目中作了進(jìn)一步的開發(fā)工作。實(shí)踐證明,SQLite能夠出色地完成嵌入式系統(tǒng)中的數(shù)據(jù)庫應(yīng)用需求。 參考文獻(xiàn) 1Michael Owens. Embedding an SQL Database with SQLite. Linux Journal, 20030601 2How To Compile. http://www.sqlite.org/ 3薛啟康. Linux環(huán)境下的數(shù)據(jù)庫. 中國計(jì)算機(jī)報(bào), 2001總期號:1009
|