/ Check-in [07da0a0b]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Changes to the multiplex VFS to optionally (compiler define) allow the "chunk extension" to overwrite the right-most chars of the filename instead of simply being appended.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:07da0a0beffda324d28fd2768c542ff69d4dbff2
User & Date: shaneh 2010-11-08 19:16:16
Context
2010-11-09
20:33
Fix an assert that fired incorrectly when PRAGMA omit_readlock was set. check-in: e0687582 user: shaneh tags: trunk
17:49
Merge with latest trunk changes. check-in: 4b5c93bc user: dan tags: experimental
2010-11-08
19:16
Changes to the multiplex VFS to optionally (compiler define) allow the "chunk extension" to overwrite the right-most chars of the filename instead of simply being appended. check-in: 07da0a0b user: shaneh tags: trunk
2010-11-05
20:50
Fix to xTruncate and more journal mode tests for the multiplex VFS. check-in: 65fa1164 user: shaneh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/test_config.c.

   518    518   #endif
   519    519   
   520    520   #ifdef SQLITE_SECURE_DELETE
   521    521     Tcl_SetVar2(interp, "sqlite_options", "secure_delete", "1", TCL_GLOBAL_ONLY);
   522    522   #else
   523    523     Tcl_SetVar2(interp, "sqlite_options", "secure_delete", "0", TCL_GLOBAL_ONLY);
   524    524   #endif
          525  +
          526  +#ifdef SQLITE_MULTIPLEX_EXT_OVWR
          527  +  Tcl_SetVar2(interp, "sqlite_options", "multiplex_ext_overwrite", "1", TCL_GLOBAL_ONLY);
          528  +#else
          529  +  Tcl_SetVar2(interp, "sqlite_options", "multiplex_ext_overwrite", "0", TCL_GLOBAL_ONLY);
          530  +#endif
   525    531   
   526    532   #ifdef YYTRACKMAXSTACKDEPTH
   527    533     Tcl_SetVar2(interp, "sqlite_options", "yytrackmaxstackdepth", "1", TCL_GLOBAL_ONLY);
   528    534   #else
   529    535     Tcl_SetVar2(interp, "sqlite_options", "yytrackmaxstackdepth", "0", TCL_GLOBAL_ONLY);
   530    536   #endif
   531    537   

Changes to src/test_multiplex.c.

    22     22   #include "sqlite3.h"
    23     23   #include <string.h>
    24     24   #include <assert.h>
    25     25   #include "sqliteInt.h"
    26     26   
    27     27   /************************ Shim Definitions ******************************/
    28     28   
           29  +/* This is the limit on the chunk size.  It may be changed by calling
           30  +** the sqlite3_multiplex_set() interface.
           31  +*/
    29     32   #define SQLITE_MULTIPLEX_CHUNK_SIZE 0x40000000
           33  +/* Default limit on number of chunks.  Care should be taken
           34  +** so that values for chunks numbers fit in the SQLITE_MULTIPLEX_EXT_FMT
           35  +** format specifier. It may be changed by calling
           36  +** the sqlite3_multiplex_set() interface.
           37  +*/
    30     38   #define SQLITE_MULTIPLEX_MAX_CHUNKS 32
    31         -#define SQLITE_MULTIPLEX_EXT_FMT    "-%04d"
           39  +
           40  +/* If SQLITE_MULTIPLEX_EXT_OVWR is defined, the 
           41  +** last SQLITE_MULTIPLEX_EXT_SZ characters of the 
           42  +** filename will be overwritten, otherwise, the 
           43  +** multiplex extension is simply appended to the filename.
           44  +** Ex.  (undefined) test.db -> test.db01
           45  +**      (defined)   test.db -> test.01
           46  +** Chunk 0 does not have a modified extension.
           47  +*/
           48  +#define SQLITE_MULTIPLEX_EXT_FMT    "%02d"
           49  +#define SQLITE_MULTIPLEX_EXT_SZ     2
    32     50   
    33     51   /************************ Object Definitions ******************************/
    34     52   
    35     53   /* Forward declaration of all object types */
    36     54   typedef struct multiplexGroup multiplexGroup;
    37     55   typedef struct multiplexConn multiplexConn;
    38     56   
................................................................................
    41     59   ** makeup a single SQLite DB file.  This allows the size of the DB
    42     60   ** to exceed the limits imposed by the file system.
    43     61   **
    44     62   ** There is an instance of the following object for each defined multiplex
    45     63   ** group.
    46     64   */
    47     65   struct multiplexGroup {
    48         -  sqlite3_file *pReal[SQLITE_MULTIPLEX_MAX_CHUNKS]; /* Handles to each chunk */
    49         -  char bOpen[SQLITE_MULTIPLEX_MAX_CHUNKS];          /* 0 if chunk not opened */
    50         -  char *zName;                                      /* Base filename of this group */
    51         -  int nName;                                        /* Length of base filename */
    52         -  int flags;                                        /* Flags used for original opening */
           66  +  sqlite3_file **pReal;            /* Handles to each chunk */
           67  +  char *bOpen;                     /* 0 if chunk not opened */
           68  +  char *zName;                     /* Base filename of this group */
           69  +  int nName;                       /* Length of base filename */
           70  +  int flags;                       /* Flags used for original opening */
    53     71     multiplexGroup *pNext, *pPrev;   /* Doubly linked list of all group objects */
    54     72   };
    55     73   
    56     74   /*
    57     75   ** An instance of the following object represents each open connection
    58     76   ** to a file that is multiplex'ed.  This object is a 
    59     77   ** subclass of sqlite3_file.  The sqlite3_file object for the underlying
................................................................................
   133    151   */
   134    152   static sqlite3_file *multiplexSubOpen(multiplexConn *pConn, int iChunk, int *rc, int *pOutFlags){
   135    153     multiplexGroup *pGroup = pConn->pGroup;
   136    154     sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs;        /* Real VFS */
   137    155     if( iChunk<gMultiplex.nMaxChunks ){
   138    156       sqlite3_file *pSubOpen = pGroup->pReal[iChunk];    /* Real file descriptor */
   139    157       if( !pGroup->bOpen[iChunk] ){
   140         -      pGroup->zName[pGroup->nName] = '\0';
   141         -      if( iChunk ) sqlite3_snprintf(pGroup->nName+6, pGroup->zName+pGroup->nName, SQLITE_MULTIPLEX_EXT_FMT, iChunk);
   142         -      *rc = pOrigVfs->xOpen(pOrigVfs, pGroup->zName, pSubOpen, pGroup->flags, pOutFlags);
          158  +      memcpy(gMultiplex.zName, pGroup->zName, pGroup->nName+1);
          159  +      if( iChunk ){
          160  +#ifdef SQLITE_MULTIPLEX_EXT_OVWR
          161  +        sqlite3_snprintf(SQLITE_MULTIPLEX_EXT_SZ+1, gMultiplex.zName+pGroup->nName-SQLITE_MULTIPLEX_EXT_SZ, SQLITE_MULTIPLEX_EXT_FMT, iChunk);
          162  +#else
          163  +        sqlite3_snprintf(SQLITE_MULTIPLEX_EXT_SZ+1, gMultiplex.zName+pGroup->nName, SQLITE_MULTIPLEX_EXT_FMT, iChunk);
          164  +#endif
          165  +      }
          166  +      *rc = pOrigVfs->xOpen(pOrigVfs, gMultiplex.zName, pSubOpen, pGroup->flags, pOutFlags);
   143    167         if( *rc==SQLITE_OK ){
   144    168           pGroup->bOpen[iChunk] = -1;
   145    169           return pSubOpen;
   146    170         }
   147    171         return NULL;
   148    172       }
   149    173       *rc = SQLITE_OK;
................................................................................
   172    196     int rc;                                        /* Result code */
   173    197     multiplexConn *pMultiplexOpen;                 /* The new multiplex file descriptor */
   174    198     multiplexGroup *pGroup;                        /* Corresponding multiplexGroup object */
   175    199     sqlite3_file *pSubOpen;                        /* Real file descriptor */
   176    200     sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs;   /* Real VFS */
   177    201     int nName = sqlite3Strlen30(zName);
   178    202     int i;
          203  +  int sz;
   179    204   
   180    205     UNUSED_PARAMETER(pVfs);
   181    206   
   182    207     /* We need to create a group structure and manage
   183    208     ** access to this group of files.
   184    209     */
   185    210     multiplexEnter();
   186    211     pMultiplexOpen = (multiplexConn*)pConn;
   187         -  /* allocate space for group, file handles, 
   188         -  ** and file name (+ extra for "-0000\0") 
   189         -  */
   190         -  pGroup = sqlite3_malloc( sizeof(multiplexGroup) + (pOrigVfs->szOsFile*gMultiplex.nMaxChunks) + nName + 6 );
          212  +  /* allocate space for group */
          213  +  sz = sizeof(multiplexGroup)                         /* multiplexGroup */
          214  +     + (sizeof(sqlite3_file *)*gMultiplex.nMaxChunks) /* pReal[] */
          215  +     + (pOrigVfs->szOsFile*gMultiplex.nMaxChunks)     /* *pReal */
          216  +     + gMultiplex.nMaxChunks                          /* bOpen[] */
          217  +     + nName + 1;                                     /* zName */
          218  +#ifndef SQLITE_MULTIPLEX_EXT_OVWR
          219  +  sz += SQLITE_MULTIPLEX_EXT_SZ;
          220  +  assert(nName+SQLITE_MULTIPLEX_EXT_SZ < pOrigVfs->mxPathname);
          221  +#else
          222  +  assert(nName >= SQLITE_MULTIPLEX_EXT_SZ);
          223  +  assert(nName < pOrigVfs->mxPathname);
          224  +#endif
          225  +  pGroup = sqlite3_malloc( sz );
   191    226     if( pGroup==0 ){
   192    227       rc=SQLITE_NOMEM;
   193    228     }else{
          229  +    /* assign pointers to extra space allocated */
          230  +    char *p = (char *)&pGroup[1];
   194    231       pMultiplexOpen->pGroup = pGroup;
   195         -    memset(pGroup, 0, sizeof(multiplexGroup) + (pOrigVfs->szOsFile*gMultiplex.nMaxChunks) + nName + 6);
   196         -    /* assign pointers to extra space for file handles */
          232  +    memset(pGroup, 0, sz);
          233  +    pGroup->pReal = (sqlite3_file **)p;
          234  +    p += (sizeof(sqlite3_file *)*gMultiplex.nMaxChunks);
   197    235       for(i=0; i<gMultiplex.nMaxChunks; i++){
   198         -      pGroup->pReal[i] = (sqlite3_file *)((char *)&pGroup[1] + (pOrigVfs->szOsFile*i));
          236  +      pGroup->pReal[i] = (sqlite3_file *)p;
          237  +      p += pOrigVfs->szOsFile;
   199    238       }
   200         -    pGroup->zName = (char *)&pGroup[1] + (pOrigVfs->szOsFile*gMultiplex.nMaxChunks);
          239  +    pGroup->bOpen = p;
          240  +    p += gMultiplex.nMaxChunks;
          241  +    pGroup->zName = p;
          242  +    /* save off base filename, name length, and original open flags  */
   201    243       memcpy(pGroup->zName, zName, nName+1);
   202    244       pGroup->nName = nName;
   203    245       pGroup->flags = flags;
   204    246       pSubOpen = multiplexSubOpen(pMultiplexOpen, 0, &rc, pOutFlags);
   205    247       if( pSubOpen ){
   206    248         if( pSubOpen->pMethods->iVersion==1 ){
   207    249           pMultiplexOpen->base.pMethods = &gMultiplex.sIoMethodsV1;
................................................................................
   219    261     multiplexLeave();
   220    262     return rc;
   221    263   }
   222    264   
   223    265   /*
   224    266   ** This is the xDelete method used for the "multiplex" VFS.
   225    267   ** It attempts to delete the filename specified, as well
   226         -** as addiitional files with the "-####" extension.
          268  +** as additional files with the SQLITE_MULTIPLEX_EXT_FMT extension.
   227    269   */
   228    270   static int multiplexDelete(
   229    271     sqlite3_vfs *pVfs,         /* The multiplex VFS */
   230    272     const char *zName,         /* Name of file to delete */
   231    273     int syncDir
   232    274   ){
   233    275     sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs;   /* Real VFS */
................................................................................
   238    280     UNUSED_PARAMETER(pVfs);
   239    281   
   240    282     multiplexEnter();
   241    283     memcpy(gMultiplex.zName, zName, nName+1);
   242    284     for(i=0; i<gMultiplex.nMaxChunks; i++){
   243    285       int rc2;
   244    286       int exists = 0;
   245         -    if( i ) sqlite3_snprintf(nName+6, gMultiplex.zName+nName, SQLITE_MULTIPLEX_EXT_FMT, i);
          287  +    if( i ){
          288  +#ifdef SQLITE_MULTIPLEX_EXT_OVWR
          289  +        sqlite3_snprintf(SQLITE_MULTIPLEX_EXT_SZ+1, gMultiplex.zName+nName-SQLITE_MULTIPLEX_EXT_SZ, SQLITE_MULTIPLEX_EXT_FMT, i);
          290  +#else
          291  +        sqlite3_snprintf(SQLITE_MULTIPLEX_EXT_SZ+1, gMultiplex.zName+nName, SQLITE_MULTIPLEX_EXT_FMT, i);
          292  +#endif
          293  +    }
   246    294       rc2 = pOrigVfs->xAccess(pOrigVfs, gMultiplex.zName, SQLITE_ACCESS_EXISTS, &exists);
   247    295       if( rc2==SQLITE_OK && exists){
   248    296         /* if it exists, delete it */
   249    297         rc2 = pOrigVfs->xDelete(pOrigVfs, gMultiplex.zName, syncDir);
   250    298         if( rc2!=SQLITE_OK ) rc = rc2;
   251    299       }else{
   252    300         /* stop at first "gap" */
................................................................................
   368    416     multiplexGroup *pGroup = p->pGroup;
   369    417     int rc = SQLITE_OK;
   370    418     int rc2;
   371    419     int i;
   372    420     sqlite3_file *pSubOpen;
   373    421     sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs;   /* Real VFS */
   374    422     multiplexEnter();
          423  +  memcpy(gMultiplex.zName, pGroup->zName, pGroup->nName+1);
   375    424     /* delete the chunks above the truncate limit */
   376    425     for(i=(int)(size/gMultiplex.nChunkSize)+1; i<gMultiplex.nMaxChunks; i++){
   377    426       /* close any open chunks before deleting them */
   378    427       if( pGroup->bOpen[i] ){
   379    428         pSubOpen = pGroup->pReal[i];
   380    429         rc2 = pSubOpen->pMethods->xClose(pSubOpen);
   381    430         if( rc2!=SQLITE_OK ) rc = SQLITE_IOERR_TRUNCATE;
   382    431         pGroup->bOpen[i] = 0;
   383    432       }
   384         -    sqlite3_snprintf(pGroup->nName+6, pGroup->zName+pGroup->nName, SQLITE_MULTIPLEX_EXT_FMT, i);
   385         -    rc2 = pOrigVfs->xDelete(pOrigVfs, pGroup->zName, 0);
          433  +#ifdef SQLITE_MULTIPLEX_EXT_OVWR
          434  +    sqlite3_snprintf(SQLITE_MULTIPLEX_EXT_SZ+1, gMultiplex.zName+pGroup->nName-SQLITE_MULTIPLEX_EXT_SZ, SQLITE_MULTIPLEX_EXT_FMT, i);
          435  +#else
          436  +    sqlite3_snprintf(SQLITE_MULTIPLEX_EXT_SZ+1, gMultiplex.zName+pGroup->nName, SQLITE_MULTIPLEX_EXT_FMT, i);
          437  +#endif
          438  +    rc2 = pOrigVfs->xDelete(pOrigVfs, gMultiplex.zName, 0);
   386    439       if( rc2!=SQLITE_OK ) rc = SQLITE_IOERR_TRUNCATE;
   387    440     }
   388    441     pSubOpen = multiplexSubOpen(p, (int)(size/gMultiplex.nChunkSize), &rc2, NULL);
   389    442     if( pSubOpen ){
   390    443       rc2 = pSubOpen->pMethods->xTruncate(pSubOpen, size%gMultiplex.nChunkSize);
   391    444       if( rc2!=SQLITE_OK ) rc = rc2;
   392    445     }else{
................................................................................
   431    484       sqlite3_file *pSubOpen = NULL;
   432    485       /* if not opened already, check to see if the chunk exists */
   433    486       if( pGroup->bOpen[i] ){
   434    487         pSubOpen = pGroup->pReal[i];
   435    488       }else{
   436    489         sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs;   /* Real VFS */
   437    490         int exists = 0;
   438         -      pGroup->zName[pGroup->nName] = '\0';
   439         -      if( i ) sqlite3_snprintf(pGroup->nName+6, pGroup->zName+pGroup->nName, SQLITE_MULTIPLEX_EXT_FMT, i);
   440         -      rc2 = pOrigVfs->xAccess(pOrigVfs, pGroup->zName, SQLITE_ACCESS_EXISTS, &exists);
          491  +      memcpy(gMultiplex.zName, pGroup->zName, pGroup->nName+1);
          492  +      if( i ){
          493  +#ifdef SQLITE_MULTIPLEX_EXT_OVWR
          494  +        sqlite3_snprintf(SQLITE_MULTIPLEX_EXT_SZ+1, gMultiplex.zName+pGroup->nName-SQLITE_MULTIPLEX_EXT_SZ, SQLITE_MULTIPLEX_EXT_FMT, i);
          495  +#else
          496  +        sqlite3_snprintf(SQLITE_MULTIPLEX_EXT_SZ+1, gMultiplex.zName+pGroup->nName, SQLITE_MULTIPLEX_EXT_FMT, i);
          497  +#endif
          498  +      }
          499  +      rc2 = pOrigVfs->xAccess(pOrigVfs, gMultiplex.zName, SQLITE_ACCESS_EXISTS, &exists);
   441    500         if( rc2==SQLITE_OK && exists){
   442    501           /* if it exists, open it */
   443    502           pSubOpen = multiplexSubOpen(p, i, &rc, NULL);
   444    503         }else{
   445    504           /* stop at first "gap" */
   446    505           break;
   447    506         }
................................................................................
   449    508       if( pSubOpen ){
   450    509         sqlite3_int64 sz;
   451    510         rc2 = pSubOpen->pMethods->xFileSize(pSubOpen, &sz);
   452    511         if( rc2!=SQLITE_OK ){
   453    512           rc = rc2;
   454    513         }else{
   455    514           *pSize += sz;
          515  +        assert(sz<=gMultiplex.nChunkSize);
   456    516         }
   457    517       }else{
   458    518         break;
   459    519       }
   460    520     }
   461    521     multiplexLeave();
   462    522     return rc;
................................................................................
   683    743     int nChunkSize,                 /* Max chunk size */
   684    744     int nMaxChunks                  /* Max number of chunks */
   685    745   ){
   686    746     if( !gMultiplex.isInitialized ) return SQLITE_MISUSE;
   687    747     if( gMultiplex.pGroups ) return SQLITE_MISUSE;
   688    748     if( nChunkSize<32 ) return SQLITE_MISUSE;
   689    749     if( nMaxChunks<1 ) return SQLITE_MISUSE;
   690         -  if( nMaxChunks>SQLITE_MULTIPLEX_MAX_CHUNKS ) return SQLITE_MISUSE;
          750  +  if( nMaxChunks>99 ) return SQLITE_MISUSE;
   691    751     multiplexEnter();
   692    752     gMultiplex.nChunkSize = nChunkSize;
   693    753     gMultiplex.nMaxChunks = nMaxChunks;
   694    754     multiplexLeave();
   695    755     return SQLITE_OK;
   696    756   }
   697    757   

Changes to test/multiplex.test.

    13     13   set testdir [file dirname $argv0]
    14     14   source $testdir/tester.tcl
    15     15   source $testdir/malloc_common.tcl
    16     16   
    17     17   set g_chunk_size 2147483648
    18     18   set g_max_chunks 32
    19     19   
           20  +# This handles appending the chunk number
           21  +# to the end of the filename.  if 
           22  +# SQLITE_MULTIPLEX_EXT_OVWR is defined, then
           23  +# it overwrites the last 2 bytes of the 
           24  +# file name with the chunk number.
           25  +proc multiplex_name {name chunk} {
           26  +  if {$chunk==0} { return $name }
           27  +  set num [format "%02d" $chunk]
           28  +  ifcapable {multiplex_ext_overwrite} {
           29  +    set name [string range $name 0 [expr [string length $name]-2-1]]
           30  +  }
           31  +  return $name$num
           32  +}
           33  +
           34  +# This saves off the parameters and calls the 
           35  +# underlying sqlite3_multiplex_set() API.
    20     36   proc multiplex_set {chunk_size max_chunks} {
    21     37     global g_chunk_size
    22     38     global g_max_chunks
    23     39     set g_chunk_size $chunk_size
    24     40     set g_max_chunks $max_chunks
    25     41     sqlite3_multiplex_set $chunk_size $max_chunks
    26     42   }
    27     43   
           44  +# This attempts to delete the base file and 
           45  +# and files with the chunk extension.
    28     46   proc multiplex_delete {name} {
    29     47     global g_max_chunks
    30         -  forcedelete $name
    31         -  forcedelete $name-journal
    32         -  forcedelete $name-wal
    33         -  for {set i 1} {$i<$g_max_chunks} {incr i} {
    34         -    set num [format "%04d" $i]
    35         -    forcedelete $name-$num
    36         -    forcedelete $name-journal-$num
    37         -    forcedelete $name-wal-$num
           48  +  for {set i 0} {$i<$g_max_chunks} {incr i} {
           49  +    forcedelete [multiplex_name $name $i]
           50  +    forcedelete [multiplex_name $name-journal $i]
           51  +    forcedelete [multiplex_name $name-wal $i]
    38     52     }
    39     53   }
    40     54   
    41     55   db close
    42     56   
    43     57   #-------------------------------------------------------------------------
    44     58   #   multiplex-1.1.*: Test initialize and shutdown.
................................................................................
    54     68   do_test multiplex-1.8 { sqlite3_multiplex_shutdown }               {SQLITE_OK}
    55     69   
    56     70   do_test multiplex-1.9  { sqlite3_multiplex_initialize "" 1 }       {SQLITE_OK}
    57     71   do_test multiplex-1.10.1 { multiplex_set 32768 16 }                {SQLITE_OK}
    58     72   do_test multiplex-1.10.2 { multiplex_set 32768 -1 }                {SQLITE_MISUSE}
    59     73   do_test multiplex-1.10.3 { multiplex_set -1 16 }                   {SQLITE_MISUSE}
    60     74   do_test multiplex-1.10.4 { multiplex_set 31 16 }                   {SQLITE_MISUSE}
    61         -do_test multiplex-1.10.5 { multiplex_set 32768 33 }                {SQLITE_MISUSE}
           75  +do_test multiplex-1.10.5 { multiplex_set 32768 100 }               {SQLITE_MISUSE}
    62     76   do_test multiplex-1.11 { sqlite3_multiplex_shutdown }              {SQLITE_OK}
    63     77   
    64     78   
    65     79   #-------------------------------------------------------------------------
    66     80   # Some simple warm-body tests with a single database file in rollback 
    67     81   # mode:
    68     82   #
................................................................................
    94    108     }
    95    109     execsql {
    96    110       CREATE TABLE t1(a, b);
    97    111       INSERT INTO t1 VALUES(1, randomblob(1100));
    98    112       INSERT INTO t1 VALUES(2, randomblob(1100));
    99    113     }
   100    114   } {}
   101         -do_test multiplex-2.1.3 { file size test.db } {4096}
          115  +do_test multiplex-2.1.3 { file size [multiplex_name test.db 0] } {4096}
   102    116   do_test multiplex-2.1.4 {
   103    117     execsql { INSERT INTO t1 VALUES(3, randomblob(1100)) }
   104    118   } {}
   105    119   
   106    120   do_test multiplex-2.2.1 {
   107    121     execsql { INSERT INTO t1 VALUES(3, randomblob(1100)) }
   108    122   } {}
   109         -do_test multiplex-2.2.3 { file size test.db } {6144}
          123  +do_test multiplex-2.2.3 { file size [multiplex_name test.db 0] } {6144}
   110    124   
   111    125   do_test multiplex-2.3.1 {
   112    126     sqlite3 db2 bak.db
   113    127     db2 close
   114    128   } {}
   115    129   
   116    130   do_test multiplex-2.4.1 {
   117    131     sqlite3_multiplex_shutdown
   118    132   } {SQLITE_MISUSE}
   119    133   do_test multiplex-2.4.2 {
   120    134     execsql { INSERT INTO t1 VALUES(3, randomblob(1100)) }
   121    135   } {}
   122         -do_test multiplex-2.4.4 { file size test.db } {7168}
          136  +do_test multiplex-2.4.4 { file size [multiplex_name test.db 0] } {7168}
   123    137   do_test multiplex-2.4.99 {
   124    138     db close
   125    139     sqlite3_multiplex_shutdown
   126    140   } {SQLITE_OK}
   127    141   
   128    142   
   129    143   do_test multiplex-2.5.1 {
................................................................................
   168    182     db eval {SELECT a,length(b) FROM t1 WHERE a=2}
   169    183   } {2 4000}
   170    184   
   171    185   do_test multiplex-2.5.8 {
   172    186     db eval {SELECT a,length(b) FROM t1 WHERE a=4}
   173    187   } {4 4000}
   174    188   
   175         -do_test multiplex-2.5.9 { file size test.db } [list $g_chunk_size]
   176         -do_test multiplex-2.5.10 { file size test.db-0001 } [list $g_chunk_size]
          189  +do_test multiplex-2.5.9 { file size [multiplex_name test.db 0] } [list $g_chunk_size]
          190  +do_test multiplex-2.5.10 { file size [multiplex_name test.db 1] } [list $g_chunk_size]
   177    191   
   178    192   do_test multiplex-2.5.99 {
   179    193     db close
   180    194     sqlite3_multiplex_shutdown
   181    195   } {SQLITE_OK}
   182    196   
   183    197   
................................................................................
   212    226         db eval {SELECT b FROM t1 WHERE a=1}
   213    227       } {one}
   214    228   
   215    229       do_test multiplex-2.6.5.$sz.$jmode {
   216    230         db eval {SELECT length(b) FROM t1 WHERE a=2}
   217    231       } [list $g_chunk_size]
   218    232   
   219         -    do_test multiplex-2.6.6.$sz.$jmode { file size test.db } [list $g_chunk_size]
          233  +    do_test multiplex-2.6.6.$sz.$jmode { file size [multiplex_name test.db 0] } [list $g_chunk_size]
   220    234   
   221    235       do_test multiplex-2.6.99.$sz.$jmode {
   222    236         db close
   223    237         sqlite3_multiplex_shutdown
   224    238       } {SQLITE_OK}
   225    239   
   226    240     }
................................................................................
   245    259     execsql {
   246    260       PRAGMA page_size = 1024;
   247    261       PRAGMA journal_mode = delete;
   248    262       PRAGMA auto_vacuum = off;
   249    263       CREATE TABLE t1(a PRIMARY KEY, b);
   250    264       INSERT INTO t1 VALUES(1, 'one');
   251    265     }
   252         -  file size test.db
          266  +  file size [multiplex_name test.db 0]
   253    267   } {3072}
   254    268   do_test multiplex-3.1.3 {
   255    269     sqlite3 db2 test.db
   256    270     execsql { CREATE TABLE t2(a, b) } db2
   257    271   } {}
   258    272   do_test multiplex-3.1.4 {
   259    273     execsql { CREATE TABLE t3(a, b) }
................................................................................
   279    293         PRAGMA page_size = 1024;
   280    294         PRAGMA journal_mode = delete;
   281    295         PRAGMA auto_vacuum = off;
   282    296         CREATE TABLE t1(a, b);
   283    297       } $db
   284    298     }
   285    299   
   286         -  list [file size test.db] [file size test2.db]
          300  +  list [file size [multiplex_name test.db 0]] [file size [multiplex_name test2.db 0]]
   287    301   } {2048 2048}
   288    302   
   289    303   do_test multiplex-3.2.1b {
   290    304     sqlite3 db1b test.db
   291    305     sqlite3 db2b test2.db
   292    306   } {}
   293    307