plugin_auditordb_postgres.c (24083B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2014-2024 Taler Systems SA 4 5 TALER is free software; you can redistribute it and/or modify it under the 6 terms of the GNU General Public License as published by the Free Software 7 Foundation; either version 3, or (at your option) any later version. 8 9 TALER is distributed in the hope that it will be useful, but WITHOUT ANY 10 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 11 A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 13 You should have received a copy of the GNU General Public License along with 14 TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> 15 */ 16 /** 17 * @file plugin_auditordb_postgres.c 18 * @brief Low-level (statement-level) Postgres database access for the auditor 19 * @author Christian Grothoff 20 * @author Gabor X Toth 21 */ 22 #include "taler/platform.h" 23 #include "taler/taler_pq_lib.h" 24 #include <pthread.h> 25 #include <libpq-fe.h> 26 #include "pg_delete_auditor_closure_lag.h" 27 #include "pg_delete_early_aggregation.h" 28 #include "pg_delete_generic.h" 29 #include "pg_delete_pending_deposit.h" 30 #include "pg_delete_purse_info.h" 31 #include "pg_delete_reserve_in_inconsistency.h" 32 #include "pg_del_denomination_balance.h" 33 #include "pg_del_reserve_info.h" 34 #include "pg_get_auditor_progress.h" 35 #include "pg_get_balance.h" 36 #include "pg_get_balances.h" 37 #include "pg_get_denomination_balance.h" 38 #include "pg_get_deposit_confirmations.h" 39 #include "pg_get_purse_info.h" 40 #include "pg_get_reserve_info.h" 41 #include "pg_get_wire_fee_summary.h" 42 #include "pg_helper.h" 43 #include "pg_insert_auditor_progress.h" 44 #include "pg_insert_balance.h" 45 #include "pg_insert_denomination_balance.h" 46 #include "pg_insert_deposit_confirmation.h" 47 #include "pg_insert_early_aggregation.h" 48 #include "pg_insert_exchange_signkey.h" 49 #include "pg_insert_historic_denom_revenue.h" 50 #include "pg_insert_historic_reserve_revenue.h" 51 #include "pg_insert_pending_deposit.h" 52 #include "pg_insert_purse_info.h" 53 #include "pg_insert_reserve_info.h" 54 #include "pg_select_reserve_in_inconsistency.h" 55 #include "pg_select_historic_denom_revenue.h" 56 #include "pg_select_historic_reserve_revenue.h" 57 #include "pg_get_progress_points.h" 58 #include "pg_select_pending_deposits.h" 59 #include "pg_select_purse_expired.h" 60 #include "pg_update_generic_suppressed.h" 61 #include "pg_update_auditor_progress.h" 62 #include "pg_update_denomination_balance.h" 63 #include "pg_update_purse_info.h" 64 #include "pg_update_reserve_info.h" 65 #include "pg_update_wire_fee_summary.h" 66 #include "pg_get_amount_arithmetic_inconsistency.h" 67 #include "pg_get_coin_inconsistency.h" 68 #include "pg_get_row_inconsistency.h" 69 #include "pg_update_balance.h" 70 #include "pg_select_early_aggregations.h" 71 72 #include "pg_insert_coin_inconsistency.h" 73 #include "pg_insert_row_inconsistency.h" 74 #include "pg_insert_amount_arithmetic_inconsistency.h" 75 76 #include "pg_get_auditor_closure_lags.h" 77 #include "pg_insert_auditor_closure_lags.h" 78 79 #include "pg_get_emergency_by_count.h" 80 #include "pg_insert_emergency_by_count.h" 81 82 #include "pg_get_emergency.h" 83 #include "pg_insert_emergency.h" 84 85 #include "pg_get_bad_sig_losses.h" 86 #include "pg_insert_bad_sig_losses.h" 87 88 #include "pg_get_denomination_key_validity_withdraw_inconsistency.h" 89 #include "pg_insert_denomination_key_validity_withdraw_inconsistency.h" 90 91 #include "pg_get_fee_time_inconsistency.h" 92 #include "pg_insert_fee_time_inconsistency.h" 93 94 #include "pg_get_purse_not_closed_inconsistencies.h" 95 #include "pg_insert_purse_not_closed_inconsistencies.h" 96 97 #include "pg_get_reserve_balance_insufficient_inconsistency.h" 98 #include "pg_insert_reserve_balance_insufficient_inconsistency.h" 99 100 #include "pg_get_reserve_in_inconsistency.h" 101 #include "pg_lookup_reserve_in_inconsistency.h" 102 #include "pg_insert_reserve_in_inconsistency.h" 103 104 #include "pg_get_reserve_not_closed_inconsistency.h" 105 #include "pg_insert_reserve_not_closed_inconsistency.h" 106 107 #include "pg_get_denominations_without_sigs.h" 108 #include "pg_insert_denominations_without_sigs.h" 109 110 #include "pg_get_misattribution_in_inconsistency.h" 111 #include "pg_insert_misattribution_in_inconsistency.h" 112 113 #include "pg_get_reserves.h" 114 #include "pg_get_purses.h" 115 116 #include "pg_get_denomination_pending.h" 117 #include "pg_insert_denomination_pending.h" 118 119 #include "pg_get_exchange_signkeys.h" 120 121 #include "pg_get_wire_format_inconsistency.h" 122 #include "pg_insert_wire_format_inconsistency.h" 123 124 #include "pg_get_wire_out_inconsistency.h" 125 #include "pg_insert_wire_out_inconsistency.h" 126 #include "pg_delete_wire_out_inconsistency_if_matching.h" 127 128 #include "pg_get_reserve_balance_summary_wrong_inconsistency.h" 129 #include "pg_insert_reserve_balance_summary_wrong_inconsistency.h" 130 131 #include "pg_get_row_minor_inconsistencies.h" 132 #include "pg_insert_row_minor_inconsistencies.h" 133 134 #define LOG(kind,...) GNUNET_log_from (kind, "taler-auditordb-postgres", \ 135 __VA_ARGS__) 136 137 138 /** 139 * Drop all auditor tables OR deletes recoverable auditor state. 140 * This should only be used by testcases or when restarting the 141 * auditor from scratch. 142 * 143 * @param cls the `struct PostgresClosure` with the plugin-specific state 144 * @param drop_exchangelist drop all tables, including schema versioning 145 * and the exchange and deposit_confirmations table; NOT to be 146 * used when restarting the auditor 147 * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure 148 */ 149 static enum GNUNET_GenericReturnValue 150 postgres_drop_tables (void *cls, 151 bool drop_exchangelist) 152 { 153 struct PostgresClosure *pc = cls; 154 struct GNUNET_PQ_Context *conn; 155 enum GNUNET_GenericReturnValue ret; 156 157 conn = GNUNET_PQ_connect_with_cfg (pc->cfg, 158 "auditordb-postgres", 159 NULL, 160 NULL, 161 NULL); 162 if (NULL == conn) 163 return GNUNET_SYSERR; 164 ret = GNUNET_PQ_exec_sql (conn, 165 (drop_exchangelist) ? "drop" : "restart"); 166 GNUNET_PQ_disconnect (conn); 167 return ret; 168 } 169 170 171 /** 172 * Create the necessary tables if they are not present 173 * 174 * @param cls the `struct PostgresClosure` with the plugin-specific state 175 * @param support_partitions true to support partitioning 176 * @param num_partitions number of partitions to use 177 * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure 178 */ 179 static enum GNUNET_GenericReturnValue 180 postgres_create_tables (void *cls, 181 bool support_partitions, 182 uint32_t num_partitions) 183 { 184 struct PostgresClosure *pc = cls; 185 enum GNUNET_GenericReturnValue ret = GNUNET_OK; 186 struct GNUNET_PQ_Context *conn; 187 struct GNUNET_PQ_QueryParam params[] = { 188 support_partitions 189 ? GNUNET_PQ_query_param_uint32 (&num_partitions) 190 : GNUNET_PQ_query_param_null (), 191 GNUNET_PQ_query_param_end 192 }; 193 struct GNUNET_PQ_PreparedStatement ps[] = { 194 GNUNET_PQ_make_prepare ("create_tables", 195 "SELECT" 196 " auditor.do_create_tables" 197 " ($1);"), 198 GNUNET_PQ_PREPARED_STATEMENT_END 199 }; 200 struct GNUNET_PQ_ExecuteStatement es[] = { 201 GNUNET_PQ_make_try_execute ("SET search_path TO auditor;"), 202 GNUNET_PQ_EXECUTE_STATEMENT_END 203 }; 204 205 conn = GNUNET_PQ_connect_with_cfg (pc->cfg, 206 "auditordb-postgres", 207 "auditor-", 208 es, 209 ps); 210 if (NULL == conn) 211 { 212 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 213 "Failed to connect to database\n"); 214 return GNUNET_SYSERR; 215 } 216 if (0 > 217 GNUNET_PQ_eval_prepared_non_select (conn, 218 "create_tables", 219 params)) 220 { 221 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 222 "Failed to run 'create_tables' prepared statement\n"); 223 ret = GNUNET_SYSERR; 224 } 225 if (GNUNET_OK == ret) 226 { 227 ret = GNUNET_PQ_exec_sql (conn, 228 "procedures"); 229 if (GNUNET_OK != ret) 230 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 231 "Failed to load stored procedures\n"); 232 } 233 GNUNET_PQ_disconnect (conn); 234 return ret; 235 } 236 237 238 /** 239 * Register callback to be invoked on events of type @a es. 240 * 241 * @param cls database context to use 242 * @param es specification of the event to listen for 243 * @param timeout how long to wait for the event 244 * @param cb function to call when the event happens, possibly 245 * mulrewardle times (until cancel is invoked) 246 * @param cb_cls closure for @a cb 247 * @return handle useful to cancel the listener 248 */ 249 static struct GNUNET_DB_EventHandler * 250 postgres_event_listen (void *cls, 251 const struct GNUNET_DB_EventHeaderP *es, 252 struct GNUNET_TIME_Relative timeout, 253 GNUNET_DB_EventCallback cb, 254 void *cb_cls) 255 { 256 struct PostgresClosure *pg = cls; 257 258 return GNUNET_PQ_event_listen (pg->conn, 259 es, 260 timeout, 261 cb, 262 cb_cls); 263 } 264 265 266 /** 267 * Stop notifications. 268 * 269 * @param eh handle to unregister. 270 */ 271 static void 272 postgres_event_listen_cancel (struct GNUNET_DB_EventHandler *eh) 273 { 274 GNUNET_PQ_event_listen_cancel (eh); 275 } 276 277 278 /** 279 * Notify all that listen on @a es of an event. 280 * 281 * @param cls database context to use 282 * @param es specification of the event to generate 283 * @param extra additional event data provided 284 * @param extra_size number of bytes in @a extra 285 */ 286 static void 287 postgres_event_notify (void *cls, 288 const struct GNUNET_DB_EventHeaderP *es, 289 const void *extra, 290 size_t extra_size) 291 { 292 struct PostgresClosure *pg = cls; 293 294 return GNUNET_PQ_event_notify (pg->conn, 295 es, 296 extra, 297 extra_size); 298 } 299 300 301 /** 302 * Connect to the db if the connection does not exist yet. 303 * 304 * @param[in,out] pg the plugin-specific state 305 * @return #GNUNET_OK on success 306 */ 307 static enum GNUNET_GenericReturnValue 308 setup_connection (struct PostgresClosure *pg) 309 { 310 struct GNUNET_PQ_ExecuteStatement es[] = { 311 GNUNET_PQ_make_try_execute ("SET search_path TO auditor;"), 312 GNUNET_PQ_EXECUTE_STATEMENT_END 313 }; 314 struct GNUNET_PQ_Context *db_conn; 315 316 if (NULL != pg->conn) 317 { 318 GNUNET_PQ_reconnect_if_down (pg->conn); 319 return GNUNET_OK; 320 } 321 db_conn = GNUNET_PQ_connect_with_cfg2 (pg->cfg, 322 "auditordb-postgres", 323 "auditor-", 324 es, 325 NULL, /* prepared statements */ 326 GNUNET_PQ_FLAG_CHECK_CURRENT); 327 if (NULL == db_conn) 328 return GNUNET_SYSERR; 329 pg->conn = db_conn; 330 pg->prep_gen++; 331 return GNUNET_OK; 332 } 333 334 335 /** 336 * Do a pre-flight check that we are not in an uncommitted transaction. 337 * If we are, rollback the previous transaction and output a warning. 338 * 339 * @param cls the `struct PostgresClosure` with the plugin-specific state 340 * @return #GNUNET_OK on success, 341 * #GNUNET_NO if we rolled back an earlier transaction 342 * #GNUNET_SYSERR if we have no DB connection 343 */ 344 static enum GNUNET_GenericReturnValue 345 postgres_preflight (void *cls) 346 { 347 struct PostgresClosure *pg = cls; 348 struct GNUNET_PQ_ExecuteStatement es[] = { 349 GNUNET_PQ_make_execute ("ROLLBACK"), 350 GNUNET_PQ_EXECUTE_STATEMENT_END 351 }; 352 353 if ( (NULL == pg->conn) && 354 (GNUNET_OK != 355 setup_connection (pg)) ) 356 return GNUNET_SYSERR; 357 if (NULL == pg->transaction_name) 358 return GNUNET_OK; /* all good */ 359 if (GNUNET_OK == 360 GNUNET_PQ_exec_statements (pg->conn, 361 es)) 362 { 363 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 364 "BUG: Preflight check rolled back transaction `%s'!\n", 365 pg->transaction_name); 366 } 367 else 368 { 369 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 370 "BUG: Preflight check failed to rollback transaction `%s'!\n", 371 pg->transaction_name); 372 } 373 pg->transaction_name = NULL; 374 return GNUNET_NO; 375 } 376 377 378 /** 379 * Start a transaction. 380 * 381 * @param cls the `struct PostgresClosure` with the plugin-specific state 382 * @return #GNUNET_OK on success 383 */ 384 static enum GNUNET_GenericReturnValue 385 postgres_start (void *cls) 386 { 387 struct PostgresClosure *pg = cls; 388 struct GNUNET_PQ_ExecuteStatement es[] = { 389 GNUNET_PQ_make_execute ("START TRANSACTION ISOLATION LEVEL SERIALIZABLE"), 390 GNUNET_PQ_EXECUTE_STATEMENT_END 391 }; 392 393 postgres_preflight (cls); 394 if (GNUNET_OK != 395 GNUNET_PQ_exec_statements (pg->conn, 396 es)) 397 { 398 TALER_LOG_ERROR ("Failed to start transaction\n"); 399 GNUNET_break (0); 400 return GNUNET_SYSERR; 401 } 402 return GNUNET_OK; 403 } 404 405 406 /** 407 * Roll back the current transaction of a database connection. 408 * 409 * @param cls the `struct PostgresClosure` with the plugin-specific state 410 */ 411 static void 412 postgres_rollback (void *cls) 413 { 414 struct PostgresClosure *pg = cls; 415 struct GNUNET_PQ_ExecuteStatement es[] = { 416 GNUNET_PQ_make_execute ("ROLLBACK"), 417 GNUNET_PQ_EXECUTE_STATEMENT_END 418 }; 419 420 GNUNET_break (GNUNET_OK == 421 GNUNET_PQ_exec_statements (pg->conn, 422 es)); 423 } 424 425 426 /** 427 * Commit the current transaction of a database connection. 428 * 429 * @param cls the `struct PostgresClosure` with the plugin-specific state 430 * @return transaction status code 431 */ 432 static enum GNUNET_DB_QueryStatus 433 postgres_commit (void *cls) 434 { 435 struct PostgresClosure *pg = cls; 436 struct GNUNET_PQ_QueryParam params[] = { 437 GNUNET_PQ_query_param_end 438 }; 439 440 PREPARE (pg, 441 "do_commit", 442 "COMMIT"); 443 return GNUNET_PQ_eval_prepared_non_select (pg->conn, 444 "do_commit", 445 params); 446 } 447 448 449 /** 450 * Function called to perform "garbage collection" on the 451 * database, expiring records we no longer require. 452 * 453 * @param cls closure 454 * @return #GNUNET_OK on success, 455 * #GNUNET_SYSERR on DB errors 456 */ 457 static enum GNUNET_GenericReturnValue 458 postgres_gc (void *cls) 459 { 460 struct PostgresClosure *pg = cls; 461 struct GNUNET_TIME_Absolute now = {0}; 462 struct GNUNET_PQ_QueryParam params_time[] = { 463 GNUNET_PQ_query_param_absolute_time (&now), 464 GNUNET_PQ_query_param_end 465 }; 466 struct GNUNET_PQ_Context *conn; 467 enum GNUNET_DB_QueryStatus qs; 468 struct GNUNET_PQ_PreparedStatement ps[] = { 469 GNUNET_PQ_PREPARED_STATEMENT_END 470 }; 471 struct GNUNET_PQ_ExecuteStatement es[] = { 472 GNUNET_PQ_make_try_execute ("SET search_path TO auditor;"), 473 GNUNET_PQ_EXECUTE_STATEMENT_END 474 }; 475 476 now = GNUNET_TIME_absolute_get (); 477 conn = GNUNET_PQ_connect_with_cfg (pg->cfg, 478 "auditordb-postgres", 479 NULL, 480 es, 481 ps); 482 if (NULL == conn) 483 return GNUNET_SYSERR; 484 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 485 "FIXME: Auditor GC not implemented (#9433)\n"); 486 qs = GNUNET_PQ_eval_prepared_non_select (conn, 487 "gc_auditor", 488 params_time); 489 GNUNET_PQ_disconnect (conn); 490 if (0 > qs) 491 { 492 GNUNET_break (0); 493 return GNUNET_SYSERR; 494 } 495 return GNUNET_OK; 496 } 497 498 499 /** 500 * Initialize Postgres database subsystem. 501 * 502 * @param cls a configuration instance 503 * @return NULL on error, otherwise a `struct TALER_AUDITORDB_Plugin` 504 */ 505 void * 506 libtaler_plugin_auditordb_postgres_init (void *cls); 507 508 /* Declaration used to squash compiler warning */ 509 void * 510 libtaler_plugin_auditordb_postgres_init (void *cls) 511 { 512 const struct GNUNET_CONFIGURATION_Handle *cfg = cls; 513 struct PostgresClosure *pg; 514 struct TALER_AUDITORDB_Plugin *plugin; 515 516 pg = GNUNET_new (struct PostgresClosure); 517 pg->cfg = cfg; 518 if (GNUNET_OK != 519 TALER_config_get_currency (cfg, 520 "exchange", 521 &pg->currency)) 522 { 523 GNUNET_free (pg); 524 return NULL; 525 } 526 527 plugin = GNUNET_new (struct TALER_AUDITORDB_Plugin); 528 plugin->cls = pg; 529 plugin->preflight = &postgres_preflight; 530 plugin->drop_tables = &postgres_drop_tables; 531 plugin->create_tables = &postgres_create_tables; 532 plugin->event_listen = &postgres_event_listen; 533 plugin->event_listen_cancel = &postgres_event_listen_cancel; 534 plugin->event_notify = &postgres_event_notify; 535 plugin->start = &postgres_start; 536 plugin->commit = &postgres_commit; 537 plugin->rollback = &postgres_rollback; 538 plugin->gc = &postgres_gc; 539 540 plugin->get_auditor_progress 541 = &TAH_PG_get_auditor_progress; 542 543 plugin->get_balance = &TAH_PG_get_balance; 544 plugin->get_balances = &TAH_PG_get_balances; 545 546 plugin->insert_auditor_progress 547 = &TAH_PG_insert_auditor_progress; 548 plugin->insert_balance 549 = &TAH_PG_insert_balance; 550 plugin->update_generic_suppressed 551 = &TAH_PG_update_generic_suppressed; 552 plugin->delete_generic 553 = &TAH_PG_delete_generic; 554 plugin->delete_wire_out_inconsistency_if_matching 555 = &TAH_PG_delete_wire_out_inconsistency_if_matching; 556 557 plugin->delete_auditor_closure_lag 558 = &TAH_PG_delete_auditor_closure_lag; 559 560 plugin->update_auditor_progress 561 = &TAH_PG_update_auditor_progress; 562 plugin->insert_deposit_confirmation 563 = &TAH_PG_insert_deposit_confirmation; 564 plugin->get_deposit_confirmations 565 = &TAH_PG_get_deposit_confirmations; 566 567 plugin->get_amount_arithmetic_inconsistency 568 = &TAH_PG_get_amount_arithmetic_inconsistency; 569 plugin->get_coin_inconsistency 570 = &TAH_PG_get_coin_inconsistency; 571 plugin->get_row_inconsistency 572 = &TAH_PG_get_row_inconsistency; 573 574 575 plugin->insert_amount_arithmetic_inconsistency 576 = &TAH_PG_insert_amount_arithmetic_inconsistency; 577 plugin->insert_coin_inconsistency 578 = &TAH_PG_insert_coin_inconsistency; 579 plugin->insert_row_inconsistency 580 = &TAH_PG_insert_row_inconsistency; 581 582 plugin->insert_reserve_info 583 = &TAH_PG_insert_reserve_info; 584 plugin->update_reserve_info 585 = &TAH_PG_update_reserve_info; 586 plugin->get_reserve_info 587 = &TAH_PG_get_reserve_info; 588 plugin->del_reserve_info 589 = &TAH_PG_del_reserve_info; 590 591 plugin->insert_pending_deposit 592 = &TAH_PG_insert_pending_deposit; 593 plugin->select_pending_deposits 594 = &TAH_PG_select_pending_deposits; 595 plugin->delete_pending_deposit 596 = &TAH_PG_delete_pending_deposit; 597 598 plugin->insert_purse_info 599 = &TAH_PG_insert_purse_info; 600 plugin->update_purse_info 601 = &TAH_PG_update_purse_info; 602 plugin->get_purse_info 603 = &TAH_PG_get_purse_info; 604 plugin->delete_purse_info 605 = &TAH_PG_delete_purse_info; 606 plugin->select_purse_expired 607 = &TAH_PG_select_purse_expired; 608 609 plugin->insert_denomination_balance 610 = &TAH_PG_insert_denomination_balance; 611 plugin->update_denomination_balance 612 = &TAH_PG_update_denomination_balance; 613 plugin->del_denomination_balance 614 = &TAH_PG_del_denomination_balance; 615 plugin->get_denomination_balance 616 = &TAH_PG_get_denomination_balance; 617 618 plugin->insert_historic_denom_revenue 619 = &TAH_PG_insert_historic_denom_revenue; 620 621 plugin->select_historic_denom_revenue 622 = &TAH_PG_select_historic_denom_revenue; 623 624 plugin->insert_historic_reserve_revenue 625 = &TAH_PG_insert_historic_reserve_revenue; 626 plugin->select_historic_reserve_revenue 627 = &TAH_PG_select_historic_reserve_revenue; 628 629 630 plugin->insert_emergency = &TAH_PG_insert_emergency; 631 plugin->get_emergency = &TAH_PG_get_emergency; 632 633 plugin->insert_emergency_by_count = &TAH_PG_insert_emergency_by_count; 634 plugin->get_emergency_by_count = &TAH_PG_get_emergency_by_count; 635 636 637 plugin->insert_denomination_key_validity_withdraw_inconsistency = 638 &TAH_PG_insert_denomination_key_validity_withdraw_inconsistency; 639 plugin->get_denomination_key_validity_withdraw_inconsistency = 640 &TAH_PG_get_denomination_key_validity_withdraw_inconsistency; 641 642 plugin->insert_purse_not_closed_inconsistencies = 643 &TAH_PG_insert_purse_not_closed_inconsistencies; 644 plugin->get_purse_not_closed_inconsistencies = 645 &TAH_PG_get_purse_not_closed_inconsistencies; 646 647 648 plugin->insert_reserve_balance_insufficient_inconsistency = 649 &TAH_PG_insert_reserve_balance_insufficient_inconsistency; 650 plugin->get_reserve_balance_insufficient_inconsistency = 651 &TAH_PG_get_reserve_balance_insufficient_inconsistency; 652 653 plugin->insert_bad_sig_losses = &TAH_PG_insert_bad_sig_losses; 654 plugin->get_bad_sig_losses = &TAH_PG_get_bad_sig_losses; 655 656 plugin->insert_auditor_closure_lags = &TAH_PG_insert_auditor_closure_lags; 657 plugin->get_auditor_closure_lags = &TAH_PG_get_auditor_closure_lags; 658 659 plugin->insert_reserve_in_inconsistency = 660 &TAH_PG_insert_reserve_in_inconsistency; 661 plugin->get_reserve_in_inconsistency 662 = &TAH_PG_get_reserve_in_inconsistency; 663 plugin->lookup_reserve_in_inconsistency 664 = &TAH_PG_lookup_reserve_in_inconsistency; 665 666 plugin->insert_reserve_not_closed_inconsistency = 667 &TAH_PG_insert_reserve_not_closed_inconsistency; 668 plugin->get_reserve_not_closed_inconsistency = 669 &TAH_PG_get_reserve_not_closed_inconsistency; 670 671 plugin->insert_denominations_without_sigs = 672 &TAH_PG_insert_denominations_without_sigs; 673 plugin->get_denominations_without_sigs = 674 &TAH_PG_get_denominations_without_sigs; 675 676 plugin->get_progress_points 677 = &TAH_PG_get_progress_points; 678 679 680 plugin->insert_misattribution_in_inconsistency = 681 &TAH_PG_insert_misattribution_in_inconsistency; 682 plugin->get_misattribution_in_inconsistency = 683 &TAH_PG_get_misattribution_in_inconsistency; 684 685 plugin->get_reserves = &TAH_PG_get_reserves; 686 plugin->get_purses = &TAH_PG_get_purses; 687 688 plugin->insert_denomination_pending = &TAH_PG_insert_denomination_pending; 689 plugin->get_denomination_pending = &TAH_PG_get_denomination_pending; 690 691 plugin->get_exchange_signkeys = &TAH_PG_get_exchange_signkeys; 692 693 plugin->insert_wire_format_inconsistency = 694 &TAH_PG_insert_wire_format_inconsistency; 695 plugin->get_wire_format_inconsistency = &TAH_PG_get_wire_format_inconsistency; 696 697 plugin->insert_early_aggregation 698 = &TAH_PG_insert_early_aggregation; 699 plugin->delete_early_aggregation 700 = &TAH_PG_delete_early_aggregation; 701 702 plugin->insert_wire_out_inconsistency 703 = &TAH_PG_insert_wire_out_inconsistency; 704 plugin->get_wire_out_inconsistency 705 = &TAH_PG_get_wire_out_inconsistency; 706 plugin->select_reserve_in_inconsistency 707 = &TAH_PG_select_reserve_in_inconsistency; 708 plugin->delete_reserve_in_inconsistency 709 = &TAH_PG_delete_reserve_in_inconsistency; 710 plugin->select_early_aggregations 711 = &TAH_PG_select_early_aggregations; 712 713 plugin->insert_reserve_balance_summary_wrong_inconsistency = 714 &TAH_PG_insert_reserve_balance_summary_wrong_inconsistency; 715 plugin->get_reserve_balance_summary_wrong_inconsistency = 716 &TAH_PG_get_reserve_balance_summary_wrong_inconsistency; 717 718 719 plugin->insert_row_minor_inconsistencies = 720 &TAH_PG_insert_row_minor_inconsistencies; 721 plugin->get_row_minor_inconsistencies = &TAH_PG_get_row_minor_inconsistencies; 722 723 plugin->insert_fee_time_inconsistency = &TAH_PG_insert_fee_time_inconsistency; 724 plugin->get_fee_time_inconsistency = &TAH_PG_get_fee_time_inconsistency; 725 726 plugin->update_balance 727 = &TAH_PG_update_balance; 728 729 plugin->insert_exchange_signkey 730 = &TAH_PG_insert_exchange_signkey; 731 732 return plugin; 733 } 734 735 736 /** 737 * Shutdown Postgres database subsystem. 738 * 739 * @param cls a `struct TALER_AUDITORDB_Plugin` 740 * @return NULL (always) 741 */ 742 void * 743 libtaler_plugin_auditordb_postgres_done (void *cls); 744 745 /* Declaration used to squash compiler warning */ 746 void * 747 libtaler_plugin_auditordb_postgres_done (void *cls) 748 { 749 struct TALER_AUDITORDB_Plugin *plugin = cls; 750 struct PostgresClosure *pg = plugin->cls; 751 752 if (NULL != pg->conn) 753 GNUNET_PQ_disconnect (pg->conn); 754 GNUNET_free (pg->currency); 755 GNUNET_free (pg); 756 GNUNET_free (plugin); 757 return NULL; 758 } 759 760 761 /* end of plugin_auditordb_postgres.c */