45#define BUSY_TIMEOUT_MS 1000
52#define LOG_SQLITE(db, level, cmd) do { GNUNET_log_from (level, \
53 "peerstore-sqlite", _ ( \
54 "`%s' failed at %s:%d with error: %s\n"), \
61#define LOG(kind, ...) GNUNET_log_from (kind, "peerstore-sqlite", __VA_ARGS__)
133 const char *sub_system,
138 sqlite3_stmt *stmt =
plugin->delete_peerstoredata;
192 sqlite3_stmt *stmt =
plugin->expire_peerstoredata;
209 if (SQLITE_DONE != sqlite3_step (stmt))
220 sqlite3_changes (
plugin->dbh));
243 const char *sub_system,
260 "Executing iterate request on sqlite db.\n");
272 stmt =
plugin->select_peerstoredata;
286 stmt =
plugin->select_peerstoredata_by_key;
303 stmt =
plugin->select_peerstoredata_by_pid;
318 stmt =
plugin->select_peerstoredata_by_all;
328 "sqlite3_bind_XXXX");
336 for (uint64_t i = 0; i < limit; i++)
338 sret = sqlite3_step (stmt);
339 if (SQLITE_DONE == sret)
342 "Iteration done (no results)\n");
346 if (SQLITE_ROW != sret)
365 "Returning a matched record.\n");
407 const char *sub_system,
436 stmt =
plugin->insert_peerstoredata;
446 if (SQLITE_DONE != sqlite3_step (stmt))
474 result = sqlite3_exec (dbh,
480 "Executed `%s' / %d\n",
485 _ (
"Error executing SQL query: %s\n %s\n"),
486 sqlite3_errmsg (dbh),
508 result = sqlite3_prepare_v2 (dbh,
512 (
const char **) &tail);
514 "Prepared `%s' / %p: %d\n",
520 _ (
"Error preparing SQL query: %s\n %s\n"),
521 sqlite3_errmsg (dbh),
563 if (SQLITE_OK != sqlite3_open (
plugin->fn,
567 _ (
"Unable to initialize SQLite: %s.\n"),
568 sqlite3_errmsg (
plugin->dbh));
572 "PRAGMA temp_store=MEMORY");
574 "PRAGMA synchronous=OFF");
576 "PRAGMA legacy_file_format=OFF");
578 "PRAGMA auto_vacuum=INCREMENTAL");
580 "PRAGMA encoding=\"UTF-8\"");
582 "PRAGMA page_size=4096");
583 sqlite3_busy_timeout (
plugin->dbh,
587 "CREATE TABLE IF NOT EXISTS peerstoredata (\n"
588 " uid INTEGER PRIMARY KEY,"
589 " sub_system TEXT NOT NULL,\n"
590 " peer_id BLOB NOT NULL,\n"
591 " key TEXT NOT NULL,\n"
592 " value BLOB NULL,\n"
593 " expiry INT8 NOT NULL" ");");
596 sqlite3_exec (
plugin->dbh,
597 "CREATE INDEX IF NOT EXISTS peerstoredata_key_index ON peerstoredata (sub_system, peer_id, key, uid)",
603 _ (
"Unable to create indices: %s.\n"),
604 sqlite3_errmsg (
plugin->dbh));
610 "INSERT INTO peerstoredata (sub_system, peer_id, key, value, expiry)"
611 " VALUES (?,?,?,?,?);",
612 &
plugin->insert_peerstoredata);
614 "SELECT uid,sub_system,peer_id,key,value,expiry FROM peerstoredata"
615 " WHERE sub_system = ?"
619 &
plugin->select_peerstoredata);
621 "SELECT uid,sub_system,peer_id,key,value,expiry FROM peerstoredata"
622 " WHERE sub_system = ?"
627 &
plugin->select_peerstoredata_by_pid);
629 "SELECT uid,sub_system,peer_id,key,value,expiry FROM peerstoredata"
630 " WHERE sub_system = ?"
635 &
plugin->select_peerstoredata_by_key);
637 "SELECT uid,sub_system,peer_id,key,value,expiry FROM peerstoredata"
638 " WHERE sub_system = ?"
644 &
plugin->select_peerstoredata_by_all);
646 "DELETE FROM peerstoredata"
648 &
plugin->expire_peerstoredata);
650 "DELETE FROM peerstoredata"
651 " WHERE sub_system = ?"
652 " AND peer_id = ?" " AND key = ?",
653 &
plugin->delete_peerstoredata);
669 while (NULL != (stmt = sqlite3_next_stmt (
plugin->dbh,
672 result = sqlite3_finalize (stmt);
675 "Failed to close statement %p: %d\n",
679 if (SQLITE_OK != sqlite3_close (
plugin->dbh))
719 "Sqlite plugin is running\n");
742 "Sqlite plugin is finished\n");
struct GNUNET_GETOPT_CommandLineOption options[]
static int ret
Final status code.
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
static struct GNUNET_TESTING_PluginFunctions * plugin
Plugin to dynamically load a test case.
struct GNUNET_HashCode key
The key used in the DHT.
static char * value
Value of the record to add/remove.
static int result
Global testing status.
Plugin API for the peerstore database backend.
API to the peerstore service.
helper functions for Sqlite3 DB interactions
struct GNUNET_SQ_QueryParam GNUNET_SQ_query_param_fixed_size(const void *ptr, size_t ptr_size)
Generate query parameter for a buffer ptr of ptr_size bytes.
enum GNUNET_GenericReturnValue GNUNET_SQ_extract_result(sqlite3_stmt *result, struct GNUNET_SQ_ResultSpec *rs)
Extract results from a query result according to the given specification.
void GNUNET_SQ_cleanup_result(struct GNUNET_SQ_ResultSpec *rs)
Free all memory that was allocated in rs during GNUNET_SQ_extract_result().
struct GNUNET_SQ_ResultSpec GNUNET_SQ_result_spec_string(char **dst)
0-terminated string expected.
struct GNUNET_SQ_QueryParam GNUNET_SQ_query_param_uint64(const uint64_t *x)
Generate query parameter for an uint16_t in host byte order.
struct GNUNET_SQ_ResultSpec GNUNET_SQ_result_spec_absolute_time(struct GNUNET_TIME_Absolute *at)
Absolute time expected.
struct GNUNET_SQ_QueryParam GNUNET_SQ_query_param_absolute_time(const struct GNUNET_TIME_Absolute *x)
Generate query parameter for an absolute time value.
#define GNUNET_SQ_result_spec_end
End of result parameter specification.
struct GNUNET_SQ_ResultSpec GNUNET_SQ_result_spec_variable_size(void **dst, size_t *sptr)
Variable-size result expected.
#define GNUNET_SQ_query_param_auto_from_type(x)
Generate fixed-size query parameter with size determined by variable type.
enum GNUNET_GenericReturnValue GNUNET_SQ_bind(sqlite3_stmt *stmt, const struct GNUNET_SQ_QueryParam *params)
Execute binding operations for a prepared statement.
void GNUNET_SQ_reset(sqlite3 *dbh, sqlite3_stmt *stmt)
Reset stmt and log error.
#define GNUNET_SQ_query_param_end
End of query parameter specification.
struct GNUNET_SQ_QueryParam GNUNET_SQ_query_param_string(const char *ptr)
Generate query parameter for a string.
#define GNUNET_SQ_result_spec_auto_from_type(dst)
We expect a fixed-size result, with size determined by the type of * dst
struct GNUNET_SQ_ResultSpec GNUNET_SQ_result_spec_uint64(uint64_t *u64)
uint64_t expected.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_filename(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be the name of a file or directory.
enum GNUNET_GenericReturnValue GNUNET_DISK_file_test(const char *fil)
Check that fil corresponds to a filename (of a file that exists and that is not a directory).
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create_for_file(const char *filename)
Create the directory structure for storing a file.
#define GNUNET_log(kind,...)
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
void(* GNUNET_PEERSTORE_PluginProcessor)(void *cls, uint64_t seq, const struct GNUNET_PEERSTORE_Record *record, const char *emsg)
Function called by PEERSTORE for each matching record.
GNUNET_PEERSTORE_StoreOption
Options for storing values in PEERSTORE.
void(* GNUNET_PEERSTORE_Continuation)(void *cls, int success)
Continuation called with a status result.
@ GNUNET_PEERSTORE_STOREOPTION_REPLACE
Delete any previous values for the given key before storing the given value.
static unsigned int size
Size of the "table".
#define BUSY_TIMEOUT_MS
After how many ms "busy" should a DB operation fail for good? A low value makes sure that we are more...
static int sql_prepare(sqlite3 *dbh, const char *sql, sqlite3_stmt **stmt)
Prepare a SQL statement.
static int peerstore_sqlite_store_record(void *cls, const char *sub_system, const struct GNUNET_PeerIdentity *peer, const char *key, const void *value, size_t size, struct GNUNET_TIME_Absolute expiry, enum GNUNET_PEERSTORE_StoreOption options, GNUNET_PEERSTORE_Continuation cont, void *cont_cls)
Store a record in the peerstore.
#define LOG_SQLITE(db, level, cmd)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' on file 'file...
static int peerstore_sqlite_expire_records(void *cls, struct GNUNET_TIME_Absolute now, GNUNET_PEERSTORE_Continuation cont, void *cont_cls)
Delete expired records (expiry < now)
static void database_shutdown(struct Plugin *plugin)
Shutdown database connection and associate data structures.
void * libgnunet_plugin_peerstore_sqlite_done(void *cls)
Exit point from the plugin.
static int peerstore_sqlite_iterate_records(void *cls, const char *sub_system, const struct GNUNET_PeerIdentity *peer, const char *key, uint64_t serial, uint64_t limit, GNUNET_PEERSTORE_PluginProcessor iter, void *iter_cls)
Iterate over the records given an optional peer id and/or key.
static int sql_exec(sqlite3 *dbh, const char *sql)
Prepare a SQL statement.
static int peerstore_sqlite_delete_records(void *cls, const char *sub_system, const struct GNUNET_PeerIdentity *peer, const char *key)
Delete records with the given key.
static int database_setup(struct Plugin *plugin)
Initialize the database connections and associated data structures (create tables and indices as need...
void * libgnunet_plugin_peerstore_sqlite_init(void *cls)
Entry point for the plugin.
void * cls
Closure for all of the callbacks.
struct returned by the initialization function of the plugin
void * cls
Closure to pass to all plugin functions.
int(* iterate_records)(void *cls, const char *sub_system, const struct GNUNET_PeerIdentity *peer, const char *key, uint64_t serial, uint64_t limit, GNUNET_PEERSTORE_PluginProcessor iter, void *iter_cls)
Iterate over the records given an optional peer id and/or key.
int(* store_record)(void *cls, const char *sub_system, const struct GNUNET_PeerIdentity *peer, const char *key, const void *value, size_t size, struct GNUNET_TIME_Absolute expiry, enum GNUNET_PEERSTORE_StoreOption options, GNUNET_PEERSTORE_Continuation cont, void *cont_cls)
Store a record in the peerstore.
int(* expire_records)(void *cls, struct GNUNET_TIME_Absolute now, GNUNET_PEERSTORE_Continuation cont, void *cont_cls)
Delete expired records (expiry < now)
size_t value_size
Size of value BLOB.
struct GNUNET_PeerIdentity peer
Peer Identity.
void * value
Record value BLOB.
struct GNUNET_TIME_Absolute expiry
Expiry time of entry.
char * sub_system
Responsible sub system string.
char * key
Record key string.
The identity of the host (wraps the signing key of the peer).
Description of a DB query parameter.
Description of a DB result cell.
void * cls
Closure for conv and cleaner.
Time for absolute times used by GNUnet, in microseconds.
struct GNUNET_BLOCK_PluginFunctions * api
Plugin API.
sqlite3_stmt * expire_peerstoredata
Precompiled SQL for deleting expired records from peerstoredata.
sqlite3_stmt * insert_peerstoredata
Precompiled SQL for inserting into peerstoredata.
char * fn
Filename used for the DB.
sqlite3_stmt * select_peerstoredata
Precompiled SQL for selecting from peerstoredata.
struct GNUNET_PQ_Context * dbh
Native Postgres database handle.
const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
sqlite3_stmt * select_peerstoredata_by_all
Precompiled SQL for selecting from peerstoredata.
sqlite3_stmt * delete_peerstoredata
Precompiled SQL for deleting records with given key.
sqlite3_stmt * select_peerstoredata_by_key
Precompiled SQL for selecting from peerstoredata.
sqlite3_stmt * select_peerstoredata_by_pid
Precompiled SQL for selecting from peerstoredata.