]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
In the command-line shell, enhance the ".schema" command show that it
authordrh <drh@noemail.net>
Thu, 15 Jun 2017 12:21:09 +0000 (12:21 +0000)
committerdrh <drh@noemail.net>
Thu, 15 Jun 2017 12:21:09 +0000 (12:21 +0000)
shows the schema for ATTACH-ed databases in addition to "main".

FossilOrigin-Name: 48e086284a76da10a85315bc992e2294bd4711e35ec5a5abaa16e39a6a69d206

manifest
manifest.uuid
src/shell.c

index 0c507aca093170a973957e7a92c19c1e50567958..3f17a44ce25d2795649b14d92212bbdd368b14b7 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Enhance\sthe\ssqlite3_analyzer.exe\sutility\sso\sthat\sit\scomputes\sand\sshows\sthe\nnumber\sof\sbytes\sof\smetadata\son\sbtree\spages\sand\sper\stable\sand\sindex\sentry.
-D 2017-06-15T00:52:03.263
+C In\sthe\scommand-line\sshell,\senhance\sthe\s".schema"\scommand\sshow\sthat\sit\nshows\sthe\sschema\sfor\sATTACH-ed\sdatabases\sin\saddition\sto\s"main".
+D 2017-06-15T12:21:09.255
 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb
 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
 F Makefile.msc 8eeb80162074004e906b53d7340a12a14c471a83743aab975947e95ce061efcc
@@ -406,7 +406,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
 F src/resolve.c adf3ef9843135b1383321ad751f16f5a40c3f37925154555a3e61653d2a954e8
 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
 F src/select.c 0d2afdbdba5fbc61432c5454a35e0236e7aa4aa3756986a7d51b81a508e8083a
-F src/shell.c a43292634af8e3528fec5c6e3360f122fc807a0af619d566ea44fdb98dcfca78
+F src/shell.c 41671b1b9cfed9d1686699ae91ce6ee6e2a8cac5d148a99e2a363a209c549ad8
 F src/sqlite.h.in 67fa8bd29808e7988e0ce36c8d4c6043eb1727f94522fc612687aa5af51931e6
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
 F src/sqlite3ext.h 58fd0676d3111d02e62e5a35992a7d3da5d3f88753acc174f2d37b774fbbdd28
@@ -1582,7 +1582,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P c433672dd8ab625628bde2f4f40a2dc000ed915dbe91833d3f753d8ab51baf25
-R 3118b76870f7c5e12e646d6dc51a9560
+P 43ad41efa9e1fdd79a9804197a227491236495f14ed56c656224d6ce181703c1
+R d9f0817a6699b9c8517903bc72312e9f
 U drh
-Z 30d19856ae4fa68d439f06a24db9ac5d
+Z 79d9a69908657f1d338372f7df43a962
index a8b314a01d95155a3a857d2207f82f8b9a5d93f8..533cc2e1a1a558304b287ac594030399e15299c8 100644 (file)
@@ -1 +1 @@
-43ad41efa9e1fdd79a9804197a227491236495f14ed56c656224d6ce181703c1
\ No newline at end of file
+48e086284a76da10a85315bc992e2294bd4711e35ec5a5abaa16e39a6a69d206
\ No newline at end of file
index 36f6970d1f14451f8284a1e249839c32da6563e8..706d3ada6859c02f85e34b76163c5cec82bcca82 100644 (file)
@@ -1185,6 +1185,61 @@ static unsigned char *SHA3Final(SHA3Context *p){
   return &p->u.x[p->nRate];
 }
 
+/*
+** SQL function:  shell_add_schema(S,X)
+**
+** Add the schema name X to the CREATE statement in S and return the result.
+** Examples:
+**
+**    CREATE TABLE t1(x)   ->   CREATE TABLE xyz.t1(x);
+**
+** Also works on
+**
+**    CREATE INDEX
+**    CREATE UNIQUE INDEX
+**    CREATE VIEW
+**    CREATE TRIGGER
+**    CREATE VIRTUAL TABLE
+**
+** This UDF is used by the .schema command to insert the schema name of
+** attached databases into the middle of the sqlite_master.sql field.
+*/
+static void shellAddSchemaName(
+  sqlite3_context *pCtx,
+  int nVal,
+  sqlite3_value **apVal
+){
+  static const char *aPrefix[] = {
+     "TABLE",
+     "INDEX",
+     "UNIQUE INDEX",
+     "VIEW",
+     "TRIGGER",
+     "VIRTUAL TABLE"
+  };
+  int i = 0, n;
+  const char *zIn = (const char*)sqlite3_value_text(apVal[0]);
+  const char *zSchema = (const char*)sqlite3_value_text(apVal[1]);
+  assert( nVal==2 );
+  if( zIn!=0 && strncmp(zIn, "CREATE ", 7)==0 ){
+    for(i=0; i<sizeof(aPrefix)/sizeof(aPrefix[0]); i++){
+      int n = strlen30(aPrefix[i]);
+      if( strncmp(zIn+7, aPrefix[i], n)==0 && zIn[n+7]==' ' ){
+        char cQuote = quoteChar(zSchema);
+        char *z;
+        if( cQuote ){
+         z = sqlite3_mprintf("%.*s \"%w\".%s", n+7, zIn, zSchema, zIn+n+8);
+        }else{
+          z = sqlite3_mprintf("%.*s %s.%s", n+7, zIn, zSchema, zIn+n+8);
+        }
+        sqlite3_result_text(pCtx, z, -1, sqlite3_free);
+        return;
+      }
+    }
+  }
+  sqlite3_result_value(pCtx, apVal[0]);
+}
+
 /*
 ** Implementation of the sha3(X,SIZE) function.
 **
@@ -3536,6 +3591,9 @@ static void open_db(ShellState *p, int keepAlive){
                             sha3QueryFunc, 0, 0);
     sqlite3_create_function(p->db, "sha3_query", 2, SQLITE_UTF8, 0,
                             sha3QueryFunc, 0, 0);
+    sqlite3_create_function(p->db, "shell_add_schema", 2, SQLITE_UTF8, 0,
+                            shellAddSchemaName, 0, 0);
+                            
   }
 }
 
@@ -5689,12 +5747,17 @@ static int do_meta_command(char *zLine, ShellState *p){
   }else
 
   if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
+    ShellText sSelect;
     ShellState data;
     char *zErrMsg = 0;
+    const char *zDiv = 0;
+    int iSchema = 0;
+
     open_db(p, 0);
     memcpy(&data, p, sizeof(data));
     data.showHeader = 0;
     data.cMode = data.mode = MODE_Semi;
+    initText(&sSelect);
     if( nArg>=2 && optionMatch(azArg[1], "indent") ){
       data.cMode = data.mode = MODE_Pretty;
       nArg--;
@@ -5732,33 +5795,62 @@ static int do_meta_command(char *zLine, ShellState *p){
         callback(&data, 1, new_argv, new_colv);
         rc = SQLITE_OK;
       }else{
-        char *zSql;
-        zSql = sqlite3_mprintf(
-          "SELECT sql FROM "
-          "  (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
-          "     FROM sqlite_master UNION ALL"
-          "   SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
-          "WHERE lower(tbl_name) LIKE %Q"
-          "  AND type!='meta' AND sql NOTNULL "
-          "ORDER BY rowid", azArg[1]);
-        rc = sqlite3_exec(p->db, zSql, callback, &data, &zErrMsg);
-        sqlite3_free(zSql);
+        zDiv = "(";
       }
     }else if( nArg==1 ){
-      rc = sqlite3_exec(p->db,
-         "SELECT sql FROM "
-         "  (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
-         "     FROM sqlite_master UNION ALL"
-         "   SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
-         "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
-         "ORDER BY rowid",
-         callback, &data, &zErrMsg
-      );
+      zDiv = "(";
     }else{
       raw_printf(stderr, "Usage: .schema ?--indent? ?LIKE-PATTERN?\n");
       rc = 1;
       goto meta_command_exit;
     }
+    if( zDiv ){
+      sqlite3_stmt *pStmt = 0;
+      sqlite3_prepare_v2(p->db, "SELECT name FROM pragma_database_list",
+                         -1, &pStmt, 0);
+      appendText(&sSelect, "SELECT sql FROM", 0);
+      iSchema = 0;
+      while( sqlite3_step(pStmt)==SQLITE_ROW ){
+        const char *zDb = (const char*)sqlite3_column_text(pStmt, 0);
+        char zScNum[30];
+        sqlite3_snprintf(sizeof(zScNum), zScNum, "%d", ++iSchema);
+        appendText(&sSelect, zDiv, 0);
+        zDiv = " UNION ALL ";
+        if( strcmp(zDb, "main")!=0 ){
+          appendText(&sSelect, "SELECT shell_add_schema(sql,", 0);
+          appendText(&sSelect, sqlite3_column_text(pStmt, 0), '"');
+          appendText(&sSelect, ") AS sql, type, tbl_name, name, rowid,", 0);
+          appendText(&sSelect, zScNum, 0);
+          appendText(&sSelect, " AS snum, ", 0);
+          appendText(&sSelect, zDb, '\'');
+          appendText(&sSelect, " AS sname FROM ", 0);
+          appendText(&sSelect, sqlite3_column_text(pStmt, 0), '"');
+          appendText(&sSelect, ".sqlite_master", 0);
+        }else{
+          appendText(&sSelect, "SELECT sql, type, tbl_name, name, rowid, ", 0);
+          appendText(&sSelect, zScNum, 0);
+          appendText(&sSelect, " AS snum, 'main' AS sname FROM sqlite_master",0);
+        }
+      }
+      sqlite3_finalize(pStmt);
+      appendText(&sSelect, ") WHERE ", 0);
+      if( nArg>1 ){
+        char *zQarg = sqlite3_mprintf("%Q", azArg[1]);
+        if( strchr(azArg[1], '.') ){
+          appendText(&sSelect, "lower(printf('%s.%s',sname,tbl_name))", 0);
+        }else{
+          appendText(&sSelect, "lower(tbl_name)", 0);
+        }
+        appendText(&sSelect, strchr(azArg[1], '*') ? " GLOB " : " LIKE ", 0);
+        appendText(&sSelect, zQarg, 0);
+        appendText(&sSelect, " AND ", 0);
+        sqlite3_free(zQarg);
+      }
+      appendText(&sSelect, "type!='meta' AND sql IS NOT NULL"
+                           " ORDER BY snum, rowid", 0);
+      rc = sqlite3_exec(p->db, sSelect.z, callback, &data, &zErrMsg);
+      freeText(&sSelect);
+    }
     if( zErrMsg ){
       utf8_printf(stderr,"Error: %s\n", zErrMsg);
       sqlite3_free(zErrMsg);