sqlite 第三版C/C++接口
1.0 概述
sqlite 3.0是sqlite的新版本,它继承于sqlite 2.8.13,但带有一个不兼容的文件格式和API。sqlite 3.0依据以下需求而创建:
必须迁移到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比较。
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*,sqlite3_stmt**,const char**); int sqlite3_prepare16(sqlite3*,const void*,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 n,void(*)(void*)); int sqlite3_bind_double(sqlite3_stmt*,double); int sqlite3_bind_int(sqlite3_stmt*,int); int sqlite3_bind_int64(sqlite3_stmt*,long long int); int sqlite3_bind_null(sqlite3_stmt*,int); int sqlite3_bind_text(sqlite3_stmt*,void(*)(void*)); int sqlite3_bind_text16(sqlite3_stmt*,void(*)(void*)); int sqlite3_bind_value(sqlite3_stmt*,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 (*xFunc)(sqlite3_context*,sqlite3_value**),void (*xStep)(sqlite3_context*,void (*xFinal)(sqlite3_context*) ); int sqlite3_create_function16( sqlite3*,const void *zFunctionName,void (*xFinal)(sqlite3_context*) ); #define sqlITE_UTF8 1 #define sqlITE_UTF16 2 #define sqlITE_UTF16BE 3 #define sqlITE_UTF16LE 4 #define sqlITE_ANY 5nArg参数指定函数的参数个数。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*,void(*)(void*)); void sqlite3_result_double(sqlite3_context*,double); void sqlite3_result_error(sqlite3_context*,int); void sqlite3_result_error16(sqlite3_context*,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*,void(*)(void*)); void sqlite3_result_text16(sqlite3_context*,void(*)(void*)); void sqlite3_result_value(sqlite3_context*,sqlite3_value*); void *sqlite3_get_auxdata(sqlite3_context*,int); void sqlite3_set_auxdata(sqlite3_context*,void (*)(void*));2.4用户定义排序
接下来程序用来实现用户定义的排序:sqlite3_create_collation(sqlite3*,const char *zName,int(*xCompare)(void*,const void*)); sqlite3_create_collation16(sqlite3*,const void *zName,const void*)); sqlite3_collation_needed(sqlite3*,void(*)(void*,sqlite3*,const char*)); sqlite3_collation_needed16(sqlite3*,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汇总序列名。