summaryrefslogtreecommitdiff
path: root/src/backenddb/plugin_merchantdb_postgres.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backenddb/plugin_merchantdb_postgres.c')
-rw-r--r--src/backenddb/plugin_merchantdb_postgres.c147
1 files changed, 146 insertions, 1 deletions
diff --git a/src/backenddb/plugin_merchantdb_postgres.c b/src/backenddb/plugin_merchantdb_postgres.c
index b882b24b..0cb2149a 100644
--- a/src/backenddb/plugin_merchantdb_postgres.c
+++ b/src/backenddb/plugin_merchantdb_postgres.c
@@ -154,6 +154,84 @@ postgres_create_tables (void *cls)
/**
+ * Register callback to be invoked on events of type @a es.
+ *
+ * Unlike many other calls, this function is thread-safe
+ * and may be called from threads that are different
+ * from the one that setup @a db. However, the @a cb
+ * will always be called from the thread that runs
+ * #GNUNET_PQ_event_do_poll() or the GNUnet scheduler.
+ *
+ * @param db database context to use
+ * @param es specification of the event to listen for
+ * @param cb function to call when the event happens, possibly
+ * multiple times (until #GNUNET_PQ_event_listen_cancel() is invoked)
+ * @param cb_cls closure for @a cb
+ * @return handle useful to cancel the listener
+ */
+static struct GNUNET_DB_EventHandler *
+postgres_event_listen (void *cls,
+ const struct GNUNET_DB_EventHeaderP *es,
+ GNUNET_DB_EventCallback cb,
+ void *cb_cls)
+{
+ struct PostgresClosure *pg = cls;
+
+ return GNUNET_PQ_event_listen (pg->conn,
+ es,
+ cb,
+ cb_cls);
+}
+
+
+/**
+ * Stop notifications.
+ *
+ * Unlike many other calls, this function is thread-safe
+ * and may be called from threads that are different
+ * from the one that setup @a db. However, the @a cb
+ * will always be called from the thread that runs
+ * #GNUNET_PQ_event_do_poll() or the GNUnet scheduler.
+ *
+ * @param eh handle to unregister.
+ */
+static void
+postgres_event_listen_cancel (struct GNUNET_DB_EventHandler *eh)
+{
+ GNUNET_PQ_event_listen_cancel (eh);
+}
+
+
+/**
+ * Notify all that listen on @a es of an event.
+ *
+ * Unlike many other calls, this function is thread-safe
+ * and may be called from threads that are different
+ * from the one that setup @a db. However, the @a cb
+ * will always be called from the thread that runs
+ * #GNUNET_PQ_event_do_poll() or the GNUnet scheduler.
+ *
+ * @param db database context to use
+ * @param es specification of the event to generate
+ * @param extra additional event data provided
+ * @param extra_size number of bytes in @a extra
+ */
+static void
+postgres_event_notify (void *cls,
+ const struct GNUNET_DB_EventHeaderP *es,
+ const void *extra,
+ size_t extra_size)
+{
+ struct PostgresClosure *pg = cls;
+
+ return GNUNET_PQ_event_notify (pg->conn,
+ es,
+ extra,
+ extra_size);
+}
+
+
+/**
* Do a pre-flight check that we are not in an uncommitted transaction.
* If we are, die.
* Does not return anything, as we will continue regardless of the outcome.
@@ -597,6 +675,47 @@ postgres_lookup_instances (void *cls,
/**
+ * Lookup all one of the instances this backend has configured.
+ *
+ * @param cls closure
+ * @param id instance ID to resolve
+ * @param active_only only find 'active' instances
+ * @param cb function to call on all instances found
+ * @param cb_cls closure for @a cb
+ */
+static enum GNUNET_DB_QueryStatus
+postgres_lookup_instance (void *cls,
+ const char *id,
+ bool active_only,
+ TALER_MERCHANTDB_InstanceCallback cb,
+ void *cb_cls)
+{
+ struct PostgresClosure *pg = cls;
+ struct LookupInstancesContext lic = {
+ .cb = cb,
+ .cb_cls = cb_cls,
+ .active_only = active_only,
+ .pg = pg
+ };
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_string (id),
+ GNUNET_PQ_query_param_end
+ };
+ enum GNUNET_DB_QueryStatus qs;
+
+ check_connection (pg);
+ qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
+ "lookup_instance",
+ params,
+ &lookup_instances_cb,
+ &lic);
+ if (0 > lic.qs)
+ return lic.qs;
+ return qs;
+}
+
+
+/**
* Lookup authentication data of an instance.
*
* @param cls closure
@@ -6419,6 +6538,27 @@ postgres_connect (void *cls)
",default_pay_delay"
" FROM merchant_instances",
0),
+ /* for postgres_lookup_instance() */
+ GNUNET_PQ_make_prepare ("lookup_instance",
+ "SELECT"
+ " merchant_serial"
+ ",merchant_pub"
+ ",auth_hash"
+ ",auth_salt"
+ ",merchant_id"
+ ",merchant_name"
+ ",address"
+ ",jurisdiction"
+ ",default_max_deposit_fee_val"
+ ",default_max_deposit_fee_frac"
+ ",default_max_wire_fee_val"
+ ",default_max_wire_fee_frac"
+ ",default_wire_fee_amortization"
+ ",default_wire_transfer_delay"
+ ",default_pay_delay"
+ " FROM merchant_instances"
+ " WHERE merchant_id=$1",
+ 1),
/* for postgres_insert_instance() */
GNUNET_PQ_make_prepare ("insert_instance",
"INSERT INTO merchant_instances"
@@ -8823,6 +8963,7 @@ postgres_connect (void *cls)
ps);
if (NULL == pg->conn)
return GNUNET_SYSERR;
+ GNUNET_PQ_event_scheduler_start (pg->conn);
return GNUNET_OK;
}
@@ -8858,7 +8999,6 @@ libtaler_plugin_merchantdb_postgres_init (void *cls)
TALER_config_get_currency (cfg,
&pg->currency))
{
- GNUNET_PQ_disconnect (pg->conn);
GNUNET_free (pg->sql_dir);
GNUNET_free (pg);
return NULL;
@@ -8868,12 +9008,16 @@ libtaler_plugin_merchantdb_postgres_init (void *cls)
plugin->connect = &postgres_connect;
plugin->create_tables = &postgres_create_tables;
plugin->drop_tables = &postgres_drop_tables;
+ plugin->event_listen = &postgres_event_listen;
+ plugin->event_listen_cancel = &postgres_event_listen_cancel;
+ plugin->event_notify = &postgres_event_notify;
plugin->preflight = &postgres_preflight;
plugin->start = &postgres_start;
plugin->start_read_committed = &postgres_start_read_committed;
plugin->rollback = &postgres_rollback;
plugin->commit = &postgres_commit;
plugin->lookup_instances = &postgres_lookup_instances;
+ plugin->lookup_instance = &postgres_lookup_instance;
plugin->lookup_instance_auth = &postgres_lookup_instance_auth;
plugin->insert_instance = &postgres_insert_instance;
plugin->insert_account = &postgres_insert_account;
@@ -8967,6 +9111,7 @@ libtaler_plugin_merchantdb_postgres_done (void *cls)
if (NULL != pg->conn)
{
+ GNUNET_PQ_event_scheduler_stop (pg->conn);
GNUNET_PQ_disconnect (pg->conn);
pg->conn = NULL;
}