32#define LOG(kind, ...) GNUNET_log_from (kind, "datacache-sqlite", __VA_ARGS__)
34#define LOG_STRERROR_FILE(kind, op, fn) \
35 GNUNET_log_from_strerror_file (kind, "datacache-sqlite", op, fn)
42#define OVERHEAD (sizeof(struct GNUNET_HashCode) + 36)
124#define LOG_SQLITE(db, level, cmd) \
128 _ ("`%s' failed at %s:%d with error: %s\n"), \
132 sqlite3_errmsg (db)); \
142#define SQLITE3_EXEC(db, cmd) \
147 sqlite3_exec (db, cmd, NULL, NULL, &emsg)) \
149 LOG (GNUNET_ERROR_TYPE_ERROR, \
150 _ ("`%s' failed at %s:%d with error: %s\n"), \
155 sqlite3_free (emsg); \
171 sqlite3_stmt **ppStmt)
175 return sqlite3_prepare (dbh,
179 (
const char **) &
dummy);
193 uint32_t xor_distance,
197 uint32_t type32 = (uint32_t) block->
type;
198 uint32_t ro32 = (uint32_t) block->
ro;
215 "Processing PUT of %u bytes with key `%s' and expiration %s\n",
234 sqlite3_step (
plugin->insert_stmt))
302 "Processing GET for key `%s'\n",
313 plugin->get_count_any_stmt);
317 sqlite3_step (
plugin->get_count_any_stmt))
323 plugin->get_count_any_stmt);
325 "No content found when processing GET for key `%s'\n",
329 total = sqlite3_column_int (
plugin->get_count_any_stmt,
332 plugin->get_count_any_stmt);
338 "No content found when processing GET for key `%s'\n",
349 off = (off + 1) % total;
362 sqlite3_step (
plugin->get_any_stmt))
386 "Found %u-byte result when processing GET for key `%s'\n",
427 uint32_t type32 =
type;
463 "Processing GET for key `%s'\n",
478 sqlite3_step (
plugin->get_count_stmt))
486 "No content found when processing GET for key `%s'\n",
490 total = sqlite3_column_int (
plugin->get_count_stmt,
499 "No content found when processing GET for key `%s'\n",
510 off = (off + 1) % total;
523 sqlite3_step (
plugin->get_stmt))
547 "Found %u-byte result when processing GET for key `%s'\n",
550 if ( (NULL != iter) &&
644 plugin->del_expired_stmt);
648 sqlite3_step (
plugin->del_expired_stmt)) ||
654 plugin->del_expired_stmt);
656 sqlite3_step (
plugin->del_select_stmt))
690 sqlite3_step (
plugin->del_stmt))
727 unsigned int num_results,
732 uint32_t type32 =
type;
733 uint32_t num_results32 = num_results;
764 "Processing GET_CLOSEST for key `%s'\n",
774 plugin->get_closest_stmt);
779 sqlite3_step (
plugin->get_closest_stmt))
802 "Found %u-byte result at %s when processing GET_CLOSE\n",
816 plugin->get_closest_stmt);
846 sqlite3_open (
":memory:",
862 sqlite3_open (fn_utf8,
884 "CREATE TABLE ds180 ("
885 " type INTEGER NOT NULL DEFAULT 0,"
886 " ro INTEGER NOT NULL DEFAULT 0,"
887 " expire INTEGER NOT NULL,"
888 " key BLOB NOT NULL DEFAULT '',"
889 " prox INTEGER NOT NULL,"
890 " value BLOB NOT NULL,"
891 " trunc BLOB NOT NULL,"
892 " path BLOB DEFAULT '')");
894 "CREATE INDEX idx_hashidx"
895 " ON ds180 (key,type,expire)");
897 "CREATE INDEX idx_prox_expire"
898 " ON ds180 (prox,expire)");
900 "CREATE INDEX idx_expire_only"
901 " ON ds180 (expire)");
910 " (type, ro, expire, key, prox, value, path, trunc)"
911 " VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
915 "SELECT COUNT(*) FROM ds180 "
919 &
plugin->get_count_stmt)) ||
922 "SELECT COUNT(*) FROM ds180 "
923 "WHERE key=? AND expire >= ?",
924 &
plugin->get_count_any_stmt)) ||
927 "SELECT value,expire,path,trunc,ro"
936 "SELECT value,expire,path,trunc,type,ro"
941 &
plugin->get_any_stmt)) ||
944 "SELECT _ROWID_,key,value FROM ds180"
946 " ORDER BY expire ASC LIMIT 1",
947 &
plugin->del_expired_stmt)) ||
950 "SELECT _ROWID_,key,value FROM ds180"
951 " ORDER BY prox ASC, expire ASC LIMIT 1",
952 &
plugin->del_select_stmt)) ||
955 "DELETE FROM ds180 WHERE _ROWID_=?",
960 " SELECT value,expire,path,trunc,type,ro,key"
964 " AND ( (type=?3) or (0 == ?3) )"
965 " ORDER BY KEY ASC LIMIT ?4)"
968 " SELECT value,expire,path,trunc,type,ro,key"
972 " AND ( (type=?3) or (0 == ?3) )"
973 " ORDER BY KEY DESC LIMIT ?4)",
974 &
plugin->get_closest_stmt)))
980 sqlite3_close (
plugin->dbh));
992 "Sqlite datacache running\n");
1012#if SQLITE_VERSION_NUMBER >= 3007000
1016#if ! WINDOWS || defined(__CYGWIN__)
1017 if ( (NULL !=
plugin->fn) &&
1018 (0 != unlink (
plugin->fn)) )
1024 sqlite3_finalize (
plugin->insert_stmt);
1025 sqlite3_finalize (
plugin->get_count_stmt);
1026 sqlite3_finalize (
plugin->get_count_any_stmt);
1027 sqlite3_finalize (
plugin->get_stmt);
1028 sqlite3_finalize (
plugin->get_any_stmt);
1029 sqlite3_finalize (
plugin->del_select_stmt);
1030 sqlite3_finalize (
plugin->del_expired_stmt);
1031 sqlite3_finalize (
plugin->del_stmt);
1032 sqlite3_finalize (
plugin->get_closest_stmt);
1034#if SQLITE_VERSION_NUMBER >= 3007000
1035 if (SQLITE_BUSY ==
result)
1039 "Tried to close sqlite without finalizing all prepared statements.\n"));
1040 stmt = sqlite3_next_stmt (
plugin->dbh,
1042 while (NULL != stmt)
1044 result = sqlite3_finalize (stmt);
1047 "Failed to close statement %p: %d\n",
1050 stmt = sqlite3_next_stmt (
plugin->dbh,
struct GNUNET_MQ_Envelope * env
static struct GNUNET_TESTING_PluginFunctions * plugin
Plugin to dynamically load a test case.
static char * data
The data to insert into the dht.
struct GNUNET_HashCode key
The key used in the DHT.
static struct in_addr dummy
Target "dummy" address of the packet we pretend to respond to.
static uint32_t type
Type string converted to DNS type value.
static size_t data_size
Number of bytes in data.
static int result
Global testing status.
API for database backends for the datacache.
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_QueryParam GNUNET_SQ_query_param_uint32(const uint32_t *x)
Generate query parameter for an uint32_t in host byte order.
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_ResultSpec GNUNET_SQ_result_spec_uint32(uint32_t *u32)
uint32_t 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.
#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_yesno(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Get a configuration value that should be in a set of "YES" or "NO".
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
@ GNUNET_CRYPTO_QUALITY_WEAK
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
enum GNUNET_GenericReturnValue(* GNUNET_DATACACHE_Iterator)(void *cls, const struct GNUNET_DATACACHE_Block *block)
An iterator over a set of items stored in the datacache.
GNUNET_DHT_RouteOption
Options for routing.
char * GNUNET_DISK_mktemp(const char *t)
Create an (empty) temporary file on disk.
GNUNET_GenericReturnValue
Named constants for return values.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
static ssize_t sqlite_plugin_put(void *cls, uint32_t xor_distance, const struct GNUNET_DATACACHE_Block *block)
Store an item in the datastore.
#define OVERHEAD
How much overhead do we assume per entry in the datacache?
#define SQLITE3_EXEC(db, cmd)
Execute SQL statement.
void * libgnunet_plugin_datacache_sqlite_init(void *cls)
Entry point for the plugin.
#define LOG_SQLITE(db, level, cmd)
Log an error message at log-level level that indicates a failure of the command cmd with the error fr...
static unsigned int sqlite_plugin_get(void *cls, const struct GNUNET_HashCode *key, enum GNUNET_BLOCK_Type type, GNUNET_DATACACHE_Iterator iter, void *iter_cls)
Iterate over the results for a particular key in the datastore.
static int sq_prepare(sqlite3 *dbh, const char *zSql, sqlite3_stmt **ppStmt)
Prepare a SQL statement.
static enum GNUNET_GenericReturnValue sqlite_plugin_del(void *cls)
Delete the entry with the lowest expiration value from the datacache right now.
static unsigned int get_any(void *cls, const struct GNUNET_HashCode *key, GNUNET_DATACACHE_Iterator iter, void *iter_cls)
Iterate over the results for a particular key in the datastore.
#define LOG_STRERROR_FILE(kind, op, fn)
static unsigned int get_typed(void *cls, const struct GNUNET_HashCode *key, enum GNUNET_BLOCK_Type type, GNUNET_DATACACHE_Iterator iter, void *iter_cls)
Iterate over the results for a particular key in the datastore.
void * libgnunet_plugin_datacache_sqlite_done(void *cls)
Exit point from the plugin.
static unsigned int sqlite_plugin_get_closest(void *cls, const struct GNUNET_HashCode *key, enum GNUNET_BLOCK_Type type, unsigned int num_results, GNUNET_DATACACHE_Iterator iter, void *iter_cls)
Iterate over the results that are "close" to a particular key in the datacache.
GNUNET_BLOCK_Type
WARNING: This header is generated! In order to add DHT block types, you must register them in GANA,...
@ GNUNET_BLOCK_TYPE_ANY
Identifier for any block.
void * cls
Closure for all of the callbacks.
Information about a block stored in the datacache.
const struct GNUNET_DHT_PathElement * put_path
PUT path taken by the block, array of peer identities.
enum GNUNET_BLOCK_Type type
Type of the block.
const void * data
Actual block data.
enum GNUNET_DHT_RouteOption ro
Options for routing for the block.
struct GNUNET_PeerIdentity trunc_peer
If the path was truncated, this is the peer ID at which the path was truncated.
struct GNUNET_HashCode key
Key of the block.
size_t data_size
Number of bytes in data.
unsigned int put_path_length
Length of the put_path array.
struct GNUNET_TIME_Absolute expiration_time
When does the block expire?
The datastore service will pass a pointer to a struct of this type as the first and only argument to ...
void * cls
Closure to use for callbacks.
struct returned by the initialization function of the plugin
void * cls
Closure to pass to all plugin functions.
A (signed) path tracking a block's flow through the DHT is represented by an array of path elements,...
Description of a DB query parameter.
Description of a DB result cell.
void * cls
Closure to pass to start_testcase.
Time for absolute times used by GNUnet, in microseconds.
sqlite3 * dbh
Handle to the sqlite database.
struct GNUNET_BLOCK_PluginFunctions * api
Plugin API.
sqlite3_stmt * get_any_stmt
Prepared statement for sqlite_plugin_get.
unsigned int num_items
Number of key-value pairs in the database.
sqlite3_stmt * get_stmt
Prepared statement for sqlite_plugin_get.
sqlite3_stmt * insert_stmt
Prepared statement for sqlite_plugin_put.
sqlite3_stmt * del_select_stmt
Prepared statement for sqlite_plugin_del.
sqlite3_stmt * get_count_stmt
Prepared statement for sqlite_plugin_get.
sqlite3_stmt * del_expired_stmt
Prepared statement for sqlite_plugin_del.
char * fn
Filename used for the DB.
sqlite3_stmt * get_closest_stmt
Prepared statement for sqlite_plugin_get_closest.
sqlite3_stmt * del_stmt
Prepared statement for sqlite_plugin_del.
struct GNUNET_DATACACHE_PluginEnvironment * env
Our execution environment.
sqlite3_stmt * get_count_any_stmt
Prepared statement for sqlite_plugin_get.
struct GNUNET_PQ_Context * dbh
Native Postgres database handle.