/**
 * Entry point for the plugin.
 *
 * @param cls the "struct GNUNET_DATASTORE_PluginEnvironment*"
 * @return NULL on error, othrewise the plugin context
 */
void *
libgnunet_plugin_datastore_sqlite_init (void *cls)
{
  static struct Plugin plugin;
  struct GNUNET_DATASTORE_PluginEnvironment *env = cls;
  struct GNUNET_DATASTORE_PluginFunctions *api;

  if (plugin.env != NULL)
    return NULL;                /* can only initialize once! */
  memset (&plugin, 0, sizeof (struct Plugin));
  plugin.env = env;
  if (GNUNET_OK != database_setup (env->cfg, &plugin))
  {
    database_shutdown (&plugin);
    return NULL;
  }
  api = GNUNET_malloc (sizeof (struct GNUNET_DATASTORE_PluginFunctions));
  api->cls = &plugin;
  api->estimate_size = &sqlite_plugin_estimate_size;
  api->put = &sqlite_plugin_put;
  api->update = &sqlite_plugin_update;
  api->get_key = &sqlite_plugin_get_key;
  api->get_replication = &sqlite_plugin_get_replication;
  api->get_expiration = &sqlite_plugin_get_expiration;
  api->get_zero_anonymity = &sqlite_plugin_get_zero_anonymity;
  api->get_keys = &sqlite_plugin_get_keys;
  api->drop = &sqlite_plugin_drop;
  GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "sqlite",
                   _("Sqlite database running\n"));
  return api;
}
예제 #2
0
/*
** verify succesful insertion of a molecular signature into a newly created
** rdtree virtual table.
*/
int main(int argc, char *argv[])
{
  int rc = SQLITE_OK;
  char *errMsg = 0;
  sqlite3 *db = 0;
  int closedb = 1;
  int rowid_count;
  int parent_count;
  int node_count;

  char sql1[] = "select count(*) from xyz_rowid";
  char sql2[] = "select count(*) from xyz_parent";
  char sql3[] = "select count(*) from xyz_node";

  if ((rc = database_setup(":memory:", argv[1], &db, &errMsg)) != SQLITE_OK) {
    closedb = 0;
    printf("Failed database initialization\n");
  }
  else if ((rc = create_rdtree(db, "xyz", 4, &errMsg)) != SQLITE_OK) {
    printf("Failed creation of virtual rdtree table\n");
  }
  else if ((rc = insert_bitstring(db, "xyz", -1, 
				  "\x01\x02\x04\x08", 4)) != SQLITE_OK) {
    printf("Failed insertion\n");
  }
  else if ((rc = select_integer(db, sql1, &rowid_count)) != SQLITE_OK) {
    printf("Couldn't query rowid table\n");
  }
  else if ((rc = select_integer(db, sql2, &parent_count)) != SQLITE_OK) {
    printf("Couldn't query parent table\n");
  }
  else if ((rc = select_integer(db, sql3, &node_count)) != SQLITE_OK) {
    printf("Couldn't query node table\n");
  }
  else if (rowid_count != 1) {
    printf("Unexpected number of rowid records\n");
    rc = SQLITE_MISMATCH;
  }
  else if (parent_count != 0) {
    printf("Unexpected number of parent records\n");
    rc = SQLITE_MISMATCH;
  }
  else if (node_count != 1) {
    printf("Unexpected number of node records\n");
    rc = SQLITE_MISMATCH;
  }

  if (closedb) {
    int rc2 = sqlite3_close(db);
    if (SQLITE_OK == rc) { rc = rc2; }
  }

  if (errMsg) {
    printf("%s\n", errMsg);
    sqlite3_free(errMsg);
  }

  return rc;
}
예제 #3
0
/**
 * Entry point for the plugin.
 *
 * @param cls The struct GNUNET_CONFIGURATION_Handle.
 * @return NULL on error, otherwise the plugin context
 */
void *
libgnunet_plugin_peerstore_sqlite_init (void *cls)
{
  static struct Plugin plugin;
  const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
  struct GNUNET_PEERSTORE_PluginFunctions *api;

  if (NULL != plugin.cfg)
    return NULL;                /* can only initialize once! */
  memset (&plugin, 0, sizeof (struct Plugin));
  plugin.cfg = cfg;
  if (GNUNET_OK != database_setup (&plugin))
  {
    database_shutdown (&plugin);
    return NULL;
  }
  api = GNUNET_new (struct GNUNET_PEERSTORE_PluginFunctions);
  api->cls = &plugin;
  api->store_record = &peerstore_sqlite_store_record;
  api->iterate_records = &peerstore_sqlite_iterate_records;
  api->expire_records = &peerstore_sqlite_expire_records;
  LOG (GNUNET_ERROR_TYPE_DEBUG, "Sqlite plugin is running\n");
  return api;
}
예제 #4
0
/**
 * Entry point for the plugin.
 *
 * @param cls the "struct GNUNET_NAMECACHE_PluginEnvironment*"
 * @return NULL on error, otherwise the plugin context
 */
void *
libgnunet_plugin_namecache_sqlite_init (void *cls)
{
  static struct Plugin plugin;
  const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
  struct GNUNET_NAMECACHE_PluginFunctions *api;

  if (NULL != plugin.cfg)
    return NULL;                /* can only initialize once! */
  memset (&plugin, 0, sizeof (struct Plugin));
  plugin.cfg = cfg;
  if (GNUNET_OK != database_setup (&plugin))
  {
    database_shutdown (&plugin);
    return NULL;
  }
  api = GNUNET_new (struct GNUNET_NAMECACHE_PluginFunctions);
  api->cls = &plugin;
  api->cache_block = &namecache_sqlite_cache_block;
  api->lookup_block = &namecache_sqlite_lookup_block;
  LOG (GNUNET_ERROR_TYPE_INFO,
       _("Sqlite database running\n"));
  return api;
}
/**
 * Execute statement that gets a row and call the callback
 * with the result.  Resets the statement afterwards.
 *
 * @param plugin the plugin
 * @param stmt the statement
 * @param proc processor to call
 * @param proc_cls closure for 'proc'
 */
static void
execute_get (struct Plugin *plugin, sqlite3_stmt * stmt,
             PluginDatumProcessor proc, void *proc_cls)
{
  int n;
  struct GNUNET_TIME_Absolute expiration;
  unsigned long long rowid;
  unsigned int size;
  int ret;

  n = sqlite3_step (stmt);
  switch (n)
  {
  case SQLITE_ROW:
    size = sqlite3_column_bytes (stmt, 5);
    rowid = sqlite3_column_int64 (stmt, 6);
    if (sqlite3_column_bytes (stmt, 4) != sizeof (GNUNET_HashCode))
    {
      GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, "sqlite",
                       _
                       ("Invalid data in database.  Trying to fix (by deletion).\n"));
      if (SQLITE_OK != sqlite3_reset (stmt))
        LOG_SQLITE (plugin, NULL,
                    GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
                    "sqlite3_reset");
      if (GNUNET_OK == delete_by_rowid (plugin, rowid))
        plugin->env->duc (plugin->env->cls,
                          -(size + GNUNET_DATASTORE_ENTRY_OVERHEAD));
      break;
    }
    expiration.abs_value = sqlite3_column_int64 (stmt, 3);
    GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite",
                     "Found reply in database with expiration %llu\n",
                     (unsigned long long) expiration.abs_value);
    ret = proc (proc_cls, sqlite3_column_blob (stmt, 4) /* key */ ,
                size, sqlite3_column_blob (stmt, 5) /* data */ ,
                sqlite3_column_int (stmt, 0) /* type */ ,
                sqlite3_column_int (stmt, 1) /* priority */ ,
                sqlite3_column_int (stmt, 2) /* anonymity */ ,
                expiration, rowid);
    if (SQLITE_OK != sqlite3_reset (stmt))
      LOG_SQLITE (plugin, NULL,
                  GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
                  "sqlite3_reset");
    if ((GNUNET_NO == ret) && (GNUNET_OK == delete_by_rowid (plugin, rowid)))
      plugin->env->duc (plugin->env->cls,
                        -(size + GNUNET_DATASTORE_ENTRY_OVERHEAD));
    return;
  case SQLITE_DONE:
    /* database must be empty */
    if (SQLITE_OK != sqlite3_reset (stmt))
      LOG_SQLITE (plugin, NULL,
                  GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
                  "sqlite3_reset");
    break;
  case SQLITE_BUSY:
  case SQLITE_ERROR:
  case SQLITE_MISUSE:
  default:
    LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
                "sqlite3_step");
    if (SQLITE_OK != sqlite3_reset (stmt))
      LOG_SQLITE (plugin, NULL,
                  GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
                  "sqlite3_reset");
    GNUNET_break (0);
    database_shutdown (plugin);
    database_setup (plugin->env->cfg, plugin);
    break;
  }
  if (SQLITE_OK != sqlite3_reset (stmt))
    LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
                "sqlite3_reset");
  proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
}
/**
 * Store an item in the datastore.
 *
 * @param cls closure
 * @param key key for the item
 * @param size number of bytes in data
 * @param data content stored
 * @param type type of the content
 * @param priority priority of the content
 * @param anonymity anonymity-level for the content
 * @param replication replication-level for the content
 * @param expiration expiration time for the content
 * @param msg set to an error message
 * @return GNUNET_OK on success
 */
static int
sqlite_plugin_put (void *cls, const GNUNET_HashCode * key, uint32_t size,
                   const void *data, enum GNUNET_BLOCK_Type type,
                   uint32_t priority, uint32_t anonymity, uint32_t replication,
                   struct GNUNET_TIME_Absolute expiration, char **msg)
{
  struct Plugin *plugin = cls;
  int n;
  int ret;
  sqlite3_stmt *stmt;
  GNUNET_HashCode vhash;
  uint64_t rvalue;

  if (size > MAX_ITEM_SIZE)
    return GNUNET_SYSERR;
  GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite",
                   "Storing in database block with type %u/key `%s'/priority %u/expiration in %llu ms (%lld).\n",
                   type, GNUNET_h2s (key), priority,
                   (unsigned long long)
                   GNUNET_TIME_absolute_get_remaining (expiration).rel_value,
                   (long long) expiration.abs_value);
  GNUNET_CRYPTO_hash (data, size, &vhash);
  stmt = plugin->insertContent;
  rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX);
  if ((SQLITE_OK != sqlite3_bind_int (stmt, 1, replication)) ||
      (SQLITE_OK != sqlite3_bind_int (stmt, 2, type)) ||
      (SQLITE_OK != sqlite3_bind_int (stmt, 3, priority)) ||
      (SQLITE_OK != sqlite3_bind_int (stmt, 4, anonymity)) ||
      (SQLITE_OK != sqlite3_bind_int64 (stmt, 5, expiration.abs_value)) ||
      (SQLITE_OK != sqlite3_bind_int64 (stmt, 6, rvalue)) ||
      (SQLITE_OK !=
       sqlite3_bind_blob (stmt, 7, key, sizeof (GNUNET_HashCode),
                          SQLITE_TRANSIENT)) ||
      (SQLITE_OK !=
       sqlite3_bind_blob (stmt, 8, &vhash, sizeof (GNUNET_HashCode),
                          SQLITE_TRANSIENT)) ||
      (SQLITE_OK != sqlite3_bind_blob (stmt, 9, data, size, SQLITE_TRANSIENT)))
  {
    LOG_SQLITE (plugin, msg, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
                "sqlite3_bind_XXXX");
    if (SQLITE_OK != sqlite3_reset (stmt))
      LOG_SQLITE (plugin, NULL,
                  GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
                  "sqlite3_reset");
    return GNUNET_SYSERR;
  }
  n = sqlite3_step (stmt);
  switch (n)
  {
  case SQLITE_DONE:
    plugin->env->duc (plugin->env->cls, size + GNUNET_DATASTORE_ENTRY_OVERHEAD);
    GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite",
                     "Stored new entry (%u bytes)\n",
                     size + GNUNET_DATASTORE_ENTRY_OVERHEAD);
    ret = GNUNET_OK;
    break;
  case SQLITE_BUSY:
    GNUNET_break (0);
    LOG_SQLITE (plugin, msg, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
                "sqlite3_step");
    ret = GNUNET_SYSERR;
    break;
  default:
    LOG_SQLITE (plugin, msg, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
                "sqlite3_step");
    if (SQLITE_OK != sqlite3_reset (stmt))
      LOG_SQLITE (plugin, NULL,
                  GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
                  "sqlite3_reset");
    database_shutdown (plugin);
    database_setup (plugin->env->cfg, plugin);
    return GNUNET_SYSERR;
  }
  if (SQLITE_OK != sqlite3_reset (stmt))
    LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
                "sqlite3_reset");
  return ret;
}