diff --git a/dap_chain_global_db.c b/dap_chain_global_db.c index 591e8bd500e49efd595a6e02a1c682c95e008547..71b053b8efe5176800210862335b751b3b2565aa 100755 --- a/dap_chain_global_db.c +++ b/dap_chain_global_db.c @@ -10,7 +10,6 @@ #include "dap_chain_common.h" #include "dap_strfuncs.h" //#include "dap_chain_global_db_pvt.h" -#include "dap_chain_global_db_driver.h" #include "dap_chain_global_db_hist.h" #include "dap_chain_global_db.h" @@ -334,6 +333,41 @@ bool dap_chain_global_db_del(const char *a_key) { return dap_chain_global_db_gr_del(a_key, GROUP_LOCAL_GENERAL); } + + +/** + * Read last item in global_db + * + * @param data_size[out] size of output array + * @return array (note:not Null-terminated string) on NULL in case of an error + */ +dap_store_obj_t* dap_chain_global_db_get_last(const char *a_group) +{ + // Read data + lock(); + dap_store_obj_t *l_store_obj = dap_chain_global_db_driver_read_last(a_group); + unlock(); + return l_store_obj; +} + + + + +/** + * Read the entire database with condition into an array of size bytes + * + * @param data_size[out] size of output array + * @return array (note:not Null-terminated string) on NULL in case of an error + */ +dap_store_obj_t* dap_chain_global_db_cond_load(const char *a_group, uint64_t a_first_id, size_t *a_data_size_out) +{ + // Read data + lock(); + dap_store_obj_t *l_store_obj = dap_chain_global_db_driver_cond_read(a_group, a_first_id, a_data_size_out); + unlock(); + return l_store_obj; +} + /** * Read the entire database into an array of size bytes * diff --git a/dap_chain_global_db.h b/dap_chain_global_db.h index e80ba73d3031015a5628d806e23921c9cde8b350..17a9aae76976d9e63ec4e63ad74dc89e060fa155 100755 --- a/dap_chain_global_db.h +++ b/dap_chain_global_db.h @@ -7,6 +7,8 @@ #include "dap_common.h" #include "dap_config.h" #include "dap_list.h" +#include "dap_chain_global_db_driver.h" + #define GROUP_LOCAL_HISTORY "global.history" #define GROUP_LOCAL_NODE_LAST_TS "local.node.last_ts" @@ -73,6 +75,8 @@ bool dap_chain_global_db_del(const char *a_key); * @param data_size[out] size of output array * @return array (note:not Null-terminated string) on NULL in case of an error */ +dap_store_obj_t* dap_chain_global_db_get_last(const char *a_group); +dap_store_obj_t* dap_chain_global_db_cond_load(const char *a_group, uint64_t a_first_id, size_t *a_data_size_out); dap_global_db_obj_t** dap_chain_global_db_gr_load(const char *a_group, size_t *a_data_size_out); dap_global_db_obj_t** dap_chain_global_db_load(size_t *a_data_size_out); @@ -98,7 +102,7 @@ uint8_t* dap_db_log_pack(dap_global_db_obj_t *a_obj, size_t *a_data_size_out); // Parse data from dap_db_log_pack() void* dap_db_log_unpack(const void *a_data, size_t a_data_size, size_t *a_store_obj_count); // Get timestamp from dap_db_log_pack() -time_t dap_db_log_unpack_get_timestamp(uint8_t *a_data, size_t a_data_size); +//time_t dap_db_log_unpack_get_timestamp(uint8_t *a_data, size_t a_data_size); // Get last timestamp in log time_t dap_db_log_get_last_timestamp(void); diff --git a/dap_chain_global_db_driver.c b/dap_chain_global_db_driver.c old mode 100644 new mode 100755 index 9e67016b43b565101c7d94e2facff7933c06e4aa..bb456a1f4595abc27f16b436d07fa2fb7d9fd605 --- a/dap_chain_global_db_driver.c +++ b/dap_chain_global_db_driver.c @@ -398,7 +398,7 @@ static int save_write_buf(void) } if(s_drv_callback.transaction_end) s_drv_callback.transaction_end(); - printf("** writing ended cnt=%d\n", cnt); + //printf("** writing ended cnt=%d\n", cnt); // writing ended pthread_mutex_lock(&s_mutex_write_end); pthread_cond_broadcast(&s_cond_write_end); @@ -430,7 +430,6 @@ int dap_chain_global_db_driver_appy(pdap_store_obj_t a_store_obj, size_t a_store //dap_store_obj_t *l_store_obj = dap_store_obj_copy(a_store_obj, a_store_count); if(!a_store_obj || !a_store_count) return -1; - a_store_obj->type = 'a'; // add all records into write buffer pthread_mutex_lock(&s_mutex_add_end); for(size_t i = 0; i < a_store_count; i++) { @@ -460,7 +459,7 @@ int dap_chain_global_db_driver_appy(pdap_store_obj_t a_store_obj, size_t a_store int dap_chain_global_db_driver_add(pdap_store_obj_t a_store_obj, size_t a_store_count) { - a_store_obj->type = 'd'; + a_store_obj->type = 'a'; return dap_chain_global_db_driver_appy(a_store_obj, a_store_count); } @@ -470,6 +469,42 @@ int dap_chain_global_db_driver_delete(pdap_store_obj_t a_store_obj, size_t a_sto return dap_chain_global_db_driver_appy(a_store_obj, a_store_count); } +/** + * Read last items + * + * a_group - group name + */ +dap_store_obj_t* dap_chain_global_db_driver_read_last(const char *a_group) +{ + dap_store_obj_t *l_ret = NULL; + // wait apply write buffer + wait_write_buf(); + // read records using the selected database engine + if(s_drv_callback.read_last_store_obj) + l_ret = s_drv_callback.read_last_store_obj(a_group); + return l_ret; +} + +/** + * Read several items + * + * a_group - group name + * a_key - key name, may by NULL, it means reading the whole group + * a_id - from this id + * a_count_out[in], how many items to read, 0 - no limits + * a_count_out[out], how many items was read + */ +dap_store_obj_t* dap_chain_global_db_driver_cond_read(const char *a_group, uint64_t id, size_t *a_count_out) +{ + dap_store_obj_t *l_ret = NULL; + // wait apply write buffer + wait_write_buf(); + // read records using the selected database engine + if(s_drv_callback.read_cond_store_obj) + l_ret = s_drv_callback.read_cond_store_obj(a_group, id, a_count_out); + return l_ret; +} + /** * Read several items * diff --git a/dap_chain_global_db_driver.h b/dap_chain_global_db_driver.h old mode 100644 new mode 100755 index efd2631763ae086f76531870362e8b32af1cb684..b0e099d41408ceea3d77ba7eab03cedfdb525a5b --- a/dap_chain_global_db_driver.h +++ b/dap_chain_global_db_driver.h @@ -27,13 +27,12 @@ #include <stddef.h> #include <stdint.h> -//#include <ctime> #include "dap_common.h" typedef struct dap_store_obj { - time_t timestamp; + uint64_t id; + time_t timestamp; uint8_t type; -// char *section; char *group; char *key; uint8_t *value; @@ -48,11 +47,15 @@ typedef struct dap_store_obj_pkt { typedef int (*dap_db_driver_write_callback_t)(dap_store_obj_t*); typedef dap_store_obj_t* (*dap_db_driver_read_callback_t)(const char *,const char *, size_t *); +typedef dap_store_obj_t* (*dap_db_driver_read_cond_callback_t)(const char *,uint64_t , size_t *); +typedef dap_store_obj_t* (*dap_db_driver_read_last_callback_t)(const char *); typedef int (*dap_db_driver_callback_t)(void); typedef struct dap_db_driver_callbacks { dap_db_driver_write_callback_t apply_store_obj; dap_db_driver_read_callback_t read_store_obj; + dap_db_driver_read_last_callback_t read_last_store_obj; + dap_db_driver_read_cond_callback_t read_cond_store_obj; dap_db_driver_callback_t transaction_start; dap_db_driver_callback_t transaction_end; dap_db_driver_callback_t deinit; @@ -70,6 +73,8 @@ char* dap_chain_global_db_driver_hash(const uint8_t *data, size_t data_size); int dap_chain_global_db_driver_appy(pdap_store_obj_t a_store_obj, size_t a_store_count); int dap_chain_global_db_driver_add(pdap_store_obj_t a_store_obj, size_t a_store_count); int dap_chain_global_db_driver_delete(pdap_store_obj_t a_store_obj, size_t a_store_count); +dap_store_obj_t* dap_chain_global_db_driver_read_last(const char *a_group); +dap_store_obj_t* dap_chain_global_db_driver_cond_read(const char *a_group, uint64_t id, size_t *a_count_out); dap_store_obj_t* dap_chain_global_db_driver_read(const char *a_group, const char *a_key, size_t *count_out); dap_store_obj_pkt_t *dap_store_packet_multiple(pdap_store_obj_t a_store_obj, diff --git a/dap_chain_global_db_driver_sqlite.c b/dap_chain_global_db_driver_sqlite.c old mode 100644 new mode 100755 index e3ec3ef143f9c7ca3b0fae1f0f3e3b1a5696f61e..0a9ad3e311ce13940db012729df929fc44b02048 --- a/dap_chain_global_db_driver_sqlite.c +++ b/dap_chain_global_db_driver_sqlite.c @@ -97,6 +97,8 @@ int dap_db_driver_sqlite_init(const char *a_filename_db, dap_db_driver_callbacks // a_drv_callback->apply_store_obj = dap_db_driver_sqlite_apply_store_obj; a_drv_callback->read_store_obj = dap_db_driver_sqlite_read_store_obj; + a_drv_callback->read_cond_store_obj = dap_db_driver_sqlite_read_cond_store_obj; + a_drv_callback->read_last_store_obj = dap_db_driver_sqlite_read_last_store_obj; a_drv_callback->transaction_start = dap_db_driver_sqlite_start_transaction; a_drv_callback->transaction_end = dap_db_driver_sqlite_end_transaction; a_drv_callback->deinit = dap_db_driver_sqlite_deinit; @@ -245,8 +247,8 @@ static int dap_db_driver_sqlite_create_group_table(const char *a_table_name) return -1; } DAP_DELETE(l_query); - // create unique index - hash - l_query = dap_strdup_printf("create unique index if not exists 'idx_hash_%s' ON '%s' (hash)", a_table_name, + // create unique index - key + l_query = dap_strdup_printf("create unique index if not exists 'idx_key_%s' ON '%s' (key)", a_table_name, a_table_name); if(dap_db_driver_sqlite_exec(s_db, (const char*) l_query, &l_error_message) != SQLITE_OK) { log_it(L_ERROR, "Create unique index : %s\n", l_error_message); @@ -442,22 +444,32 @@ int dap_db_driver_sqlite_end_transaction(void) */ int dap_db_driver_sqlite_apply_store_obj(dap_store_obj_t *a_store_obj) { - if(!a_store_obj || !a_store_obj->group || !a_store_obj->key || !a_store_obj->value || !a_store_obj->value_len) + if(!a_store_obj || !a_store_obj->group) return -1; char *l_query = NULL; char *l_error_message = NULL; if(a_store_obj->type == 'a') { + if(!a_store_obj->key || !a_store_obj->value || !a_store_obj->value_len) + return -1; dap_chain_hash_fast_t l_hash; dap_hash_fast(a_store_obj->value, a_store_obj->value_len, &l_hash); char *l_blob_hash = dap_db_driver_get_string_from_blob((uint8_t*) &l_hash, sizeof(dap_chain_hash_fast_t)); char *l_blob_value = dap_db_driver_get_string_from_blob(a_store_obj->value, a_store_obj->value_len); + //add one record l_query = sqlite3_mprintf("insert into '%s' values(NULL, '%s', x'%s', '%lld', x'%s')", a_store_obj->group, a_store_obj->key, l_blob_hash, a_store_obj->timestamp, l_blob_value); dap_db_driver_sqlite_free(l_blob_hash); dap_db_driver_sqlite_free(l_blob_value); } else if(a_store_obj->type == 'd') { + //delete one record + if(a_store_obj->key) + l_query = sqlite3_mprintf("delete from '%s' where key = '%s'", + a_store_obj->group, a_store_obj->key); + // remove all group + else + l_query = sqlite3_mprintf("drop table if exists '%s'", a_store_obj->group); } else { log_it(L_ERROR, "Unknown store_obj type '0x%x'", a_store_obj->type); @@ -473,7 +485,7 @@ int dap_db_driver_sqlite_apply_store_obj(dap_store_obj_t *a_store_obj) dap_db_driver_sqlite_free(l_query); // entry with the same hash is already present if(l_ret == SQLITE_CONSTRAINT) { - log_it(L_INFO, "Entry with the same hash is already present, %s", l_error_message); + log_it(L_INFO, "Entry with the same key is already present, %s", l_error_message); dap_db_driver_sqlite_free(l_error_message); return 0; } @@ -486,6 +498,141 @@ int dap_db_driver_sqlite_apply_store_obj(dap_store_obj_t *a_store_obj) return 0; } +static void fill_one_item(const char *a_group, dap_store_obj_t *a_obj, SQLITE_ROW_VALUE *a_row) +{ + a_obj->group = dap_strdup(a_group); + + for(int l_iCol = 0; l_iCol < a_row->count; l_iCol++) { + SQLITE_VALUE *l_cur_val = a_row->val + l_iCol; + switch (l_iCol) { + case 0: + if(l_cur_val->type == SQLITE_INTEGER) + a_obj->id = l_cur_val->val.val_int64; + break; // id + case 1: + if(l_cur_val->type == SQLITE_INTEGER) + a_obj->timestamp = l_cur_val->val.val_int64; + break; // ts + case 2: + if(l_cur_val->type == SQLITE_TEXT) + a_obj->key = dap_strdup(l_cur_val->val.val_str); + break; // key + case 3: + if(l_cur_val->type == SQLITE_BLOB) + { + a_obj->value_len = (size_t) l_cur_val->len; + a_obj->value = DAP_NEW_SIZE(uint8_t, a_obj->value_len); + memcpy(a_obj->value, l_cur_val->val.val_blob, a_obj->value_len); + } + break; // value + } + } + +} + +/** + * Read last items + * + * a_group - group name + */ +dap_store_obj_t* dap_db_driver_sqlite_read_last_store_obj(const char *a_group) +{ + dap_store_obj_t *l_obj = NULL; + char *l_error_message = NULL; + sqlite3_stmt *l_res; + if(!a_group) + return NULL; + char *l_str_query = sqlite3_mprintf("SELECT id,ts,key,value FROM '%s' ORDER BY id DESC LIMIT 1", a_group); + int l_ret = dap_db_driver_sqlite_query(s_db, l_str_query, &l_res, &l_error_message); + sqlite3_free(l_str_query); + if(l_ret != SQLITE_OK) { + log_it(L_ERROR, "read last l_ret=%d, %s\n", sqlite3_errcode(s_db), sqlite3_errmsg(s_db)); + dap_db_driver_sqlite_free(l_error_message); + return NULL; + } + + SQLITE_ROW_VALUE *l_row = NULL; + l_ret = dap_db_driver_sqlite_fetch_array(l_res, &l_row); + if(l_ret != SQLITE_ROW && l_ret != SQLITE_DONE) + { + log_it(L_ERROR, "read l_ret=%d, %s\n", sqlite3_errcode(s_db), sqlite3_errmsg(s_db)); + } + if(l_ret == SQLITE_ROW && l_row) { + l_obj = DAP_NEW_Z(dap_store_obj_t); + fill_one_item(a_group, l_obj, l_row); + } + dap_db_driver_sqlite_row_free(l_row); + dap_db_driver_sqlite_query_free(l_res); + + return l_obj; +} + +/** + * Read several items with conditoin + * + * a_group - group name + * a_id - read from this id + * a_count_out[in], how many items to read, 0 - no limits + * a_count_out[out], how many items was read + */ +dap_store_obj_t* dap_db_driver_sqlite_read_cond_store_obj(const char *a_group, uint64_t a_id, size_t *a_count_out) +{ + dap_store_obj_t *l_obj = NULL; + char *l_error_message = NULL; + sqlite3_stmt *l_res; + if(!a_group) + return NULL; + // no limit + int l_count_out = 0; + if(a_count_out) + l_count_out = *a_count_out; + char *l_str_query; + if(l_count_out) + l_str_query = sqlite3_mprintf("SELECT id,ts,key,value FROM '%s' WHERE id>'%lld' ORDER BY id ASC LIMIT %d", + a_group, a_id, l_count_out); + else + l_str_query = sqlite3_mprintf("SELECT id,ts,key,value FROM '%s' WHERE id>'%lld' ORDER BY id ASC", + a_group, a_id); + int l_ret = dap_db_driver_sqlite_query(s_db, l_str_query, &l_res, &l_error_message); + sqlite3_free(l_str_query); + if(l_ret != SQLITE_OK) { + log_it(L_ERROR, "read l_ret=%d, %s\n", sqlite3_errcode(s_db), sqlite3_errmsg(s_db)); + dap_db_driver_sqlite_free(l_error_message); + return NULL; + } + + //int b = qlite3_column_count(s_db); + SQLITE_ROW_VALUE *l_row = NULL; + l_count_out = 0; + int l_count_sized = 0; + do { + l_ret = dap_db_driver_sqlite_fetch_array(l_res, &l_row); + if(l_ret != SQLITE_ROW && l_ret != SQLITE_DONE) + { + log_it(L_ERROR, "read l_ret=%d, %s\n", sqlite3_errcode(s_db), sqlite3_errmsg(s_db)); + } + if(l_ret == SQLITE_ROW && l_row) { + // realloc memory + if(l_count_out >= l_count_sized) { + l_count_sized += 10; + l_obj = DAP_REALLOC(l_obj, sizeof(dap_store_obj_t) * l_count_sized); + memset(l_obj + l_count_out, 0, sizeof(dap_store_obj_t) * (l_count_sized - l_count_out)); + } + // fill current item + dap_store_obj_t *l_obj_cur = l_obj + l_count_out; + fill_one_item(a_group, l_obj_cur, l_row); + l_count_out++; + } + dap_db_driver_sqlite_row_free(l_row); + } while(l_row); + + dap_db_driver_sqlite_query_free(l_res); + + if(a_count_out) + *a_count_out = l_count_out; + return l_obj; +} + /** * Read several items * @@ -508,18 +655,18 @@ dap_store_obj_t* dap_db_driver_sqlite_read_store_obj(const char *a_group, const char *l_str_query; if(a_key) { if(l_count_out) - l_str_query = sqlite3_mprintf("SELECT ts,key,value FROM '%s' WHERE key='%s' LIMIT %d ORDER BY id ASC", + l_str_query = sqlite3_mprintf("SELECT id,ts,key,value FROM '%s' WHERE key='%s' ORDER BY id ASC LIMIT %d", a_group, a_key, l_count_out); else - l_str_query = sqlite3_mprintf("SELECT ts,key,value FROM '%s' WHERE key='%s' ORDER BY id ASC", a_group, - a_key); + l_str_query = sqlite3_mprintf("SELECT id,ts,key,value FROM '%s' WHERE key='%s' ORDER BY id ASC", + a_group, a_key); } else { if(l_count_out) - l_str_query = sqlite3_mprintf("SELECT ts,key,value FROM '%s' LIMIT %d ORDER BY id ASC", - a_group, a_key, l_count_out); + l_str_query = sqlite3_mprintf("SELECT id,ts,key,value FROM '%s' ORDER BY id ASC LIMIT %d", + a_group, l_count_out); else - l_str_query = sqlite3_mprintf("SELECT ts,key,value FROM '%s' ORDER BY id ASC", a_group, a_key); + l_str_query = sqlite3_mprintf("SELECT id,ts,key,value FROM '%s' ORDER BY id ASC", a_group); } int l_ret = dap_db_driver_sqlite_query(s_db, l_str_query, &l_res, &l_error_message); sqlite3_free(l_str_query); @@ -540,37 +687,15 @@ dap_store_obj_t* dap_db_driver_sqlite_read_store_obj(const char *a_group, const log_it(L_ERROR, "read l_ret=%d, %s\n", sqlite3_errcode(s_db), sqlite3_errmsg(s_db)); } if(l_ret == SQLITE_ROW && l_row) { + // realloc memory if(l_count_out >= l_count_sized) { l_count_sized += 10; l_obj = DAP_REALLOC(l_obj, sizeof(dap_store_obj_t) * l_count_sized); memset(l_obj + l_count_out, 0, sizeof(dap_store_obj_t) * (l_count_sized - l_count_out)); } + // fill currrent item dap_store_obj_t *l_obj_cur = l_obj + l_count_out; - - l_obj_cur->group = dap_strdup(a_group); - l_obj_cur->key = dap_strdup(a_key); - - for(int l_iCol = 0; l_iCol < l_row->count; l_iCol++) { - SQLITE_VALUE *cur_val = l_row->val + l_iCol; - switch (l_iCol) { - case 0: - if(cur_val->type == SQLITE_INTEGER) - l_obj_cur->timestamp = cur_val->val.val_int64; - break; // ts - case 1: - if(cur_val->type == SQLITE_TEXT) - l_obj_cur->key = dap_strdup(cur_val->val.val_str); - break; // key - case 2: - if(cur_val->type == SQLITE_BLOB) - { - l_obj_cur->value_len = (size_t) cur_val->len; - l_obj_cur->value = DAP_NEW_SIZE(uint8_t, l_obj_cur->value_len); - memcpy(l_obj_cur->value, cur_val->val.val_blob, l_obj_cur->value_len); - } - break;// value - } - } + fill_one_item(a_group, l_obj_cur, l_row); l_count_out++; } dap_db_driver_sqlite_row_free(l_row); diff --git a/dap_chain_global_db_driver_sqlite.h b/dap_chain_global_db_driver_sqlite.h old mode 100644 new mode 100755 index bb33f18a8d7abe5facb2e3e6ae056dd714aaa9db..202bf7fc0e2ca50c45bea2bb8ddbf9d9d8b118b9 --- a/dap_chain_global_db_driver_sqlite.h +++ b/dap_chain_global_db_driver_sqlite.h @@ -44,4 +44,6 @@ int dap_db_driver_sqlite_end_transaction(void); // Apply data (write or delete) int dap_db_driver_sqlite_apply_store_obj(dap_store_obj_t *a_store_obj); // Read data +dap_store_obj_t* dap_db_driver_sqlite_read_last_store_obj(const char *a_group); +dap_store_obj_t* dap_db_driver_sqlite_read_cond_store_obj(const char *a_group, uint64_t a_id, size_t *a_count_out); dap_store_obj_t* dap_db_driver_sqlite_read_store_obj(const char *a_group, const char *a_key, size_t *a_count_out); diff --git a/dap_chain_global_db_hist.c b/dap_chain_global_db_hist.c index 345858e202beac3a4d1a174a6a086d5fa5c02011..b3704aa2c6f29b8ddeb944bf9e0afa5d79823b27 100755 --- a/dap_chain_global_db_hist.c +++ b/dap_chain_global_db_hist.c @@ -24,7 +24,7 @@ static int dap_db_history_unpack_hist(char *l_str_in, dap_global_db_hist_t *a_re if(l_count != 4) return -1; a_rec_out->type = l_strv[0][0]; - a_rec_out->keys_count = strtoul(l_strv[1], NULL,10); + a_rec_out->keys_count = strtoul(l_strv[1], NULL, 10); a_rec_out->group = dap_strdup(l_strv[2]); a_rec_out->keys = dap_strdup(l_strv[3]); dap_strfreev(l_strv); @@ -73,15 +73,15 @@ uint8_t* dap_db_log_pack(dap_global_db_obj_t *a_obj, size_t *a_data_size_out) while(l_keys[i]) { dap_store_obj_t *l_obj = NULL; // add record - read record - if(l_rec.type=='a') + if(l_rec.type == 'a') l_obj = (dap_store_obj_t*) dap_chain_global_db_obj_get(l_keys[i], l_rec.group); // delete record - save only key for record - else if(l_rec.type=='d'){// //section=strdup("kelvin_nodes"); - l_obj = (dap_store_obj_t*)DAP_NEW_Z(dap_store_obj_t); + else if(l_rec.type == 'd') { // //section=strdup("kelvin_nodes"); + l_obj = (dap_store_obj_t*) DAP_NEW_Z(dap_store_obj_t); l_obj->group = dap_strdup(l_rec.group); l_obj->key = dap_strdup(l_keys[i]); } - if (l_obj == NULL){ + if(l_obj == NULL) { dap_store_obj_free(l_store_obj, l_count); dap_strfreev(l_keys); return NULL; @@ -106,8 +106,6 @@ uint8_t* dap_db_log_pack(dap_global_db_obj_t *a_obj, size_t *a_data_size_out) } - - /** * Add data to the history log */ @@ -125,7 +123,7 @@ bool dap_db_history_add(char a_type, pdap_store_obj_t a_store_obj, size_t a_dap_ l_rec.keys = a_store_obj->key; else { // make keys vector - char **l_keys = DAP_NEW_Z_SIZE(char*, sizeof(char*) * ( ((size_t) a_dap_store_count) + 1)); + char **l_keys = DAP_NEW_Z_SIZE(char*, sizeof(char*) * (((size_t ) a_dap_store_count) + 1)); size_t i; for(i = 0; i < a_dap_store_count; i++) { // if it is marked, the data has not been saved @@ -144,8 +142,8 @@ bool dap_db_history_add(char a_type, pdap_store_obj_t a_store_obj, size_t a_dap_ // key - timestamp // value - keys of added/deleted data l_store_data.key = dap_db_new_history_timestamp(); - l_store_data.value = (uint8_t*) strdup(l_str) ; - l_store_data.value_len = l_str_len+1; + l_store_data.value = (uint8_t*) strdup(l_str); + l_store_data.value_len = l_str_len + 1; l_store_data.group = GROUP_LOCAL_HISTORY; l_store_data.timestamp = time(NULL); int l_res = dap_chain_global_db_driver_add(&l_store_data, 1); @@ -171,22 +169,27 @@ bool dap_db_history_truncate(void) */ time_t dap_db_log_get_last_timestamp(void) { - char *last_key = NULL; - size_t l_data_size_out = 0; - dap_global_db_obj_t **l_objs = dap_chain_global_db_gr_load(GROUP_LOCAL_HISTORY, &l_data_size_out); - if(l_data_size_out > 0) - last_key = l_objs[0]->key; - for(size_t i = 1; i < l_data_size_out; i++) { - dap_global_db_obj_t *l_obj_cur = l_objs[i]; - if(strcmp(last_key, l_obj_cur->key) < 0) { - last_key = l_obj_cur->key; - //printf("l_obj_cur->key=%s last_key\n", l_obj_cur->key); - } - //printf("l_obj_cur->key=%s\n", l_obj_cur->key); + //dap_store_obj_t *l_last_obj = dap_chain_global_db_driver_read_last( + dap_store_obj_t *l_last_obj = dap_chain_global_db_get_last(GROUP_LOCAL_HISTORY); + if(l_last_obj) { + return l_last_obj->id; } - time_t l_ret_time = last_key? strtoll(last_key, NULL, 10): 0; - dap_chain_global_db_objs_delete(l_objs); - return l_ret_time; + /* char *last_key = NULL; + size_t l_data_size_out = 0; + dap_global_db_obj_t **l_objs = dap_chain_global_db_gr_load(GROUP_LOCAL_HISTORY, &l_data_size_out); + if(l_data_size_out > 0) + last_key = l_objs[0]->key; + for(size_t i = 1; i < l_data_size_out; i++) { + dap_global_db_obj_t *l_obj_cur = l_objs[i]; + if(strcmp(last_key, l_obj_cur->key) < 0) { + last_key = l_obj_cur->key; + //printf("l_obj_cur->key=%s last_key\n", l_obj_cur->key); + } + //printf("l_obj_cur->key=%s\n", l_obj_cur->key); + } + time_t l_ret_time = last_key? strtoll(last_key, NULL, 10): 0; + dap_chain_global_db_objs_delete(l_objs); + return l_ret_time;*/ } static int compare_items(const void * l_a, const void * l_b) @@ -203,24 +206,41 @@ static int compare_items(const void * l_a, const void * l_b) dap_list_t* dap_db_log_get_list(time_t first_timestamp) { dap_list_t *l_list = NULL; - size_t l_list_count = 0; - char *l_first_key_str = dap_strdup_printf("%lld", (int64_t) first_timestamp); size_t l_data_size_out = 0; - dap_global_db_obj_t **l_objs = dap_chain_global_db_gr_load(GROUP_LOCAL_HISTORY, &l_data_size_out); + dap_store_obj_t *l_objs = dap_chain_global_db_cond_load(GROUP_LOCAL_HISTORY, first_timestamp, &l_data_size_out); + //dap_global_db_obj_t **l_objs = dap_chain_global_db_gr_load(GROUP_LOCAL_HISTORY, first_timestamp, &l_data_size_out); for(size_t i = 0; i < l_data_size_out; i++) { - dap_global_db_obj_t *l_obj_cur = l_objs[i]; -// log_it(L_DEBUG,"%lld and %lld tr",strtoll(l_obj_cur->key,NULL,10), first_timestamp ); - if( strtoll(l_obj_cur->key,NULL,10) > (long long) first_timestamp ) { - dap_global_db_obj_t *l_item = DAP_NEW(dap_global_db_obj_t); - l_item->key = dap_strdup(l_obj_cur->key); - l_item->value =(uint8_t*) dap_strdup((char*) l_obj_cur->value); - l_list = dap_list_append(l_list, l_item); - l_list_count++; - } + dap_store_obj_t *l_obj_cur = l_objs + i; + dap_global_db_obj_t *l_item = DAP_NEW(dap_global_db_obj_t); + l_item->key = dap_strdup(l_obj_cur->key); + l_item->value = (uint8_t*) dap_strdup((char*) l_obj_cur->value); + l_list = dap_list_append(l_list, l_item); } - // sort list by key (time str) - //dap_list_sort(l_list, (dap_callback_compare_t) compare_items); - log_it(L_DEBUG,"Prepared %u items (list size %u)", l_list_count, dap_list_length(l_list)); + dap_store_obj_free(l_objs, l_data_size_out); + + return l_list; + /* + size_t l_list_count = 0; + char *l_first_key_str = dap_strdup_printf("%lld", (int64_t) first_timestamp); + size_t l_data_size_out = 0; + + for(size_t i = 0; i < l_data_size_out; i++) { + dap_global_db_obj_t *l_obj_cur = l_objs[i]; + // log_it(L_DEBUG,"%lld and %lld tr",strtoll(l_obj_cur->key,NULL,10), first_timestamp ); + if( strtoll(l_obj_cur->key,NULL,10) > (long long) first_timestamp ) { + dap_global_db_obj_t *l_item = DAP_NEW(dap_global_db_obj_t); + l_item->key = dap_strdup(l_obj_cur->key); + l_item->value =(uint8_t*) dap_strdup((char*) l_obj_cur->value); + l_list = dap_list_append(l_list, l_item); + l_list_count++; + } + } + // sort list by key (time str) + //dap_list_sort(l_list, (dap_callback_compare_t) compare_items); + log_it(L_DEBUG,"Prepared %u items (list size %u)", l_list_count, dap_list_length(l_list)); + DAP_DELETE(l_first_key_str); + dap_chain_global_db_objs_delete(l_objs); + */ /*/ dbg - sort result l_data_size_out = dap_list_length(l_list); for(size_t i = 0; i < l_data_size_out; i++) { @@ -229,9 +249,6 @@ dap_list_t* dap_db_log_get_list(time_t first_timestamp) printf("2 %d %s\n", i, l_item->key); }*/ - DAP_DELETE(l_first_key_str); - dap_chain_global_db_objs_delete(l_objs); - return l_list; } /**