VC2005 +SQLite 3.6.3 編譯、測試開發手記

http://www.cnblogs.com/giszhang/articles/1307509.html

VC2005 +SQLite 3.6.3 編譯、測試開發手記

偶然的機會對SQLite有了興趣,花了半天的時間小小研究了一下,包括VC2005環境下SQLite的編譯,開發測試等。

初次接觸,只是測試了基本的數據庫操作功能,更多的高級功能有待以後繼續深入研究,廢話少說,言歸正傳。

現在SQLite的最新版本是 V3.6.3,發佈於2008922,詳見http://sqlite.org/的介紹。

還是補充一句什麼是SQLite吧,“SQLite是一款輕型的數據庫,它的設計目標是嵌入式的,而且目前已經在很多嵌入式產品中使用了它,它佔用資源非常的低,在嵌入式設備中,可能只需要幾百K的內存就夠了。它能夠支持Windows/Linux/Unix等等主流的操作系統,同時能夠跟很多程序語言相結合,比如TclPHPJava等,還有ODBC接口,同樣比起MysqlPostgreSQL這兩款開源世界著名的數據庫管理系統來講,它的處理速度比他們都快。”

簡單的說,SQLite的特點就是小巧、高效,SQLite數據庫只有一個文件,也可以說是文件數據庫吧,對於某些桌面應用以及嵌入式應用來說,SQLite可以提供相當高效的數據存儲方案。如果你正在位自己的應用程序尋找一種數據管理方案的話,不妨考慮一下SQLite

接着說SQLite如何在VC環境下進行開發。

SQLite官網上當下來的,可以有SQLite命令行程序,還可以有運行支持的DLL,當然開源的SQLite還提供了完整的源碼。

嵌入SQLite開發的程序發佈時,需要提供SQLiteDll就行了,但是對於開發者來說,最方便的還是用Lib輔助開發,因此我們自己來編譯SQLite就很有必要了(當然,也可以通過DLL直接獲取Lib,但自己編譯出來的感覺不一樣,哈哈:) )。

好了,首先從http://sqlite.org/download.html上把最新的源碼下載下來,注意,Source Code有好幾個版本,沒搞太清楚各個版本都是幹啥的,這裏我們下載下來sqlite-source-3_6_3.zipZip格式的,不是gz的,呵呵),當然把sqlite-amalgamation-3.6.3.tar.gz下載下來也是最好的,因爲我們後面可能需要其中的一個文件(sqlite3.def),不想下的話,從別的地方找一下就Ok了。

有了源碼以後,我們先建立一個Win32的空白DLL項目,比如這裏項目爲SQLiteLib,然後把剛纔下載的SQLite源碼解壓到一個文件夾(如sqlite-source),把這個文件夾複製到項目文件夾裏,並加入到新建的工程中。

這樣就完成了第一步,但是這個時侯如果你編譯的話,會發現有好幾個錯誤和N個警告。首先在項目解決方案裏移除以下幾個文件tclsqlite.cshell.crtree.cfts3.cfts3_hash.cfts3_icu.cfts3_porter.cfts3_tokenizer1.cfts3_tokenizer.c

其中tclsqlite.c用於生成基於TCLAPI,如果要編譯,這需要另外下載tcl.hshell.c用於生成命令行模式的sqlite.exerTree.c是建立數據庫R樹索引的模塊,fts3*.c是全文索引模塊,這兩個擴展模塊直接編譯的時候會提示以下錯誤,

1>fts3.obj : errorLNK2005: _sqlite3_extension_init 已經在 rtree.obj 中定義

1>fts3.obj : errorLNK2005: _sqlite3_api 已經在 rtree.obj 中定義

1>fts3_tokenizer.obj :error LNK2005: _sqlite3_api 已經在 rtree.obj 中定義

至於原因,一時半會兒也沒找出來,就先不管它了,從項目中移除上面幾個文件再編譯就Ok了(移除Rtree.c是因爲發現用其編譯出來的庫時會出錯)。

(呵呵,初次測試的目的是基本應用,所以具體錯誤的原因就沒深究,有興趣的可以共同探討一下,主要是Rtree和全文檢索模塊的應用)

接下里,我們在工程屬性裏,把“N”個警告忽略掉,配置屬性àC/C++->高級à禁用特定警告裏,設置“4267;4244;4018;4996;”。

然後再編譯世界就清淨了,呵呵,順利編譯出的有DLLLib文件,接下里我們對SQLite進行簡單的功能測試,體驗一下SQLite編程的便利。

/************************************************/

建立一個新的測試工程,這裏我們選擇MFC應用程序(DialogBased),例如項目SQLiteDEmo

在項目文件夾下建立一個Lib文件夾,把剛纔生成的Lib文件和Sqlite3.h複製到該文件夾下,爲了方便可以把SQLiteLibSQLiteDemo在一個解決方案裏管理,設置共同的輸出路徑,並在生成時間裏自動拷貝庫文件,這樣不用每次都手動來操作,還能保證用到的都是最新的編譯版本。

SQLiteDemo項目屬性裏,配置屬性à鏈接器à輸入à附加依賴性,設置爲“$(SolutionDir)lib/SQLite3.lib”,這樣就把SQLite庫引用到了我們的工程中。

然後,在用到SQLite的文件裏包含頭文件 #include "../lib/sqlite3.h"

/************************************************/

接下來,我們進行簡單的SQLite應用。

 

//連接數據庫

void CSQLiteDemoDlg::OnBnClickedButtonConnect()

{

UpdateData();

m_strDB.Trim(_T(" /t/n"));;

if( m_strDB.IsEmpty() )

{

//AfxMessageBox(_T("請檢查數據庫參數!"));

m_strResult += _T("請檢查數據庫參數!/r/n");

return;

}

//

int result = 0;

//

LPSTR szTmp = new char[MAX_PATH];

wsprintfA(szTmp, "%ls", m_strDB);

result = sqlite3_open( szTmp, &m_db );//關鍵代碼, 連接數據庫

if( result )

{

//AfxMessageBox(_T("連接數據庫失敗!"));

m_strResult += m_strDB;

m_strResult += _T("/r/n");

m_strResult += _T("連接數據庫失敗!/r/n");

sqlite3_close(m_db);

}

else

{

m_strResult += m_strDB;

m_strResult += _T("/r/n");

SqliteQuery(_T("select name, sql from sqlite_master"));

//AfxMessageBox(_T("連接數據庫成功!"));

m_strResult += _T("連接數據庫成功!/r/n");

}

//

delete[] szTmp;

}

 

//執行語句

void CSQLiteDemoDlg::SqliteExec(CString strSQL)

{

strSQL.Trim(_T(" /t/n"));

if( strSQL.IsEmpty() )

{

//AfxMessageBox(_T("請檢查參數!"));

m_strResult += _T("請檢查執行語句!/r/n");

UpdateData(FALSE);

return;

}

//

int result = 0;

//

LPSTR szTmp = new char[MAX_PATH];

wsprintfA(szTmp, "%ls", strSQL);

 

LPSTR szMsg = NULL;

 

result = sqlite3_exec( m_db, szTmp, 0, 0, &szMsg);

 

if( result!=SQLITE_OK )

{

//AfxMessageBox(CString(szMsg));

m_strResult += CString(szMsg);

m_strResult += _T("/r/n");

}

 

delete[] szTmp;

}

 

//查詢

void CSQLiteDemoDlg::SqliteQuery(CString strQuery)

{

m_strResult += _T("-----------------------------------/r/n");

double dbStartTime = clock();

//

char **ppTb = NULL;

int nRow, nCol;

nRow = nCol = 0;

//

strQuery.Trim(_T(" /t/n"));;

if( strQuery.IsEmpty() )

{

//AfxMessageBox(_T("請檢查查詢參數!"));

m_strResult += _T("請檢查查詢參數!/r/n");

return;

}

m_strResult += strQuery;

m_strResult += _T("/r/n");

int result = 0;

//

LPSTR szTmp = new char[MAX_PATH];

wsprintfA(szTmp, "%ls", strQuery);

LPSTR szMsg = NULL;

result = sqlite3_get_table( m_db, szTmp, &ppTb, &nRow, &nCol, &szMsg );

if( result!=SQLITE_OK )

AfxMessageBox(CString(szMsg));

else

{

CString strRes;

for( int i=0;i<=nRow;i++ )

{

strRes = _T("");

for( int j=0;j<nCol;j++ )

{

if( j>0 )

strRes += _T("/t|    ");

strRes += *(ppTb + i*nCol + j);

}

strRes += "/r/n";

m_strResult += strRes;

}

}

m_strResult += _T("-----------------------------------/r/n");

double dbEndTime = clock();

CString strTime;

strTime.Format(_T("查詢花費時間: %.2f毫秒"), (double)(dbEndTime-dbStartTime));

m_strResult += strTime;

m_strResult += _T("/r/n");

//

sqlite3_free_table(ppTb);

delete[] szTmp;

UpdateData(FALSE);

}

///////////////////////////////////////////////////////////////////////////

以上是簡單的功能測試,測試工程點擊這裏SQLiteDemo.zip這裏 下載。

歡迎大家就SQLite進行交流,好東西大家分享~~

發佈了138 篇原創文章 · 獲贊 9 · 訪問量 102萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章