SQLite的C语言接口

最近接手了一个Linux下内核编程的项目,在阅读项目原有代码的基础上,学到了很多新知识,总结一下记录在这里。

在这个项目中,使用SQLite存储用户数据,因此需要在C语言中实现SQLite的访问和增删改查处理。

实际上由于C语言不支持面向对象的操作,因此无法使用对象关系模型来进行处理,只能在C语言中使用SQL语句操纵数据库。

基本操作

打开数据库

需要指定数据库文件的路径,如果不存在的话就会在指定的路径创建一个db文件保存数据库的数据。

#include <sqlite3.h>
sqlite3 * db;
// 连接数据库
rc = sqlite3_open("fvault.db", & db);
if (rc) {
  printf("%s\n", "SQLITE OPEN ERROR");
  sqlite3_close(db);
  exit(1);
}

执行SQL语句

通过将SQL语句写在字符串中,可以执行SQL语句,在执行SQL语句时,可以设置一个回调函数,数据库操作结束后会调用回调函数对数据库返回的数据做响应的处理。

sqlite3_exec的参数分别为数据库对象、SQL语句、回调函数、互调函数的参数、错误信息指针。

无回调函数

#define CREATE "CREATE TABLE IF NOT EXISTS fvault"\
               "("                                \
               "inode INTEGER PRIMARY KEY,"       \
               "owner INTEGER"                    \
               ")"

rc = sqlite3_exec(db, CREATE, NULL, 0, NULL);
if (rc != SQLITE_OK) {
    printf("%s\n", "ERROR");
    sqlite3_close(db);
    exit(1);
}

无参数的回调函数

// 回调函数,对于数据库返回的每一行都执行一次
// void* NotUsed        参数保留位置,无参数时不使用
// int argc             返回字段的个数
// char ** argv         每一个字段的值
// char ** azCoolName   字段的名称
static int callback_get_filelist(void * NotUsed, int argc, char ** argv, char ** azColName) {
    for (int i = 0; i < argc; i++)
        printf("%s\n", argv[i]);
    return 0;
}

// 执行SQL语句
#define SELECT1 "SELECT inode, owner FROM fvault"
uid_t owner = 1000;
snprintf(sql, 63, SELECT1, owner);
rc = sqlite3_exec(db, sql, callback_get_filelist, 0, NULL);
if (rc != SQLITE_OK) {
    printf("%s\n", "ERROR");
    sqlite3_close(db);
    exit(1);
}

有参数的回调函数

使用第四个参数传递参数的指针,在回调函数中可以实现赋值。

// 回调函数,对于数据库返回的每一行都执行一次
// void* result         输入的参数
// int argc             返回字段的个数
// char ** argv         每一个字段的值
// char ** azCoolName   字段的名称
static int callback_get_fileowner(void * result, int argc, char ** argv, char ** azColName) {
    // 将查询得到的值赋给参数
    if (argc == 1)
        * (uid_t *)result = atoi(* argv);

    return 0;
}

// 执行SQL语句
#define SELECT2 "SELECT owner FROM fvault WHERE inode = %lu LIMIT 1"
unsigned long inode = 40075;
snprintf(sql, 63, SELECT2, inode);
rc = sqlite3_exec(db, sql, callback_get_fileowner, & result, NULL);
if (rc != SQLITE_OK) {
    printf("%s\n", "ERROR");
    sqlite3_close(db);
    exit(1);
}

关闭数据库

sqlite3_close(db);

编译

安装依赖

需要使用apt安装依赖的库文件

sudo apt install libsqlite3-dev

指定库

编译时需要指定库文件

gcc main.c -l sqlite3 -o main

总结

可以参考SQLite的C接口或者参考官网提供的接口文档

Lei Yang
Lei Yang
PhD candidate

My research interests include visual speech recognition and semantics segmentation.