exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

taler-exchange-dbinit.c (8371B)


      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 "taler/platform.h"
     23 #include <gnunet/gnunet_util_lib.h>
     24 #include "taler/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 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   if (NULL ==
     93       (plugin = TALER_EXCHANGEDB_plugin_load (cfg,
     94                                               true)))
     95   {
     96     fprintf (stderr,
     97              "Failed to initialize database plugin.\n");
     98     global_ret = EXIT_NOTINSTALLED;
     99     return;
    100   }
    101   if (reset_db)
    102   {
    103     if (GNUNET_OK !=
    104         plugin->drop_tables (plugin->cls))
    105     {
    106       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   if (GNUNET_OK !=
    111       plugin->create_tables (plugin->cls,
    112                              force_create_partitions || num_partitions > 0,
    113                              num_partitions))
    114   {
    115     fprintf (stderr,
    116              "Failed to initialize database.\n");
    117     global_ret = EXIT_NOPERMISSION;
    118     goto exit;
    119   }
    120   if (gc_db || clear_shards)
    121   {
    122     if (GNUNET_OK !=
    123         plugin->preflight (plugin->cls))
    124     {
    125       fprintf (stderr,
    126                "Failed to prepare database.\n");
    127       global_ret = EXIT_NOPERMISSION;
    128       goto exit;
    129     }
    130     if (clear_shards)
    131     {
    132       if (GNUNET_OK !=
    133           plugin->delete_shard_locks (plugin->cls))
    134       {
    135         fprintf (stderr,
    136                  "Clearing revolving shards failed!\n");
    137       }
    138     }
    139     if (gc_db)
    140     {
    141       if (GNUNET_SYSERR == plugin->gc (plugin->cls))
    142       {
    143         fprintf (stderr,
    144                  "Garbage collection failed!\n");
    145       }
    146     }
    147   }
    148   if (inject_auditor)
    149   {
    150     if (GNUNET_SYSERR ==
    151         plugin->inject_auditor_triggers (plugin->cls))
    152     {
    153       fprintf (stderr,
    154                "Injecting auditor triggers failed!\n");
    155       global_ret = EXIT_FAILURE;
    156     }
    157   }
    158   if (NULL != disable_rules)
    159   {
    160     if (0 == strcasecmp (disable_rules,
    161                          "exchange"))
    162     {
    163       fprintf (stderr,
    164                "'exchange' is not a customization rule set!\n");
    165       global_ret = EXIT_INVALIDARGUMENT;
    166       goto exit;
    167     }
    168     if (GNUNET_OK !=
    169         plugin->preflight (plugin->cls))
    170     {
    171       fprintf (stderr,
    172                "Preflight check failed!\n");
    173       global_ret = EXIT_FAILURE;
    174       goto exit;
    175     }
    176     switch (plugin->disable_rules (plugin->cls,
    177                                    disable_rules))
    178     {
    179     case GNUNET_DB_STATUS_HARD_ERROR:
    180       fprintf (stderr,
    181                "Hard DB error trying to disable customization!\n");
    182       global_ret = EXIT_FAILURE;
    183       goto exit;
    184     case GNUNET_DB_STATUS_SOFT_ERROR:
    185       /* single call, should not be possible */
    186       GNUNET_break (0);
    187       global_ret = EXIT_FAILURE;
    188       goto exit;
    189     case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
    190       GNUNET_log (GNUNET_ERROR_TYPE_INFO,
    191                   "Nothing to do to disable customization schema `%s'\n",
    192                   disable_rules);
    193       break;
    194     case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
    195       break;
    196     }
    197   }
    198   if (NULL != enable_rules)
    199   {
    200     if (0 == strcasecmp (enable_rules,
    201                          "exchange"))
    202     {
    203       fprintf (stderr,
    204                "'exchange' is not a customization rule set!\n");
    205       global_ret = EXIT_INVALIDARGUMENT;
    206       goto exit;
    207     }
    208     if (GNUNET_OK !=
    209         plugin->enable_rules (plugin->cls,
    210                               enable_rules))
    211     {
    212       fprintf (stderr,
    213                "Enabling customization `%s' failed!\n",
    214                enable_rules);
    215       global_ret = EXIT_FAILURE;
    216       goto exit;
    217     }
    218   }
    219 exit:
    220   TALER_EXCHANGEDB_plugin_unload (plugin);
    221   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 main (int argc,
    235       char *const *argv)
    236 {
    237   const struct GNUNET_GETOPT_CommandLineOption options[] = {
    238     GNUNET_GETOPT_option_flag ('a',
    239                                "inject-auditor",
    240                                "inject auditor triggers",
    241                                &inject_auditor),
    242     GNUNET_GETOPT_option_string ('d',
    243                                  "disable-customization",
    244                                  "SCHEMA",
    245                                  "remove customization rules of SCHEMA",
    246                                  &disable_rules),
    247     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     GNUNET_GETOPT_option_flag ('g',
    253                                "gc",
    254                                "garbage collect database",
    255                                &gc_db),
    256     GNUNET_GETOPT_option_flag ('r',
    257                                "reset",
    258                                "reset database (DANGEROUS: all existing data is lost!)",
    259                                &reset_db),
    260     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     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     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   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   if (GNUNET_SYSERR == ret)
    285     return EXIT_INVALIDARGUMENT;
    286   if (GNUNET_NO == ret)
    287     return EXIT_SUCCESS;
    288   return global_ret;
    289 }
    290 
    291 
    292 /* end of taler-exchange-dbinit.c */