Linux下sqlite3移植与编程

目标平台: LOONGSON-1B 开发板
内核: Linux 3.0
编译平台: ubuntu10.04
交叉工具链: gcc-3.4.6-2f

简介
sqlite3一款主要用于嵌入式的轻量级数据库,本文旨在为sqlite3移植以及linux C下sqlite3编程提供技术文档。
备注:本文所有操作均在root用户下进行。

1、交叉编译sqlite3
1.1 下载sqlite3
进入sqlite官网: http://www.sqlite.org/download.html
或在ubuntu终端通过命令获取sqlite3源码:
#apt-get source sqlite3
这里选择通过ubuntu命令下载得到源码包sqlite3-3.6.22

1.2 交叉编译与移植sqlite3
#./configure --host=mipsel-linux --prefix=/cross/sqlite3_install
#make
#make install
编译安装完成后,在sqlite3_install目录下分别生成bin、include和lib目录。将bin/sqlite3与lib/libsqlite3.so.0.8.6分别拷至文件系统/bin目录与/lib目录下,并将libsqlite3.so.0.8.6更名为libsqlite3.so.0完成移植。

2、sqlite3编程
sqlite提供了一些C函数接口,通过向这些接口传入标准的sql语句可操作数据库。
2.1 sqlite3数据结构
sqlite3 *类型是sqlite3编程中最重要的数据类型,它贯穿数据库操作的始末。从数据库打开开始,sqlite就要为这个类型准备内存空间,直到数据库关闭。

2.2 sqlite3常用函数
  1. int sqlite3_open(const char *filename, sqlite3 **ppdb); 
  2. int sqlite3_close(sqlite3 *db); 
  3. int sqlite3_exec(sqlite3 *db, const char *sql, int (*sqlite3_callback)(void *,int, char**,char**), void *, char **errmsg); 
  4. char *sqlite3_mprintf(const char*, va_list); 
  5. int sqlite3_free(char *); 
  6. int sqlite3_get_table(sqlite3 *, const char *sql, char **resultp, int *nrow, int *ncolumn, char **errmsg); 
  7. void sqlite3_free_table(char **resultp); 
int sqlite3_open(const char *filename, sqlite3 **ppdb);
int sqlite3_close(sqlite3 *db);
int sqlite3_exec(sqlite3 *db, const char *sql, int (*sqlite3_callback)(void *,int, char**,char**), void *, char **errmsg);
char *sqlite3_mprintf(const char*, va_list);
int sqlite3_free(char *);
int sqlite3_get_table(sqlite3 *, const char *sql, char **resultp, int *nrow, int *ncolumn, char **errmsg);
void sqlite3_free_table(char **resultp);
前三个函数基本能满足所有对 sqlite3 数据库的操作,后四个可根据情选择使用。

1. 打开/创建数据库
int sqlite3_open(const char *filename, sqlite3 **ppdb);
其中,filename为需要创建或打开的数据库名;ppdb为前面提到的sqlite3类型。正确则返回SQLITE_OK,该变量由sqlite3.h定义。
例:
  1. sqlite3 *db; 
  2. sqlite_open("test.db", &db); 
sqlite3 *db;
sqlite_open("test.db", &db);

2. 关闭数据库
int sqlite3_close(sqlite3 *db);
例:
  1. sqlite3_close(db); 
sqlite3_close(db);

3. 构建sql语句
char *sqlite3_mprintf(const char*, va_list);
int sqlite3_free(char *);
sqlite3_mprintf( )的功能类似于sprintf( )函数,它们主要区别在于sprintf对存储的目标字符串需要先分配内存,而sqlite3_mprintf函数内已封装了内存分配操作,返回目标字符串的内存首地址。
sqlite3_mprintf( )sqlite3_free( )总是成对出现,否则会造成内存泄露。
例:
  1. char *sql = NULL; 
  2. sql = sqlite3_mprintf("delete from %s where %s = %d;", val1, val2, val3); 
  3. ... 
  4. sqlite3_free(sql); 
char *sql = NULL;
sql = sqlite3_mprintf("delete from %s where %s = %d;", val1, val2, val3);
...
sqlite3_free(sql);

4. 执行sql语句(可带回调函数)
int sqlite3_exec(sqlite3 *db, const char *sql, int (*sqlite3_callback)(void *,int, char**,char**), void *, char **errmsg);
sqlite3_exec( )的功能是执行一条或多条sql语句,语句间用‘;’号隔开。执行成功返回SQLITE_OK;
形参说明:
sqlite3 *dbsqlite3_open( )得到的sqlite3*指针。
const char *sql:要执行的标准sql语句。
int (*sqlite3_callback)(void *,int,char**,char**):回调函数,执行完指定sql函数后所执行的函数,该函数的传参由sqlie3_exec( )执行sql语句后根据返回结果传入相应参数;回调函数每返回一行记录回调一次;回调函数必须定义成这个函数类型,若无需传入回调函数可直接置NULL
void *:用户可传递一个任意类型的指针参数,该参数会传给回调函数使用;若无传参可直接置NULL
char **errmsg:执行sql语句失败后返回的错误信息可通过该变量获取。

sqlite3_exec( )的回调函数
int (*sqlite3_callback)(void *,int,char**,char**);
例,回调函数的定义:
int callback_fun(void *para, int n_column, char **column_value, char ** column_name);
形参说明:
void *para:在sqlite3_exec( )函数传入void *的参数。
int n_column:存储一条记录的字段数,即列数。
char **column_value:保存记录的数据,它实际是个一维数组,每个元素都是一个char *值,以字符串数据方式记录一个字段的内容。
char **column_name:该参数跟column_value对应,保存该字段的名称。
例,回调函数的一个原型例子:
  1. int callback_fun(void *para, int n_column, char **column_value, char ** column_name) 
  2.     int i; 
  3.     printf("记录包含%d个字段(列)\n", n_column); //列数 
  4.     for(i = 0; i < n_column; i++) 
  5.     { 
  6.         printf("字段名:%s >> 字段值:%s\n", column_name, column_value); 
  7.     } 
  8.     return 0; 
int callback_fun(void *para, int n_column, char **column_value, char ** column_name)
{
    int i;
    printf("记录包含%d个字段(列)\n", n_column); //列数
    for(i = 0; i < n_column; i++)
    {
        printf("字段名:%s >> 字段值:%s\n", column_name, column_value);
    }
    return 0;
}


5. 非回调查询
int sqlite3_get_table(sqlite3 *, const char *sql, char **resultp, int *nrow, int *ncolumn, char **errmsg);
void sqlite3_free_table(char **resultp);
sqlite3_get_table( )sqlite_free_table( )不管查询是否成功,它们必须成对使用,否则会造成内存泄露。

sqlite3_get_table( )形参说明:
sqlite3 *sqlite3_open( )得到的sqlite3*指针。
const char *sql:要执行的标准sql语句。
char **resultp:保存字段的名称与值;resultp也是一个一维数组,它的内存布局是,第一行是字段名称,后面紧接是每个字段的值。
假如数据表一行数据记录包含3个字段:field1field2field3,各字段对应的值如下:
  field1        field2         field3
val1_1       val2_1       val3_1
val1_2      val2_2       val3_2
则它们在resultp的内存分布如下:

resultp[0]

resultp[1]

resultp[2]

resultp[3]

resultp[4]

resultp[5]

resultp[6]

resultp[7]

resultp[8]

field1field1field1val1_1val2_1val3_1val1_2val2_2val3_2

int *nrow:保存记录的行数。
int *ncolumn:保存记录的字段数(列数)
char **errmsg:执行sql语句失败后返回的错误信息可通过该变量获取。
例,sqlite3_get_table( )函数用法例子:

  1. int main(void
  2.     sqlite3 *db; 
  3.     char *table_name = "test_table"
  4.     char *sql = NULL; 
  5.     int ret, i, j; 
  6.  
  7.     int n_row, n_column, index; 
  8.     char **dbresult; 
  9.     char *errmsg; 
  10.  
  11.     ret = sqlite3_open("./test.db", &db); 
  12.     if(ret != SQLITE_OK) 
  13.     { 
  14.         return -1; 
  15.     } 
  16.  
  17.     sql = sqlite3_mprintf("select * from %s;", table_name); 
  18.  
  19.     ret = sqlite_exec(db, sql, &dbresult, &n_row, &n_column, &errmsg); 
  20.     if(ret != SQLITE_OK) 
  21.     { 
  22.          printf("error:%s\n", errmsg); 
  23.          return -1; 
  24.     } 
  25.  
  26.     index = n_column; 
  27.     printf("查到%d行记录\n", n_row); 
  28.     for(i = 0; i < n_row; i++) 
  29.     { 
  30.         printf("第%d行记录\n", i+1); 
  31.         for(j = 0; j < n_column; j++) 
  32.         { 
  33.             printf("字段名:%s >> 字段值:%s\n", dbresult[j], dbresult[index]); 
  34.             index++; 
  35.         } 
  36.     } 
  37.     sqlite3_free_table(dbresult); 
  38.     sqlite3_free(sql); 
  39.  
  40.     reutrn 0; 
int main(void)
{
    sqlite3 *db;
    char *table_name = "test_table";
    char *sql = NULL;
    int ret, i, j;

    int n_row, n_column, index;
    char **dbresult;
    char *errmsg;

    ret = sqlite3_open("./test.db", &db);
    if(ret != SQLITE_OK)
    {
        return -1;
    }

    sql = sqlite3_mprintf("select * from %s;", table_name);

    ret = sqlite_exec(db, sql, &dbresult, &n_row, &n_column, &errmsg);
    if(ret != SQLITE_OK)
    {
         printf("error:%s\n", errmsg);
         return -1;
    }

    index = n_column;
    printf("查到%d行记录\n", n_row);
    for(i = 0; i < n_row; i++)
    {
        printf("第%d行记录\n", i+1);
        for(j = 0; j < n_column; j++)
        {
            printf("字段名:%s >> 字段值:%s\n", dbresult[j], dbresult[index]);
            index++;
        }
    }
    sqlite3_free_table(dbresult);
    sqlite3_free(sql);

    reutrn 0;
}


参考资料:
http://blog.csdn.net/shyodx/article/details/6901812
http://blog.chinaunix.net/uid-9255716-id-107972.html
http://hi.baidu.com/zzf6222009/blog/item/8a654c51c0cfb2d8b645ae28.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值