sqlite3 执行命令 显示结果 插入图片 保存图片 例子

时间:2021-12-07 05:35:26
以下修改了api的名字,3修改成了x,如果使用标准sqlite3,需要将sqlite3 修改成sqlitex。某些函数的判断已经省去,如需要,可以加上做错误判断。
#include <stdio.h>
#include <malloc.h>
#include <fcntl.h>
#include <string.h>
#include "sqlite3.h"

/* 第二种方法,执行sql语句,并显示查询后的结果。在回调函数中处理查询后的结果,如果有结果就会显示,没有就不会显示。 */
int callback(void* p,int i,char** argv,char** c1){
        printf("callback i=%d\n",i);
        int max =i;
        for (i;i>0;i--){
                printf("argv[%d]=%s\n",i,argv[max - i]);
        }
        return 0;
}

/* cmd{ "create table epg1(num interger primary key, program text);" "insert into epg1 (num, program) values (1, 'cctv-1')" "select * from epg1;" -->may error 4, cause callback return not 0. "update epg1 set num=1, program='cctv-2' where num=1;" "delete from epg1 where num=1;" } */

int operatorDB1(sqlite3 *ppDb, char* cmd){
        int ret = sqlitex_exec(ppDb,cmd,&callback,NULL,NULL);
        if (ret !=SQLITE_OK ){
                printf("exec error,ret=%d\n",ret);
                return ret;
        }
        ret = sqlitex_close(ppDb);
        if (ret !=SQLITE_OK ){
                printf("close error,ret=%d\n",ret);
                return ret;
        }
        return SQLITE_OK;
}

/* 第二种方法,执行sql语句,并显示查询后的结果。 */
int operatorDB2(sqlite3 *ppDb,char* cmd){
    sqlitex_stmt * stmt;
    int ret = sqlitex_prepare_v2(ppDb,cmd,-1,&stmt,NULL);
    if (ret != SQLITE_OK){
            printf("prepare_v2 error,ret=%d\n",ret);
            sqlitex_finalize(stmt);
            //operatorDB1(ppDb,cmd); 
            return ret;
    }
    while( sqlitex_step(stmt) ==SQLITE_ROW){
            int id = sqlitex_column_int(stmt, 0);//返回列的值
            printf("step id=%d\n",id);
            int num= sqlitex_column_int(stmt, 0);
            printf("step 0 num=%d\n",num);
            const char* str = (const char *)sqlitex_column_text(stmt, 1);
            printf("step 1 str=%s\n",str);

    }
    sqlitex_finalize(stmt);
}

/* 读取图片,这里只是个例子,可以分别保存图片,这里保存了一次图片。 */
int readPic(sqlite3 *ppDb,char* cmd){
        sqlitex_stmt * stmt;
        int ret = sqlitex_prepare_v2(ppDb,cmd,-1,&stmt,NULL);
        if (ret != SQLITE_OK){
                printf("prepare_v2 error,ret=%d\n",ret);
                sqlitex_finalize(stmt);
                //operatorDB1(ppDb,cmd); 
                return ret;
        }
        while( sqlitex_step(stmt) ==SQLITE_ROW){
                int id = sqlitex_column_int(stmt, 0);
                printf("step id=%d\n",id);
                int num= sqlitex_column_int(stmt, 0);
                printf("step ---->num=%d\n",num);
                if (id !=3){
                        const char* str = (const char *)sqlitex_column_blob(stmt, 1);
                        printf("step ---->str=%s\n",str);
                }else{
                        const void* str = (const void *)sqlitex_column_blob(stmt, 1);
                        printf("step ---->save pic new.jpg\n");
                        int len = sqlitex_column_bytes(stmt, 1);
                        int fd = open("./new.jpg",O_CREAT|O_RDWR,0644);
                        write(fd,str,len);
                        close(fd);
                }

        }
        sqlitex_finalize(stmt);
}

/* 插入图片,使用如下命令: ./a.out epg.db "insert into epg1 (num, program) values (4, :aaa);" 如果数据库在这一行里面有数据了,再插入是没有用的。 */
int insertPic(sqlite3 *ppDb,char* cmd){
        printf("operatorDB3 0\n");
        int fd = open("./Chrysanthemum.jpg",O_RDONLY,0644);
        int filesize=lseek(fd,0,SEEK_END);
        char *buf= (char*)malloc(filesize);
        memset(buf,0,filesize);
        lseek(fd,0,SEEK_SET);
        printf("insertPic filesize=%d\n",filesize);
        int readsize = read(fd,buf,filesize);
        printf("buf= %s,readsize=%d\n",(char*)buf,readsize);
        close(fd);

        sqlitex_stmt * stmt;
        int ret = sqlitex_prepare_v2(ppDb,cmd,-1,&stmt,NULL);
        if (ret != SQLITE_OK){
                printf("prepare_v2 error,ret=%d\n",ret);
                sqlitex_finalize(stmt);
                return ret;
        }
        int index = sqlitex_bind_parameter_index(stmt, ":aaa");
        sqlitex_bind_blob(stmt,index,buf, readsize, SQLITE_STATIC);
        sqlitex_step(stmt);
        sqlitex_finalize(stmt);
        free(buf); //不要过早释放
        return 0;
}

/* main函数不那么智能,使用哪个函数就替换一下 */
void main(int argc,char* argv[]){
        printf("main start\n");
        if (argc<3){
                printf("Usage: ./xxx database cmd\n");
                return;
        }
        printf("argv[0]=%s,argv[1]=%s,argv[2]=%s\n",argv[0],argv[1],argv[2]);
        sqlite3 *ppDb;
        int ret = sqlitex_open_v2(argv[1],&ppDb,SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE,NULL);
        if (ret !=SQLITE_OK ){
                printf("open error,ret=%d\n",ret);
                return ;
        }
        operatorDB2(ppDb,argv[2]);//替换这里的函数
        printf("main end\n");
}

Makefile

main: sqlite3
        gcc main.c -L. -lsqlite3 -ldl

sqlite3:
        gcc  sqlite3.c  -fPIC -shared  -lpthread -o libsqlite3.so

clean:
        rm libsqlite3.so a.out
 
 

sqlite3命令下载(Precompiled Binaries for Linux):

http://www.sqlite.org/download.html

直接下载linux版本,已经编译好了的命令,可以直接用。


也可以直接下载源码编译生成bin文件。(未尝试)

--------------------------------------------------------------------------------

sqlite3用例:跑测试用例的时候需要指定自己的库的位置

export LD_LIBRARY_PATH=/home/gany/samba/sqlite3:$LD_LIBRARY_PATH

用例的main函数在demo下(sqlite3简单测试用例)

含有makefile

另外依赖的库由如下两个文件编译而成:

sqlite3.c  sqlite3.h (应该是官方源码,可以直接生成so,用例程序可以依赖这个so)

sqlite3依赖dl库,所以编译应用程序的时候还需要加上 -ldl  (dlopen、dlclose)