【原创】基于嵌入式系统的SQLite C/C++接口
0赞由于早期的SQLite 只支持5 个C/C++接口,因而非常容易学习和使用,但是随着SQLite 功能的增强,新
的C/C++接口不断的增加进来,到现在有超过150 个不同的API 接口。这往往使初学者望而却步。幸运的是,
大多数SQLite 中的C/C++接口是专用的,因而很少被使用到。尽管有这么多的调用接口,核心的API 仍然相
对简单和便于调用。
以下举例常用的SQLite 数据库与用户应用程序C/C++接口
sqlite3_open()
该接口打开与一个SQLite 数据库文件的连接并返回一个数据库连接对象。这通常是应用程序调用的第一
个SQLite API 接口而且也是调用其他SQLite API 接口前需要调用的接口。许多SQLite 接口需要一个指向数
据库连接对象的指针作为它们的第一个参数,因而这些接口也可以理解成是数据库连接对象的操作接口。该
接口就是创建了这样一个数据库连接对象。
sqlite3_prepare()
该接口把一个SQL 语句文本转换成一个预处理语句对象并返回一个指向该对象的指针。这个接口需要一
个由先前调用sqlite3_open()返回的数据库连接对象指针以及一个预处理的SQL 语句文本字符串为参数。这
个API 并不实际解析SQL 语句,仅仅是为后续的解析而对SQL 语句进行的预处理。
sqlite3_step()
该接口用于解析一个由先前通过sqlite3_prepare()接口创建的预处理语句,直至返回第一列结果为止。
通过再次调用sqlite3_step()可以返回下一列的结果,继续不断地调用sqlite3_step()直至整个语句完成为
止。对于那些并不返回结果的语句(例如:INSERT,UPDATE,DELETE 语句)一次调用sqlite3_step()就完成了
语句的处理。
sqlite3_column()
该接口返回一个由sqlite3_step()解析的预处理语句结果集中当前行的某一列数据。每次执行
sqlite3_step()都返回一个新的结果集中的一行。可以多次调用sqlite3_column()接口返回那一行中所有列
的数据。就像上面所说的那样,SQLite API 中并没有sqlite3_column()这样的接口。取而代之的是一组用于
从结果集中查询出各个列项各种数据类型数据的函数接口。在这组函数接口中,有些接口返回结果集的大小,
有些返回结果集的列数。
-- sqlite3_column_blob()
-- sqlite3_column_bytes()
-- sqlite3_column_bytes16()
-- sqlite3_column_count()
-- sqlite3_column_double()
-- sqlite3_column_int()
-- sqlite3_column_int64()
-- sqlite3_column_text()
-- sqlite3_column_text16()
-- sqlite3_column_type()
-- sqlite3_column_value()
sqlite3_finalize()
该接口销毁之前调用sqlite3_prepare()创建的预处理语句。每一个预处理语句都必须调用这个接口进行
销毁以避免内存泄漏。
sqlite3_close()
该接口关闭一个由之前调用sqlite3_open()创建的数据库连接。所有与该连接相关的预处理语句都必须
在关闭连接之前销毁。
一个应用程序可以通过执行以下几个步骤执行一条SQL 语句:
(1) 使用sqlite3_prepare()创建一个预处理语句。
(2) 重复调用sqlite3_step()解析执行预处理语句。
(3) 对于查询操作,两次调用sqlite3_step()之间通过sqlite3_column()接口查询返回的结果。
(4) 最后,使用sqlite3_finalize()销毁预处理语句。
上述就是有效使用SQLite 所需要知道的知识,其余的仅仅是些需要补充的细节而已。
sqlite3_exec()
该接口是执行上述四个步骤的一个方便的应用调用封装接口,传递给sqlite3_exec()的回调函数用于处
理每一列返回的结果集。
关键代码分析
1、consoleshell.c 源码分析
consoleshell.c 源文件主要是建立用户终端显示控制台菜单,并根据用户的输入字符,调用相应的接口
函数。
#include "consoleshell.h"
char shell_s[]="\nshell> ";
void get_line(char *cmd);
/**
**
**控制台
**
*/
void * consoleshell(){
int count=0;
int i;
char cmd[256]={0,};
int rc = sqliteDB_open();
char name[40],id[40];
int price = 0;
/* 打印终端控制台菜单 */
printf("\n<DB control shell>");
printf("\n [1] select all the records in table merchandise");
printf("\n [2] select the the record which you known its name");
printf("\n [3] select the record by the id");
printf("\n [4] delete record");
printf("\n [5] add record");
printf("\n [**] help menu");
printf("\n [0] print the end of the context an exit");
while(1){
printf(shell_s);
fflush(stdout);
/* 获取用户终端输入 */
get_line(cmd);
/* 根据输入批处理SQLite 接口调用 */
if(strncmp("1",cmd,1)==0){
/* 选择全部商品记录 */
sqliteDB_opt_select_all();
}else if(strncmp("2",cmd,1)==0){
/* 根据名字查找商品记录 */
printf("\nenter the record name ");
printf("\nname:");
scanf("%s",name);
fflush(stdin);//刷新缓冲区
if(!sqliteDB_exist(name))
continue;
sqliteDB_opt_select(name);
}else if(strncmp("3",cmd,1)==0){
/* 根据ID 查找商品记录 */
printf("\nenter the record id ");
printf("\nid:");
scanf("%s",id);
fflush(stdin);//刷新缓冲区
sqliteDB_opt_select_by_id(id);
}else if(strncmp("4",cmd,1)==0){
/* 根据名字删除商品记录 */
printf("\nplease enter the info of the record you want to
delete!");
printf("\nname:");
scanf("%s",name);
fflush(stdin);//刷新缓冲区
if(!sqliteDB_exist(name))
continue;
sqliteDB_opt_select(name);
//删除之前应再次询问是否删除,不可回滚
sqliteDB_opt_delete(name);
}else if(strncmp("5",cmd,1)==0){
/* 增加商品记录 */
printf("\nplease enter the info of the record you want to
add!\nid:");
printf("\nenter the record id ");
printf("\nid:");
scanf("%s",id);
printf("\nname:");
scanf("%s",name);
fflush(stdin);//刷新缓冲区
printf("\nprice:");
scanf("%d",&price);
fflush(stdin);//刷新缓冲区
sqliteDB_opt_add(name,id,price);
}else if(strncmp("**",cmd,2)==0){
/* 显示帮助控制台菜单 */
printf("\n<DB control shell>");
printf("\n [1] select all the records in table
merchandise");
printf("\n [2] select the the record which you known its
name");
printf("\n [3] select the record by the BarCode Scanner");
printf("\n [4] delete record");
printf("\n [5] add record");
printf("\n [**] help menu");
printf("\n [0] print the end of the context an exit");
}else if(strncmp("0",cmd,1)==0){
/* 退出 关闭数据库 */
sqliteDB_close();//关闭数据库连接
break;
// }else if(cmd[0] != "0"){
}else if(strncmp("0",cmd,1)!=0){
system(cmd);
}
}
}
/* 获取用户终端输入 */
void get_line(char *cmd){
int i=0;
while(1){
cmd[i]=getchar();
if(cmd[i]==10){
cmd[i]=0;
break;
}
fflush(stdout);
i++;
}
}
2、SQLite.c 源程序分析
该源码文件主要是对SQLite 数据的C/C++接口封装,提供consoleshell.c 中程序调用。
/*
*建立与数据库的连接
*/
int sqliteDB_open(){
int rc;//操作标志
printf("\ncreat database:test.db\n\ncreat table:table
merchandise(contents:id name price)\n\nand add two records\n");
rc = sqlite3_open("test.db", &db);
if( rc ){
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
sqlite3_close(db);
exit(1);
}
printf("\nOpen sucess!");
/* 建立商品初始化table */
if(!sqliteDB_create_table())
printf("\ntable exist");
return 1;
}
/*
* 关闭与数据库的连接
*/
int sqliteDB_close(){
if(db != 0)
sqlite3_close(db);
}
/*
* 添加一条记录到已知或未知数据库表
*/
int sqliteDB_opt_add(char *name,char *id,int price){
int rc;
char *zErrMsg = 0;
char *sql=0;//动态生成的SQL 语句
/* 定义SQL 语句格式字符串 */
char tem_sql[256]="insert into merchandise values('";
char tem_sql0[5] = "','";
char tem_sql1[5] = "',";
char tem_sql2[5] = ");";
char tem_price[20];
sprintf(tem_price, " %d" , price);//将int 数据转换为字符串
/* 组合SQL 语句格式 */
sql = strcat(tem_sql,name);
sql = strcat(sql,tem_sql0);
sql = strcat(sql,id);
sql = strcat(sql,tem_sql1);
sql = strcat(sql,tem_price);
sql = strcat(sql,tem_sql2);
/* 添加记录到SQLite */
rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
if( rc!=SQLITE_OK ){
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
以上由于篇幅有限,给出部分代码,其他接口原理相同,大家可以自行分析该文件全部源码。