New file |
| | |
| | | /******************************************************************************** |
| | | * Copyright: (C) 2020 LingYun IoT System Studio |
| | | * All rights reserved. |
| | | * |
| | | * Filename: sqlite_cli.c |
| | | * Description: This head file is for client to save TLV packet in sqlite. |
| | | * |
| | | * Version: 1.0.0(2020年05月13日) |
| | | * Author: Guo Wenxue <guowenxue@gmail.com> |
| | | * ChangeLog: 1, Release initial version on "2020年05月13日 12时14分23秒" |
| | | * |
| | | ********************************************************************************/ |
| | | |
| | | #include "sqlite_cli.h" |
| | | #include "logger.h" |
| | | |
| | | static sqlite3 *s_clidb = NULL; |
| | | |
| | | /* description: open or create sqlite database if not exist |
| | | * input args: |
| | | * $db_file: sqlite database file name |
| | | * return value: <0: failure 0:ok |
| | | * */ |
| | | int clidb_init(const char *db_file) |
| | | { |
| | | char sql[256]; |
| | | char *errmsg = NULL; |
| | | |
| | | if( !db_file ) |
| | | { |
| | | log_err("Invalid input arguments\n"); |
| | | return -1; |
| | | } |
| | | |
| | | /*+-------------------------------------------------+ |
| | | *| TLV packet database already exist, just open it | |
| | | *+-------------------------------------------------+*/ |
| | | if( 0==access(db_file, F_OK) ) |
| | | { |
| | | if( SQLITE_OK != sqlite3_open(db_file, &s_clidb) ) |
| | | { |
| | | log_err("open TLV packet database file '%s' failure\n", db_file); |
| | | return -2; |
| | | } |
| | | log_nrml("open TLV packet database file '%s' ok\n", db_file); |
| | | return 0; |
| | | } |
| | | |
| | | /*+---------------------------------------------------+ |
| | | *| TLV packet database not exist, create and init it | |
| | | *+---------------------------------------------------+*/ |
| | | |
| | | if( SQLITE_OK != sqlite3_open(db_file, &s_clidb) ) |
| | | { |
| | | log_err("create TLV packet database file '%s' failure\n", db_file); |
| | | return -2; |
| | | } |
| | | |
| | | /* SQLite continues without syncing as soon as it has handed data off to the operating system */ |
| | | sqlite3_exec(s_clidb, "pragma synchronous = OFF; ", NULL, NULL, NULL); |
| | | |
| | | /* enable full auto vacuum, Auto increase/decrease */ |
| | | sqlite3_exec(s_clidb, "pragma auto_vacuum = 2 ; ", NULL, NULL, NULL); |
| | | |
| | | /* Create firehost table in the database */ |
| | | strncpy(sql, "create table tlvpack(packet blob);", sizeof(sql)); |
| | | if( SQLITE_OK != sqlite3_exec(s_clidb, sql, NULL, NULL, &errmsg) ) |
| | | { |
| | | log_err("create table in tlv packet database file '%s' failure: %s\n", db_file, errmsg); |
| | | sqlite3_free(errmsg); /* free errmsg */ |
| | | sqlite3_close(s_clidb); /* close databse */ |
| | | unlink(db_file); /* remove database file */ |
| | | } |
| | | |
| | | log_nrml("create and init TLV packet database file '%s' ok\n", db_file); |
| | | return 0; |
| | | } |
| | | |
| | | |
| | | /* description: close sqlite database handler |
| | | * return value: none |
| | | */ |
| | | void clidb_term(void) |
| | | { |
| | | log_warn("close tlv client sqlite database now\n"); |
| | | sqlite3_close(s_clidb); |
| | | |
| | | return ; |
| | | |
| | | } |
| | | |
| | | |
| | | /* description: push TLV packet into database |
| | | * input args: |
| | | * $pack: tlv packet pointer |
| | | * return value: <0: failure 0:ok |
| | | */ |
| | | int clidb_push_tlvpack(tlv_buf_t *pack) |
| | | { |
| | | int rv = 0; |
| | | char *errmsg = NULL; |
| | | sqlite3_stmt *stat = NULL; |
| | | |
| | | if( !pack ) |
| | | { |
| | | log_err("Invalid input arguments\n"); |
| | | return -1; |
| | | } |
| | | |
| | | if( ! s_clidb ) |
| | | { |
| | | log_err("client tlv packet database not opened\n"); |
| | | return -2; |
| | | } |
| | | |
| | | rv = sqlite3_prepare_v2(s_clidb, "insert into tlvpack(packet) values(?)", -1, &stat, NULL); |
| | | if(SQLITE_OK!=rv || !stat) |
| | | { |
| | | log_err("blob add sqlite3_prepare_v2 failure\n"); |
| | | rv = -2; |
| | | goto OUT; |
| | | } |
| | | |
| | | if( SQLITE_OK != sqlite3_bind_blob(stat, 1, pack, sizeof(*pack), NULL) ) |
| | | { |
| | | log_err("blob add sqlite3_bind_blob failure\n"); |
| | | rv = -3; |
| | | goto OUT; |
| | | } |
| | | |
| | | rv = sqlite3_step(stat); |
| | | if( SQLITE_DONE!=rv && SQLITE_ROW!=rv ) |
| | | { |
| | | log_err("blob add sqlite3_step failure\n"); |
| | | rv = -4; |
| | | goto OUT; |
| | | } |
| | | |
| | | OUT: |
| | | sqlite3_finalize(stat); |
| | | |
| | | if( rv < 0 ) |
| | | log_nrml("add new TLV packet report data into database failure, rv=%d\n", rv); |
| | | else |
| | | log_nrml("add new TLV packet report data into database ok\n"); |
| | | |
| | | return rv; |
| | | } |
| | | |
| | | |
| | | /* description: push TLV packet into database |
| | | * input args: |
| | | * $pack: tlv packet pointer |
| | | * $id: item ID pointer, which can be used as key when remove |
| | | * return value: <0: failure 0:ok |
| | | */ |
| | | int clidb_pop_tlvpack(tlv_buf_t *pack, int *id) |
| | | { |
| | | int rv = 0; |
| | | sqlite3_stmt *stat = NULL; |
| | | const tlv_buf_t *blob_ptr; |
| | | |
| | | if( !id || ! pack ) |
| | | { |
| | | log_err("invalid input arguments\n"); |
| | | return -1; |
| | | } |
| | | |
| | | if( ! s_clidb ) |
| | | { |
| | | log_err("client tlv packet database not opened\n"); |
| | | return -2; |
| | | } |
| | | |
| | | /* Only query the first packet record */ |
| | | rv = sqlite3_prepare_v2(s_clidb, "select rowid,packet from tlvpack limit 0,1;", -1, &stat, NULL); |
| | | if(SQLITE_OK!=rv || !stat) |
| | | { |
| | | log_err("firehost sqlite3_prepare_v2 failure\n"); |
| | | rv = -3; |
| | | goto out; |
| | | } |
| | | |
| | | rv = sqlite3_step(stat); |
| | | if( SQLITE_DONE!=rv && SQLITE_ROW!=rv ) |
| | | { |
| | | log_err("firehost sqlite3_step failure\n"); |
| | | rv = -5; |
| | | goto out; |
| | | } |
| | | |
| | | /* 2rd argument<0> means first segement is rowid */ |
| | | *id = sqlite3_column_int(stat, 0); |
| | | if(*id <= 0) |
| | | { |
| | | rv = 0; |
| | | goto out; |
| | | } |
| | | |
| | | /* 2rd argument<1> means first segement is packet */ |
| | | blob_ptr = sqlite3_column_blob(stat, 1); |
| | | if( !blob_ptr ) |
| | | { |
| | | rv = 0; |
| | | goto out; |
| | | } |
| | | |
| | | memcpy(pack, blob_ptr, sizeof(*pack)); |
| | | |
| | | log_trace("Read TLV packet from database:\n"); |
| | | logger_dump(LOG_LEVEL_TRACE, (char *)pack->buf, pack->len); |
| | | |
| | | rv = 1; |
| | | |
| | | out: |
| | | sqlite3_finalize(stat); |
| | | |
| | | if( rv < 0) |
| | | log_err("query TLV packet from database failure, rv=%d\n", rv); |
| | | else if( rv > 0 ) |
| | | log_nrml("query TLV packet from database ok\n"); |
| | | |
| | | return rv; |
| | | |
| | | } |
| | | |
| | | |
| | | /* description: remove sepcified TLV packet from database |
| | | * input args: |
| | | * $id: remove item ID |
| | | * return value: <0: failure 0:ok |
| | | */ |
| | | int clidb_del_tlvpack(int id) |
| | | { |
| | | char sql[SQL_COMMAND_LEN]; |
| | | char *errmsg = NULL; |
| | | |
| | | if( !id ) |
| | | { |
| | | log_err("invalid input arguments\n"); |
| | | return -1; |
| | | } |
| | | |
| | | if( ! s_clidb ) |
| | | { |
| | | log_err("client tlv packet database not opened\n"); |
| | | return -2; |
| | | } |
| | | |
| | | /* remove packet from db */ |
| | | memset(sql, 0, sizeof(sql)); |
| | | snprintf(sql, sizeof(sql), "delete from tlvpack where rowid=%d;", id); |
| | | if( SQLITE_OK != sqlite3_exec(s_clidb, sql, NULL, 0, &errmsg) ) |
| | | { |
| | | log_err("delete TLV packet ID[%d] from database failure: %s\n", id, errmsg); |
| | | sqlite3_free(errmsg); |
| | | return -2; |
| | | } |
| | | log_warn("delete TLV packet ID[%d] from database ok\n", id); |
| | | |
| | | /* Vacuum the database */ |
| | | sqlite3_exec(s_clidb, "VACUUM;", NULL, 0, NULL); |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | |
| | | |