⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kv_sqlite.c

📁 GNUnet是一个安全的点对点网络框架
💻 C
📖 第 1 页 / 共 2 页
字号:
      sprintf (create,               "CREATE TABLE %s (gn_key BLOB, gn_val BLOB, gn_age BIGINT)",               table);      if (sqlite3_exec (dbh->dbh, create, NULL, NULL, NULL) != SQLITE_OK)        {          LOG_SQLITE (dbh->dbh, LOG_ERROR, "sqlite_create");          sqlite3_finalize (stmt);          GNUNET_free (create);          return NULL;        }      GNUNET_free (create);    }  sqlite3_finalize (stmt);  /* FIXME: more indexes */  idx = GNUNET_malloc (len + 34);  sprintf (idx, "CREATE INDEX idx_key ON %s (gn_key)", table);  sqlite3_exec (dbh->dbh, idx, NULL, NULL, NULL);  GNUNET_free (idx);  ret = GNUNET_malloc (sizeof (GNUNET_KeyValueRecord));  ret->table = GNUNET_strdup (table);  ret->db = GNUNET_strdup (database);  return ret;}/** * @brief Get data from a Key/Value-Table * @param kv handle to the table * @param key the key to retrieve * @param keylen length of the key * @param sort 0 = dont, sort, 1 = random, 2 = sort by age * @param limit limit result set to n rows * @param handler callback function to be called for every result (may be NULL) * @param closure optional parameter for handler */static void *get (GNUNET_KeyValueRecord * kv,     void *key,     int keylen,     unsigned int sort, unsigned int limit, GNUNET_KeyValueProcessor handler,     void *closure){  unsigned int len, enclen, retlen;  char *sel, *order, *where, limit_spec[30];  sqlite3_stmt *stmt;  void *ret;  sqliteHandle *dbh;  unsigned char *key_enc;  void *ret_dec;  dbh = getDBHandle (kv->db);  if (dbh == NULL)    return NULL;  ret = NULL;  ret_dec = NULL;  len = strlen (kv->table);  sel = GNUNET_malloc (len + 45);  if (key)    {      where = "WHERE gn_key = ?";      key_enc = GNUNET_malloc (keylen * 2 + 1);      enclen = sqlite_encode_binary (key, keylen, key_enc);    }  else    {      where = "";      key_enc = NULL;      enclen = 0;               /* make gcc happy */    }  switch (sort)    {    case 1:      order = "BY RANDOM()";      break;    case 2:      order = "BY gn_age desc";      break;    default:      order = "";      break;    }  if (limit != 0)    sprintf (limit_spec, "LIMIT %u", limit);  else    *limit_spec = 0;  sprintf (sel,           "SELECT gn_val FROM %s %s %s %s",           kv->table, where, order, limit_spec);  sq_prepare (dbh, sel, &stmt);  if (key)    sqlite3_bind_blob (stmt, 1, key_enc, enclen, SQLITE_STATIC);  while (sqlite3_step (stmt) == SQLITE_ROW)    {      retlen = sqlite3_column_bytes (stmt, 0);      ret = (void *) sqlite3_column_blob (stmt, 0);      /* free previous result, only the last in the result set         is returned to the caller */      GNUNET_free_non_null (ret_dec);      ret_dec = GNUNET_malloc (retlen);      retlen = sqlite_decode_binary_n (ret, ret_dec, retlen);      if (handler)        if (handler (closure, ret, retlen) != GNUNET_OK)          {            GNUNET_free (sel);            GNUNET_free_non_null (key_enc);            GNUNET_free (ret_dec);            sqlite3_finalize (stmt);            return ret;          }    }  sqlite3_finalize (stmt);  GNUNET_free (sel);  GNUNET_free_non_null (key_enc);  return ret_dec;}/** * @brief Store Key/Value-Pair in a table * @param kv handle to the table * @param key key of the pair * @param keylen length of the key (int because of SQLite!) * @param val value of the pair * @param vallen length of the value (int because of SQLite!) * @param optional creation time * @return GNUNET_OK on success, GNUNET_SYSERR otherwise */static intput (GNUNET_KeyValueRecord * kv, void *key, int keylen, void *val, int vallen,     unsigned long long age){  unsigned int len;  char *ins;  sqlite3_stmt *stmt;  sqliteHandle *dbh;  unsigned char *key_enc, *val_enc;  unsigned int keyenc_len, valenc_len;  dbh = getDBHandle (kv->db);  if (dbh == NULL)    return GNUNET_SYSERR;  len = strlen (kv->table);  ins = GNUNET_malloc (len + 68);  sprintf (ins,           "INSERT INTO %s(gn_key, gn_val, gn_age) values (?, ?, ?)",           kv->table);  key_enc = GNUNET_malloc (keylen * 2);  keyenc_len = sqlite_encode_binary (key, keylen, key_enc);  val_enc = GNUNET_malloc (vallen * 2);  valenc_len = sqlite_encode_binary (val, vallen, val_enc);  sq_prepare (dbh, ins, &stmt);  sqlite3_bind_blob (stmt, 1, key_enc, keyenc_len, SQLITE_STATIC);  sqlite3_bind_blob (stmt, 2, val_enc, valenc_len, SQLITE_STATIC);  sqlite3_bind_int64 (stmt, 3, age);  if (sqlite3_step (stmt) != SQLITE_DONE)    {      GNUNET_free (ins);      GNUNET_free (key_enc);      GNUNET_free (val_enc);      LOG_SQLITE (dbh->dbh, LOG_ERROR, "put");      sqlite3_finalize (stmt);      return GNUNET_SYSERR;    }  sqlite3_finalize (stmt);  GNUNET_free (ins);  GNUNET_free (key_enc);  GNUNET_free (val_enc);  return GNUNET_OK;}/** * @brief Delete values from a Key/Value-Table * @param key key to delete (may be NULL) * @param keylen length of the key * @param age age of the items to delete (may be 0) * @return GNUNET_OK on success, GNUNET_SYSERR otherwise */static intdel (GNUNET_KeyValueRecord * kv, void *key, int keylen,     unsigned long long age){  unsigned int len;  char *del, *key_where, *age_where;  sqlite3_stmt *stmt;  int bind;  sqliteHandle *dbh;  unsigned char *keyenc;  unsigned int keyenc_len;  dbh = getDBHandle (kv->db);  if (dbh == NULL)    return GNUNET_SYSERR;  len = strlen (kv->table);  del = GNUNET_malloc (len + 52);  bind = 1;  if (key)    key_where = "gn_key = ?";  else    key_where = "";  if (age)    age_where = "gn_age = ?";  else    age_where = "";  sprintf (del, "DELETE from %s where %s %s %s", kv->table, key_where,           age ? "or" : "", age_where);  sq_prepare (dbh, del, &stmt);  if (key)    {      keyenc = GNUNET_malloc (keylen * 2);      keyenc_len = sqlite_encode_binary (key, keylen, keyenc);      sqlite3_bind_blob (stmt, 1, keyenc, keyenc_len, SQLITE_STATIC);      bind++;    }  else    {      keyenc = NULL;    }  if (age)    sqlite3_bind_int64 (stmt, bind, age);  if (sqlite3_step (stmt) != SQLITE_DONE)    {      GNUNET_free (del);      GNUNET_free_non_null (keyenc);      LOG_SQLITE (dbh->dbh, LOG_ERROR, "delete");      sqlite3_finalize (stmt);      return GNUNET_SYSERR;    }  sqlite3_finalize (stmt);  GNUNET_free (del);  GNUNET_free_non_null (keyenc);  return GNUNET_OK;}/** * @brief Close a handle to a Key/Value-Table * @param kv the handle to close */static voidcloseTable (GNUNET_KeyValueRecord * kv){  GNUNET_free (kv->table);  GNUNET_free (kv->db);}/** * @brief Drop a Key/Value-Table * @param the handle to the table * @return GNUNET_OK on success, GNUNET_SYSERR otherwise */static intdropTable (GNUNET_KeyValueRecord * kv){  sqlite3_stmt *stmt;  sqliteHandle *dbh;  char *drop;  dbh = getDBHandle (kv->db);  if (dbh == NULL)    return GNUNET_SYSERR;  drop = GNUNET_malloc (12 + strlen (kv->table));  sprintf (drop, "DROP TABLE %s", kv->table);  sq_prepare (dbh, drop, &stmt);  if (sqlite3_step (stmt) != SQLITE_DONE)    {      GNUNET_free (drop);      LOG_SQLITE (dbh->dbh, LOG_ERROR, "drop");      sqlite3_finalize (stmt);      return GNUNET_SYSERR;    }  sqlite3_finalize (stmt);  GNUNET_free (drop);  closeTable (kv);  return GNUNET_OK;}GNUNET_KVstore_ServiceAPI *provide_module_kvstore_sqlite (GNUNET_CoreAPIForPlugins * capi){  static GNUNET_KVstore_ServiceAPI api;  ectx = capi->ectx;#if DEBUG_SQLITE  GNUNET_GE_LOG (ectx,                 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,                 "KV-SQLite: initializing database\n");#endif  lock = GNUNET_mutex_create (GNUNET_NO);  coreAPI = capi;  api.closeTable = &closeTable;  api.del = &del;  api.get = &get;  api.getTable = &getTable;  api.put = &put;  api.dropTable = dropTable;  api.dropDatabase = dropDatabase;  return &api;}/** * Shutdown the module. */voidrelease_module_kvstore_sqlite (){  unsigned int idx;  for (idx = 0; idx < databases; idx++)    close_database (dbs[idx]);  GNUNET_array_grow (dbs, databases, 0);#if DEBUG_SQLITE  GNUNET_GE_LOG (ectx,                 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,                 "SQLite KVStore: database shutdown\n");#endif  GNUNET_mutex_destroy (lock);  coreAPI = NULL;}/* end of kv_sqlite.c */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -