Changeset: 35bc925d2e12 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/35bc925d2e12
Modified Files:
        clients/ChangeLog
        clients/mapiclient/dump.c
        clients/mapiclient/mclient.c
        clients/mapiclient/msqldump.1
        clients/mapiclient/msqldump.c
        clients/mapiclient/msqldump.h
        tools/monetdbe/monetdbe_mapi.c
Branch: default
Log Message:

Implemented % wildcards for the -t option of msqldump.


diffs (243 lines):

diff --git a/clients/ChangeLog b/clients/ChangeLog
--- a/clients/ChangeLog
+++ b/clients/ChangeLog
@@ -1,6 +1,12 @@
 # ChangeLog file for clients
 # This file is updated with Maddlog
 
+* Wed Jan 24 2024 Sjoerd Mullender <[email protected]>
+- The --table (-t) option of msqldump now accepts SQL-style % wildcard
+  characters to dump all tables that match the pattern.  E.g. -t
+  %test%.%test% dumps all tables with 'test' in both the schema and
+  table name.
+
 * Wed Jan 10 2024 Sjoerd Mullender <[email protected]>
 - Implemented interrupt handling in mclient.  When using mclient
   interactively, an interrupt (usually control-C) stops whatever the
diff --git a/clients/mapiclient/dump.c b/clients/mapiclient/dump.c
--- a/clients/mapiclient/dump.c
+++ b/clients/mapiclient/dump.c
@@ -249,7 +249,7 @@ bailout:
                else if (mapi_error(mid))
                        mapi_explain_query(hdl, stderr);
                else
-                       fprintf(stderr, "malloc failure1\n");
+                       fprintf(stderr, "malloc failure\n");
                mapi_close_handle(hdl);
        } else if (mapi_error(mid))
                mapi_explain(mid, stderr);
@@ -2086,24 +2086,112 @@ dump_table_defaults(Mapi mid, const char
 int
 dump_table(Mapi mid, const char *schema, const char *tname, stream *toConsole,
                   bool describe, bool foreign, bool useInserts, bool 
databaseDump,
-                  bool noescape)
+                  bool noescape, bool percent)
 {
        char *sname = NULL;
-       int rc;
+       int rc = 1;
 
        if (schema == NULL) {
                if ((sname = strchr(tname, '.')) != NULL) {
                        size_t len = sname - tname + 1;
 
                        sname = malloc(len);
-                       if (sname == NULL)
+                       if (sname == NULL) {
+                               fprintf(stderr, "malloc failure\n");
                                return 1;
+                       }
                        strcpy_len(sname, tname, len);
                        tname += len;
                } else if ((sname = get_schema(mid)) == NULL) {
                        return 1;
                }
                schema = sname;
+
+               if (percent && (strchr(schema, '%') != NULL || strchr(tname, 
'%') != NULL)) {
+                       char *s = sescape(schema);
+                       char *t = sescape(tname);
+                       if (s == NULL || t == NULL) {
+                               free(s);
+                               free(t);
+                               fprintf(stderr, "malloc failure\n");
+                               goto doreturn;
+                       }
+                       size_t qlen = strlen(s) + strlen(t) + 256;
+                       char *query = malloc(qlen);
+                       if (query == NULL) {
+                               free(s);
+                               free(t);
+                               fprintf(stderr, "malloc failure\n");
+                               goto doreturn;
+                       }
+                       snprintf(query, qlen, "SELECT s.name, t.name FROM 
sys._tables t, sys.schemas s WHERE t.schema_id = s.id AND s.name LIKE '%s' AND 
t.name LIKE '%s' ORDER BY t.id", s, t);
+                       free(s);
+                       free(t);
+                       MapiHdl hdl = mapi_query(mid, query);
+                       free(query);
+                       if (hdl == NULL) {
+                               if (mapi_error(mid))
+                                       mapi_explain(mid, stderr);
+                               else
+                                       fprintf(stderr, "malloc failure\n");
+                               goto doreturn;
+                       }
+                       if (mapi_error(mid)) {
+                               if (mapi_result_error(hdl))
+                                       mapi_explain_result(hdl, stderr);
+                               else if (mapi_error(mid))
+                                       mapi_explain_query(hdl, stderr);
+                               else
+                                       fprintf(stderr, "malloc failure\n");
+                               mapi_close_handle(hdl);
+                               goto doreturn;
+                       }
+                       struct tables {
+                               char *schema;
+                               char *table;
+                       } *tables;
+                       int64_t rows = mapi_get_row_count(hdl);
+                       if (rows == 0) {
+                               mapi_close_handle(hdl);
+                               fprintf(stderr, "no tables matching %s.%s\n", 
schema, tname);
+                               goto doreturn;
+                       }
+                       tables = malloc(rows * sizeof(struct tables));
+                       if (tables == NULL) {
+                               mapi_close_handle(hdl);
+                               fprintf(stderr, "malloc failure\n");
+                               goto doreturn;
+                       }
+                       for (int64_t i = 0; i < rows; i++) {
+                               mapi_fetch_row(hdl);
+                               tables[i].schema = strdup(mapi_fetch_field(hdl, 
0));
+                               tables[i].table = strdup(mapi_fetch_field(hdl, 
1));
+                               if (tables[i].schema == NULL || tables[i].table 
== NULL) {
+                                       do {
+                                               free(tables[i].schema);
+                                               free(tables[i].table);
+                                       } while (i-- > 0);
+                                       free(tables);
+                                       mapi_close_handle(hdl);
+                                       fprintf(stderr, "malloc failure\n");
+                                       goto doreturn;
+                               }
+                       }
+                       mapi_close_handle(hdl);
+                       for (int64_t i = 0; i < rows; i++) {
+                               rc = dump_table(mid, tables[i].schema, 
tables[i].table, toConsole,
+                                                               describe, 
foreign, useInserts, databaseDump,
+                                                               noescape, 
false);
+                               if (rc != 0)
+                                       break;
+                       }
+                       for (int64_t i = 0; i < rows; i++) {
+                               free(tables[i].schema);
+                               free(tables[i].table);
+                       }
+                       free(tables);
+                       goto doreturn;
+               }
        }
 
        rc = describe_table(mid, schema, tname, toConsole, foreign, 
databaseDump);
@@ -2115,6 +2203,7 @@ dump_table(Mapi mid, const char *schema,
                rc = dump_table_access(mid, schema, tname, toConsole);
        if (rc == 0 && !databaseDump)
                rc = dump_table_defaults(mid, schema, tname, toConsole);
+  doreturn:
        free(sname);                            /* may be NULL, but that's OK */
        return rc;
 }
@@ -3073,7 +3162,7 @@ dump_database(Mapi mid, stream *toConsol
                        }
                }
                int ptype = atoi(type), dont_describe = (ptype == 3 || ptype == 
5);
-               rc = dump_table(mid, schema, name, toConsole, dont_describe || 
describe, describe, useInserts, true, noescape);
+               rc = dump_table(mid, schema, name, toConsole, dont_describe || 
describe, describe, useInserts, true, noescape, false);
                free(id);
                free(schema);
                free(name);
diff --git a/clients/mapiclient/mclient.c b/clients/mapiclient/mclient.c
--- a/clients/mapiclient/mclient.c
+++ b/clients/mapiclient/mclient.c
@@ -2640,8 +2640,8 @@ doFile(Mapi mid, stream *fp, bool useins
 
                                                start_pager(&saveFD);
 #endif
-                                               if (x & MD_TABLE || x & MD_VIEW)
-                                                       dump_table(mid, NULL, 
line, toConsole, true, true, false, false, false);
+                                               if (x & (MD_TABLE | MD_VIEW))
+                                                       dump_table(mid, NULL, 
line, toConsole, true, true, false, false, false, false);
                                                if (x & MD_SEQ)
                                                        describe_sequence(mid, 
NULL, line, toConsole);
                                                if (x & MD_FUNC)
@@ -2799,7 +2799,7 @@ doFile(Mapi mid, stream *fp, bool useins
 #endif
                                        if (*line) {
                                                mnstr_printf(toConsole, "START 
TRANSACTION;\n");
-                                               dump_table(mid, NULL, line, 
toConsole, false, true, useinserts, false, false);
+                                               dump_table(mid, NULL, line, 
toConsole, false, true, useinserts, false, false, false);
                                                mnstr_printf(toConsole, 
"COMMIT;\n");
                                        } else
                                                dump_database(mid, toConsole, 
false, useinserts, false);
diff --git a/clients/mapiclient/msqldump.1 b/clients/mapiclient/msqldump.1
--- a/clients/mapiclient/msqldump.1
+++ b/clients/mapiclient/msqldump.1
@@ -98,8 +98,17 @@ query.
 \fB\-\-functions\fP (\fB\-f\fP)
 Only dump functions definitions.
 .TP
-\fB\-\-table=\fP\fItable\fP (\fB\-t\fP \fItable\fP)
-Only dump the specified \fItable\fP.
+\fB\-\-table=[\fIschema\fP\fB.\fP]\fItable\fP (\fB\-t\fP 
[\fIschema\fP\fB.\fP]\fItable\fP)
+Only dump the specified table.
+If
+.I schema
+is not specified, the user's current schema is used.
+When either
+.I schema
+or
+.I table
+contains percent characters, all tables matching the (SQL) search
+pattern are dumped.
 .TP
 \fB\-\-quiet\fP (\fB\-q\fP)
 Don't print the welcome message.
diff --git a/clients/mapiclient/msqldump.c b/clients/mapiclient/msqldump.c
--- a/clients/mapiclient/msqldump.c
+++ b/clients/mapiclient/msqldump.c
@@ -284,7 +284,7 @@ main(int argc, char **argv)
                mnstr_printf(out, "COMMIT;\n");
        } else if (table) {
                mnstr_printf(out, "START TRANSACTION;\n");
-               c = dump_table(mid, NULL, table, out, describe, true, 
useinserts, false, noescape);
+               c = dump_table(mid, NULL, table, out, describe, true, 
useinserts, false, noescape, true);
                mnstr_printf(out, "COMMIT;\n");
        } else
                c = dump_database(mid, out, describe, useinserts, noescape);
diff --git a/clients/mapiclient/msqldump.h b/clients/mapiclient/msqldump.h
--- a/clients/mapiclient/msqldump.h
+++ b/clients/mapiclient/msqldump.h
@@ -12,7 +12,7 @@
 
 extern int describe_sequence(Mapi mid, const char *schema, const char *sname, 
stream *toConsole);
 extern int describe_schema(Mapi mid, const char *sname, stream *toConsole);
-extern int dump_table(Mapi mid, const char *schema, const char *tname, stream 
*toConsole, bool describe, bool foreign, bool useInserts, bool databaseDump, 
bool noescape);
+extern int dump_table(Mapi mid, const char *schema, const char *tname, stream 
*toConsole, bool describe, bool foreign, bool useInserts, bool databaseDump, 
bool noescape, bool percent);
 extern int dump_functions(Mapi mid, stream *toConsole, char set_schema, const 
char *sname, const char *fname, const char *id);
 extern int dump_database(Mapi mid, stream *toConsole, bool describe, bool 
useInserts, bool noescape);
 extern void dump_version(Mapi mid, stream *toConsole, const char *prefix);
diff --git a/tools/monetdbe/monetdbe_mapi.c b/tools/monetdbe/monetdbe_mapi.c
--- a/tools/monetdbe/monetdbe_mapi.c
+++ b/tools/monetdbe/monetdbe_mapi.c
@@ -313,7 +313,7 @@ monetdbe_mapi_dump_table(monetdbe_databa
        /* open file stream */
        stream *fd = open_wastream(filename);
        if (fd) {
-               if (dump_table(&mid, sname, tname, fd, false, false, false, 
false, false)) {
+               if (dump_table(&mid, sname, tname, fd, false, false, false, 
false, false, false)) {
                        if (mid.msg)
                                msg = mid.msg;
                }
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to