SQLite第三版 C/C++介面

來源:互聯網
上載者:User

SQLite 第三版C/C++介面

1.0 概述

SQLite 3.0是SQLite的新版本,它繼承於SQLite 2.8.13,但帶有一個不相容的檔案格式和API。SQLite 3.0依據以下需求而建立:

  • 支援UTF-16。
  • 使用者可定義的文本排序。
  • 以索引列的形式儲存BLOB。

必須遷移到3.0版來實現的原因是每一個改變與資料庫檔案格式不相容。另外一些不相容的改變,如清除的API,在下面的理論中介紹最好是一次性去掉你的不相容的變化。

3.0版的API與2.X版的相似,但也有一些重要的改變。最顯著的是出現在所有的API函數和資料據結構前的“sqlite_”首碼被改為“sqlite3_”。這避免二類API間的混亂並且允許連結器同時應對SQLite 2.X和SQLite 3.0。

在UTF-16的C類型應該是什麼樣子上沒有統一。因此,SQLite用一個通用的類型void *來指向UTF-16字串。客戶軟體可以轉換void*到任何與之系統相適應的資料類型。

2.0 C/C++介面

除了幾個資料結構和#define,SQLite 3.0的API包括了83個獨立的函數。(一個完整的API參考作為一個獨立的文檔提供。)幸運的是,介面不是與它所顯示的大小一般複雜。簡單的程式仍可以通過僅僅三個函數工作:sqlite3_open()、sqlite3_exec()和sqlite3_close()。更多的資料庫引擎運行控制可以用sqlite3_prepare()來編譯一個SQLite語句成位元組代碼並通過sqlite3_step()來執行它。一個用sqlite3_column_開頭的命令序列可以用來提取關於查詢結果的資訊。許多介面函數是以UTF-8和UTF-16的形式成對出現的。並且有一個用於實現使用者定義SQL函數和使用者定義的text比較。

2.1 開啟與關閉一個資料庫

typedef struct sqlite3 sqlite3;
int sqlite3_open(const char*, sqlite3**);
int sqlite3_open16(const void*, sqlite3**);
int sqlite3_close(sqlite3*);
const char *sqlite3_errmsg(sqlite3*);
const void *sqlite3_errmsg16(sqlite3*);
int sqlite3_errcode(sqlite3*);

sqlite3_open()程式返回一個整型錯誤碼,而不是像sqlite2做的那樣返回一個指向sqlite3結構。sqlite3_open()與sqlite3_open16()間的區別是sqlite3_open16()採用UTF-16(以本地位元組順序)作為資料庫檔案名。如果一個新資料庫檔案需要被建立,那麼sqlite3_open16()設定本地的文本運算式為UTF-16而sqlite3_open()設定文本運算式為UTF-8。

資料庫檔案開啟與建立延遲到使用者實際的時候(被開啟或建立)。這允許可選項和參數,如本地文本表示和預設的頁大小,通過用PRAGMA語句設定。

sqlite3_errcode()指令返回一個最近的主API調用的結果代碼。sqlite3_errmsg()返回一個最近錯誤的英文資訊。錯誤碼資訊可能是暫時的 - 它可能在接下來的任何SQLite函數調用時消失。sqlite3_errmsg16()象sqlite3_errsmg()一樣工作,除了它以本地位元組順序返回一個UTF-16錯誤資訊。

SQLite 3 的錯誤碼與版本2相比並沒有變化。它們如下所示

#define SQLITE_OK           0   /* 成功的結果 */#define SQLITE_ERROR        1   /* SQL 錯誤或沒有資料庫 */#define SQLITE_INTERNAL     2   /* 一個SQLite內部的邏輯錯誤 */#define SQLITE_PERM         3   /* 存取許可被拒絕 */#define SQLITE_ABORT        4   /* 需要一個中斷的Callback指令 */#define SQLITE_BUSY         5   /* 資料據庫檔案被鎖定 */#define SQLITE_LOCKED       6   /* 資料庫中的一個表被鎖定 */#define SQLITE_NOMEM        7   /* malloc()失敗 */#define SQLITE_READONLY     8   /* 試圖寫一個唯讀資料庫 */#define SQLITE_INTERRUPT    9   /* 操作被sqlite_interrupt()結束 */#define SQLITE_IOERR       10   /* 某種磁碟I/O錯誤發生 */#define SQLITE_CORRUPT     11   /* 資料庫磁碟鏡像異常 */#define SQLITE_NOTFOUND    12   /* (Internal Only) 表或記錄不存在 */#define SQLITE_FULL        13   /* 資料庫滿插入失敗 */#define SQLITE_CANTOPEN    14   /* 不能開啟資料庫檔案 */#define SQLITE_PROTOCOL    15   /* 資料庫錯定協議錯 */#define SQLITE_EMPTY       16   /* (Internal Only)資料庫表為空白 */#define SQLITE_SCHEMA      17   /* 資料庫結構被改變 */#define SQLITE_TOOBIG      18   /* 一個表的行資料過多 */#define SQLITE_CONSTRAINT  19   /* 由於約束衝突而中止 */#define SQLITE_MISMATCH    20   /* 資料類型不匹配 */#define SQLITE_MISUSE      21   /* 庫被不正確使用 */#define SQLITE_NOLFS       22   /* 主機不支援的OS特性 */#define SQLITE_AUTH        23   /* 授權被否定 */#define SQLITE_ROW         100  /* sqlite_step()有另一行就緒 */#define SQLITE_DONE        101  /* sqlite_step()已經完成執行 */
2.2 執行SQL語句
typedef int (*sqlite_callback)(void*,int,char**, char**);int sqlite3_exec(sqlite3*, const char *sql, sqlite_callback, void*, char**);
sqlite3_exec()函數的工作與SQLite 2版本中的方式非常像。在第二個參數中給出的0或多個SQL語句被編譯執行。查詢結果被返回給予個Callback函數。更多的資訊參見API參考。
在SQLite 3中,sqlite3_exec()函數像包含一個預定義語句介面的調用的容器。
typedef struct sqlite3_stmt sqlite3_stmt;int sqlite3_prepare(sqlite3*, const char*, int, sqlite3_stmt**, const char**);int sqlite3_prepare16(sqlite3*, const void*, int, sqlite3_stmt**, const void**);int sqlite3_finalize(sqlite3_stmt*);int sqlite3_reset(sqlite3_stmt*);
sqlite3_prepare介面編譯單個SQL語句成為可執行檔位元組代碼。這個介面是現在比較好的存取資料庫的方式。
sqlite3_prepare()的SQL語句是一個UTF-8的字串。sqlite3_prepare16()也是一樣除了字串輸入為UTF-16外。只有輸入字串的第一個語句被編譯。第四個參數被一個指向下一個(未編譯的)SQLite語句的指標,如果有的話。sqlite3_finalize()函數處理一個準備好的SQL語句。在資料庫關閉前所有的準備好的SQL語句必須被結束。sqlite_reset()函數重設準備好的語句以便於它可以被再一次執行。
SQL語句可以包含“?”或“?nnn”或":aa“標識符這裡"nnn"是一個整數而"aa"是一個標識。這些標識符表示未定義的文字值(或者“萬用字元”)(它們)為後面的sqlite3_bind介面所填寫充。每個萬用字元有一個相應的資料它是在運算式中的序列或者"nnn"以一個"?nnn"的形式。這允許同樣的萬用字元出現而不是在該語句中出現一次,在這種情況下萬用字元將被以相同的值真充。無約束的萬用字元將有NULL值。
   int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));   int sqlite3_bind_double(sqlite3_stmt*, int, double);   int sqlite3_bind_int(sqlite3_stmt*, int, int);   int sqlite3_bind_int64(sqlite3_stmt*, int, long long int);   int sqlite3_bind_null(sqlite3_stmt*, int);   int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*));   int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int n, void(*)(void*));   int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
這是一個sqlite3_bind指令用於給準備好的語句指派指的分類。無定義萬用字元被解釋為NULL。綁定不能被sqlite3_reset重設。但萬用字元在sqlite3_reset之後可以被重新綁定為新值。
一個SQL語句準備好之後(可選界定),它以用下面語句執行:
   int sqlite3_step(sqlite3_stmt*);sqlite3_step()指令在返回結果集的一條記錄時返回SQLITE_ROW,或者如果完成執行剛返回SQLITE_DONE或者正常或者取決於一個錯誤。如果不能開啟一個資料庫檔案它也許返回SQLITE_BUSY。如果一個程式返順一個SQLITE_ROW值,然後接下來指令可以被用來提取關於結果集行的資訊:
   const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);   int sqlite3_column_bytes(sqlite3_stmt*, int iCol);   int sqlite3_column_bytes16(sqlite3_stmt*, int iCol);   int sqlite3_column_count(sqlite3_stmt*);   const char *sqlite3_column_decltype(sqlite3_stmt *, int iCol);   const void *sqlite3_column_decltype16(sqlite3_stmt *, int iCol);   double sqlite3_column_double(sqlite3_stmt*, int iCol);   int sqlite3_column_int(sqlite3_stmt*, int iCol);   long long int sqlite3_column_int64(sqlite3_stmt*, int iCol);   const char *sqlite3_column_name(sqlite3_stmt*, int iCol);   const void *sqlite3_column_name16(sqlite3_stmt*, int iCol);   const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);   const void *sqlite3_column_text16(sqlite3_stmt*, int iCol);   int sqlite3_column_type(sqlite3_stmt*, int iCol);sqlite3_column_count()函數返回結果集中列數。sqlite3_cloumn_count()可以在sqlite3_prepare()之後任意時刻調用。sqlte3_data_count()的功能與sqlite3_column_count()相似除了它只在sqlite3_step()後使用有效。如果當前調用了sqlite3_step()返回SQLITE_DONE或者一個錯誤碼,那麼sqlite3_data_count()將返回0除此之外sqlite3_cloumn_count()將繼續返回結果集的行數。
返回結果通過另外的sqlite3_column_***()函數檢查,所有的都帶有一個列號作為它們的第二參數。列是從左至右從0開始運引。注意這與參數不同,它是從一開始索引。
sqlite3_column_type()函數返回第幾列的資料類型。傳回值是以下值之一:
   #define SQLITE_INTEGER  1   #define SQLITE_FLOAT    2   #define SQLITE_TEXT     3   #define SQLITE_BLOB     4   #define SQLITE_NULL     5sqlite3_column_decltype()返回一個以CREATE TABLE語句聲明列類型文本。對於一個運算式來說,傳回值是一個Null 字元串。sqlite3_column_bytes()返回第n列的名字。sqlite3_column_bytes()返回一個類型為BLOB或UTF-8編碼的TEXT類型的位元組數。sqlite3_column_bytes16()對BLOB類型返回相同的值而TEXT類型返回以UTF-16編碼的位元組數。sqlite3_column_text()返回UTF-8資料。sqlite3_column_text16()返回UTF-16資料。sqlite3_column_int()返回主機本地的INTEGER資料。sqlite_column_int64返回64位整數。最後,sqlite_column_duble()返回浮點類型的數。
通過sqlite3_column_type()擷取資料不是必須的。如果一個不同的格式需要的時候,資料類型將會自動轉換。
2.3 使用者定義函數
使用者定義函數可以用下面的涵數實現:
   typedef struct sqlite3_value sqlite3_value;   int sqlite3_create_function(     sqlite3 *,     const char *zFunctionName,     int nArg,     int eTextRep,     void*,     void (*xFunc)(sqlite3_context*,int,sqlite3_value**),     void (*xStep)(sqlite3_context*,int,sqlite3_value**),     void (*xFinal)(sqlite3_context*)   );   int sqlite3_create_function16(     sqlite3*,     const void *zFunctionName,     int nArg,     int eTextRep,     void*,     void (*xFunc)(sqlite3_context*,int,sqlite3_value**),     void (*xStep)(sqlite3_context*,int,sqlite3_value**),     void (*xFinal)(sqlite3_context*)   );   #define SQLITE_UTF8     1   #define SQLITE_UTF16    2   #define SQLITE_UTF16BE  3   #define SQLITE_UTF16LE  4   #define SQLITE_ANY      5
nArg參數指定函數的參數個數。0值表明任何個數的參數是允許的。eTextRep參數指明在這個函數中何種文本描述值。這個參數值應該是上面定義的一個類型。SQLite 3允許相同函數用不同的運算式。資料庫引擎最小數量文本轉換需要。
通常函數公指定xFunc並保持xFunc和xStep為空白。彙總函數指定xStep和xFinal並保持xFunc為空白。sqlite3_create_aggregate()API也一樣。
函數名用UTF-8指定。一個分離的sqlite_craetefunction16()API作用與sqlite_create_function()相同除了函數名用UTF-16主機位元組順指定。
注意函數參數是是一個指向sqlite3_value結構的指標而不是像SQLite 2.X指向字串的指標。接下來的函數用來從下面這些值中取得有用的資訊:
   const void *sqlite3_value_blob(sqlite3_value*);   int sqlite3_value_bytes(sqlite3_value*);   int sqlite3_value_bytes16(sqlite3_value*);   double sqlite3_value_double(sqlite3_value*);   int sqlite3_value_int(sqlite3_value*);   long long int sqlite3_value_int64(sqlite3_value*);   const unsigned char *sqlite3_value_text(sqlite3_value*);   const void *sqlite3_value_text16(sqlite3_value*);   int sqlite3_value_type(sqlite3_value*);
用接下來的API函數實現擷取內容並報告結果:
   void *sqlite3_aggregate_context(sqlite3_context*, int nbyte);   void *sqlite3_user_data(sqlite3_context*);   void sqlite3_result_blob(sqlite3_context*, const void*, int n, void(*)(void*));   void sqlite3_result_double(sqlite3_context*, double);   void sqlite3_result_error(sqlite3_context*, const char*, int);   void sqlite3_result_error16(sqlite3_context*, const void*, int);   void sqlite3_result_int(sqlite3_context*, int);   void sqlite3_result_int64(sqlite3_context*, long long int);   void sqlite3_result_null(sqlite3_context*);   void sqlite3_result_text(sqlite3_context*, const char*, int n, void(*)(void*));   void sqlite3_result_text16(sqlite3_context*, const void*, int n, void(*)(void*));   void sqlite3_result_value(sqlite3_context*, sqlite3_value*);   void *sqlite3_get_auxdata(sqlite3_context*, int);   void sqlite3_set_auxdata(sqlite3_context*, int, void*, void (*)(void*));
2.4使用者定義排序
接下來程式用來實現使用者定義的排序:
   sqlite3_create_collation(sqlite3*, const char *zName, int eTextRep, void*,      int(*xCompare)(void*,int,const void*,int,const void*));   sqlite3_create_collation16(sqlite3*, const void *zName, int eTextRep, void*,      int(*xCompare)(void*,int,const void*,int,const void*));   sqlite3_collation_needed(sqlite3*, void*,       void(*)(void*,sqlite3*,int eTextRep,const char*));   sqlite3_collation_needed16(sqlite3*, void*,      void(*)(void*,sqlite3*,int eTextRep,const void*));
sqlite3_create_collation()函數指定一個排序名和相應的函數實現排序。比較函數僅僅用來比較文本值。
eTextRep參數SQLITE_UTF8, SQLITE_UTF16, SQLITE_UTF16BE或SQLITE_ANY中之一來指定用哪個文本運算式工作。
面對相同的UTF-8, UTF-16LE和UTF-16BE匯總序列獨立的比較函數存在。
sqlite3_create_collation16()功能與sqlite3_create_collation()一樣,除了排序的名字被主機位元組順序列的UTF-16代替UTF-8。
sqlite3_collation_needed()函數註冊Callback函數在遇到未知的排序序列時讓資料庫引擎調用。
Callback函數可以尋找一個相應的比較函數並在必要的時候調用sqlit3_create_collation()。
Callback函數的第四個參數是UTF-8格式的匯總序列的名字。
對於sqlite3_collatin_need16()函數,Callback函數調用發送主機位元組順序的UTF-16匯總序列名。
 
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.