LCOV - code coverage report
Current view: top level - clients/mapiclient - msqldump.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 65 137 47.4 %
Date: 2021-10-13 02:24:04 Functions: 1 2 50.0 %

          Line data    Source code
       1             : /*
       2             :  * This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0.  If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       5             :  *
       6             :  * Copyright 1997 - July 2008 CWI, August 2008 - 2021 MonetDB B.V.
       7             :  */
       8             : 
       9             : #include "monetdb_config.h"
      10             : #ifndef HAVE_GETOPT_LONG
      11             : #  include "monet_getopt.h"
      12             : #else
      13             : # ifdef HAVE_GETOPT_H
      14             : #  include "getopt.h"
      15             : # endif
      16             : #endif
      17             : #include "mapi.h"
      18             : #include <unistd.h>
      19             : #include <sys/stat.h>
      20             : #include <string.h>
      21             : #include <time.h>
      22             : 
      23             : #include "stream.h"
      24             : #include "msqldump.h"
      25             : #define LIBMUTILS 1
      26             : #include "mprompt.h"
      27             : #include "mutils.h"           /* mercurial_revision */
      28             : #include "dotmonetdb.h"
      29             : 
      30             : static _Noreturn void usage(const char *prog, int xit);
      31             : 
      32             : static void
      33           0 : usage(const char *prog, int xit)
      34             : {
      35           0 :         fprintf(stderr, "Usage: %s [ options ] [ dbname ]\n", prog);
      36           0 :         fprintf(stderr, "\nOptions are:\n");
      37           0 :         fprintf(stderr, " -h hostname | --host=hostname    host to connect to\n");
      38           0 :         fprintf(stderr, " -p portnr   | --port=portnr      port to connect to\n");
      39           0 :         fprintf(stderr, " -u user     | --user=user        user id\n");
      40           0 :         fprintf(stderr, " -d database | --database=database  database to connect to\n");
      41           0 :         fprintf(stderr, " -f          | --functions        dump functions\n");
      42           0 :         fprintf(stderr, " -t table    | --table=table      dump a database table\n");
      43           0 :         fprintf(stderr, " -D          | --describe         describe database\n");
      44           0 :         fprintf(stderr, " -N          | --inserts          use INSERT INTO statements\n");
      45           0 :         fprintf(stderr, " -e          | --noescape         use NO ESCAPE\n");
      46           0 :         fprintf(stderr, " -q          | --quiet            don't print welcome message\n");
      47           0 :         fprintf(stderr, " -X          | --Xdebug           trace mapi network interaction\n");
      48           0 :         fprintf(stderr, " -?          | --help             show this usage message\n");
      49           0 :         fprintf(stderr, "--functions and --table are mutually exclusive\n");
      50           0 :         exit(xit);
      51             : }
      52             : 
      53             : int
      54             : #ifdef _MSC_VER
      55             : wmain(int argc, wchar_t **wargv)
      56             : #else
      57          25 : main(int argc, char **argv)
      58             : #endif
      59             : {
      60             :         int port = 0;
      61             :         char *user = NULL;
      62             :         char *passwd = NULL;
      63             :         char *host = NULL;
      64             :         char *dbname = NULL;
      65          25 :         DotMonetdb dotfile = {0};
      66             :         bool trace = false;
      67             :         bool describe = false;
      68             :         bool functions = false;
      69             :         bool useinserts = false;
      70             :         bool noescape = false;
      71             :         int c;
      72             :         Mapi mid;
      73             :         bool quiet = false;
      74             :         stream *out;
      75             :         bool user_set_as_flag = false;
      76             :         char *table = NULL;
      77             :         static struct option long_options[] = {
      78             :                 {"host", 1, 0, 'h'},
      79             :                 {"port", 1, 0, 'p'},
      80             :                 {"database", 1, 0, 'd'},
      81             :                 {"describe", 0, 0, 'D'},
      82             :                 {"functions", 0, 0, 'f'},
      83             :                 {"table", 1, 0, 't'},
      84             :                 {"inserts", 0, 0, 'N'},
      85             :                 {"noescape", 0, 0, 'e'},
      86             :                 {"Xdebug", 0, 0, 'X'},
      87             :                 {"user", 1, 0, 'u'},
      88             :                 {"quiet", 0, 0, 'q'},
      89             :                 {"version", 0, 0, 'v'},
      90             :                 {"help", 0, 0, '?'},
      91             :                 {0, 0, 0, 0}
      92             :         };
      93             : #ifdef _MSC_VER
      94             :         char **argv = malloc((argc + 1) * sizeof(char *));
      95             :         if (argv == NULL) {
      96             :                 fprintf(stderr, "cannot allocate memory for argument conversion\n");
      97             :                 exit(1);
      98             :         }
      99             :         for (int i = 0; i < argc; i++) {
     100             :                 if ((argv[i] = wchartoutf8(wargv[i])) == NULL) {
     101             :                         fprintf(stderr, "cannot convert argument to UTF-8\n");
     102             :                         exit(1);
     103             :                 }
     104             :         }
     105             :         argv[argc] = NULL;
     106             : #endif
     107             : 
     108          25 :         parse_dotmonetdb(&dotfile);
     109          25 :         user = dotfile.user;
     110          25 :         passwd = dotfile.passwd;
     111          25 :         dbname = dotfile.dbname;
     112          25 :         host = dotfile.host;
     113          25 :         port = dotfile.port;
     114             : 
     115         123 :         while ((c = getopt_long(argc, argv, "h:p:d:Dft:NeXu:qv?", long_options, NULL)) != -1) {
     116          99 :                 switch (c) {
     117           0 :                 case 'u':
     118           0 :                         if (user)
     119           0 :                                 free(user);
     120           0 :                         user = strdup(optarg);
     121             :                         user_set_as_flag = true;
     122           0 :                         break;
     123          24 :                 case 'h':
     124          24 :                         host = optarg;
     125          24 :                         break;
     126          24 :                 case 'p':
     127          24 :                         assert(optarg != NULL);
     128             :                         port = atoi(optarg);
     129          24 :                         break;
     130          24 :                 case 'd':
     131          24 :                         if (dbname)
     132           0 :                                 free(dbname);
     133          24 :                         dbname = strdup(optarg);
     134          24 :                         break;
     135             :                 case 'D':
     136             :                         describe = true;
     137             :                         break;
     138           1 :                 case 'N':
     139             :                         useinserts = true;
     140           1 :                         break;
     141           0 :                 case 'e':
     142             :                         noescape = true;
     143           0 :                         break;
     144           1 :                 case 'f':
     145           1 :                         if (table)
     146           0 :                                 usage(argv[0], -1);
     147             :                         functions = true;
     148             :                         break;
     149           0 :                 case 't':
     150           0 :                         if (table || functions)
     151           0 :                                 usage(argv[0], -1);
     152           0 :                         table = optarg;
     153           0 :                         break;
     154          24 :                 case 'q':
     155             :                         quiet = true;
     156          24 :                         break;
     157           0 :                 case 'X':
     158             :                         trace = true;
     159           0 :                         break;
     160           1 :                 case 'v': {
     161           1 :                         printf("msqldump, the MonetDB interactive database "
     162             :                                "dump tool, version %s", MONETDB_VERSION);
     163             : #ifdef MONETDB_RELEASE
     164             :                         printf(" (%s)", MONETDB_RELEASE);
     165             : #else
     166           1 :                         const char *rev = mercurial_revision();
     167           1 :                         if (strcmp(rev, "Unknown") != 0)
     168           0 :                                 printf(" (hg id: %s)", rev);
     169             : #endif
     170           1 :                         printf("\n");
     171           1 :                         return 0;
     172             :                 }
     173           0 :                 case '?':
     174             :                         /* a bit of a hack: look at the option that the
     175             :                            current `c' is based on and see if we recognize
     176             :                            it: if -? or --help, exit with 0, else with -1 */
     177           0 :                         usage(argv[0], strcmp(argv[optind - 1], "-?") == 0 || strcmp(argv[optind - 1], "--help") == 0 ? 0 : -1);
     178           0 :                 default:
     179           0 :                         usage(argv[0], -1);
     180             :                 }
     181             :         }
     182             : 
     183          24 :         if (optind == argc - 1)
     184           0 :                 dbname = strdup(argv[optind]);
     185          24 :         else if (optind != argc)
     186           0 :                 usage(argv[0], -1);
     187             : 
     188             :         /* when config file would provide defaults */
     189          24 :         if (user_set_as_flag)
     190             :                 passwd = NULL;
     191             : 
     192          24 :         if(dbname == NULL){
     193           0 :                 printf("msqldump, please specify a database\n");
     194           0 :                 usage(argv[0], -1);
     195             :         }
     196          24 :         if (user == NULL)
     197           0 :                 user = simple_prompt("user", BUFSIZ, 1, prompt_getlogin());
     198          24 :         if (passwd == NULL)
     199           0 :                 passwd = simple_prompt("password", BUFSIZ, 0, NULL);
     200             : 
     201          24 :         mid = mapi_mapi(host, port, user, passwd, "sql", dbname);
     202          24 :         if (user)
     203          24 :                 free(user);
     204          24 :         if (passwd)
     205          24 :                 free(passwd);
     206             :         if (dbname)
     207          24 :                 free(dbname);
     208          24 :         if (mid == NULL) {
     209           0 :                 fprintf(stderr, "failed to allocate Mapi structure\n");
     210           0 :                 exit(2);
     211             :         }
     212          24 :         mapi_set_time_zone(mid, 0);
     213          24 :         mapi_reconnect(mid);
     214          24 :         if (mapi_error(mid)) {
     215           0 :                 mapi_explain(mid, stderr);
     216           0 :                 exit(2);
     217             :         }
     218          24 :         if (!quiet) {
     219           0 :                 const char *motd = mapi_get_motd(mid);
     220             : 
     221           0 :                 if (motd)
     222           0 :                         fprintf(stderr, "%s", motd);
     223             :         }
     224          24 :         mapi_trace(mid, trace);
     225          24 :         mapi_cache_limit(mid, -1);
     226             : 
     227          24 :         out = stdout_wastream();
     228          24 :         if (out == NULL) {
     229           0 :                 fprintf(stderr, "failed to allocate stream: %s\n", mnstr_peek_error(NULL));
     230           0 :                 exit(2);
     231             :         }
     232          24 :         if (!quiet) {
     233             :                 char buf[27];
     234           0 :                 time_t t = time(0);
     235             :                 char *p;
     236             : 
     237             : #ifdef HAVE_CTIME_R3
     238             :                 ctime_r(&t, buf, sizeof(buf));
     239             : #else
     240             : #ifdef HAVE_CTIME_R
     241           0 :                 ctime_r(&t, buf);
     242             : #else
     243             :                 strcpy_len(buf, ctime(&t), sizeof(buf));
     244             : #endif
     245             : #endif
     246           0 :                 if ((p = strrchr(buf, '\n')) != NULL)
     247           0 :                         *p = 0;
     248             : 
     249           0 :                 mnstr_printf(out,
     250             :                              "-- msqldump version %s", MONETDB_VERSION);
     251             : #ifdef MONETDB_RELEASE
     252             :                 mnstr_printf(out, " (%s)", MONETDB_RELEASE);
     253             : #else
     254           0 :                 const char *rev = mercurial_revision();
     255           0 :                 if (strcmp(rev, "Unknown") != 0)
     256           0 :                         mnstr_printf(out, " (hg id: %s)", rev);
     257             : #endif
     258           0 :                 mnstr_printf(out, " %s %s%s\n",
     259             :                              describe ? "describe" : "dump",
     260           0 :                              functions ? "functions" : table ? "table " : "database",
     261             :                              table ? table : "");
     262           0 :                 dump_version(mid, out, "-- server:");
     263           0 :                 mnstr_printf(out, "-- %s\n", buf);
     264             :         }
     265          24 :         if (functions) {
     266           1 :                 mnstr_printf(out, "START TRANSACTION;\n");
     267           1 :                 c = dump_functions(mid, out, true, NULL, NULL, NULL);
     268           1 :                 mnstr_printf(out, "COMMIT;\n");
     269          23 :         } else if (table) {
     270           0 :                 mnstr_printf(out, "START TRANSACTION;\n");
     271           0 :                 c = dump_table(mid, NULL, table, out, describe, true, useinserts, false, noescape);
     272           0 :                 mnstr_printf(out, "COMMIT;\n");
     273             :         } else
     274          23 :                 c = dump_database(mid, out, describe, useinserts, noescape);
     275          24 :         mnstr_flush(out, MNSTR_FLUSH_DATA);
     276             : 
     277          24 :         mapi_destroy(mid);
     278          24 :         if (mnstr_errnr(out)) {
     279           0 :                 char *err = mnstr_error(out);
     280           0 :                 fprintf(stderr, "%s: %s\n", argv[0], err);
     281           0 :                 free(err);
     282           0 :                 return 1;
     283             :         }
     284             : 
     285          24 :         mnstr_destroy(out);
     286          24 :         return c;
     287             : }

Generated by: LCOV version 1.14