现在的位置: 首页 > 综合 > 正文

SQLite第三版 C/C++接口

2013年08月01日 ⁄ 综合 ⁄ 共 9011字 ⁄ 字号 评论关闭

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     5
sqlite3_column_decltype()返回一个以CREATE TABLE语句声明列类型文本。对于一个表达式来说,返回值是一个空字符串。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汇总序列名。
 

抱歉!评论已关闭.