LCOV - code coverage report
Current view: top level - exchange-tools - taler-exchange-dbinit.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 36 87 41.4 %
Date: 2025-06-05 21:03:14 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /*
       2             :   This file is part of TALER
       3             :   Copyright (C) 2014-2025 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 exchange-tools/taler-exchange-dbinit.c
      18             :  * @brief Create tables for the exchange database.
      19             :  * @author Florian Dold
      20             :  * @author Christian Grothoff
      21             :  */
      22             : #include "platform.h"
      23             : #include <gnunet/gnunet_util_lib.h>
      24             : #include "taler_exchangedb_lib.h"
      25             : 
      26             : 
      27             : /**
      28             :  * Return value from main().
      29             :  */
      30             : static int global_ret;
      31             : 
      32             : /**
      33             :  * -a option: inject auditor triggers
      34             :  */
      35             : static int inject_auditor;
      36             : 
      37             : /**
      38             :  * -r option: do full DB reset
      39             :  */
      40             : static int reset_db;
      41             : 
      42             : /**
      43             :  * -e option: enable custom rules
      44             :  */
      45             : static char *enable_rules;
      46             : 
      47             : /**
      48             :  * -d option: disable custom rules
      49             :  */
      50             : static char *disable_rules;
      51             : 
      52             : /**
      53             :  * -s option: clear revolving shard locks
      54             :  */
      55             : static int clear_shards;
      56             : 
      57             : /**
      58             :  * -g option: garbage collect DB
      59             :  */
      60             : static int gc_db;
      61             : 
      62             : /**
      63             :  * -P option: setup a partitioned database
      64             :  */
      65             : static uint32_t num_partitions;
      66             : 
      67             : /**
      68             :  * -f option: force partitions to be created when there is only one
      69             :  */
      70             : static int force_create_partitions;
      71             : 
      72             : /**
      73             :  * Main function that will be run.
      74             :  *
      75             :  * @param cls closure
      76             :  * @param args remaining command-line arguments
      77             :  * @param cfgfile name of the configuration file used (for saving, can be NULL!)
      78             :  * @param cfg configuration
      79             :  */
      80             : static void
      81          57 : run (void *cls,
      82             :      char *const *args,
      83             :      const char *cfgfile,
      84             :      const struct GNUNET_CONFIGURATION_Handle *cfg)
      85             : {
      86             :   struct TALER_EXCHANGEDB_Plugin *plugin;
      87             : 
      88             :   (void) cls;
      89             :   (void) args;
      90             :   (void) cfgfile;
      91             : 
      92          57 :   if (NULL ==
      93          57 :       (plugin = TALER_EXCHANGEDB_plugin_load (cfg,
      94             :                                               true)))
      95             :   {
      96           0 :     fprintf (stderr,
      97             :              "Failed to initialize database plugin.\n");
      98           0 :     global_ret = EXIT_NOTINSTALLED;
      99           0 :     return;
     100             :   }
     101          57 :   if (reset_db)
     102             :   {
     103          20 :     if (GNUNET_OK !=
     104          20 :         plugin->drop_tables (plugin->cls))
     105             :     {
     106           3 :       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     107             :                   "Could not drop tables as requested. Either database was not yet initialized, or permission denied. Consult the logs. Will still try to create new tables.\n");
     108             :     }
     109             :   }
     110          57 :   if (GNUNET_OK !=
     111         114 :       plugin->create_tables (plugin->cls,
     112          57 :                              force_create_partitions || num_partitions > 0,
     113             :                              num_partitions))
     114             :   {
     115           0 :     fprintf (stderr,
     116             :              "Failed to initialize database.\n");
     117           0 :     global_ret = EXIT_NOPERMISSION;
     118           0 :     goto exit;
     119             :   }
     120          57 :   if (gc_db || clear_shards)
     121             :   {
     122          33 :     if (GNUNET_OK !=
     123          33 :         plugin->preflight (plugin->cls))
     124             :     {
     125           0 :       fprintf (stderr,
     126             :                "Failed to prepare database.\n");
     127           0 :       global_ret = EXIT_NOPERMISSION;
     128           0 :       goto exit;
     129             :     }
     130          33 :     if (clear_shards)
     131             :     {
     132           0 :       if (GNUNET_OK !=
     133           0 :           plugin->delete_shard_locks (plugin->cls))
     134             :       {
     135           0 :         fprintf (stderr,
     136             :                  "Clearing revolving shards failed!\n");
     137             :       }
     138             :     }
     139          33 :     if (gc_db)
     140             :     {
     141          33 :       if (GNUNET_SYSERR == plugin->gc (plugin->cls))
     142             :       {
     143           0 :         fprintf (stderr,
     144             :                  "Garbage collection failed!\n");
     145             :       }
     146             :     }
     147             :   }
     148          57 :   if (inject_auditor)
     149             :   {
     150           0 :     if (GNUNET_SYSERR ==
     151           0 :         plugin->inject_auditor_triggers (plugin->cls))
     152             :     {
     153           0 :       fprintf (stderr,
     154             :                "Injecting auditor triggers failed!\n");
     155           0 :       global_ret = EXIT_FAILURE;
     156             :     }
     157             :   }
     158          57 :   if (NULL != disable_rules)
     159             :   {
     160           0 :     if (0 == strcasecmp (disable_rules,
     161             :                          "exchange"))
     162             :     {
     163           0 :       fprintf (stderr,
     164             :                "'exchange' is not a customization rule set!\n");
     165           0 :       global_ret = EXIT_INVALIDARGUMENT;
     166           0 :       goto exit;
     167             :     }
     168           0 :     if (GNUNET_OK !=
     169           0 :         plugin->preflight (plugin->cls))
     170             :     {
     171           0 :       fprintf (stderr,
     172             :                "Preflight check failed!\n");
     173           0 :       global_ret = EXIT_FAILURE;
     174           0 :       goto exit;
     175             :     }
     176           0 :     switch (plugin->disable_rules (plugin->cls,
     177             :                                    disable_rules))
     178             :     {
     179           0 :     case GNUNET_DB_STATUS_HARD_ERROR:
     180           0 :       fprintf (stderr,
     181             :                "Hard DB error trying to disable customization!\n");
     182           0 :       global_ret = EXIT_FAILURE;
     183           0 :       goto exit;
     184           0 :     case GNUNET_DB_STATUS_SOFT_ERROR:
     185             :       /* single call, should not be possible */
     186           0 :       GNUNET_break (0);
     187           0 :       global_ret = EXIT_FAILURE;
     188           0 :       goto exit;
     189           0 :     case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
     190           0 :       GNUNET_log (GNUNET_ERROR_TYPE_INFO,
     191             :                   "Nothing to do to disable customization schema `%s'\n",
     192             :                   disable_rules);
     193           0 :       break;
     194           0 :     case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
     195           0 :       break;
     196             :     }
     197             :   }
     198          57 :   if (NULL != enable_rules)
     199             :   {
     200           0 :     if (0 == strcasecmp (enable_rules,
     201             :                          "exchange"))
     202             :     {
     203           0 :       fprintf (stderr,
     204             :                "'exchange' is not a customization rule set!\n");
     205           0 :       global_ret = EXIT_INVALIDARGUMENT;
     206           0 :       goto exit;
     207             :     }
     208           0 :     if (GNUNET_OK !=
     209           0 :         plugin->enable_rules (plugin->cls,
     210             :                               enable_rules))
     211             :     {
     212           0 :       fprintf (stderr,
     213             :                "Enabling customization `%s' failed!\n",
     214             :                enable_rules);
     215           0 :       global_ret = EXIT_FAILURE;
     216           0 :       goto exit;
     217             :     }
     218             :   }
     219          57 : exit:
     220          57 :   TALER_EXCHANGEDB_plugin_unload (plugin);
     221          57 :   plugin = NULL;
     222             : }
     223             : 
     224             : 
     225             : /**
     226             :  * The main function of the database initialization tool.
     227             :  * Used to initialize the Taler Exchange's database.
     228             :  *
     229             :  * @param argc number of arguments from the command line
     230             :  * @param argv command line arguments
     231             :  * @return 0 ok, non-zero on error
     232             :  */
     233             : int
     234          57 : main (int argc,
     235             :       char *const *argv)
     236             : {
     237          57 :   const struct GNUNET_GETOPT_CommandLineOption options[] = {
     238          57 :     GNUNET_GETOPT_option_flag ('a',
     239             :                                "inject-auditor",
     240             :                                "inject auditor triggers",
     241             :                                &inject_auditor),
     242          57 :     GNUNET_GETOPT_option_string ('d',
     243             :                                  "disable-customization",
     244             :                                  "SCHEMA",
     245             :                                  "remove customization rules of SCHEMA",
     246             :                                  &disable_rules),
     247          57 :     GNUNET_GETOPT_option_string ('e',
     248             :                                  "enable-customization",
     249             :                                  "SCHEMA",
     250             :                                  "enable or update (to latest version) the customization rules of SCHEMA",
     251             :                                  &enable_rules),
     252          57 :     GNUNET_GETOPT_option_flag ('g',
     253             :                                "gc",
     254             :                                "garbage collect database",
     255             :                                &gc_db),
     256          57 :     GNUNET_GETOPT_option_flag ('r',
     257             :                                "reset",
     258             :                                "reset database (DANGEROUS: all existing data is lost!)",
     259             :                                &reset_db),
     260          57 :     GNUNET_GETOPT_option_flag ('s',
     261             :                                "shardunlock",
     262             :                                "unlock all revolving shard locks (use after system crash or shard size change while services are not running)",
     263             :                                &clear_shards),
     264          57 :     GNUNET_GETOPT_option_uint ('P',
     265             :                                "partition",
     266             :                                "NUMBER",
     267             :                                "Setup a partitioned database where each table which can be partitioned holds NUMBER partitions on a single DB node",
     268             :                                &num_partitions),
     269          57 :     GNUNET_GETOPT_option_flag ('f',
     270             :                                "force",
     271             :                                "Force partitions to be created if there is only one partition",
     272             :                                &force_create_partitions),
     273             :     GNUNET_GETOPT_OPTION_END
     274             :   };
     275             :   enum GNUNET_GenericReturnValue ret;
     276             : 
     277          57 :   ret = GNUNET_PROGRAM_run (
     278             :     TALER_EXCHANGE_project_data (),
     279             :     argc, argv,
     280             :     "taler-exchange-dbinit",
     281             :     gettext_noop ("Initialize Taler exchange database"),
     282             :     options,
     283             :     &run, NULL);
     284          57 :   if (GNUNET_SYSERR == ret)
     285           0 :     return EXIT_INVALIDARGUMENT;
     286          57 :   if (GNUNET_NO == ret)
     287           0 :     return EXIT_SUCCESS;
     288          57 :   return global_ret;
     289             : }
     290             : 
     291             : 
     292             : /* end of taler-exchange-dbinit.c */

Generated by: LCOV version 1.16