]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Manual merge of new .connection shell command
authorlarrybr <larrybr@noemail.net>
Mon, 26 Jul 2021 01:35:47 +0000 (01:35 +0000)
committerlarrybr <larrybr@noemail.net>
Mon, 26 Jul 2021 01:35:47 +0000 (01:35 +0000)
FossilOrigin-Name: 0d41f7f93c273cd2d0b92269ac1705f66daefa4eb7c24ed8f3662ef45a5397f9

manifest
manifest.uuid
src/shell.c.in

index d4a887b606d82a4346a4a818b149a5b79ff147a8..1eedcbe2b534fc5701377b6eb39895bcafa68f9b 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Much\sself-doc\simprovement\sfor\sshell.c\sgeneration.\sMisleading\serror\smessage\sfixed.
-D 2021-07-11T12:58:51.966
+C Manual\smerge\sof\snew\s.connection\sshell\scommand
+D 2021-07-26T01:35:47.674
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -545,7 +545,7 @@ F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c
 F src/resolve.c b379c5ffe3b692e9c64fa37817cc0efa204b7c9468a818309dde85fd132d9d81
 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
 F src/select.c 4fa607bab6bcc580f12dbaf9c800b2250a1e408f10321a1d3bcb1dd30c447e62
-F src/shell.c.in 95d72eae73d2c9bb76934c0bb9f083c0a770822640ef167cb15276102d1b7e52
+F src/shell.c.in fbc62e5ac7f79dd5f31fcd4ca719bc9cc959e147ae8fbb8630883a250a539b54
 F src/sqlite.h.in ecf5aa981da30c33da3e9f353bf3ebf055d3c380c80d6a4f954e58d18ccd6df1
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
 F src/sqlite3ext.h e97f4e9b509408fea4c4e9bef5a41608dfac343b4d3c7a990dedde1e19af9510
@@ -1919,7 +1919,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 827ea61d7d509fb6356aeab9e4fdd7619c1eeb4e8860d71ccb79a91737f9dde9
-R 8d6fc3f0c488c96ecd42108ef059ec74
+P 7738ce1b2b97fa29125ed8391670cda9343b87a476ad01f4421fea30e0d4dfe1
+R e40233741ba2186d11491dc0171c1a99
 U larrybr
-Z 3572dfa7570a81d67634e9e7f808d789
+Z d7243f2870d6870902d201b4510ac8d9
index b10ca4f14c9af1f514d01c8d2c697b21cf1198ad..72eafa7ff740cc5e4d1d7a858b8b52ced30d9aba 100644 (file)
@@ -1 +1 @@
-7738ce1b2b97fa29125ed8391670cda9343b87a476ad01f4421fea30e0d4dfe1
\ No newline at end of file
+0d41f7f93c273cd2d0b92269ac1705f66daefa4eb7c24ed8f3662ef45a5397f9
\ No newline at end of file
index 51f8375f4336cae80a1beae71076180aec63faed..2050f3819261b307b18e1fd10e145effa0926ed5 100644 (file)
@@ -985,7 +985,7 @@ static void shellAddSchemaName(
   sqlite3 *db = sqlite3_context_db_handle(pCtx);
   UNUSED_PARAMETER(nVal);
   if( zIn!=0 && strncmp(zIn, "CREATE ", 7)==0 ){
-    for(i=0; i<(int)(sizeof(aPrefix)/sizeof(aPrefix[0])); i++){
+    for(i=0; i<ArraySize(aPrefix); i++){
       int n = strlen30(aPrefix[i]);
       if( strncmp(zIn+7, aPrefix[i], n)==0 && zIn[n+7]==' ' ){
         char *z = 0;
@@ -1142,19 +1142,22 @@ struct ShellState {
   char nullValue[20];    /* The text to print when a NULL comes back from
                          ** the database */
   char outfile[FILENAME_MAX]; /* Filename for *out */
-  const char *zDbFilename;    /* name of the database file */
-  char *zFreeOnClose;         /* Filename to free when closing */
-  const char *zVfs;           /* Name of VFS to use */
   sqlite3_stmt *pStmt;   /* Current statement if any. */
   FILE *pLog;            /* Write log output here */
+  struct AuxDb {         /* Storage space for auxiliary database connections */
+    sqlite3 *db;               /* Connection pointer */
+    const char *zDbFilename;   /* Filename used to open the connection */
+    char *zFreeOnClose;        /* Free this memory allocation on close */
+#if defined(SQLITE_ENABLE_SESSION)
+    int nSession;              /* Number of active sessions */
+    OpenSession aSession[4];   /* Array of sessions.  [0] is in focus. */
+#endif
+  } aAuxDb[5],           /* Array of all database connections */
+    *pAuxDb;             /* Currently active database connection */
   int *aiIndent;         /* Array of indents used in MODE_Explain */
   int nIndent;           /* Size of array aiIndent[] */
   int iIndent;           /* Index of current op in aiIndent[] */
   EQPGraph sGraph;       /* Information for the graphical EXPLAIN QUERY PLAN */
-#if defined(SQLITE_ENABLE_SESSION)
-  int nSession;             /* Number of active sessions */
-  OpenSession aSession[4];  /* Array of sessions.  [0] is in focus. */
-#endif
   ExpertInfo expert;        /* Valid if previous command was ".expert OPT..." */
 };
 
@@ -3997,15 +4000,16 @@ static void session_close(OpenSession *pSession){
 ** Close all OpenSession objects and release all associated resources.
 */
 #if defined(SQLITE_ENABLE_SESSION)
-static void session_close_all(ShellState *p){
-  int i;
-  for(i=0; i<p->nSession; i++){
-    session_close(&p->aSession[i]);
+static void session_close_all(ShellState *p, int i){
+  int j;
+  struct AuxDb *pAuxDb = i<0 ? p->pAuxDb : &p->aAuxDb[i];
+  for(j=0; j<pAuxDb->nSession; j++){
+    session_close(&pAuxDb->aSession[j]);
   }
-  p->nSession = 0;
+  pAuxDb->nSession = 0;
 }
 #else
-# define session_close_all(X)
+# define session_close_all(X,Y)
 #endif
 
 /*
@@ -4070,8 +4074,8 @@ int deduceDatabaseType(const char *zName, int dfltZip){
 #ifndef SQLITE_OMIT_DESERIALIZE
 /*
 ** Reconstruct an in-memory database using the output from the "dbtotxt"
-** program.  Read content from the file in p->zDbFilename.  If p->zDbFilename
-** is 0, then read from standard input.
+** program.  Read content from the file in p->aAuxDb[].zDbFilename.
+** If p->aAuxDb[].zDbFilename is 0, then read from standard input.
 */
 static unsigned char *readHexDb(ShellState *p, int *pnData){
   unsigned char *a = 0;
@@ -4082,12 +4086,13 @@ static unsigned char *readHexDb(ShellState *p, int *pnData){
   int j, k;
   int rc;
   FILE *in;
+  const char *zDbFilename = p->pAuxDb->zDbFilename;
   unsigned int x[16];
   char zLine[1000];
-  if( p->zDbFilename ){
-    in = fopen(p->zDbFilename, "r");
+  if( zDbFilename ){
+    in = fopen(zDbFilename, "r");
     if( in==0 ){
-      utf8_printf(stderr, "cannot open \"%s\" for reading\n", p->zDbFilename);
+      utf8_printf(stderr, "cannot open \"%s\" for reading\n", zDbFilename);
       return 0;
     }
     nLine = 0;
@@ -4329,17 +4334,18 @@ static void shellEscapeCrnl(
 */
 static void open_db(ShellState *p, int openFlags){
   if( p->db==0 ){
+    const char *zDbFilename = p->pAuxDb->zDbFilename;
     if( p->openMode==SHELL_OPEN_UNSPEC ){
-      if( p->zDbFilename==0 || p->zDbFilename[0]==0 ){
+      if( zDbFilename==0 || zDbFilename[0]==0 ){
         p->openMode = SHELL_OPEN_NORMAL;
       }else{
-        p->openMode = (u8)deduceDatabaseType(p->zDbFilename, 
+        p->openMode = (u8)deduceDatabaseType(p->pAuxDb->zDbFilename, 
                              (openFlags & OPEN_DB_ZIPFILE)!=0);
       }
     }
     switch( p->openMode ){
       case SHELL_OPEN_APPENDVFS: {
-        sqlite3_open_v2(p->zDbFilename, &p->db, 
+        sqlite3_open_v2(zDbFilename, &p->db, 
            SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|p->openFlags, "apndvfs");
         break;
       }
@@ -4353,13 +4359,13 @@ static void open_db(ShellState *p, int openFlags){
         break;
       }
       case SHELL_OPEN_READONLY: {
-        sqlite3_open_v2(p->zDbFilename, &p->db,
+        sqlite3_open_v2(zDbFilename, &p->db,
             SQLITE_OPEN_READONLY|p->openFlags, 0);
         break;
       }
       case SHELL_OPEN_UNSPEC:
       case SHELL_OPEN_NORMAL: {
-        sqlite3_open_v2(p->zDbFilename, &p->db,
+        sqlite3_open_v2(zDbFilename, &p->db,
            SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|p->openFlags, 0);
         break;
       }
@@ -4367,7 +4373,7 @@ static void open_db(ShellState *p, int openFlags){
     globalDb = p->db;
     if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
       utf8_printf(stderr,"Error: unable to open database \"%s\": %s\n",
-          p->zDbFilename, sqlite3_errmsg(p->db));
+          zDbFilename, sqlite3_errmsg(p->db));
       if( openFlags & OPEN_DB_KEEPALIVE ){
         sqlite3_open(":memory:", &p->db);
         return;
@@ -4414,7 +4420,7 @@ static void open_db(ShellState *p, int openFlags){
 #endif
     if( p->openMode==SHELL_OPEN_ZIPFILE ){
       char *zSql = sqlite3_mprintf(
-         "CREATE VIRTUAL TABLE zip USING zipfile(%Q);", p->zDbFilename);
+         "CREATE VIRTUAL TABLE zip USING zipfile(%Q);", zDbFilename);
       sqlite3_exec(p->db, zSql, 0, 0, 0);
       sqlite3_free(zSql);
     }
@@ -4425,7 +4431,7 @@ static void open_db(ShellState *p, int openFlags){
       int nData = 0;
       unsigned char *aData;
       if( p->openMode==SHELL_OPEN_DESERIALIZE ){
-        aData = (unsigned char*)readFile(p->zDbFilename, &nData);
+        aData = (unsigned char*)readFile(zDbFilename, &nData);
       }else{
         aData = readHexDb(p, &nData);
         if( aData==0 ){
@@ -7043,12 +7049,13 @@ DISPATCHABLE_COMMAND( breakpoint 3 1 1 ){
 }
 
 /*****************
- * The .changes, .check and .clone commands
+ * The .changes, .check, .clone and .connection commands
  */
 COLLECT_HELP_TEXT[
   ".changes on|off          Show number of rows changed by SQL",
   ".check GLOB              Fail if output since .testcase does not match",
   ".clone NEWDB             Clone data into NEWDB from the existing database",
+  ".connection [close] [#]  Open or close an auxiliary database connection",
 ];
 DISPATCHABLE_COMMAND( changes 3 2 2 ){
   setOrClearFlag(p, SHFLG_CountChanges, azArg[1]);
@@ -7084,7 +7091,52 @@ DISPATCHABLE_COMMAND( clone ? 2 2 ){
   tryToClone(p, azArg[1]);
   return 0;
 }
-
+DISPATCHABLE_COMMAND( connection ? 1 4 ){
+  if( nArg==1 ){
+    /* List available connections */
+    int i;
+    for(i=0; i<ArraySize(p->aAuxDb); i++){
+      const char *zFile = p->aAuxDb[i].zDbFilename;
+      if( p->aAuxDb[i].db==0 && p->pAuxDb!=&p->aAuxDb[i] ){
+       zFile = "(not open)";
+      }else if( zFile==0 ){
+       zFile = "(memory)";
+      }else if( zFile[0]==0 ){
+       zFile = "(temporary-file)";
+      }
+      if( p->pAuxDb == &p->aAuxDb[i] ){
+       utf8_printf(stdout, "ACTIVE %d: %s\n", i, zFile);
+      }else if( p->aAuxDb[i].db!=0 ){
+       utf8_printf(stdout, "       %d: %s\n", i, zFile);
+      }
+    }
+  }else if( nArg==2 && IsDigit(azArg[1][0]) && azArg[1][1]==0 ){
+    int i = azArg[1][0] - '0';
+    if( p->pAuxDb != &p->aAuxDb[i] && i>=0 && i<ArraySize(p->aAuxDb) ){
+      p->pAuxDb->db = p->db;
+      p->pAuxDb = &p->aAuxDb[i];
+      globalDb = p->db = p->pAuxDb->db;
+      p->pAuxDb->db = 0;
+    }
+  }else if( nArg==3 && strcmp(azArg[1], "close")==0
+           && IsDigit(azArg[2][0]) && azArg[2][1]==0 ){
+    int i = azArg[2][0] - '0';
+    if( i<0 || i>=ArraySize(p->aAuxDb) ){
+      /* No-op */
+    }else if( p->pAuxDb == &p->aAuxDb[i] ){
+      raw_printf(stderr, "cannot close the active database connection\n");
+      return 1;
+    }else if( p->aAuxDb[i].db ){
+      session_close_all(p, i);
+      close_db(p->aAuxDb[i].db);
+      p->aAuxDb[i].db = 0;
+    }
+  }else{
+    raw_printf(stderr, "Usage: .connection [close] [CONNECTION-NUMBER]\n");
+    return 1;
+  }
+  return 0;
+}
 
 /*****************
  * The .databases, .dbconfig and .dbinfo commands
@@ -8386,12 +8438,12 @@ DISPATCHABLE_COMMAND( open 3 1 0 ){
   int iName = 1;           /* Index in azArg[] of the filename */
   int newFlag = 0;         /* True to delete file before opening */
   /* Close the existing database */
-  session_close_all(p);
+  session_close_all(p, -1);
   close_db(p->db);
   p->db = 0;
-  p->zDbFilename = 0;
-  sqlite3_free(p->zFreeOnClose);
-  p->zFreeOnClose = 0;
+  p->pAuxDb->zDbFilename = 0;
+  sqlite3_free(p->pAuxDb->zFreeOnClose);
+  p->pAuxDb->zFreeOnClose = 0;
   p->openMode = SHELL_OPEN_UNSPEC;
   p->openFlags = 0;
   p->szMax = 0;
@@ -8433,18 +8485,18 @@ DISPATCHABLE_COMMAND( open 3 1 0 ){
   /* If a filename is specified, try to open it first */
   if( zNewFilename || p->openMode==SHELL_OPEN_HEXDB ){
     if( newFlag ) shellDeleteFile(zNewFilename);
-    p->zDbFilename = zNewFilename;
+    p->pAuxDb->zDbFilename = zNewFilename;
     open_db(p, OPEN_DB_KEEPALIVE);
     if( p->db==0 ){
       utf8_printf(stderr, "Error: cannot open '%s'\n", zNewFilename);
       sqlite3_free(zNewFilename);
     }else{
-      p->zFreeOnClose = zNewFilename;
+      p->pAuxDb->zFreeOnClose = zNewFilename;
     }
   }
   if( p->db==0 ){
     /* As a fall-back open a TEMP database */
-    p->zDbFilename = 0;
+    p->pAuxDb->zDbFilename = 0;
     open_db(p, 0);
   }
   return 0;
@@ -9269,22 +9321,23 @@ DISPATCHABLE_COMMAND( separator ? 2 3 ){
 }
 DISPATCHABLE_COMMAND( session 3 2 0 ){
   int rc = 0;
-  OpenSession *pSession = &p->aSession[0];
+  struct AuxDb *pAuxDb = p->pAuxDb;
+  OpenSession *pSession = &pAuxDb->aSession[0];
   char **azCmd = &azArg[1];
   int iSes = 0;
   int nCmd = nArg - 1;
   int i;
   open_db(p, 0);
   if( nArg>=3 ){
-    for(iSes=0; iSes<p->nSession; iSes++){
-      if( strcmp(p->aSession[iSes].zName, azArg[1])==0 ) break;
+    for(iSes=0; iSes<pAuxDb->nSession; iSes++){
+      if( strcmp(pAuxDb->aSession[iSes].zName, azArg[1])==0 ) break;
     }
-    if( iSes<p->nSession ){
-      pSession = &p->aSession[iSes];
+    if( iSes<pAuxDb->nSession ){
+      pSession = &pAuxDb->aSession[iSes];
       azCmd++;
       nCmd--;
     }else{
-      pSession = &p->aSession[0];
+      pSession = &pAuxDb->aSession[0];
       iSes = 0;
     }
   }
@@ -9346,9 +9399,9 @@ DISPATCHABLE_COMMAND( session 3 2 0 ){
       */
       if( strcmp(azCmd[0], "close")==0 ){
         if( nCmd!=1 ) goto session_syntax_error;
-        if( p->nSession ){
+        if( pAuxDb->nSession ){
           session_close(pSession);
-          p->aSession[iSes] = p->aSession[--p->nSession];
+          pAuxDb->aSession[iSes] = pAuxDb->aSession[--pAuxDb->nSession];
         }
       }else
 
@@ -9359,7 +9412,7 @@ DISPATCHABLE_COMMAND( session 3 2 0 ){
           int ii;
           if( nCmd>2 ) goto session_syntax_error;
           ii = nCmd==1 ? -1 : booleanValue(azCmd[1]);
-          if( p->nSession ){
+          if( pAuxDb->nSession ){
             ii = sqlite3session_enable(pSession->p, ii);
             utf8_printf(p->out, "session %s enable flag = %d\n",
                         pSession->zName, ii);
@@ -9372,7 +9425,7 @@ DISPATCHABLE_COMMAND( session 3 2 0 ){
           if( strcmp(azCmd[0], "filter")==0 ){
             int ii, nByte;
             if( nCmd<2 ) goto session_syntax_error;
-            if( p->nSession ){
+            if( pAuxDb->nSession ){
               for(ii=0; ii<pSession->nFilter; ii++){
                 sqlite3_free(pSession->azFilter[ii]);
               }
@@ -9397,7 +9450,7 @@ DISPATCHABLE_COMMAND( session 3 2 0 ){
               int ii;
               if( nCmd>2 ) goto session_syntax_error;
               ii = nCmd==1 ? -1 : booleanValue(azCmd[1]);
-              if( p->nSession ){
+              if( pAuxDb->nSession ){
                 ii = sqlite3session_indirect(pSession->p, ii);
                 utf8_printf(p->out, "session %s indirect flag = %d\n",
                             pSession->zName, ii);
@@ -9410,7 +9463,7 @@ DISPATCHABLE_COMMAND( session 3 2 0 ){
               if( strcmp(azCmd[0], "isempty")==0 ){
                 int ii;
                 if( nCmd!=1 ) goto session_syntax_error;
-                if( p->nSession ){
+                if( pAuxDb->nSession ){
                   ii = sqlite3session_isempty(pSession->p);
                   utf8_printf(p->out, "session %s isempty flag = %d\n",
                               pSession->zName, ii);
@@ -9421,8 +9474,8 @@ DISPATCHABLE_COMMAND( session 3 2 0 ){
                 ** List all currently open sessions
                 */
                 if( strcmp(azCmd[0],"list")==0 ){
-                  for(i=0; i<p->nSession; i++){
-                    utf8_printf(p->out, "%d %s\n", i, p->aSession[i].zName);
+                  for(i=0; i<pAuxDb->nSession; i++){
+                    utf8_printf(p->out, "%d %s\n", i, pAuxDb->aSession[i].zName);
                   }
                 }else
 
@@ -9435,17 +9488,18 @@ DISPATCHABLE_COMMAND( session 3 2 0 ){
                     if( nCmd!=3 ) goto session_syntax_error;
                     zName = azCmd[2];
                     if( zName[0]==0 ) goto session_syntax_error;
-                    for(i=0; i<p->nSession; i++){
-                      if( strcmp(p->aSession[i].zName,zName)==0 ){
+                    for(i=0; i<pAuxDb->nSession; i++){
+                      if( strcmp(pAuxDb->aSession[i].zName,zName)==0 ){
                         utf8_printf(stderr, "Session \"%s\" already exists\n", zName);
                         return rc;
                       }
                     }
-                    if( p->nSession>=ArraySize(p->aSession) ){
-                      raw_printf(stderr, "Maximum of %d sessions\n", ArraySize(p->aSession));
+                    if( pAuxDb->nSession>=ArraySize(pAuxDb->aSession) ){
+                      raw_printf(stderr, "Maximum of %d sessions\n",
+                                ArraySize(pAuxDb->aSession));
                       return rc;
                     }
-                    pSession = &p->aSession[p->nSession];
+                    pSession = &pAuxDb->aSession[pAuxDb->nSession];
                     rc = sqlite3session_create(p->db, azCmd[1], &pSession->p);
                     if( rc ){
                       raw_printf(stderr, "Cannot open session: error code=%d\n", rc);
@@ -9453,7 +9507,7 @@ DISPATCHABLE_COMMAND( session 3 2 0 ){
                     }
                     pSession->nFilter = 0;
                     sqlite3session_table_filter(pSession->p, session_filter, pSession);
-                    p->nSession++;
+                    pAuxDb->nSession++;
                     pSession->zName = sqlite3_mprintf("%s", zName);
                   }else{
                     /* If no command name matches, show a syntax error */
@@ -9756,7 +9810,7 @@ DISPATCHABLE_COMMAND( show ? 1 1 ){
   }
   raw_printf(p->out, "\n");
   utf8_printf(p->out, "%12.12s: %s\n", "filename",
-              p->zDbFilename ? p->zDbFilename : "");
+              p->pAuxDb->zDbFilename ? p->pAuxDb->zDbFilename : "");
   return 0;
 }
 DISPATCHABLE_COMMAND( stats ? 0 0 ){
@@ -11059,6 +11113,7 @@ static void main_init(ShellState *data) {
   memset(data, 0, sizeof(*data));
   data->normalMode = data->cMode = data->mode = MODE_List;
   data->autoExplain = 1;
+  data->pAuxDb = &data->aAuxDb[0];
   memcpy(data->colSeparator,SEP_Column, 2);
   memcpy(data->rowSeparator,SEP_Row, 2);
   data->showHeader = 0;
@@ -11222,7 +11277,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
     ** this compile-time option to embed this shell program in larger
     ** applications. */
     extern void SQLITE_SHELL_DBNAME_PROC(const char**);
-    SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
+    SQLITE_SHELL_DBNAME_PROC(&data.pAuxDb->zDbFilename);
     warnInmemoryDb = 0;
   }
 #endif
@@ -11237,8 +11292,8 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
     char *z;
     z = argv[i];
     if( z[0]!='-' ){
-      if( data.zDbFilename==0 ){
-        data.zDbFilename = z;
+      if( data.aAuxDb->zDbFilename==0 ){
+        data.aAuxDb->zDbFilename = z;
       }else{
         /* Excesss arguments are interpreted as SQL (or dot-commands) and
         ** mean that nothing is read from stdin */
@@ -11378,9 +11433,9 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
     }
   }
 
-  if( data.zDbFilename==0 ){
+  if( data.pAuxDb->zDbFilename==0 ){
 #ifndef SQLITE_OMIT_MEMORYDB
-    data.zDbFilename = ":memory:";
+    data.pAuxDb->zDbFilename = ":memory:";
     warnInmemoryDb = argc==1;
 #else
     utf8_printf(stderr,"%s: Error: no database filename specified\n", Argv0);
@@ -11395,7 +11450,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
   ** files from being created if a user mistypes the database name argument
   ** to the sqlite command-line tool.
   */
-  if( access(data.zDbFilename, 0)==0 ){
+  if( access(data.pAuxDb->zDbFilename, 0)==0 ){
     open_db(&data, 0);
   }
 
@@ -11649,10 +11704,16 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
   free(azCmd);
   set_table_name(&data, 0);
   if( data.db ){
-    session_close_all(&data);
+    session_close_all(&data, -1);
     close_db(data.db);
   }
-  sqlite3_free(data.zFreeOnClose);
+  for(i=0; i<ArraySize(data.aAuxDb); i++){
+    sqlite3_free(data.aAuxDb[i].zFreeOnClose);
+    if( data.aAuxDb[i].db ){
+      session_close_all(&data, i);
+      close_db(data.aAuxDb[i].db);
+    }
+  }
   find_home_dir(1);
   output_reset(&data);
   data.doXdgOpen = 0;