43#define BUSY_TIMEOUT_MS 1000
51#define LOG_SQLITE(db, level, cmd) do { \
52 GNUNET_log_from (level, \
53 "namestore-sqlite", _ ( \
54 "`%s' failed at %s:%d with error: %s\n"), \
61#define LOG(kind, ...) GNUNET_log_from (kind, "namestore-sqlite", __VA_ARGS__)
147 "(zone_private_key,pkey,rvalue,record_count,record_data,"
149 " VALUES (?, ?, ?, ?, ?, ?, '')",
152 "WHERE zone_private_key=? AND label=?",
155 "SELECT uid,record_count,record_data,label,editor_hint"
157 " WHERE zone_private_key=? AND pkey=?",
160 "SELECT uid,record_count,record_data,label,editor_hint"
162 " WHERE zone_private_key=? AND uid > ?"
167 "SELECT uid,record_count,record_data,label,editor_hint,zone_private_key"
172 &
plugin->iterate_all_zones),
174 " SET editor_hint_old=x.editor_hint, editor_hint=?"
175 " WHERE zone_private_key=? AND label=?"
176 " RETURNING uid,record_count,record_data,label,editor_hint_old",
180 " FROM ns098records AS old_ns098records"
181 " WHERE ns098records.zone_private_key=? AND ns098records.label=? AND ns098records.editor_hint=?",
182 &
plugin->editor_hint_clear),
193 _ (
"Failed to setup database with: `%s'\n"),
194 sqlite3_errmsg (
plugin->dbh));
203 _ (
"Failed to setup database with: `%s'\n"),
204 sqlite3_errmsg (
plugin->dbh));
223 if (NULL !=
plugin->store_records)
224 sqlite3_finalize (
plugin->store_records);
225 if (NULL !=
plugin->delete_records)
226 sqlite3_finalize (
plugin->delete_records);
227 if (NULL !=
plugin->iterate_zone)
228 sqlite3_finalize (
plugin->iterate_zone);
229 if (NULL !=
plugin->iterate_all_zones)
230 sqlite3_finalize (
plugin->iterate_all_zones);
231 if (NULL !=
plugin->zone_to_name)
232 sqlite3_finalize (
plugin->zone_to_name);
233 if (NULL !=
plugin->lookup_label)
234 sqlite3_finalize (
plugin->lookup_label);
235 if (NULL !=
plugin->editor_hint_clear)
236 sqlite3_finalize (
plugin->editor_hint_clear);
238 if (
result == SQLITE_BUSY)
242 "Tried to close sqlite without finalizing all prepared statements.\n"));
243 stmt = sqlite3_next_stmt (
plugin->dbh,
249 "Closing statement %p\n",
251 result = sqlite3_finalize (stmt);
255 "Failed to close statement %p: %d\n",
258 stmt = sqlite3_next_stmt (
plugin->dbh,
300 for (
unsigned int i = 0; i <
rd_count; i++)
303 "Checking if `%d' is zonekey type\n",
314 "Storing delegation zone record value `%s'\n",
360 "sqlite3_bind_XXXX");
365 n = sqlite3_step (
plugin->delete_records);
371 uint32_t rd_count32 = (uint32_t)
rd_count;
388 "sqlite3_bind_XXXX");
393 n = sqlite3_step (
plugin->store_records);
452 for (uint64_t i = 0; i < limit; i++)
454 sret = sqlite3_step (stmt);
456 if (SQLITE_DONE == sret)
459 "Iteration done (no results)\n");
463 if (SQLITE_ROW != sret)
530 if (NULL != zone_key)
568 const char *editor_hint)
589 "sqlite3_bind_XXXX");
639 const char *editor_hint,
640 const char *editor_hint_replacement,
649 editor_hint_replacement),
667 "sqlite3_bind_XXXX");
669 plugin->editor_hint_clear);
672 n = sqlite3_step (
plugin->editor_hint_clear);
680 "Editor hint cleared\n");
710 const char *editor_hint,
717 return lookup_records (cls, zone, label, iter, iter_cls, editor_hint);
755 stmt =
plugin->iterate_all_zones;
768 stmt =
plugin->iterate_zone;
776 "sqlite3_bind_XXXX");
823 "sqlite3_bind_XXXX");
829 "Performing reverse lookup for `%s'\n",
854 " uid INTEGER PRIMARY KEY,"
855 " zone_private_key BLOB NOT NULL,"
857 " rvalue INT8 NOT NULL,"
858 " record_count INT NOT NULL,"
859 " record_data BLOB NOT NULL,"
860 " label TEXT NOT NULL,"
861 " editor_hint TEXT NOT NULL,"
862 " editor_hint_old TEXT"
865 "ON ns098records (zone_private_key,pkey)"),
867 "ON ns098records (zone_private_key,uid)"),
876 "Failed to setup database with: `%s'\n",
877 sqlite3_errmsg (
plugin->dbh));
898 "Failed to drop database with: `%s'\n",
899 sqlite3_errmsg (
plugin->dbh));
920 "Failed to drop database with: `%s'\n",
921 sqlite3_errmsg (
plugin->dbh));
942 "Failed to drop database with: `%s'\n",
943 sqlite3_errmsg (
plugin->dbh));
964 "Failed to drop database with: `%s'\n",
965 sqlite3_errmsg (
plugin->dbh));
983 char *sqlite_filename;
1009 if ((NULL ==
plugin->dbh) &&
1010 (SQLITE_OK != sqlite3_open (sqlite_filename,
1014 _ (
"Unable to initialize SQLite: %s.\n"),
1015 sqlite3_errmsg (
plugin->dbh));
1021 sqlite3_busy_timeout (
plugin->dbh,
1056 "Database could not be connected to.\n");
1074 _ (
"SQlite database running\n"));
1098 "SQlite plugin is finished\n");
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.
static struct GNUNET_PEERSTORE_Handle * ps
Handle to the PEERSTORE service.
static uint64_t record_count
Record count.
static char * data
The data to insert into the dht.
static char * pkey
Public key of the zone to look in, in ASCII.
static unsigned int rd_count
Number of records for currently parsed set.
static struct GNUNET_GNSRECORD_Data rd[50]
The record data under a single label.
static size_t data_size
Number of bytes in data.
static int result
Global testing status.
API that can be used to manipulate GNS record data.
Plugin API for the namestore database backend.
helper functions for Sqlite3 DB interactions
struct GNUNET_SQ_PrepareStatement GNUNET_SQ_make_prepare(const char *sql, sqlite3_stmt **pstmt)
Create a struct GNUNET_SQ_PrepareStatement
struct GNUNET_SQ_ExecuteStatement GNUNET_SQ_make_execute(const char *sql)
Create a struct GNUNET_SQ_ExecuteStatement where errors are fatal.
struct GNUNET_SQ_ExecuteStatement GNUNET_SQ_make_try_execute(const char *sql)
Create a struct GNUNET_SQ_ExecuteStatement where errors should be tolerated.
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.
#define GNUNET_SQ_PREPARE_END
Terminator for executable statement list.
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_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.
enum GNUNET_GenericReturnValue GNUNET_SQ_exec_statements(sqlite3 *dbh, const struct GNUNET_SQ_ExecuteStatement *es)
Request execution of an array of statements es from Postgres.
struct GNUNET_SQ_ResultSpec GNUNET_SQ_result_spec_uint32(uint32_t *u32)
uint32_t expected.
enum GNUNET_GenericReturnValue GNUNET_SQ_prepare(sqlite3 *dbh, const struct GNUNET_SQ_PrepareStatement *ps)
Prepare all statements given in the (NULL,NULL)-terminated array at ps.
#define GNUNET_SQ_EXECUTE_STATEMENT_END
Terminator for executable statement list.
#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_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".
uint64_t GNUNET_CRYPTO_random_u64(enum GNUNET_CRYPTO_Quality mode, uint64_t max)
Generate a random unsigned 64-bit 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_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.
const char * GNUNET_GNSRECORD_z2s(const struct GNUNET_CRYPTO_PublicKey *z)
Convert a zone to a string (for printing debug messages).
int GNUNET_GNSRECORD_records_deserialize(size_t len, const char *src, unsigned int rd_count, struct GNUNET_GNSRECORD_Data *dest)
Deserialize the given records to the given destination.
ssize_t GNUNET_GNSRECORD_records_serialize(unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd, size_t dest_size, char *dest)
Serialize the given records to the given destination buffer.
enum GNUNET_GenericReturnValue GNUNET_GNSRECORD_identity_from_data(const char *data, size_t data_size, uint32_t type, struct GNUNET_CRYPTO_PublicKey *key)
Build a #GNUNET_GNSRECORD_PublicKey from zone delegation resource record data.
ssize_t GNUNET_GNSRECORD_records_get_size(unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Calculate how many bytes we will need to serialize the given records.
enum GNUNET_GenericReturnValue GNUNET_GNSRECORD_is_zonekey_type(uint32_t type)
Check if this type is one of the supported GNS zone types.
#define GNUNET_log(kind,...)
#define GNUNET_log_from(kind, comp,...)
GNUNET_GenericReturnValue
Named constants for return values.
#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_NAMESTORE_RecordIterator)(void *cls, uint64_t serial, const char *editor_hint, const struct GNUNET_CRYPTO_PrivateKey *private_key, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Function called for each matching record.
static enum GNUNET_GenericReturnValue namestore_sqlite_lookup_records(void *cls, const struct GNUNET_CRYPTO_PrivateKey *zone, const char *label, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
Lookup records in the datastore for which we are the authority.
#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 enum GNUNET_GenericReturnValue lookup_records(void *cls, const struct GNUNET_CRYPTO_PrivateKey *zone, const char *label, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls, const char *editor_hint)
Lookup records in the datastore for which we are the authority.
static enum GNUNET_GenericReturnValue database_prepare(struct Plugin *plugin)
Initialize the database connections and associated data structures (create tables and indices as need...
static enum GNUNET_GenericReturnValue namestore_sqlite_begin_tx(void *cls)
#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 enum GNUNET_GenericReturnValue namestore_sqlite_iterate_records(void *cls, const struct GNUNET_CRYPTO_PrivateKey *zone, uint64_t serial, uint64_t limit, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
Iterate over the results for a particular key and zone in the datastore.
void * libgnunet_plugin_namestore_sqlite_done(void *cls)
Exit point from the plugin.
static enum GNUNET_GenericReturnValue namestore_sqlite_edit_records(void *cls, const char *editor_hint, const struct GNUNET_CRYPTO_PrivateKey *zone, const char *label, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
Lookup records in the datastore for which we are the authority.
static enum GNUNET_GenericReturnValue namestore_sqlite_editor_hint_clear(void *cls, const char *editor_hint, const char *editor_hint_replacement, const struct GNUNET_CRYPTO_PrivateKey *zone, const char *label)
Clear editor hint.
static enum GNUNET_GenericReturnValue get_records_and_call_iterator(struct Plugin *plugin, sqlite3_stmt *stmt, const struct GNUNET_CRYPTO_PrivateKey *zone_key, uint64_t limit, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
The given 'sqlite' statement has been prepared to be run.
static enum GNUNET_GenericReturnValue namestore_sqlite_create_tables(void *cls)
static void database_shutdown(struct Plugin *plugin)
Shutdown database connection and associate data structures.
static enum GNUNET_GenericReturnValue namestore_sqlite_drop_tables(void *cls)
static enum GNUNET_GenericReturnValue namestore_sqlite_commit_tx(void *cls)
static enum GNUNET_GenericReturnValue namestore_sqlite_store_records(void *cls, const struct GNUNET_CRYPTO_PrivateKey *zone_key, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Store a record in the datastore.
static enum GNUNET_GenericReturnValue namestore_sqlite_rollback_tx(void *cls)
void * libgnunet_plugin_namestore_sqlite_init(void *cls)
Entry point for the plugin.
static enum GNUNET_GenericReturnValue database_connect(struct Plugin *plugin)
Initialize the database connections and associated data structures (create tables and indices as need...
static enum GNUNET_GenericReturnValue namestore_sqlite_zone_to_name(void *cls, const struct GNUNET_CRYPTO_PrivateKey *zone, const struct GNUNET_CRYPTO_PublicKey *value_zone, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
Look for an existing PKEY delegation record for a given public key.
void * cls
Closure for all of the callbacks.
A private key for an identity as per LSD0001.
An identity key as per LSD0001.
struct returned by the initialization function of the plugin
enum GNUNET_GenericReturnValue(* clear_editor_hint)(void *cls, const char *editor_hint, const char *editor_hint_replacement, const struct GNUNET_CRYPTO_PrivateKey *zone, const char *label)
This clears the editor hint, unless it does not match the given editor hint, in which case this is a ...
enum GNUNET_GenericReturnValue(* zone_to_name)(void *cls, const struct GNUNET_CRYPTO_PrivateKey *zone, const struct GNUNET_CRYPTO_PublicKey *value_zone, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
Look for an existing PKEY delegation record for a given public key.
enum GNUNET_GenericReturnValue(* create_tables)(void *cls)
Setup the database.
enum GNUNET_GenericReturnValue(* edit_records)(void *cls, const char *editor_hint, const struct GNUNET_CRYPTO_PrivateKey *zone, const char *label, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
Transaction-based API draft.
enum GNUNET_GenericReturnValue(* rollback_tx)(void *cls)
Tell plugin to rollback what we started with begin_tx This may be a NOP (and thus NOT roll anything b...
enum GNUNET_GenericReturnValue(* iterate_records)(void *cls, const struct GNUNET_CRYPTO_PrivateKey *zone, uint64_t serial, uint64_t limit, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
Iterate over the results for a particular zone in the datastore.
enum GNUNET_GenericReturnValue(* lookup_records)(void *cls, const struct GNUNET_CRYPTO_PrivateKey *zone, const char *label, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
Lookup records in the datastore for which we are the authority.
enum GNUNET_GenericReturnValue(* begin_tx)(void *cls)
Tell plugin that a set of procedures are coming that are ideally handled within a single TX (BEGIN/CO...
enum GNUNET_GenericReturnValue(* commit_tx)(void *cls)
Tell plugin the we finished what we started with begin_tx.
enum GNUNET_GenericReturnValue(* drop_tables)(void *cls)
Drop existing tables.
void * cls
Closure to pass to all plugin functions.
enum GNUNET_GenericReturnValue(* store_records)(void *cls, const struct GNUNET_CRYPTO_PrivateKey *zone, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Store a record in the datastore for which we are the authority.
Information needed to run a list of SQL statements using GNUNET_SQ_exec_statements().
Information needed to run a list of SQL statements using GNUNET_SQ_exec_statements().
Description of a DB query parameter.
Description of a DB result cell.
struct GNUNET_BLOCK_PluginFunctions * api
Plugin API.
sqlite3_stmt * iterate_all_zones
Precompiled SQL for iterate all records within all zones.
sqlite3_stmt * delete_records
Precompiled SQL to deltete existing records.
bool ready
Database is prepared and ready.
char * fn
Filename used for the DB.
sqlite3_stmt * store_records
Precompiled SQL to store records.
sqlite3_stmt * zone_to_name
Precompiled SQL to for reverse lookup based on PKEY.
sqlite3_stmt * lookup_label
Precompiled SQL to lookup records based on label.
struct GNUNET_PQ_Context * dbh
Native Postgres database handle.
const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
sqlite3_stmt * editor_hint_clear
Precompiled SQL to clear editor hint.
sqlite3_stmt * iterate_zone
Precompiled SQL for iterate records within a zone.