Changeset: 3375a722bb1e for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=3375a722bb1e
Modified Files:
        clients/ChangeLog
        clients/src/mapiclient/dump.c
        clients/src/mapiclient/mclient.1
        clients/src/mapiclient/mclient.c
        clients/src/mapiclient/msqldump.1
        clients/src/mapiclient/msqldump.c
        clients/src/mapiclient/msqldump.h
Branch: default
Log Message:

implement bug #2727: allow using INSERT INTO statements in dump

INSERT INTO statements are more portable, and a necessity when using
loaders that have to adhere to a query & answer protocol, such as most
data source abstractions (most well known and standardised ones: ODBC
and JDBC).


diffs (truncated from 380 to 300 lines):

diff -r 0b23355e3a17 -r 3375a722bb1e clients/ChangeLog
--- a/clients/ChangeLog Fri Dec 10 12:46:17 2010 +0100
+++ b/clients/ChangeLog Fri Dec 10 13:52:46 2010 +0100
@@ -1,6 +1,11 @@
 # ChangeLog file for clients
 # This file is updated with Maddlog
 
+* Fri Dec 10 2010 Fabian Groffen <fab...@cwi.nl>
+- Allow to dump table data using INSERT INTO statements, rather than COPY
+  INTO + CSV data using the -N/--inserts flag of mclient and msqldump.
+  Bug #2727
+
 * Wed Dec  8 2010 Fabian Groffen <fab...@cwi.nl>
 - Added support for \dn to list schemas or describe a specific one
 
diff -r 0b23355e3a17 -r 3375a722bb1e clients/src/mapiclient/dump.c
--- a/clients/src/mapiclient/dump.c     Fri Dec 10 12:46:17 2010 +0100
+++ b/clients/src/mapiclient/dump.c     Fri Dec 10 13:52:46 2010 +0100
@@ -34,14 +34,23 @@
 #endif
 
 static void
-quoted_print(stream *f, const char *s)
+quoted_print(stream *f, const char *s, const char singleq)
 {
-       mnstr_write(f, "\"", 1, 1);
+       mnstr_write(f, singleq ? "'" : "\"", 1, 1);
        while (*s) {
                switch (*s) {
                case '\\':
+                       mnstr_write(f, "\\", 1, 1);
+                       mnstr_write(f, s, 1, 1);
+                       break;
                case '"':
-                       mnstr_write(f, "\\", 1, 1);
+                       if (!singleq)
+                               mnstr_write(f, "\\", 1, 1);
+                       mnstr_write(f, s, 1, 1);
+                       break;
+               case '\'':
+                       if (singleq)
+                               mnstr_write(f, "\\", 1, 1);
                        mnstr_write(f, s, 1, 1);
                        break;
                case '\n':
@@ -59,7 +68,7 @@
                }
                s++;
        }
-       mnstr_write(f, "\"", 1, 1);
+       mnstr_write(f, singleq ? "'" : "\"", 1, 1);
 }
 
 static char *actions[] = {
@@ -1004,7 +1013,8 @@
 }
 
 int
-dump_table_data(Mapi mid, char *schema, char *tname, stream *toConsole)
+dump_table_data(Mapi mid, char *schema, char *tname, stream *toConsole,
+               const char useInserts)
 {
        int cnt, i;
        MapiHdl hdl = NULL;
@@ -1042,9 +1052,9 @@
                goto bailout;
        if (mapi_rows_affected(hdl) != 1) {
                if (mapi_rows_affected(hdl) == 0)
-                       fprintf(stderr, "Table %s.%s does not exist.\n", 
schema, tname);
+                       fprintf(stderr, "table '%s.%s' does not exist\n", 
schema, tname);
                else
-                       fprintf(stderr, "Table %s.%s not unique.\n", schema, 
tname);
+                       fprintf(stderr, "table '%s.%s' is not unique\n", 
schema, tname);
                goto bailout;
        }
        while ((mapi_fetch_row(hdl)) != 0) {
@@ -1058,25 +1068,27 @@
        mapi_close_handle(hdl);
        hdl = NULL;
 
-       snprintf(query, maxquerylen, "SELECT count(*) FROM \"%s\".\"%s\"",
-                schema, tname);
-       if ((hdl = mapi_query(mid, query)) == NULL || mapi_error(mid))
-               goto bailout;
-       if (mapi_fetch_row(hdl)) {
-               char *cntfld = mapi_fetch_field(hdl, 0);
+       if (!useInserts) {
+               snprintf(query, maxquerylen, "SELECT count(*) FROM 
\"%s\".\"%s\"",
+                        schema, tname);
+               if ((hdl = mapi_query(mid, query)) == NULL || mapi_error(mid))
+                       goto bailout;
+               if (mapi_fetch_row(hdl)) {
+                       char *cntfld = mapi_fetch_field(hdl, 0);
 
-               if (strcmp(cntfld, "0") == 0) {
-                       /* no records to dump, so return early */
-                       goto doreturn;
+                       if (strcmp(cntfld, "0") == 0) {
+                               /* no records to dump, so return early */
+                               goto doreturn;
+                       }
+
+                       mnstr_printf(toConsole,
+                                        "COPY %s RECORDS INTO \"%s\".\"%s\" "
+                                        "FROM stdin USING DELIMITERS 
'\\t','\\n','\"';\n",
+                                        cntfld, schema, tname);
                }
-
-               mnstr_printf(toConsole,
-                            "COPY %s RECORDS INTO \"%s\".\"%s\" "
-                            "FROM stdin USING DELIMITERS '\\t','\\n','\"';\n",
-                            cntfld, schema, tname);
+               mapi_close_handle(hdl);
+               hdl = NULL;
        }
-       mapi_close_handle(hdl);
-       hdl = NULL;
 
        snprintf(query, maxquerylen, "SELECT * FROM \"%s\".\"%s\"",
                 schema, tname);
@@ -1096,20 +1108,32 @@
        while (mapi_fetch_row(hdl)) {
                char *s;
 
+               if (useInserts)
+                       mnstr_printf(toConsole, "INSERT INTO \"%s\".\"%s\" 
VALUES (",
+                                       schema, tname);
+
                for (i = 0; i < cnt; i++) {
                        s = mapi_fetch_field(hdl, i);
                        if (s == NULL)
                                mnstr_printf(toConsole, "NULL");
                        else if (string[i]) {
-                               /* write double-quoted string with
+                               /* write double or single-quoted string with
                                   certain characters escaped */
-                               quoted_print(toConsole, s);
+                               quoted_print(toConsole, s, useInserts);
                        } else
                                mnstr_printf(toConsole, "%s", s);
-                       if (i < cnt - 1)
-                               mnstr_write(toConsole, "\t", 1, 1);
-                       else
-                               mnstr_write(toConsole, "\n", 1, 1);
+
+                       if (useInserts) {
+                               if (i < cnt - 1)
+                                       mnstr_printf(toConsole, ", ");
+                               else
+                                       mnstr_printf(toConsole, ");\n");
+                       } else {
+                               if (i < cnt - 1)
+                                       mnstr_write(toConsole, "\t", 1, 1);
+                               else
+                                       mnstr_write(toConsole, "\n", 1, 1);
+                       }
                }
                if (mnstr_errnr(toConsole))
                        goto bailout;
@@ -1144,13 +1168,13 @@
 }
 
 int
-dump_table(Mapi mid, char *schema, char *tname, stream *toConsole, int 
describe, int foreign)
+dump_table(Mapi mid, char *schema, char *tname, stream *toConsole, int 
describe, int foreign, const char useInserts)
 {
        int rc;
 
        rc = describe_table(mid, schema, tname, toConsole, foreign);
        if (rc == 0 && !describe)
-               rc = dump_table_data(mid, schema, tname, toConsole);
+               rc = dump_table_data(mid, schema, tname, toConsole, useInserts);
        return rc;
 }
 
@@ -1364,7 +1388,7 @@
 }
 
 int
-dump_database(Mapi mid, stream *toConsole, int describe)
+dump_database(Mapi mid, stream *toConsole, int describe, const char useInserts)
 {
        const char *start = "START TRANSACTION";
        const char *end = "ROLLBACK";
@@ -1715,7 +1739,7 @@
                        if (schema)
                                schema = strdup(schema);
                        tname = strdup(tname);
-                       rc = dump_table(mid, schema, tname, toConsole, 
describe, describe);
+                       rc = dump_table(mid, schema, tname, toConsole, 
describe, describe, useInserts);
                        if (schema)
                                free(schema);
                        free(tname);
diff -r 0b23355e3a17 -r 3375a722bb1e clients/src/mapiclient/mclient.1
--- a/clients/src/mapiclient/mclient.1  Fri Dec 10 12:46:17 2010 +0100
+++ b/clients/src/mapiclient/mclient.1  Fri Dec 10 13:52:46 2010 +0100
@@ -218,6 +218,12 @@
 .TP
 \fB\-\-dump\fP (\fB\-D\fP)
 Create an SQL dump.
+.TP
+\fB\-\-inserts\fP (\fB\-N\fP)
+Use INSERT INTO statements instead of COPY INTO + CSV values when
+dumping the data of a table.  This option can be used when trying to
+load data from MonetDB into another database, or when e.g. JDBC
+applications are used to reload the dump.
 .SS
 XQuery Options
 .TP
diff -r 0b23355e3a17 -r 3375a722bb1e clients/src/mapiclient/mclient.c
--- a/clients/src/mapiclient/mclient.c  Fri Dec 10 12:46:17 2010 +0100
+++ b/clients/src/mapiclient/mclient.c  Fri Dec 10 13:52:46 2010 +0100
@@ -1769,7 +1769,7 @@
 #define MD_SCHEMA  16
 
 static int
-doFileByLines(Mapi mid, FILE *fp, const char *prompt)
+doFileByLines(Mapi mid, FILE *fp, const char *prompt, const char useinserts)
 {
        char *line = NULL;
        char *oldbuf = NULL, *buf = NULL;
@@ -2202,10 +2202,10 @@
 #endif
                                        if (*line) {
                                                mnstr_printf(toConsole, "START 
TRANSACTION;\n");
-                                               dump_table(mid, NULL, line, 
toConsole, 0, 1);
+                                               dump_table(mid, NULL, line, 
toConsole, 0, 1, useinserts);
                                                mnstr_printf(toConsole, 
"COMMIT;\n");
                                        } else
-                                               dump_database(mid, toConsole, 
0);
+                                               dump_database(mid, toConsole, 
0, useinserts);
 #ifdef HAVE_POPEN
                                        end_pager(saveFD, saveFD_raw);
 #endif
@@ -2448,6 +2448,7 @@
        fprintf(stderr, " -r nr       | --rows=nr          for pagination\n");
        fprintf(stderr, " -w nr       | --width=nr         for pagination\n");
        fprintf(stderr, " -D          | --dump             create an SQL 
dump\n");
+       fprintf(stderr, " -N          | --inserts          use INSERT INTO 
statements when dumping\n");
 
        fprintf(stderr, "\nXQuery specific options\n");
        fprintf(stderr, " -C colname  | --collection=colname  collection 
name\n");
@@ -2473,6 +2474,7 @@
        char *colname = NULL;
        int trace = 0;
        int dump = 0;
+       int useinserts = 0;
        int algebra = -1;
        int c = 0;
        Mapi mid;
@@ -2489,6 +2491,7 @@
                {"collection", 1, 0, 'C'},
                {"database", 1, 0, 'd'},
                {"dump", 0, 0, 'D'},
+               {"inserts", 0, 0, 'N'},
                {"echo", 0, 0, 'e'},
 #ifdef HAVE_ICONV
                {"encoding", 1, 0, 'E'},
@@ -2632,7 +2635,7 @@
                mnstr_destroy(config);
        }
 
-       while ((c = getopt_long(argc, argv, "C:Dd:e"
+       while ((c = getopt_long(argc, argv, "C:DNd:e"
 #ifdef HAVE_ICONV
                                "E:"
 #endif
@@ -2728,6 +2731,9 @@
                case 'D':
                        dump = 1;
                        break;
+               case 'N':
+                       useinserts = 1;
+                       break;
                case 'd':
                        dbname = optarg;
                        break;
@@ -2836,7 +2842,7 @@
        mapi_cache_limit(mid, -1);
        if (dump) {
                if (mode == SQL) {
-                       exit(dump_database(mid, toConsole, 0));
+                       exit(dump_database(mid, toConsole, 0, useinserts));
                } else {
                        fprintf(stderr, "Dump only supported for SQL\n");
                        exit(1);
@@ -2948,7 +2954,7 @@
                                } else {
                                        /* note that since fp != stdin,
                                           we don't treat \ special */
-                                       c |= doFileByLines(mid, fp, NULL);
+                                       c |= doFileByLines(mid, fp, NULL, 
useinserts);
                                        fclose(fp);
                                }
                        } else
@@ -2972,7 +2978,7 @@
                        fromConsole = stdin;
                }
                /* use default rendering if not overruled at commandline */
-               c = doFileByLines(mid, stdin, prompt);
_______________________________________________
Checkin-list mailing list
Checkin-list@monetdb.org
http://mail.monetdb.org/mailman/listinfo/checkin-list

Reply via email to