LCOV - code coverage report
Current view: top level - clients/mapiclient - msqldump.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 87 170 51.2 %
Date: 2024-04-25 20:03:45 Functions: 1 2 50.0 %

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

Generated by: LCOV version 1.14