Chinaunix首页 | 论坛 | 博客
  • 博客访问: 34879
  • 博文数量: 15
  • 博客积分: 360
  • 博客等级: 入伍新兵
  • 技术积分: 105
  • 用 户 组: 普通用户
  • 注册时间: 2010-07-28 01:43
文章分类
文章存档

2011年(15)

分类: SQLite/嵌入式数据库

2011-07-28 19:00:26

    由于sqlite 2sqlite 3有很多借口函数都改动了,比如sqlite_open()的参数变了,sqlite_freemem()没有了,可以用sqlite3_free()来替换,而sqlite_get_table_printfsqlite_exec_printf函数都没有了,而且也没有函数可以替换。,如果将2升级到3会有许多要改动的地方,所以我在这里实现一个sqlite3_get_table_printf()函数,首先由于没有很多时间去研究sqlite3的代码结构,我只是经过参考对比sqlite 2sqlite 3的代码,然后封装出这个函数。暂时还没发现问题。

由于sqlite 2sqlite_get_table_printf调用sqlite_get_table_vprintf,sqlite_get_table_vprintf调用sqlite_vmprintf,sqlite_vmprintfsqlite3_vmprintf函数的接口是一样的,功能也一样。由此只要模仿sqlite3_vmprintf的实现流程,就可以很容易构造出我们需要的函数。

1.       sqlite3.h中添加函数声明

首先在sqlite3.h中,在SQLITE_API char *sqlite3_vmprintf(int,char*,const char*, va_list);下,加上函数声明:

SQLITE_API int sqlite3_get_table_printf(

  sqlite3*,               /* An open database */

  const char *sqlFormat, /* printf-style format string for the SQL */

  char ***resultp,       /* Result written to a char *[]  that this points to */

  int *nrow,             /* Number of result rows written here */

  int *ncolumn,          /* Number of result columns written here */

  char **errmsg,         /* Error msg written here */

  ...                    /* Arguments to the format string */

);

SQLITE_API int sqlite3_get_table_vprintf(

  sqlite3*,               /* An open database */

  const char *sqlFormat, /* printf-style format string for the SQL */

  char ***resultp,       /* Result written to a char *[]  that this points to */

  int *nrow,             /* Number of result rows written here */

  int *ncolumn,          /* Number of result columns written here */

  char **errmsg,         /* Error msg written here */

  va_list ap             /* Arguments to the format string */

);

2.       sqlite3.c中加上函数定义以及在有关结构中

1)struct sqlite3_api_routines结构体中加上函数指针,可仿照sqlite3_vmprintf()函数写:

我们在整个结构体的最后来写,为了向后的兼容性,不至于函数填多了,太乱了

int (*get_table_vprintf)(sqlite3*,const char *,char ***,int *,int *,char **,va_list);

int (*get_table_printf)(sqlite3*,const char *,char ***,int *,int *,char **,...);

2)SQLITE_CORE最后增加宏定义

#define sqlite3_get_table_vprintf      sqlite3_api->get_table_vprintf

#define sqlite3_get_table_printf       sqlite3_api->get_table_printf

3) static const sqlite3_api_routines sqlite3Apis定义的最后添加函数名

sqlite3_get_table_vprintf,

sqlite3_get_table_printf,

3.       添加函数实现

SQLITE_API int sqlite3_get_table_printf(

  sqlite3 *db,            /* An open database */

  const char *zFormat, /* printf-style format string for the SQL */

  char ***resultp,       /* Result written to a char *[]  that this points to */

  int *nrow,             /* Number of result rows written here */

  int *ncol,             /* Number of result columns written here */

  char **errmsg,         /* Error msg written here */

  ...                    /* Arguments to the format string */

){

  va_list ap;

  int rc;

  va_start(ap, errmsg);

  rc = sqlite3_get_table_vprintf(db, zFormat, resultp, nrow, ncol, errmsg, ap);

  va_end(ap);

  return rc;

}

SQLITE_API int sqlite3_get_table_vprintf(

  sqlite3 *db,            /* An open database */

  const char *zFormat, /* printf-style format string for the SQL */

  char ***resultp,       /* Result written to a char *[]  that this points to */

  int *nrow,             /* Number of result rows written here */

  int *ncolumn,          /* Number of result columns written here */

  char **errmsg,         /* Error msg written here */

  va_list ap             /* Arguments to the format string */

){

  char *zSql;

  int rc;

 

  zSql = sqlite3_vmprintf(zFormat, ap);

  rc = sqlite3_get_table(db, zSql, resultp, nrow, ncolumn, errmsg);

sqlite3_free(zSql);

  return rc;

}

注意:sqlite3_get_table_vprintf函数中有个free(zSql)要改成sqlite3_free(zSql);sqlite2中,zSqlmalloc来分配空间,而在sqlite 3中则不是。具体实现大家可以看函数实现。

4.       执行过程

把命令执行过程中所用到的sqlite3相关的库拷贝到/usr/lib下,数据库文件必须支持sqlite3格式的,如果是sqlite 2版本的话,可以使用 sqlite old.db .dump | sqlite3 new.db 命令来把2版本的数据库升级为3版本的数据库

可用如下程序测试sqlite3sqlite3_get_table_printf接口函数:

int main (void)

{

       struct sqlite3 *db_test;

       int rc, nrow, ncol;

       char *errmsg = NULL, **result = NULL;

       rc = sqlite3_open("test.db", &db_test);

       if(rc != SQLITE_OK)

       {

              printf("sqlite3 open error !\n");

       }

      

       rc = sqlite3_get_table_printf(db_test, "select * from %s", &result, &nrow, &ncol, &errmsg, "table_test");

       if(rc != SQLITE_OK)

       {

              sqlite3_free_table(result);

              printf("sqlite3 get table printf error!\n");

       } sqlite3.rar   

       else

       {

              printf("result is %Q\n",result[0]);

       }

      

       sqlite3_close(db_test);

      

}

 

我们完全可以实现sqlite3_exec_printf()函数,附件中有我改好的sqlite3.c文件,支持sqlite3_get_table_printf和sqlite3_exec_printf()函数。

阅读(1843) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~