static int open_db (SeafBranchManager *mgr) { #ifndef SEAFILE_SERVER char *db_path; const char *sql; db_path = g_build_filename (mgr->seaf->seaf_dir, BRANCH_DB, NULL); if (sqlite_open_db (db_path, &mgr->priv->db) < 0) { g_critical ("[Branch mgr] Failed to open branch db\n"); g_free (db_path); return -1; } g_free (db_path); sql = "CREATE TABLE IF NOT EXISTS Branch (" "name TEXT, repo_id TEXT, commit_id TEXT);"; if (sqlite_query_exec (mgr->priv->db, sql) < 0) return -1; sql = "CREATE INDEX IF NOT EXISTS branch_index ON Branch(repo_id, name);"; if (sqlite_query_exec (mgr->priv->db, sql) < 0) return -1; #else char *sql = "CREATE TABLE IF NOT EXISTS Branch (" "name VARCHAR(10), repo_id CHAR(41), commit_id CHAR(41)," "PRIMARY KEY (repo_id, name))"; if (seaf_db_query (mgr->seaf->db, sql) < 0) return -1; #endif return 0; }
static int open_db (SeafBranchManager *mgr) { #ifndef SEAFILE_SERVER char *db_path; const char *sql; db_path = g_build_filename (mgr->seaf->seaf_dir, BRANCH_DB, NULL); if (sqlite_open_db (db_path, &mgr->priv->db) < 0) { g_critical ("[Branch mgr] Failed to open branch db\n"); g_free (db_path); return -1; } g_free (db_path); sql = "CREATE TABLE IF NOT EXISTS Branch (" "name TEXT, repo_id TEXT, commit_id TEXT);"; if (sqlite_query_exec (mgr->priv->db, sql) < 0) return -1; sql = "CREATE INDEX IF NOT EXISTS branch_index ON Branch(repo_id, name);"; if (sqlite_query_exec (mgr->priv->db, sql) < 0) return -1; #elif defined FULL_FEATURE char *sql; switch (seaf_db_type (mgr->seaf->db)) { case SEAF_DB_TYPE_MYSQL: sql = "CREATE TABLE IF NOT EXISTS Branch (" "name VARCHAR(10), repo_id CHAR(41), commit_id CHAR(41)," "PRIMARY KEY (repo_id, name)) ENGINE = INNODB"; if (seaf_db_query (mgr->seaf->db, sql) < 0) return -1; break; case SEAF_DB_TYPE_PGSQL: sql = "CREATE TABLE IF NOT EXISTS Branch (" "name VARCHAR(10), repo_id CHAR(40), commit_id CHAR(40)," "PRIMARY KEY (repo_id, name))"; if (seaf_db_query (mgr->seaf->db, sql) < 0) return -1; break; case SEAF_DB_TYPE_SQLITE: sql = "CREATE TABLE IF NOT EXISTS Branch (" "name VARCHAR(10), repo_id CHAR(41), commit_id CHAR(41)," "PRIMARY KEY (repo_id, name))"; if (seaf_db_query (mgr->seaf->db, sql) < 0) return -1; break; } #endif return 0; }
SeafCloneManager * seaf_clone_manager_new (SeafileSession *session) { SeafCloneManager *mgr = g_new0 (SeafCloneManager, 1); char *db_path = g_build_path ("/", session->seaf_dir, CLONE_DB, NULL); if (sqlite_open_db (db_path, &mgr->db) < 0) { g_critical ("[Clone mgr] Failed to open db\n"); g_free (db_path); g_free (mgr); return NULL; } mgr->seaf = session; mgr->tasks = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)clone_task_free); return mgr; }
sqlite3 * seafile_session_config_open_db (const char *db_path) { sqlite3 *db; if (sqlite_open_db (db_path, &db) < 0) return NULL; /* * Values are stored in text. You should convert it * back to integer if needed when you read it from * db. */ char *sql = "CREATE TABLE IF NOT EXISTS Config (" "key TEXT PRIMARY KEY, " "value TEXT);"; sqlite_query_exec (db, sql); return db; }
static void sqlite_check_table_exists(char *dbfile, char *test_sql, char *create_sql) { sqlite3 *db; char *errmsg; if ((db = sqlite_open_db(dbfile))) { if (test_sql) { sqlite3_exec( db, test_sql, NULL, NULL, &errmsg ); if (errmsg) { cw_log(LOG_WARNING,"SQL ERR [%s]\n[%s]\nAuto Repairing!\n",errmsg,test_sql); sqlite3_free(errmsg); errmsg = NULL; sqlite3_exec( db, create_sql, NULL, NULL, &errmsg ); if (errmsg) { cw_log(LOG_WARNING,"SQL ERR [%s]\n[%s]\n",errmsg,create_sql); sqlite3_free(errmsg); errmsg = NULL; } } sqlite3_close(db); } } }
pse_op_error_t sqlite_get_empty_leafnode(int* leaf_node_id, sgx_measurement_t* mr_signer) { PROFILE_START("sqlite_get_empty_leafnode"); char mrsigner[65] = {0}; char sql_sentence[512] = {0}; int counter = 0; pse_op_error_t ret = OP_SUCCESS; sqlite3 *db = NULL; if(!leaf_node_id || !mr_signer) { PROFILE_END("sqlite_get_empty_leafnode"); return OP_ERROR_INVALID_PARAMETER; } // convert mr_signer to hex string for(uint32_t i=0; i < sizeof(sgx_measurement_t); i++) { char tmp[3]; if(_snprintf_s(tmp, sizeof(tmp), "%02x", ((uint8_t*)mr_signer)[i]) < 0) { ret = OP_ERROR_INTERNAL; goto clean_up; } if(0 != strncat_s(mrsigner, sizeof(mrsigner), tmp, sizeof(tmp))) { ret = OP_ERROR_INTERNAL; goto clean_up; } } ret = sqlite_open_db(&db); if(OP_SUCCESS != ret) { pse_vmc_db_state = PSE_VMC_DB_STATE_DOWN; PROFILE_END("sqlite_get_empty_leafnode"); return ret; } // check QUOTA if (_snprintf_s(sql_sentence, sizeof(sql_sentence), "select COUNTER from VMC_QUOTA_TABLE where MRSIGNER='%s';", mrsigner) < 0) { ret = OP_ERROR_INTERNAL; goto clean_up; } ret = sqlite_query_int_value(db, sql_sentence, &counter); if(OP_SUCCESS != ret && OP_ERROR_SQLITE_NOT_FOUND != ret) { goto clean_up; } if(PSE_VMC_QUOTA_SIZE <= counter) { // exceeds quota, return error. ret = OP_ERROR_DATABASE_OVER_QUOTA; goto clean_up; } // the specified MR SIGNER doesn't exceed quota. *leaf_node_id = 0; if (_snprintf_s(sql_sentence, sizeof(sql_sentence), "select min(ID) from HASH_TREE_NODE_TABLE where USED=0 and ID>%d and ID<%d;", INIT_MIN_LEAF_NODE_ID-1, INIT_MAX_LEAF_NODE_ID+1) < 0) { ret = OP_ERROR_INTERNAL; goto clean_up; } ret = sqlite_query_int_value(db, sql_sentence, leaf_node_id); if(OP_ERROR_SQLITE_NOT_FOUND == ret) { ret = OP_ERROR_DATABASE_FULL; goto clean_up; } clean_up: if(db) { sqlite3_close_v2(db); } PROFILE_END("sqlite_get_empty_leafnode"); return ret; }
pse_op_error_t sqlite_write_db(pse_vmc_hash_tree_cache_t* cache, uint8_t is_for_update_flag, op_leafnode_flag_t* op_flag_info) { PROFILE_START("sqlite_write_db"); int rc; pse_op_error_t ret = OP_SUCCESS; sqlite3_stmt* stat = NULL; sqlite3 *db = NULL; char sql_sentence[512] = {0}; int refid = 0; if( !cache) { PROFILE_END("sqlite_write_db"); return OP_ERROR_INVALID_PARAMETER; } if(is_for_update_flag && !op_flag_info) { PROFILE_END("sqlite_write_db"); return OP_ERROR_INVALID_PARAMETER; } // Backup DB first ret = backup_vmc_db_file(); if(OP_SUCCESS != ret) { pse_vmc_db_state = PSE_VMC_DB_STATE_DOWN; PROFILE_END("sqlite_write_db"); return ret; } ret = sqlite_open_db(&db); if(OP_SUCCESS != ret) { pse_vmc_db_state = PSE_VMC_DB_STATE_DOWN; PROFILE_END("sqlite_write_db"); return ret; } rc = sqlite3_exec(db, "BEGIN TRANSACTION;", NULL, NULL, NULL); EXIT_IFNOT_SQLITE_OK(rc, error) if (_snprintf_s(sql_sentence, sizeof(sql_sentence), "update HASH_TREE_NODE_TABLE set node_content=? where ID=?") < 0) { ret = OP_ERROR_INTERNAL; goto error; } rc = sqlite3_prepare_v2(db, sql_sentence, -1, &stat, 0); EXIT_IFNOT_SQLITE_OK(rc, error) // update internal nodes for (uint32_t index = 0; index < INIT_INTERNAL_NODE_NR; index++) { // update ancestors if ((ret = sqlite_update_node(stat, (uint8_t*)&cache->ancestors[index].internal, INTERNAL_NODE_SIZE, cache->ancestors[index].node_id)) != OP_SUCCESS) goto error; // update brothers of ancestors if ((ret = sqlite_update_node(stat, (uint8_t*)&cache->brother_of_ancestors[index].internal, INTERNAL_NODE_SIZE, cache->brother_of_ancestors[index].node_id)) != OP_SUCCESS) goto error; } // update leaf and its brother if ((ret = sqlite_update_node(stat, (uint8_t*)&cache->self.leaf, LEAF_NODE_SIZE, cache->self.node_id)) != OP_SUCCESS) goto error; if ((ret = sqlite_update_node(stat, (uint8_t*)&cache->brother.leaf, LEAF_NODE_SIZE, cache->brother.node_id)) != OP_SUCCESS) goto error; if(is_for_update_flag) { // update USED flag and QUOTA record char mrsigner[65] = {0}; // convert mr_signer to hex string for(uint32_t i=0; i < sizeof(sgx_measurement_t); i++) { char tmp[3]; if(_snprintf_s(tmp, sizeof(tmp), "%02x", ((uint8_t*)(&op_flag_info->mr_signer))[i]) < 0) { ret = OP_ERROR_INTERNAL; goto error; } if(0 != strncat_s(mrsigner, sizeof(mrsigner), tmp, sizeof(tmp))) { ret = OP_ERROR_INTERNAL; goto error; } } switch(op_flag_info->op_type) { case CLR_LEAFNODE_FLAG: // read REFID saved in HASH_TREE_NODE_TABLE before deleting the record. if (_snprintf_s(sql_sentence, sizeof(sql_sentence), "select REFID from HASH_TREE_NODE_TABLE where ID=%d;", cache->self.node_id) < 0) { ret = OP_ERROR_INTERNAL; goto error; } ret = sqlite_query_int_value(db, sql_sentence, &refid); if(OP_SUCCESS != ret && OP_ERROR_SQLITE_NOT_FOUND != ret) { goto error; } // clear REFID and USED flag if (_snprintf_s(sql_sentence, sizeof(sql_sentence), "update HASH_TREE_NODE_TABLE set USED=0 and REFID=0 where ID=%d;", cache->self.node_id) < 0) { ret = OP_ERROR_INTERNAL; goto error; } rc = sqlite3_exec(db, sql_sentence, NULL, NULL, NULL); if(SQLITE_OK != rc) { ret = OP_ERROR_SQLITE_INTERNAL; goto error; } if(1 != sqlite3_changes(db)) { ret = OP_ERROR_SQLITE_INTERNAL; goto error; } // update QUOTA, counter--; if (_snprintf_s(sql_sentence, sizeof(sql_sentence), "update VMC_QUOTA_TABLE set COUNTER=COUNTER-1 where ID=%d and COUNTER>0;", refid) < 0) { ret = OP_ERROR_INTERNAL; goto error; } rc = sqlite3_exec(db, sql_sentence, NULL, NULL, NULL); if(SQLITE_OK != rc) { ret = OP_ERROR_SQLITE_INTERNAL; goto error; } if(1 != sqlite3_changes(db)) { ret = OP_ERROR_SQLITE_INTERNAL; goto error; } break; case SET_LEAFNODE_FLAG: // update QUOTA, counter++; if (_snprintf_s(sql_sentence, sizeof(sql_sentence), "update VMC_QUOTA_TABLE set COUNTER=COUNTER+1 where MRSIGNER='%s';", mrsigner) < 0) { ret = OP_ERROR_INTERNAL; goto error; } rc = sqlite3_exec(db, sql_sentence, NULL, NULL, NULL); if(SQLITE_OK != rc) { ret = OP_ERROR_SQLITE_INTERNAL; goto error; } rc = sqlite3_changes(db); if(0 == rc) { // the mrsigner isn't in quota table yet, so insert it. if (_snprintf_s(sql_sentence, sizeof(sql_sentence), "insert into VMC_QUOTA_TABLE(MRSIGNER,COUNTER) values('%s', 1);", mrsigner) < 0) { ret = OP_ERROR_INTERNAL; goto error; } rc = sqlite3_exec(db, sql_sentence, NULL, NULL, NULL); if(SQLITE_OK != rc) { ret = OP_ERROR_SQLITE_INTERNAL; goto error; } if(1 != sqlite3_changes(db)) { ret = OP_ERROR_SQLITE_INTERNAL; goto error; } } else if(1 == rc) { // the mrsigner has been in quota table } else { ret = OP_ERROR_SQLITE_INTERNAL; goto error; } // read refid if (_snprintf_s(sql_sentence, sizeof(sql_sentence), "select ID from VMC_QUOTA_TABLE where MRSIGNER='%s';", mrsigner) < 0) { ret = OP_ERROR_INTERNAL; goto error; } ret = sqlite_query_int_value(db, sql_sentence, &refid); if(OP_SUCCESS != ret && OP_ERROR_SQLITE_NOT_FOUND != ret) { goto error; } // Update HASH_TREE_NODE_TABLE if (_snprintf_s(sql_sentence, sizeof(sql_sentence), "update HASH_TREE_NODE_TABLE set USED=1 where ID=%d;", cache->self.node_id) < 0) { ret = OP_ERROR_INTERNAL; goto error; } rc = sqlite3_exec(db, sql_sentence, NULL, NULL, NULL); if(SQLITE_OK != rc) { ret = OP_ERROR_SQLITE_INTERNAL; goto error; } if(1 != sqlite3_changes(db)) { ret = OP_ERROR_SQLITE_INTERNAL; goto error; } if (_snprintf_s(sql_sentence, sizeof(sql_sentence), "update HASH_TREE_NODE_TABLE set REFID=%d where ID=%d;", refid, cache->self.node_id) < 0) { ret = OP_ERROR_INTERNAL; goto error; } rc = sqlite3_exec(db, sql_sentence, NULL, NULL, NULL); if(SQLITE_OK != rc) { ret = OP_ERROR_SQLITE_INTERNAL; goto error; } if(1 != sqlite3_changes(db)) { ret = OP_ERROR_SQLITE_INTERNAL; goto error; } break; default: ret = OP_ERROR_INVALID_PARAMETER; goto error; } } rc = sqlite3_exec(db, "END TRANSACTION;", NULL, NULL, NULL); EXIT_IFNOT_SQLITE_OK(rc, error) sqlite3_finalize(stat); sqlite3_close_v2(db); PROFILE_END("sqlite_write_db"); return OP_SUCCESS; error: assert(db != NULL); sqlite3_finalize(stat); sqlite3_exec(db, "ROLLBACK TRANSACTION;", NULL, NULL, NULL); sqlite3_close_v2(db); PROFILE_END("sqlite_write_db"); return ret; }
pse_op_error_t sqlite_read_db(uint32_t leaf_id, pse_vmc_hash_tree_cache_t* cache) { PROFILE_START("sqlite_read_db"); int rc; pse_op_error_t ret = OP_SUCCESS; sqlite3_stmt* stat = NULL; char sql_sentence[1024] = {0}; int result; uint32_t node_id; const void* ptr_blob_content; uint32_t blob_len; uint32_t record_count = 0; uint32_t read_list_array[INIT_TOTAL_NODE_NUMBER_FOR_READING] = {0}; sqlite3 *db = NULL; uint8_t* node_ptr = NULL; uint32_t child_node_id = leaf_id; uint32_t internal_index = 0; uint32_t count = 0; if( !cache) { PROFILE_END("sqlite_read_db"); return OP_ERROR_INVALID_PARAMETER; } if(leaf_id < INIT_MIN_LEAF_NODE_ID || leaf_id > INIT_MAX_LEAF_NODE_ID) { PROFILE_END("sqlite_read_db"); return OP_ERROR_INVALID_PARAMETER; } ret = sqlite_open_db(&db); if(OP_SUCCESS != ret) { pse_vmc_db_state = PSE_VMC_DB_STATE_DOWN; PROFILE_END("sqlite_read_db"); return ret; } // layout of read_list_array is : Leaf Node ID + ancestor Node IDs + Brother Node IDs. find_all_related_node_index(leaf_id, read_list_array); // prepare sql statement if (_snprintf_s(sql_sentence, sizeof(sql_sentence), "select * from HASH_TREE_NODE_TABLE where ID IN (") < 0) { ret = OP_ERROR_INTERNAL; goto clean_up; } for(uint32_t index=0; index < INIT_TOTAL_NODE_NUMBER_FOR_READING; index++) { char id[10]; if (_snprintf_s(id, sizeof(id), "%u", read_list_array[index]) < 0) { ret = OP_ERROR_INTERNAL; goto clean_up; } if (strncat_s(sql_sentence, sizeof(sql_sentence), id, strnlen_s(id, 10)) != 0) { ret = OP_ERROR_INTERNAL; goto clean_up; } if (index != INIT_TOTAL_NODE_NUMBER_FOR_READING - 1) { if (strncat_s(sql_sentence, sizeof(sql_sentence), ",", 1) != 0) { ret = OP_ERROR_INTERNAL; goto clean_up; } } } if (strcat_s(sql_sentence, sizeof(sql_sentence), ") order by ID desc") != 0) { ret = OP_ERROR_INTERNAL; goto clean_up; } // prepare sql statement rc = sqlite3_prepare_v2(db, sql_sentence, -1, &stat, 0); EXIT_IFNOT_SQLITE_OK(rc, clean_up) // query // the result set are sorted, from leaf to up layers while ((result = sqlite3_step(stat)) == SQLITE_ROW) { // to calculate number of records returned record_count++; node_id = sqlite3_column_int(stat, 0); ptr_blob_content = sqlite3_column_blob(stat, 1); if(!ptr_blob_content) { ret = OP_ERROR_INVALID_VMC_DB; goto clean_up; } blob_len = sqlite3_column_bytes(stat, 1); if(1 == node_id) { assert(0); ret = OP_ERROR_INVALID_VMC_DB; goto clean_up; } else if(INIT_MIN_LEAF_NODE_ID <= node_id) { // node_id has already been checked and // it will not exceed INIT_MAX_LEAF_NODE_ID assert(node_id <= INIT_MAX_LEAF_NODE_ID); // leaf node if(blob_len != LEAF_NODE_SIZE) { ret = OP_ERROR_INVALID_VMC_DB; goto clean_up; } if (node_id == leaf_id) { cache->self.node_id = node_id; node_ptr = (uint8_t*)&cache->self.leaf; } else { cache->brother.node_id = node_id; node_ptr = (uint8_t*)&cache->brother.leaf; } } else { assert(node_id <= INIT_MAX_LEAF_NODE_ID); // internal nodes if(blob_len != INTERNAL_NODE_SIZE) { ret = OP_ERROR_INVALID_VMC_DB; goto clean_up; } if (node_id == child_node_id / 2) { // this is ancestor node node_ptr = (uint8_t*)&cache->ancestors[internal_index].internal; cache->ancestors[internal_index].node_id = node_id; } else { // this is brother of ancestors node_ptr = (uint8_t*)&cache->brother_of_ancestors[internal_index].internal; cache->brother_of_ancestors[internal_index].node_id = node_id; } count++; if (count == 2) { // internal nodes are arranged as pairs, one is ancestor, another is the brother of the ancestor count = 0; internal_index++; // go up a level child_node_id = node_id; // now current node becomes child } } // copy blob data to output buffer if(0 != memcpy_s(node_ptr, blob_len, ptr_blob_content, blob_len)) { ret = OP_ERROR_INTERNAL; goto clean_up; } } if (record_count != INIT_TOTAL_NODE_NUMBER_FOR_READING) { ret = OP_ERROR_INVALID_VMC_DB; goto clean_up; } if (result != SQLITE_DONE) { ret = OP_ERROR_SQLITE_INTERNAL; } clean_up: assert(db != NULL); sqlite3_finalize(stat); sqlite3_close_v2(db); PROFILE_END("sqlite_read_db"); return ret; }
pse_op_error_t sqlite_read_children_of_root(pse_vmc_children_of_root_t* children) { PROFILE_START("sqlite_read_children_of_root"); int rc; pse_op_error_t ret = OP_SUCCESS; sqlite3_stmt* stat = NULL; char sql_sentence[1024] = {0}; int result; uint32_t node_id; const void* ptr_blob_content; uint32_t blob_len; uint32_t record_count = 0; uint32_t read_list_array[2] = {2,3}; sqlite3 *db = NULL; assert(children != NULL); ret = sqlite_open_db(&db); if(OP_SUCCESS != ret) { pse_vmc_db_state = PSE_VMC_DB_STATE_DOWN; PROFILE_END("sqlite_read_children_of_root"); return ret; } // prepare sql statement if (_snprintf_s(sql_sentence, sizeof(sql_sentence), "select * from HASH_TREE_NODE_TABLE where ID IN (2,3) order by ID asc") < 0) { ret = OP_ERROR_INTERNAL; goto clean_up; } // prepare sql statement rc = sqlite3_prepare_v2(db, sql_sentence, -1, &stat, 0); EXIT_IFNOT_SQLITE_OK(rc, clean_up) // query while ((result = sqlite3_step(stat)) == SQLITE_ROW) { // to calculate number of records returned record_count++; if (record_count > 2) { ret = OP_ERROR_INVALID_VMC_DB; goto clean_up; } node_id = sqlite3_column_int(stat, 0); // The array read_list_array[] contains {2,3}, and the node id read from DB must be 2 or 3. if (node_id != read_list_array[record_count-1]) { ret = OP_ERROR_INVALID_VMC_DB; goto clean_up; } ptr_blob_content = sqlite3_column_blob(stat, 1); if(!ptr_blob_content) { ret = OP_ERROR_INVALID_VMC_DB; goto clean_up; } blob_len = sqlite3_column_bytes(stat, 1); // Child Node if(blob_len != INTERNAL_NODE_SIZE) { ret = OP_ERROR_INVALID_VMC_DB; goto clean_up; } // Copy children hash_tree_internal_node_t* internal_node_ptr = NULL; if (node_id == 2) { internal_node_ptr = &children->left_child.internal; } else { internal_node_ptr = &children->rigth_child.internal; } if(0 != memcpy_s(internal_node_ptr, blob_len, ptr_blob_content, blob_len)) { ret = OP_ERROR_INTERNAL; goto clean_up; } } if (record_count != 2) { ret = OP_ERROR_INVALID_VMC_DB; goto clean_up; } if (result != SQLITE_DONE) { ret = OP_ERROR_SQLITE_INTERNAL; } clean_up: sqlite3_finalize(stat); assert(db != NULL); sqlite3_close_v2(db); PROFILE_END("sqlite_read_children_of_root"); return ret; }
static int database_show(int fd, int argc, char *argv[]) { char *prefix, *family; char *sql; char *zErr = 0; int res = 0; sqlite3 *db; #ifdef HAVE_MEMCACHE database_flush_cache(); #endif sanity_check(); if (!(db = sqlite_open_db(globals.dbfile))) { return -1; } if (argc == 4) { /* Family and key tree */ prefix = argv[3]; family = argv[2]; } else if (argc == 3) { /* Family only */ family = argv[2]; prefix = NULL; } else if (argc == 2) { /* Neither */ prefix = family = NULL; } else { return RESULT_SHOWUSAGE; } if (family && prefix) { sql = sqlite3_mprintf("select * from %q where family='%q' and keys='%q'", globals.tablename, family, prefix); } else if (family) { sql = sqlite3_mprintf("select * from %q where family='%q'", globals.tablename, family); } else { sql = sqlite3_mprintf("select * from %q", globals.tablename); } if (sql) { cw_log(LOG_DEBUG, "SQL [%s]\n", sql); res = sqlite3_exec(db, sql, show_callback, &fd, &zErr ); if (zErr) { cw_log(LOG_ERROR, "SQL ERR [%s] [%s]\n", sql, zErr); res = -1; sqlite3_free(zErr); } else { res = 0; } } else { cw_log(LOG_ERROR, "Memory Error!\n"); res = -1; /* Return an error */ } if (sql) { sqlite3_free(sql); sql = NULL; } sqlite3_close(db); return RESULT_SUCCESS; }
struct cw_db_entry *cw_db_gettree(const char *family, const char *keytree) { char *sql; char *zErr = 0; int res = 0; struct cw_db_entry *tree = NULL; sqlite3 *db; int retry=0; #ifdef HAVE_MEMCACHE database_flush_cache(); #endif sanity_check(); if (!(db = sqlite_open_db(globals.dbfile))) { return NULL; } if (!family || cw_strlen_zero(family)) { family = "_undef_"; } if (family && keytree && !cw_strlen_zero(keytree)) { sql = sqlite3_mprintf("select keys,value from %q where family='%q' and keys like '%q%%'", globals.tablename, family, keytree); } else if(family) { sql = sqlite3_mprintf("select keys,value from %q where family='%q'", globals.tablename, family); } else { cw_log(LOG_ERROR, "No parameters supplied.\n"); return NULL; } if (sql) { retry_3: if (retry) cw_log(LOG_DEBUG, "SQL [%s] (retry %d)\n", sql, retry); else cw_log(LOG_DEBUG, "SQL [%s]\n", sql); res = sqlite3_exec(db, sql, tree_callback, &tree, &zErr ); if (zErr) { if (retry >= SQL_MAX_RETRIES) { cw_log(LOG_ERROR, "SQL ERR Query: [%s] Error: [%s] Retries: %d Max: %d\n", sql, zErr, retry, SQL_MAX_RETRIES); sqlite3_free(zErr); } else { cw_log(LOG_DEBUG, "SQL ERR Query: %s Error: [%s] Retries %d\n", sql, zErr, ++retry); sqlite3_free(zErr); usleep(SQL_RETRY_USEC); goto retry_3; } res = -1; } else { res = 0; } } else { cw_log(LOG_ERROR, "Memory Error!\n"); res = -1; /* Return an error */ } if (sql) { sqlite3_free(sql); sql = NULL; } sqlite3_close(db); return tree; }
static int cw_db_del_main(const char *family, const char *keys, int like, const char *value, int use_memcache ) { char *sql; char *zErr = 0; int res = 0; sqlite3 *db; char *op = "="; char *pct = ""; int retry=0; if (!family || cw_strlen_zero(family)) { family = "_undef_"; } if (like) { op = "like"; pct = "%"; } if (family && keys && value) { sql = sqlite3_mprintf("delete from %q where family %s '%q%s' and keys %s '%q%s' AND value %s '%q%s' ", globals.tablename, op, family, pct, op, keys, pct, op, value, pct ); } else if (family && keys) { sql = sqlite3_mprintf("delete from %q where family %s '%q%s' and keys %s '%q%s'", globals.tablename, op, family, pct, op, keys, pct); } else if (family) { sql = sqlite3_mprintf("delete from %q where family %s '%q%s'", globals.tablename, op, family, pct); } else { sql = sqlite3_mprintf("delete from %q", globals.tablename); } if ( !sql ) { cw_log(LOG_ERROR, "Memory Error!\n"); return -1; /* Return an error */ } #ifdef HAVE_MEMCACHE if ( memcached_data.active && use_memcache ) { //cw_log(LOG_ERROR,"MEMCACHE DEL Family %s : %s => %s (%d)\n", family, keys, value, like); if ( memcached_data.has_error ) database_cache_retry_connect(); if ( !like && !value ) { int fullkeylen; char fullkey[256] = ""; fullkeylen = snprintf(fullkey, sizeof(fullkey), "/%s/%s", family, keys); mc_delete( memcached_data.mc, fullkey, fullkeylen, 0); if ( !database_sql_queue(sql) ) { sqlite3_free(sql); return 0; } } else { // If it's a deltree or we're dropping a specific value. // then we shouldn't do anything. // The best way here is to force the flush of all the QUEUE // to the DB, clear all the cache and go on as usual. //TODO check it database_flush_cache(); } } #endif sanity_check(); if (!(db = sqlite_open_db(globals.dbfile))) { return -1; } if (sql) { retry_2: if (retry > 0) cw_log(LOG_DEBUG, "SQL Query: [%s] (retry %d)\n", sql, retry); else cw_log(LOG_DEBUG, "SQL [%s]\n", sql); res = sqlite3_exec(db, sql, NULL, NULL, &zErr ); if (zErr) { if (retry >= SQL_MAX_RETRIES) { cw_log(LOG_ERROR, "SQL ERR Query: [%s] Error: [%s] Retries: %d Max: %d\n", sql, zErr, retry, SQL_MAX_RETRIES); sqlite3_free(zErr); } else { cw_log(LOG_DEBUG, "SQL ERR Query: %s Error: [%s] Retries %d\n", sql, zErr, ++retry); sqlite3_free(zErr); usleep(SQL_RETRY_USEC); goto retry_2; } res = -1; } else { if (!sqlite3_changes(db)) res = -1; else res = 0; } } if (sql) { sqlite3_free(sql); sql = NULL; } sqlite3_close(db); return res; }
int cw_db_get(const char *family, const char *keys, char *value, int valuelen) { char *sql; char *zErr = 0; int res = 0; struct cw_db_data result; sqlite3 *db; int retry=0; if (!family || cw_strlen_zero(family)) { family = "_undef_"; } #ifdef HAVE_MEMCACHE int fullkeylen; char fullkey[256] = ""; fullkeylen = snprintf(fullkey, sizeof(fullkey), "/%s/%s", family, keys); if ( memcached_data.active ) { if ( memcached_data.has_error ) database_cache_retry_connect(); //cw_log(LOG_ERROR,"MEMCACHE GET Family %s : %s \n", family, keys); memset(value,0,valuelen); struct memcache_req *mreq; struct memcache_res *mres; mreq = mc_req_new(); mres = mc_req_add(mreq, fullkey, fullkeylen); mc_res_free_on_delete(mres, 0); mres->size = valuelen; mres->val = value; mc_get(memcached_data.mc, mreq); if ( mres->bytes ) { // FOUND //cw_log(LOG_WARNING,"MEMCACHE GET FOUND for %s: (%d) %s\n", fullkey, mres->size,(char *) mres->val); //value = mres->val; mc_req_free(mreq); return 0; } mc_req_free(mreq); } #endif sanity_check(); if (!(db = sqlite_open_db(globals.dbfile))) { return -1; } result.data = value; result.datalen = valuelen; result.rownum = 0; retry_1: if ((sql = sqlite3_mprintf("select value from %q where family='%q' and keys='%q'", globals.tablename, family, keys))) { cw_log(LOG_DEBUG, "SQL [%s]\n", sql); res = sqlite3_exec(db, sql, get_callback, &result, &zErr ); if (zErr) { if (retry >= SQL_MAX_RETRIES) { cw_log(LOG_ERROR, "SQL ERR Query: [%s] Error: [%s] Retries: %d Max: %d\n", sql, zErr, retry, SQL_MAX_RETRIES); sqlite3_free(zErr); } else { cw_log(LOG_DEBUG, "SQL ERR Query: %s Error: [%s] Retries %d\n", sql, zErr, ++retry); sqlite3_free(zErr); usleep(SQL_RETRY_USEC); goto retry_1; } res = -1; } else { if (result.rownum) res = 0; else res = -1; } } else { cw_log(LOG_ERROR, "Memory Error!\n"); res = -1; /* Return an error */ } if (sql) { sqlite3_free(sql); sql = NULL; } sqlite3_close(db); #if defined(HAVE_MEMCACHE) // We got a value out of the cache. // Store it back to the cache to improve performance. if ( !res && memcached_data.active ) { if ( memcached_data.has_error ) database_cache_retry_connect(); //cw_log(LOG_ERROR,"DB GET STANDARD RETURNING AND CACHING %s\n", value); mc_set(memcached_data.mc, fullkey, fullkeylen, value, (size_t)MCM_CSTRLEN(value), db_cache_lifetime, 0); } #endif return res; }
int cw_db_put(const char *family, const char *keys, char *value) { char *sql = NULL; char *zErr = 0; int res = 0; sqlite3 *db; int retry=0; if (!family || cw_strlen_zero(family)) { family = "_undef_"; } if ( !(sql = sqlite3_mprintf("insert into %q values('%q','%q','%q')", globals.tablename, family, keys, value)) ) { cw_log(LOG_ERROR, "Memory Error!\n"); res = -1; /* Return an error */ } cw_db_del(family, keys); #ifdef HAVE_MEMCACHE if ( memcached_data.active ) { if ( memcached_data.has_error ) database_cache_retry_connect(); //cw_log(LOG_ERROR,"MEMCACHE PUT Family %s : %s => %s (%d) \n", family, keys, value, strlen(value) ); int fullkeylen; char fullkey[256] = ""; fullkeylen = snprintf(fullkey, sizeof(fullkey), "/%s/%s", family, keys); mc_delete( memcached_data.mc, fullkey, fullkeylen, 0); if ( mc_set(memcached_data.mc, fullkey, fullkeylen, value, (size_t) strlen(value) , db_cache_lifetime, 0) == 0) { // ADD THE SQL TO THE QUEUE TO BE EXECUTED ASYNCRONOUSLY if ( !database_sql_queue(sql) ) { sqlite3_free(sql); return 0; } } else { //DIDN'T WORK // So store as we did before... } } #endif sanity_check(); if (!(db = sqlite_open_db(globals.dbfile))) { return -1; } retry_0: if ( sql ) { cw_log(LOG_DEBUG, "SQL [%s]\n", sql); res = sqlite3_exec(db, sql, NULL, NULL, &zErr ); if (zErr) { if (retry >= SQL_MAX_RETRIES) { cw_log(LOG_ERROR, "SQL ERR Query: [%s] Error: [%s] Retries: %d Max: %d\n", sql, zErr, retry, SQL_MAX_RETRIES); sqlite3_free(zErr); } else { cw_log(LOG_DEBUG, "SQL ERR Query: %s Error: [%s] Retries %d\n", sql, zErr, ++retry); sqlite3_free(zErr); usleep(SQL_RETRY_USEC); goto retry_0; } res = -1; } else { res = 0; } } if (sql) { sqlite3_free(sql); sql = NULL; } sqlite3_close(db); return res; }
static int database_flush_cache(void) { int err = 0; db_list_t *tmplist, *item, *tmpitem; char *zErr = 0; int res = 0; sqlite3 *db; int retry=0; sanity_check(); if (!(db = sqlite_open_db(globals.dbfile))) { return -1; } sqlite3_exec(db,"BEGIN",NULL,NULL,0); cw_mutex_lock(&db_list_lock); item = tmplist = db_list_head; db_list_head = NULL; db_list_tail = NULL; cw_mutex_unlock(&db_list_lock); while ( item && !err ) { retry_0: cw_log(LOG_DEBUG, "SQL [%s]\n", item->sql); res = sqlite3_exec(db, item->sql, NULL, NULL, &zErr ); if (zErr) { if (retry >= SQL_MAX_RETRIES) { cw_log(LOG_ERROR, "SQL ERR Query: [%s] Error: [%s] Retries: %d Max: %d\n", item->sql, zErr, retry, SQL_MAX_RETRIES); sqlite3_free(zErr); } else { cw_log(LOG_DEBUG, "SQL ERR Query: %s Error: [%s] Retries %d\n", item->sql, zErr, ++retry); sqlite3_free(zErr); usleep(SQL_RETRY_USEC); goto retry_0; } err++; } item = item->next; } if ( err ) { // Requeue EVERYTHING // find the tail of our tmpqueue item = tmplist; while ( item->next ) item = item->next; cw_mutex_lock(&db_list_lock); //Put the actual queue at our end and restore the old queue item->next = db_list_head; db_list_head = tmplist; cw_mutex_unlock(&db_list_lock); sqlite3_exec(db,"ROLLBACK",NULL,NULL,0); cw_log(LOG_DEBUG,"Rollback\n"); res = -1; } else { // Unqueue all items and FREE item = tmplist; while ( item ) { tmpitem = item; item = item->next; free ( tmpitem->sql ); free ( tmpitem ); } sqlite3_exec(db,"COMMIT",NULL,NULL,0); cw_log(LOG_DEBUG,"Commit\n"); res = 0; } sqlite3_close(db); return res; }