From d9523b97ecc218c2e8428eee636b6a5f557aef47 Mon Sep 17 00:00:00 2001 From: shaneh Date: Tue, 15 Mar 2011 04:45:48 +0000 Subject: [PATCH 1/7] Allow multiplex file names to be preceeded by prefix of the form ":multiplex:chunksize:maxchunks:" Still work to be done, though it compiles and prefixes are ignored. FossilOrigin-Name: cfa4a2f7ea948be0925227efca82baea509249c9 --- manifest | 15 +++++---- manifest.uuid | 2 +- src/test_multiplex.c | 75 ++++++++++++++++++++++++++++++++++++++------ 3 files changed, 76 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index a007a938e2..5ec64793db 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\scut-and-paste\stypo\sin\sdebugging\sprint\sstatement\sin\swinMutexTry(). -D 2011-03-15T02:55:28.657 +C Allow\smultiplex\sfile\snames\sto\sbe\spreceeded\sby\sprefix\sof\sthe\sform\s":multiplex:chunksize:maxchunks:"\s\nStill\swork\sto\sbe\sdone,\sthough\sit\scompiles\sand\sprefixes\sare\signored. +D 2011-03-15T04:45:48.735 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -209,7 +209,7 @@ F src/test_intarray.h 489edb9068bb926583445cb02589344961054207 F src/test_journal.c 785edd54f963aefb3c1628124170a56697c68c70 F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e F src/test_malloc.c fd6188b1501c0010fb4241ddc9f0d5ac402c688d -F src/test_multiplex.c 655cb3b663f87db7d3d2427ea127c9daacae4abc +F src/test_multiplex.c cf01141845d29639de2b6cdd6d7ef9dc0bce2888 F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec F src/test_osinst.c f408c6a181f2fb04c56273afd5c3e1e82f60392c @@ -913,7 +913,10 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 3934b004e93852c89b937ec20431de96a2e99440 -R a3bacb1f22d0b4cfa6cea5cf5efe9cdf +P def98fd23e42bda13547e38ab13fed0e6554ce99 +R 324244b8e2a2e32cd06c5dbee5aab290 +T *branch * experimental +T *sym-experimental * +T -sym-trunk * U shaneh -Z 62a7f6dd55f1de5255b8d7f88e967001 +Z b5732ca362c3f4ec7a64142aa2707561 diff --git a/manifest.uuid b/manifest.uuid index 03da2a631d..ad05a9f286 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -def98fd23e42bda13547e38ab13fed0e6554ce99 \ No newline at end of file +cfa4a2f7ea948be0925227efca82baea509249c9 \ No newline at end of file diff --git a/src/test_multiplex.c b/src/test_multiplex.c index 72a71621b4..694f7b4cb6 100644 --- a/src/test_multiplex.c +++ b/src/test_multiplex.c @@ -40,6 +40,8 @@ /************************ Shim Definitions ******************************/ +#define SQLITE_MULTIPLEX_VFS_NAME "multiplex" + /* This is the limit on the chunk size. It may be changed by calling ** the sqlite3_multiplex_set() interface. */ @@ -191,6 +193,53 @@ static sqlite3_file *multiplexSubOpen(multiplexConn *pConn, int iChunk, int *rc, return NULL; } +/* +** If the given filename begins with a valid multiplex prefix, return +** a pointer to the first character past the prefix. Otherwise +** return NULL pointer. If optional chunk size and max chunk +** values found, return them in int pointers. +*/ +static const char *multiplexParsePrefix(const char *zName, int *pChunkSize, int *pMaxChunks){ + int i; + int nChunkSize = 0; + int nMaxChunks = 0; + int lenPrefix = sqlite3Strlen30(SQLITE_MULTIPLEX_VFS_NAME)+2; + if( strncmp(zName, ":"SQLITE_MULTIPLEX_VFS_NAME":", lenPrefix)!=0 ) return 0; + /* if :multiplex: followed by ':' terminated string of digits, use + ** that value for the chunk size. */ + for(i=lenPrefix; sqlite3Isdigit(zName[i]); i++){ } + if ( zName[i]==':' ){ + if( pChunkSize ){ + if( sqlite3GetInt32(&zName[lenPrefix], &nChunkSize) ){ + *pChunkSize = nChunkSize; + } + } + lenPrefix = i+1; + /* if chunksize followed by ':' terminated string of digits, use + ** that value for the max chunks. */ + for(i=lenPrefix; sqlite3Isdigit(zName[i]); i++){ } + if ( zName[i]==':' ) { + if( pMaxChunks ){ + if( sqlite3GetInt32(&zName[lenPrefix], &nMaxChunks) ){ + *pMaxChunks = nMaxChunks; + } + } + lenPrefix = i+1; + } + } + return &zName[lenPrefix]; +} + +/* +** If the given filename that may or may not begin with a CEROD prefix, return +** a pointer to the first character of the filename past the prefix. +*/ +static const char *multiplexRootFilename(const char *zName){ + const char *zRoot = multiplexParsePrefix(zName, NULL, NULL); + if( zRoot==0 ) zRoot = zName; + return zRoot; +} + /************************* VFS Method Wrappers *****************************/ /* @@ -305,10 +354,10 @@ static int multiplexDelete( sqlite3_snprintf(SQLITE_MULTIPLEX_EXT_SZ+1, gMultiplex.zName+nName, SQLITE_MULTIPLEX_EXT_FMT, i); #endif } - rc2 = pOrigVfs->xAccess(pOrigVfs, gMultiplex.zName, SQLITE_ACCESS_EXISTS, &exists); + rc2 = pOrigVfs->xAccess(pOrigVfs, multiplexRootFilename(gMultiplex.zName), SQLITE_ACCESS_EXISTS, &exists); if( rc2==SQLITE_OK && exists){ /* if it exists, delete it */ - rc2 = pOrigVfs->xDelete(pOrigVfs, gMultiplex.zName, syncDir); + rc2 = pOrigVfs->xDelete(pOrigVfs, multiplexRootFilename(gMultiplex.zName), syncDir); if( rc2!=SQLITE_OK ) rc = rc2; }else{ /* stop at first "gap" */ @@ -319,11 +368,19 @@ static int multiplexDelete( return rc; } -static int multiplexAccess(sqlite3_vfs *a, const char *b, int c, int *d){ - return gMultiplex.pOrigVfs->xAccess(gMultiplex.pOrigVfs, b, c, d); +static int multiplexAccess(sqlite3_vfs *pVfs, const char *zName,int flgs,int *pOut){ + return gMultiplex.pOrigVfs->xAccess(gMultiplex.pOrigVfs, multiplexRootFilename(zName), flgs, pOut); } -static int multiplexFullPathname(sqlite3_vfs *a, const char *b, int c, char *d){ - return gMultiplex.pOrigVfs->xFullPathname(gMultiplex.pOrigVfs, b, c, d); +static int multiplexFullPathname(sqlite3_vfs *pVfs, const char *zName, int nOut, char *zOut){ + int n; + const char *zBase; + zBase = multiplexParsePrefix(zName, NULL, NULL); + if( zBase==0 ){ + return gMultiplex.pOrigVfs->xFullPathname(gMultiplex.pOrigVfs, zName, nOut, zOut); + } + n = (int)(zBase - zName); + memcpy(zOut, zName, n); + return gMultiplex.pOrigVfs->xFullPathname(gMultiplex.pOrigVfs, zBase, nOut - n, &zOut[n]); } static void *multiplexDlOpen(sqlite3_vfs *a, const char *b){ return gMultiplex.pOrigVfs->xDlOpen(gMultiplex.pOrigVfs, b); @@ -483,7 +540,7 @@ static int multiplexTruncate(sqlite3_file *pConn, sqlite3_int64 size){ #else sqlite3_snprintf(SQLITE_MULTIPLEX_EXT_SZ+1, gMultiplex.zName+pGroup->nName, SQLITE_MULTIPLEX_EXT_FMT, i); #endif - rc2 = pOrigVfs->xDelete(pOrigVfs, gMultiplex.zName, 0); + rc2 = pOrigVfs->xDelete(pOrigVfs, multiplexRootFilename(gMultiplex.zName), 0); if( rc2!=SQLITE_OK ) rc = SQLITE_IOERR_TRUNCATE; } pSubOpen = multiplexSubOpen(p, (int)(size/gMultiplex.nChunkSize), &rc2, NULL); @@ -544,7 +601,7 @@ static int multiplexFileSize(sqlite3_file *pConn, sqlite3_int64 *pSize){ sqlite3_snprintf(SQLITE_MULTIPLEX_EXT_SZ+1, gMultiplex.zName+pGroup->nName, SQLITE_MULTIPLEX_EXT_FMT, i); #endif } - rc2 = pOrigVfs->xAccess(pOrigVfs, gMultiplex.zName, SQLITE_ACCESS_EXISTS, &exists); + rc2 = pOrigVfs->xAccess(pOrigVfs, multiplexRootFilename(gMultiplex.zName), SQLITE_ACCESS_EXISTS, &exists); if( rc2==SQLITE_OK && exists){ /* if it exists, open it */ pSubOpen = multiplexSubOpen(p, i, &rc, NULL); @@ -738,7 +795,7 @@ int sqlite3_multiplex_initialize(const char *zOrigVfsName, int makeDefault){ gMultiplex.pOrigVfs = pOrigVfs; gMultiplex.sThisVfs = *pOrigVfs; gMultiplex.sThisVfs.szOsFile += sizeof(multiplexConn); - gMultiplex.sThisVfs.zName = "multiplex"; + gMultiplex.sThisVfs.zName = SQLITE_MULTIPLEX_VFS_NAME; gMultiplex.sThisVfs.xOpen = multiplexOpen; gMultiplex.sThisVfs.xDelete = multiplexDelete; gMultiplex.sThisVfs.xAccess = multiplexAccess; From d50deeeb7ad1279f17d49ef778ac6f2deac87b3e Mon Sep 17 00:00:00 2001 From: shaneh Date: Tue, 29 Mar 2011 05:06:46 +0000 Subject: [PATCH 2/7] In-progress changes - do not use; Removed prefix support; Added file control interface to enable/disable and adjust chunk size; added app-def function for same; FossilOrigin-Name: bc02d0c193225bd49a8d8a3295aeac752d3c2e30 --- manifest | 18 ++- manifest.uuid | 2 +- src/test_multiplex.c | 325 ++++++++++++++++++++++++------------------- src/test_multiplex.h | 48 +++++++ test/multiplex.test | 47 ++++--- 5 files changed, 263 insertions(+), 177 deletions(-) create mode 100644 src/test_multiplex.h diff --git a/manifest b/manifest index 5ec64793db..f83b7c380f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Allow\smultiplex\sfile\snames\sto\sbe\spreceeded\sby\sprefix\sof\sthe\sform\s":multiplex:chunksize:maxchunks:"\s\nStill\swork\sto\sbe\sdone,\sthough\sit\scompiles\sand\sprefixes\sare\signored. -D 2011-03-15T04:45:48.735 +C In-progress\schanges\s-\sdo\snot\suse;\sRemoved\sprefix\ssupport;\sAdded\sfile\scontrol\sinterface\sto\senable/disable\sand\sadjust\schunk\ssize;\nadded\sapp-def\sfunction\sfor\ssame; +D 2011-03-29T05:06:46.821 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -209,7 +209,8 @@ F src/test_intarray.h 489edb9068bb926583445cb02589344961054207 F src/test_journal.c 785edd54f963aefb3c1628124170a56697c68c70 F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e F src/test_malloc.c fd6188b1501c0010fb4241ddc9f0d5ac402c688d -F src/test_multiplex.c cf01141845d29639de2b6cdd6d7ef9dc0bce2888 +F src/test_multiplex.c 234f4b371d1a2ba88041e17c21e13f5273dd1b50 +F src/test_multiplex.h 22238a3286817918f1975a7c523827ea45d9fbb4 F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec F src/test_osinst.c f408c6a181f2fb04c56273afd5c3e1e82f60392c @@ -575,7 +576,7 @@ F test/misc5.test 45b2e3ed5f79af2b4f38ae362eaf4c49674575bd F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91 F test/misc7.test 29032efcd3d826fbd409e2a7af873e7939f4a4e3 F test/misuse.test 30b3a458e5a70c31e74c291937b6c82204c59f33 -F test/multiplex.test 92a4839213fd8cba8b59f86d42b7a1da1857db39 +F test/multiplex.test b813d11f2cd6a15c64d85b97c0c009afc2168226 F test/mutex1.test 78b2b9bb320e51d156c4efdb71b99b051e7a4b41 F test/mutex2.test bfeaeac2e73095b2ac32285d2756e3a65e681660 F test/nan.test a44e04df1486fcfb02d32468cbcd3c8e1e433723 @@ -913,10 +914,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P def98fd23e42bda13547e38ab13fed0e6554ce99 -R 324244b8e2a2e32cd06c5dbee5aab290 -T *branch * experimental -T *sym-experimental * -T -sym-trunk * +P cfa4a2f7ea948be0925227efca82baea509249c9 +R cd848b3ee75fe87902bd71c01c78919c U shaneh -Z b5732ca362c3f4ec7a64142aa2707561 +Z 7951456e7d17419744e4f948b8232fcd diff --git a/manifest.uuid b/manifest.uuid index ad05a9f286..9ab9b53bfe 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cfa4a2f7ea948be0925227efca82baea509249c9 \ No newline at end of file +bc02d0c193225bd49a8d8a3295aeac752d3c2e30 \ No newline at end of file diff --git a/src/test_multiplex.c b/src/test_multiplex.c index 694f7b4cb6..3855050edd 100644 --- a/src/test_multiplex.c +++ b/src/test_multiplex.c @@ -23,6 +23,10 @@ #include #include #include "sqliteInt.h" +#include "test_multiplex.h" + +#include "sqlite3ext.h" +SQLITE_EXTENSION_INIT1 /* ** For a build without mutexes, no-op the mutex calls. @@ -43,13 +47,13 @@ #define SQLITE_MULTIPLEX_VFS_NAME "multiplex" /* This is the limit on the chunk size. It may be changed by calling -** the sqlite3_multiplex_set() interface. +** the xFileControl() interface. */ #define SQLITE_MULTIPLEX_CHUNK_SIZE 0x40000000 /* Default limit on number of chunks. Care should be taken ** so that values for chunks numbers fit in the SQLITE_MULTIPLEX_EXT_FMT ** format specifier. It may be changed by calling -** the sqlite3_multiplex_set() interface. +** the xFileControl() interface. */ #define SQLITE_MULTIPLEX_MAX_CHUNKS 32 @@ -84,6 +88,9 @@ struct multiplexGroup { char *zName; /* Base filename of this group */ int nName; /* Length of base filename */ int flags; /* Flags used for original opening */ + int nChunkSize; /* Chunk size used for this group */ + int nMaxChunks; /* Max number of chunks for this group */ + int bEnabled; /* TRUE to use Multiplex VFS for this file */ multiplexGroup *pNext, *pPrev; /* Doubly linked list of all group objects */ }; @@ -142,11 +149,6 @@ static struct { */ multiplexGroup *pGroups; - /* Chunk params. - */ - int nChunkSize; - int nMaxChunks; - /* Storage for temp file names. Allocated during ** initialization to the max pathname of the underlying VFS. */ @@ -168,7 +170,7 @@ static void multiplexLeave(void){ sqlite3_mutex_leave(gMultiplex.pMutex); } static sqlite3_file *multiplexSubOpen(multiplexConn *pConn, int iChunk, int *rc, int *pOutFlags){ multiplexGroup *pGroup = pConn->pGroup; sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs; /* Real VFS */ - if( iChunknMaxChunks ){ sqlite3_file *pSubOpen = pGroup->pReal[iChunk]; /* Real file descriptor */ if( !pGroup->bOpen[iChunk] ){ memcpy(gMultiplex.zName, pGroup->zName, pGroup->nName+1); @@ -193,51 +195,34 @@ static sqlite3_file *multiplexSubOpen(multiplexConn *pConn, int iChunk, int *rc, return NULL; } -/* -** If the given filename begins with a valid multiplex prefix, return -** a pointer to the first character past the prefix. Otherwise -** return NULL pointer. If optional chunk size and max chunk -** values found, return them in int pointers. -*/ -static const char *multiplexParsePrefix(const char *zName, int *pChunkSize, int *pMaxChunks){ - int i; - int nChunkSize = 0; - int nMaxChunks = 0; - int lenPrefix = sqlite3Strlen30(SQLITE_MULTIPLEX_VFS_NAME)+2; - if( strncmp(zName, ":"SQLITE_MULTIPLEX_VFS_NAME":", lenPrefix)!=0 ) return 0; - /* if :multiplex: followed by ':' terminated string of digits, use - ** that value for the chunk size. */ - for(i=lenPrefix; sqlite3Isdigit(zName[i]); i++){ } - if ( zName[i]==':' ){ - if( pChunkSize ){ - if( sqlite3GetInt32(&zName[lenPrefix], &nChunkSize) ){ - *pChunkSize = nChunkSize; - } - } - lenPrefix = i+1; - /* if chunksize followed by ':' terminated string of digits, use - ** that value for the max chunks. */ - for(i=lenPrefix; sqlite3Isdigit(zName[i]); i++){ } - if ( zName[i]==':' ) { - if( pMaxChunks ){ - if( sqlite3GetInt32(&zName[lenPrefix], &nMaxChunks) ){ - *pMaxChunks = nMaxChunks; - } - } - lenPrefix = i+1; - } +static void multiplexControlFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + extern const char *sqlite3TestErrorName(int); + extern int multiplexFileControl(sqlite3_file *, int, void *); + sqlite3_file *db = (sqlite3_file *)sqlite3_user_data(context); + int op = sqlite3_value_int(argv[0]); + int iVal = sqlite3_value_int(argv[1]); + int rc = multiplexFileControl(db, op, &iVal); + if( rc== 0 ){ + sqlite3_result_text(context, (char *)sqlite3TestErrorName(rc), -1, SQLITE_TRANSIENT); } - return &zName[lenPrefix]; + sqlite3_result_text(context, (char *)sqlite3TestErrorName(rc), -1, SQLITE_TRANSIENT); } /* -** If the given filename that may or may not begin with a CEROD prefix, return -** a pointer to the first character of the filename past the prefix. +** This is the entry point to register the extension for the multiplex_control() function. */ -static const char *multiplexRootFilename(const char *zName){ - const char *zRoot = multiplexParsePrefix(zName, NULL, NULL); - if( zRoot==0 ) zRoot = zName; - return zRoot; +static int multiplexFuncInit( + sqlite3 *db, + char **pzErrMsg, + const sqlite3_api_routines *pApi +){ + sqlite3_create_function(db, "multiplex_control", 2, SQLITE_ANY, + db, multiplexControlFunc, 0, 0); + return 0; } /************************* VFS Method Wrappers *****************************/ @@ -274,9 +259,9 @@ static int multiplexOpen( pMultiplexOpen = (multiplexConn*)pConn; /* allocate space for group */ sz = sizeof(multiplexGroup) /* multiplexGroup */ - + (sizeof(sqlite3_file *)*gMultiplex.nMaxChunks) /* pReal[] */ - + (pOrigVfs->szOsFile*gMultiplex.nMaxChunks) /* *pReal */ - + gMultiplex.nMaxChunks /* bOpen[] */ + + (sizeof(sqlite3_file *)*SQLITE_MULTIPLEX_MAX_CHUNKS) /* pReal[] */ + + (pOrigVfs->szOsFile*SQLITE_MULTIPLEX_MAX_CHUNKS) /* *pReal */ + + SQLITE_MULTIPLEX_MAX_CHUNKS /* bOpen[] */ + nName + 1; /* zName */ #ifndef SQLITE_MULTIPLEX_EXT_OVWR sz += SQLITE_MULTIPLEX_EXT_SZ; @@ -293,14 +278,17 @@ static int multiplexOpen( char *p = (char *)&pGroup[1]; pMultiplexOpen->pGroup = pGroup; memset(pGroup, 0, sz); + pGroup->nChunkSize = SQLITE_MULTIPLEX_CHUNK_SIZE; + pGroup->nMaxChunks = SQLITE_MULTIPLEX_MAX_CHUNKS; pGroup->pReal = (sqlite3_file **)p; - p += (sizeof(sqlite3_file *)*gMultiplex.nMaxChunks); - for(i=0; inMaxChunks); + for(i=0; inMaxChunks; i++){ pGroup->pReal[i] = (sqlite3_file *)p; p += pOrigVfs->szOsFile; } + /* bOpen[] vals should all be zero from memset above */ pGroup->bOpen = p; - p += gMultiplex.nMaxChunks; + p += pGroup->nMaxChunks; pGroup->zName = p; /* save off base filename, name length, and original open flags */ memcpy(pGroup->zName, zName, nName+1); @@ -344,7 +332,7 @@ static int multiplexDelete( multiplexEnter(); memcpy(gMultiplex.zName, zName, nName+1); - for(i=0; ixAccess(pOrigVfs, multiplexRootFilename(gMultiplex.zName), SQLITE_ACCESS_EXISTS, &exists); + rc2 = pOrigVfs->xAccess(pOrigVfs, gMultiplex.zName, SQLITE_ACCESS_EXISTS, &exists); if( rc2==SQLITE_OK && exists){ /* if it exists, delete it */ - rc2 = pOrigVfs->xDelete(pOrigVfs, multiplexRootFilename(gMultiplex.zName), syncDir); + rc2 = pOrigVfs->xDelete(pOrigVfs, gMultiplex.zName, syncDir); if( rc2!=SQLITE_OK ) rc = rc2; }else{ /* stop at first "gap" */ @@ -368,19 +356,11 @@ static int multiplexDelete( return rc; } -static int multiplexAccess(sqlite3_vfs *pVfs, const char *zName,int flgs,int *pOut){ - return gMultiplex.pOrigVfs->xAccess(gMultiplex.pOrigVfs, multiplexRootFilename(zName), flgs, pOut); +static int multiplexAccess(sqlite3_vfs *a, const char *b, int c, int *d){ + return gMultiplex.pOrigVfs->xAccess(gMultiplex.pOrigVfs, b, c, d); } -static int multiplexFullPathname(sqlite3_vfs *pVfs, const char *zName, int nOut, char *zOut){ - int n; - const char *zBase; - zBase = multiplexParsePrefix(zName, NULL, NULL); - if( zBase==0 ){ - return gMultiplex.pOrigVfs->xFullPathname(gMultiplex.pOrigVfs, zName, nOut, zOut); - } - n = (int)(zBase - zName); - memcpy(zOut, zName, n); - return gMultiplex.pOrigVfs->xFullPathname(gMultiplex.pOrigVfs, zBase, nOut - n, &zOut[n]); +static int multiplexFullPathname(sqlite3_vfs *a, const char *b, int c, char *d){ + return gMultiplex.pOrigVfs->xFullPathname(gMultiplex.pOrigVfs, b, c, d); } static void *multiplexDlOpen(sqlite3_vfs *a, const char *b){ return gMultiplex.pOrigVfs->xDlOpen(gMultiplex.pOrigVfs, b); @@ -424,7 +404,7 @@ static int multiplexClose(sqlite3_file *pConn){ int i; multiplexEnter(); /* close any open handles */ - for(i=0; inMaxChunks; i++){ if( pGroup->bOpen[i] ){ sqlite3_file *pSubOpen = pGroup->pReal[i]; int rc2 = pSubOpen->pMethods->xClose(pSubOpen); @@ -455,16 +435,17 @@ static int multiplexRead( sqlite3_int64 iOfst ){ multiplexConn *p = (multiplexConn*)pConn; + multiplexGroup *pGroup = p->pGroup; int rc = SQLITE_OK; multiplexEnter(); while( iAmt > 0 ){ - int i = (int)(iOfst/gMultiplex.nChunkSize); + int i = (int)(iOfst / pGroup->nChunkSize); sqlite3_file *pSubOpen = multiplexSubOpen(p, i, &rc, NULL); if( pSubOpen ){ - int extra = ((int)(iOfst % gMultiplex.nChunkSize) + iAmt) - gMultiplex.nChunkSize; + int extra = ((int)(iOfst % pGroup->nChunkSize) + iAmt) - pGroup->nChunkSize; if( extra<0 ) extra = 0; iAmt -= extra; - rc = pSubOpen->pMethods->xRead(pSubOpen, pBuf, iAmt, iOfst%gMultiplex.nChunkSize); + rc = pSubOpen->pMethods->xRead(pSubOpen, pBuf, iAmt, iOfst % pGroup->nChunkSize); if( rc!=SQLITE_OK ) break; pBuf = (char *)pBuf + iAmt; iOfst += iAmt; @@ -489,16 +470,17 @@ static int multiplexWrite( sqlite3_int64 iOfst ){ multiplexConn *p = (multiplexConn*)pConn; + multiplexGroup *pGroup = p->pGroup; int rc = SQLITE_OK; multiplexEnter(); while( iAmt > 0 ){ - int i = (int)(iOfst/gMultiplex.nChunkSize); + int i = (int)(iOfst / pGroup->nChunkSize); sqlite3_file *pSubOpen = multiplexSubOpen(p, i, &rc, NULL); if( pSubOpen ){ - int extra = ((int)(iOfst % gMultiplex.nChunkSize) + iAmt) - gMultiplex.nChunkSize; + int extra = ((int)(iOfst % pGroup->nChunkSize) + iAmt) - pGroup->nChunkSize; if( extra<0 ) extra = 0; iAmt -= extra; - rc = pSubOpen->pMethods->xWrite(pSubOpen, pBuf, iAmt, iOfst%gMultiplex.nChunkSize); + rc = pSubOpen->pMethods->xWrite(pSubOpen, pBuf, iAmt, iOfst % pGroup->nChunkSize); if( rc!=SQLITE_OK ) break; pBuf = (char *)pBuf + iAmt; iOfst += iAmt; @@ -527,7 +509,7 @@ static int multiplexTruncate(sqlite3_file *pConn, sqlite3_int64 size){ multiplexEnter(); memcpy(gMultiplex.zName, pGroup->zName, pGroup->nName+1); /* delete the chunks above the truncate limit */ - for(i=(int)(size/gMultiplex.nChunkSize)+1; inChunkSize)+1; inMaxChunks; i++){ /* close any open chunks before deleting them */ if( pGroup->bOpen[i] ){ pSubOpen = pGroup->pReal[i]; @@ -540,12 +522,12 @@ static int multiplexTruncate(sqlite3_file *pConn, sqlite3_int64 size){ #else sqlite3_snprintf(SQLITE_MULTIPLEX_EXT_SZ+1, gMultiplex.zName+pGroup->nName, SQLITE_MULTIPLEX_EXT_FMT, i); #endif - rc2 = pOrigVfs->xDelete(pOrigVfs, multiplexRootFilename(gMultiplex.zName), 0); + rc2 = pOrigVfs->xDelete(pOrigVfs, gMultiplex.zName, 0); if( rc2!=SQLITE_OK ) rc = SQLITE_IOERR_TRUNCATE; } - pSubOpen = multiplexSubOpen(p, (int)(size/gMultiplex.nChunkSize), &rc2, NULL); + pSubOpen = multiplexSubOpen(p, (int)(size / pGroup->nChunkSize), &rc2, NULL); if( pSubOpen ){ - rc2 = pSubOpen->pMethods->xTruncate(pSubOpen, size%gMultiplex.nChunkSize); + rc2 = pSubOpen->pMethods->xTruncate(pSubOpen, size % pGroup->nChunkSize); if( rc2!=SQLITE_OK ) rc = rc2; }else{ rc = SQLITE_IOERR_TRUNCATE; @@ -562,7 +544,7 @@ static int multiplexSync(sqlite3_file *pConn, int flags){ int rc = SQLITE_OK; int i; multiplexEnter(); - for(i=0; inMaxChunks; i++){ /* if we don't have it open, we don't need to sync it */ if( pGroup->bOpen[i] ){ sqlite3_file *pSubOpen = pGroup->pReal[i]; @@ -585,7 +567,7 @@ static int multiplexFileSize(sqlite3_file *pConn, sqlite3_int64 *pSize){ int i; multiplexEnter(); *pSize = 0; - for(i=0; inMaxChunks; i++){ sqlite3_file *pSubOpen = NULL; /* if not opened already, check to see if the chunk exists */ if( pGroup->bOpen[i] ){ @@ -601,7 +583,7 @@ static int multiplexFileSize(sqlite3_file *pConn, sqlite3_int64 *pSize){ sqlite3_snprintf(SQLITE_MULTIPLEX_EXT_SZ+1, gMultiplex.zName+pGroup->nName, SQLITE_MULTIPLEX_EXT_FMT, i); #endif } - rc2 = pOrigVfs->xAccess(pOrigVfs, multiplexRootFilename(gMultiplex.zName), SQLITE_ACCESS_EXISTS, &exists); + rc2 = pOrigVfs->xAccess(pOrigVfs, gMultiplex.zName, SQLITE_ACCESS_EXISTS, &exists); if( rc2==SQLITE_OK && exists){ /* if it exists, open it */ pSubOpen = multiplexSubOpen(p, i, &rc, NULL); @@ -616,7 +598,7 @@ static int multiplexFileSize(sqlite3_file *pConn, sqlite3_int64 *pSize){ if( rc2!=SQLITE_OK ){ rc = rc2; }else{ - if( sz>gMultiplex.nChunkSize ){ + if( sz>pGroup->nChunkSize ){ rc = SQLITE_IOERR_FSTAT; } *pSize += sz; @@ -669,14 +651,49 @@ static int multiplexCheckReservedLock(sqlite3_file *pConn, int *pResOut){ */ static int multiplexFileControl(sqlite3_file *pConn, int op, void *pArg){ multiplexConn *p = (multiplexConn*)pConn; - int rc; + multiplexGroup *pGroup = p->pGroup; + int rc = SQLITE_ERROR; sqlite3_file *pSubOpen; - if ( op==SQLITE_FCNTL_SIZE_HINT || op==SQLITE_FCNTL_CHUNK_SIZE ) return SQLITE_OK; + + if( !gMultiplex.isInitialized ) return SQLITE_MISUSE; + switch( op ){ + case MULTIPLEX_CTRL_ENABLE: + if( pArg ) { + int bEnabled = *(int *)pArg; + pGroup->bEnabled = bEnabled; + rc = SQLITE_OK; + } + break; + case MULTIPLEX_CTRL_SET_CHUNK_SIZE: + if( pArg ) { + int nChunkSize = *(int *)pArg; + if( nChunkSize<32 ){ + rc = SQLITE_MISUSE; + }else{ + pGroup->nChunkSize = nChunkSize; + rc = SQLITE_OK; + } + } + break; + case MULTIPLEX_CTRL_SET_MAX_CHUNKS: + if( pArg ) { + int nMaxChunks = *(int *)pArg; + if(( nMaxChunks<1 ) || ( nMaxChunks>99 )){ + rc = SQLITE_MISUSE; + }else{ + pGroup->nMaxChunks = nMaxChunks; + rc = SQLITE_OK; + } + } + break; + default: pSubOpen = multiplexSubOpen(p, 0, &rc, NULL); if( pSubOpen ){ - return pSubOpen->pMethods->xFileControl(pSubOpen, op, pArg); + rc = pSubOpen->pMethods->xFileControl(pSubOpen, op, pArg); } - return SQLITE_ERROR; + break; + } + return rc; } /* Pass xSectorSize requests through to the original VFS unchanged. @@ -788,8 +805,6 @@ int sqlite3_multiplex_initialize(const char *zOrigVfsName, int makeDefault){ sqlite3_mutex_free(gMultiplex.pMutex); return SQLITE_NOMEM; } - gMultiplex.nChunkSize = SQLITE_MULTIPLEX_CHUNK_SIZE; - gMultiplex.nMaxChunks = SQLITE_MULTIPLEX_MAX_CHUNKS; gMultiplex.pGroups = NULL; gMultiplex.isInitialized = 1; gMultiplex.pOrigVfs = pOrigVfs; @@ -830,6 +845,9 @@ int sqlite3_multiplex_initialize(const char *zOrigVfsName, int makeDefault){ gMultiplex.sIoMethodsV2.xShmBarrier = multiplexShmBarrier; gMultiplex.sIoMethodsV2.xShmUnmap = multiplexShmUnmap; sqlite3_vfs_register(&gMultiplex.sThisVfs, makeDefault); + + sqlite3_auto_extension((void*)multiplexFuncInit); + return SQLITE_OK; } @@ -853,33 +871,10 @@ int sqlite3_multiplex_shutdown(void){ return SQLITE_OK; } -/* -** Adjust chunking params. VFS should be initialized first. -** No files should be open. Re-intializing will reset these -** to the default. -*/ -int sqlite3_multiplex_set( - int nChunkSize, /* Max chunk size */ - int nMaxChunks /* Max number of chunks */ -){ - if( !gMultiplex.isInitialized ) return SQLITE_MISUSE; - if( gMultiplex.pGroups ) return SQLITE_MISUSE; - if( nChunkSize<32 ) return SQLITE_MISUSE; - if( nMaxChunks<1 ) return SQLITE_MISUSE; - if( nMaxChunks>99 ) return SQLITE_MISUSE; - multiplexEnter(); - gMultiplex.nChunkSize = nChunkSize; - gMultiplex.nMaxChunks = nMaxChunks; - multiplexLeave(); - return SQLITE_OK; -} - /***************************** Test Code ***********************************/ #ifdef SQLITE_TEST #include -extern const char *sqlite3TestErrorName(int); - /* ** tclcmd: sqlite3_multiplex_initialize NAME MAKEDEFAULT @@ -937,36 +932,6 @@ static int test_multiplex_shutdown( return TCL_OK; } -/* -** tclcmd: sqlite3_multiplex_set CHUNK_SIZE MAX_CHUNKS -*/ -static int test_multiplex_set( - void * clientData, - Tcl_Interp *interp, - int objc, - Tcl_Obj *CONST objv[] -){ - int nChunkSize; /* Max chunk size */ - int nMaxChunks; /* Max number of chunks */ - int rc; /* Value returned by sqlite3_multiplex_set() */ - - UNUSED_PARAMETER(clientData); - - /* Process arguments */ - if( objc!=3 ){ - Tcl_WrongNumArgs(interp, 1, objv, "CHUNK_SIZE MAX_CHUNKS"); - return TCL_ERROR; - } - if( Tcl_GetIntFromObj(interp, objv[1], &nChunkSize) ) return TCL_ERROR; - if( Tcl_GetIntFromObj(interp, objv[2], &nMaxChunks) ) return TCL_ERROR; - - /* Invoke sqlite3_multiplex_set() */ - rc = sqlite3_multiplex_set(nChunkSize, nMaxChunks); - - Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_STATIC); - return TCL_OK; -} - /* ** tclcmd: sqlite3_multiplex_dump */ @@ -1000,16 +965,16 @@ static int test_multiplex_dump( Tcl_NewIntObj(pGroup->flags)); /* count number of chunks with open handles */ - for(i=0; inMaxChunks; i++){ if( pGroup->bOpen[i] ) nChunks++; } Tcl_ListObjAppendElement(interp, pGroupTerm, Tcl_NewIntObj(nChunks)); Tcl_ListObjAppendElement(interp, pGroupTerm, - Tcl_NewIntObj(gMultiplex.nChunkSize)); + Tcl_NewIntObj(pGroup->nChunkSize)); Tcl_ListObjAppendElement(interp, pGroupTerm, - Tcl_NewIntObj(gMultiplex.nMaxChunks)); + Tcl_NewIntObj(pGroup->nMaxChunks)); Tcl_ListObjAppendElement(interp, pResult, pGroupTerm); } @@ -1018,6 +983,72 @@ static int test_multiplex_dump( return TCL_OK; } +/* +** Tclcmd: test_multiplex_control HANDLE DBNAME SUB-COMMAND ?INT-VALUE? +*/ +static int test_multiplex_control( + ClientData cd, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + int rc; /* Return code from file_control() */ + int idx; /* Index in aSub[] */ + Tcl_CmdInfo cmdInfo; /* Command info structure for HANDLE */ + sqlite3 *db; /* Underlying db handle for HANDLE */ + int iValue = 0; + void *pArg = 0; + + struct SubCommand { + const char *zName; + int op; + int argtype; + } aSub[] = { + { "enable", MULTIPLEX_CTRL_ENABLE, 1 }, + { "chunk_size", MULTIPLEX_CTRL_SET_CHUNK_SIZE, 1 }, + { "max_chunks", MULTIPLEX_CTRL_SET_MAX_CHUNKS, 1 }, + { 0, 0, 0 } + }; + + if( objc!=4 && objc!=5 ){ + Tcl_WrongNumArgs(interp, 1, objv, "HANDLE DBNAME SUB-COMMAND ?INT-VALUE?"); + return TCL_ERROR; + } + + if( 0==Tcl_GetCommandInfo(interp, Tcl_GetString(objv[1]), &cmdInfo) ){ + Tcl_AppendResult(interp, "expected database handle, got \"", 0); + Tcl_AppendResult(interp, Tcl_GetString(objv[1]), "\"", 0); + return TCL_ERROR; + }else{ + db = *(sqlite3 **)cmdInfo.objClientData; + } + + rc = Tcl_GetIndexFromObjStruct( + interp, objv[3], aSub, sizeof(aSub[0]), "sub-command", 0, &idx + ); + if( rc!=TCL_OK ) return rc; + + switch( aSub[idx].argtype ){ + case 1: + if( objc!=5 ){ + Tcl_WrongNumArgs(interp, 4, objv, "INT-VALUE"); + return TCL_ERROR; + } + if( Tcl_GetIntFromObj(interp, objv[4], &iValue) ){ + return TCL_ERROR; + } + pArg = (void *)&iValue; + break; + default: + Tcl_WrongNumArgs(interp, 4, objv, "SUB-COMMAND"); + return TCL_ERROR; + } + + rc = sqlite3_file_control(db, Tcl_GetString(objv[2]), aSub[idx].op, pArg); + Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_STATIC); + return (rc==SQLITE_OK) ? TCL_OK : TCL_ERROR; +} + /* ** This routine registers the custom TCL commands defined in this ** module. This should be the only procedure visible from outside @@ -1030,8 +1061,8 @@ int Sqlitemultiplex_Init(Tcl_Interp *interp){ } aCmd[] = { { "sqlite3_multiplex_initialize", test_multiplex_initialize }, { "sqlite3_multiplex_shutdown", test_multiplex_shutdown }, - { "sqlite3_multiplex_set", test_multiplex_set }, { "sqlite3_multiplex_dump", test_multiplex_dump }, + { "sqlite3_multiplex_control", test_multiplex_control }, }; int i; diff --git a/src/test_multiplex.h b/src/test_multiplex.h new file mode 100644 index 0000000000..cc56ee92e4 --- /dev/null +++ b/src/test_multiplex.h @@ -0,0 +1,48 @@ +/* +** 2011 March 18 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file contains a VFS "shim" - a layer that sits in between the +** pager and the real VFS. +** +** This particular shim enforces a multiplex system on DB files. +** This shim shards/partitions a single DB file into smaller +** "chunks" such that the total DB file size may exceed the maximum +** file size of the underlying file system. +** +*/ + +#ifndef _TEST_MULTIPLEX_H +#define _TEST_MULTIPLEX_H + +/* +** CAPI: File-control Operations Supported by Multiplex VFS +** +** Values interpreted by the xFileControl method of a Multiplex VFS db file-handle. +** +** MULTIPLEX_CTRL_ENABLE: +** This file control is used to enable or disable the multiplex +** shim. +** +** MULTIPLEX_CTRL_SET_CHUNK_SIZE: +** This file control is used to set the maximum allowed chunk +** size for a multiplex file set. +** +** MULTIPLEX_CTRL_SET_MAX_CHUNKS: +** This file control is used to set the maximum number of chunks +** allowed to be used for a mutliplex file set. +*/ +#define MULTIPLEX_CTRL_ENABLE 214014 +#define MULTIPLEX_CTRL_SET_CHUNK_SIZE 214015 +#define MULTIPLEX_CTRL_SET_MAX_CHUNKS 214016 + + +#endif diff --git a/test/multiplex.test b/test/multiplex.test index 742ca5079e..582f71eabe 100644 --- a/test/multiplex.test +++ b/test/multiplex.test @@ -32,13 +32,17 @@ proc multiplex_name {name chunk} { } # This saves off the parameters and calls the -# underlying sqlite3_multiplex_set() API. -proc multiplex_set {chunk_size max_chunks} { +# underlying sqlite3_multiplex_control() API. +proc multiplex_set {db name chunk_size max_chunks} { global g_chunk_size global g_max_chunks set g_chunk_size $chunk_size set g_max_chunks $max_chunks - sqlite3_multiplex_set $chunk_size $max_chunks + set rc [catch {sqlite3_multiplex_control $db $name chunk_size $chunk_size} msg] + if { $rc==0 } { + set rc [catch {sqlite3_multiplex_control $db $name max_chunks $max_chunks} msg] + } + list $msg } # This attempts to delete the base file and @@ -71,14 +75,15 @@ do_test multiplex-1.7 { sqlite3_multiplex_initialize "" 1 } {SQLITE_OK} do_test multiplex-1.8 { sqlite3_multiplex_shutdown } {SQLITE_OK} do_test multiplex-1.9 { sqlite3_multiplex_initialize "" 1 } {SQLITE_OK} -do_test multiplex-1.10.1 { multiplex_set 32768 16 } {SQLITE_OK} -do_test multiplex-1.10.2 { multiplex_set 32768 -1 } {SQLITE_MISUSE} -do_test multiplex-1.10.3 { multiplex_set -1 16 } {SQLITE_MISUSE} -do_test multiplex-1.10.4 { multiplex_set 31 16 } {SQLITE_MISUSE} -do_test multiplex-1.10.5 { multiplex_set 32768 100 } {SQLITE_MISUSE} +sqlite3 db test.db +do_test multiplex-1.10.1 { multiplex_set db main 32768 16 } {SQLITE_OK} +do_test multiplex-1.10.2 { multiplex_set db main 32768 -1 } {SQLITE_MISUSE} +do_test multiplex-1.10.3 { multiplex_set db main -1 16 } {SQLITE_MISUSE} +do_test multiplex-1.10.4 { multiplex_set db main 31 16 } {SQLITE_MISUSE} +do_test multiplex-1.10.5 { multiplex_set db main 32768 100 } {SQLITE_MISUSE} +db close do_test multiplex-1.11 { sqlite3_multiplex_shutdown } {SQLITE_OK} - #------------------------------------------------------------------------- # Some simple warm-body tests with a single database file in rollback # mode: @@ -89,7 +94,7 @@ do_test multiplex-1.11 { sqlite3_multiplex_shutdown } {SQLITE_OK} # # multiplex-2.3.*: Open and close a second db. # -# multiplex-2.4.*: Try to shutdown the multiplex system before closing the db +# multiplex-2.4.*: Try to shutdown the multiplex system befor e closing the db # file. Check that this fails and the multiplex system still works # afterwards. Then close the database and successfully shut # down the multiplex system. @@ -100,7 +105,7 @@ do_test multiplex-1.11 { sqlite3_multiplex_shutdown } {SQLITE_OK} # well as varying journal mode. sqlite3_multiplex_initialize "" 1 -multiplex_set 32768 16 +multiplex_set db main 32768 16 do_test multiplex-2.1.2 { sqlite3 db test.db @@ -130,6 +135,7 @@ do_test multiplex-2.3.1 { db2 close } {} + do_test multiplex-2.4.1 { sqlite3_multiplex_shutdown } {SQLITE_MISUSE} @@ -146,11 +152,11 @@ do_test multiplex-2.4.99 { do_test multiplex-2.5.1 { multiplex_delete test.db sqlite3_multiplex_initialize "" 1 - multiplex_set 4096 16 + sqlite3 db test.db + multiplex_set db main 4096 16 } {SQLITE_OK} do_test multiplex-2.5.2 { - sqlite3 db test.db execsql { PRAGMA page_size = 1024; PRAGMA journal_mode = delete; @@ -197,6 +203,9 @@ do_test multiplex-2.5.99 { sqlite3_multiplex_shutdown } {SQLITE_OK} +return + +# TBD fix the below set all_journal_modes {delete persist truncate memory off} foreach jmode $all_journal_modes { @@ -205,7 +214,7 @@ foreach jmode $all_journal_modes { do_test multiplex-2.6.1.$sz.$jmode { multiplex_delete test.db sqlite3_multiplex_initialize "" 1 - multiplex_set $sz 32 + multiplex_set db main $sz 32 } {SQLITE_OK} do_test multiplex-2.6.2.$sz.$jmode { @@ -255,7 +264,7 @@ foreach jmode $all_journal_modes { do_test multiplex-3.1.1 { multiplex_delete test.db sqlite3_multiplex_initialize "" 1 - multiplex_set 32768 16 + multiplex_set db main 32768 16 } {SQLITE_OK} do_test multiplex-3.1.2 { sqlite3 db test.db @@ -341,7 +350,7 @@ do_test multiplex-3.2.X { # sqlite3_multiplex_initialize "" 1 -multiplex_set 32768 16 +multiplex_set db main 32768 16 # Return a list of all currently defined multiplexs. proc multiplex_list {} { @@ -403,7 +412,7 @@ do_test multiplex-4.1.12 { # sqlite3_multiplex_initialize "" 1 -multiplex_set 32768 16 +multiplex_set db main 32768 16 do_faultsim_test multiplex-5.1 -prep { catch {db close} @@ -448,7 +457,7 @@ do_faultsim_test multiplex-5.5 -prep { catch { sqlite3_multiplex_shutdown } } -body { sqlite3_multiplex_initialize "" 1 - multiplex_set 32768 16 + multiplex_set db main 32768 16 } # test that mismatch filesize is detected @@ -481,7 +490,7 @@ if {0==[info exists ::G(perm:presql)] || $::G(perm:presql) == ""} { } db close sqlite3_multiplex_initialize "" 1 - multiplex_set 4096 16 + multiplex_set db main 4096 16 sqlite3 db test.db } {} do_test multiplex-5.6.3.$jmode { From ac039688d2b7f6a55b142efba59eea84e4047f34 Mon Sep 17 00:00:00 2001 From: shaneh Date: Wed, 30 Mar 2011 21:03:07 +0000 Subject: [PATCH 3/7] Updates to multiplex.test script; misc. bug fixes; FossilOrigin-Name: c41ff2358e8af0fe2186ab4173b81fba204a57ab --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/test_multiplex.c | 23 ++++++++++++----------- test/multiplex.test | 11 ++++------- 4 files changed, 24 insertions(+), 26 deletions(-) diff --git a/manifest b/manifest index f83b7c380f..66152d91b4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In-progress\schanges\s-\sdo\snot\suse;\sRemoved\sprefix\ssupport;\sAdded\sfile\scontrol\sinterface\sto\senable/disable\sand\sadjust\schunk\ssize;\nadded\sapp-def\sfunction\sfor\ssame; -D 2011-03-29T05:06:46.821 +C Updates\sto\smultiplex.test\sscript;\s\smisc.\sbug\sfixes; +D 2011-03-30T21:03:07.666 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -209,7 +209,7 @@ F src/test_intarray.h 489edb9068bb926583445cb02589344961054207 F src/test_journal.c 785edd54f963aefb3c1628124170a56697c68c70 F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e F src/test_malloc.c fd6188b1501c0010fb4241ddc9f0d5ac402c688d -F src/test_multiplex.c 234f4b371d1a2ba88041e17c21e13f5273dd1b50 +F src/test_multiplex.c aa5da1f2847d6d6e69a41a6d8a9242860549258f F src/test_multiplex.h 22238a3286817918f1975a7c523827ea45d9fbb4 F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec @@ -576,7 +576,7 @@ F test/misc5.test 45b2e3ed5f79af2b4f38ae362eaf4c49674575bd F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91 F test/misc7.test 29032efcd3d826fbd409e2a7af873e7939f4a4e3 F test/misuse.test 30b3a458e5a70c31e74c291937b6c82204c59f33 -F test/multiplex.test b813d11f2cd6a15c64d85b97c0c009afc2168226 +F test/multiplex.test 5e03b40ebdee38d5a75ebbf38a469abede9414de F test/mutex1.test 78b2b9bb320e51d156c4efdb71b99b051e7a4b41 F test/mutex2.test bfeaeac2e73095b2ac32285d2756e3a65e681660 F test/nan.test a44e04df1486fcfb02d32468cbcd3c8e1e433723 @@ -914,7 +914,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P cfa4a2f7ea948be0925227efca82baea509249c9 -R cd848b3ee75fe87902bd71c01c78919c +P bc02d0c193225bd49a8d8a3295aeac752d3c2e30 +R 48cf934a82b0a69cbaf131357eaf96fa U shaneh -Z 7951456e7d17419744e4f948b8232fcd +Z e448ef64d054580e4db4bcfd141ad84b diff --git a/manifest.uuid b/manifest.uuid index 9ab9b53bfe..78855b3796 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bc02d0c193225bd49a8d8a3295aeac752d3c2e30 \ No newline at end of file +c41ff2358e8af0fe2186ab4173b81fba204a57ab \ No newline at end of file diff --git a/src/test_multiplex.c b/src/test_multiplex.c index 3855050edd..a1768f0c4b 100644 --- a/src/test_multiplex.c +++ b/src/test_multiplex.c @@ -25,9 +25,6 @@ #include "sqliteInt.h" #include "test_multiplex.h" -#include "sqlite3ext.h" -SQLITE_EXTENSION_INIT1 - /* ** For a build without mutexes, no-op the mutex calls. */ @@ -216,13 +213,12 @@ static void multiplexControlFunc( ** This is the entry point to register the extension for the multiplex_control() function. */ static int multiplexFuncInit( - sqlite3 *db, - char **pzErrMsg, - const sqlite3_api_routines *pApi + sqlite3 *db ){ - sqlite3_create_function(db, "multiplex_control", 2, SQLITE_ANY, + int rc; + rc = sqlite3_create_function(db, "multiplex_control", 2, SQLITE_ANY, db, multiplexControlFunc, 0, 0); - return 0; + return rc; } /************************* VFS Method Wrappers *****************************/ @@ -686,11 +682,16 @@ static int multiplexFileControl(sqlite3_file *pConn, int op, void *pArg){ } } break; + case SQLITE_FCNTL_SIZE_HINT: + case SQLITE_FCNTL_CHUNK_SIZE: + /* no-op these */ + rc = SQLITE_OK; + break; default: - pSubOpen = multiplexSubOpen(p, 0, &rc, NULL); - if( pSubOpen ){ + pSubOpen = multiplexSubOpen(p, 0, &rc, NULL); + if( pSubOpen ){ rc = pSubOpen->pMethods->xFileControl(pSubOpen, op, pArg); - } + } break; } return rc; diff --git a/test/multiplex.test b/test/multiplex.test index 582f71eabe..ce76fdfeab 100644 --- a/test/multiplex.test +++ b/test/multiplex.test @@ -203,9 +203,6 @@ do_test multiplex-2.5.99 { sqlite3_multiplex_shutdown } {SQLITE_OK} -return - -# TBD fix the below set all_journal_modes {delete persist truncate memory off} foreach jmode $all_journal_modes { @@ -214,11 +211,11 @@ foreach jmode $all_journal_modes { do_test multiplex-2.6.1.$sz.$jmode { multiplex_delete test.db sqlite3_multiplex_initialize "" 1 + sqlite3 db test.db multiplex_set db main $sz 32 } {SQLITE_OK} do_test multiplex-2.6.2.$sz.$jmode { - sqlite3 db test.db db eval { PRAGMA page_size = 1024; PRAGMA auto_vacuum = off; @@ -264,10 +261,10 @@ foreach jmode $all_journal_modes { do_test multiplex-3.1.1 { multiplex_delete test.db sqlite3_multiplex_initialize "" 1 + sqlite3 db test.db multiplex_set db main 32768 16 } {SQLITE_OK} do_test multiplex-3.1.2 { - sqlite3 db test.db execsql { PRAGMA page_size = 1024; PRAGMA journal_mode = delete; @@ -490,9 +487,9 @@ if {0==[info exists ::G(perm:presql)] || $::G(perm:presql) == ""} { } db close sqlite3_multiplex_initialize "" 1 - multiplex_set db main 4096 16 sqlite3 db test.db - } {} + multiplex_set db main 4096 16 + } {SQLITE_OK} do_test multiplex-5.6.3.$jmode { catchsql { INSERT INTO t1 VALUES(6, randomblob(1100)); From 78c4de4c71d7ae69111090b3ed33bd83e78501b7 Mon Sep 17 00:00:00 2001 From: shaneh Date: Thu, 31 Mar 2011 05:31:24 +0000 Subject: [PATCH 4/7] Additional test cases; Round chunk size up to a multiple of max page size; FossilOrigin-Name: 36e364a3fe7d3a9a521189ff0262611a492c21dc --- manifest | 16 ++++++------- manifest.uuid | 2 +- src/test_multiplex.c | 54 +++++++++++++++++++++++++++++++++----------- src/test_multiplex.h | 45 +++++++++++++++++++++++++++++++++++- test/multiplex.test | 48 +++++++++++++++++++++++++-------------- 5 files changed, 125 insertions(+), 40 deletions(-) diff --git a/manifest b/manifest index 66152d91b4..266e9254d8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Updates\sto\smultiplex.test\sscript;\s\smisc.\sbug\sfixes; -D 2011-03-30T21:03:07.666 +C Additional\stest\scases;\s\sRound\schunk\ssize\sup\sto\sa\smultiple\sof\smax\spage\ssize; +D 2011-03-31T05:31:24.274 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -209,8 +209,8 @@ F src/test_intarray.h 489edb9068bb926583445cb02589344961054207 F src/test_journal.c 785edd54f963aefb3c1628124170a56697c68c70 F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e F src/test_malloc.c fd6188b1501c0010fb4241ddc9f0d5ac402c688d -F src/test_multiplex.c aa5da1f2847d6d6e69a41a6d8a9242860549258f -F src/test_multiplex.h 22238a3286817918f1975a7c523827ea45d9fbb4 +F src/test_multiplex.c 6edf785c1ca9468f7d5ead21e73aeec350931588 +F src/test_multiplex.h 7bb4e7505e38996125d346177eab7ac4f8a2cbef F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec F src/test_osinst.c f408c6a181f2fb04c56273afd5c3e1e82f60392c @@ -576,7 +576,7 @@ F test/misc5.test 45b2e3ed5f79af2b4f38ae362eaf4c49674575bd F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91 F test/misc7.test 29032efcd3d826fbd409e2a7af873e7939f4a4e3 F test/misuse.test 30b3a458e5a70c31e74c291937b6c82204c59f33 -F test/multiplex.test 5e03b40ebdee38d5a75ebbf38a469abede9414de +F test/multiplex.test e58dbe5b5a3b84a1f5b96408e29efdcd6f833f16 F test/mutex1.test 78b2b9bb320e51d156c4efdb71b99b051e7a4b41 F test/mutex2.test bfeaeac2e73095b2ac32285d2756e3a65e681660 F test/nan.test a44e04df1486fcfb02d32468cbcd3c8e1e433723 @@ -914,7 +914,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P bc02d0c193225bd49a8d8a3295aeac752d3c2e30 -R 48cf934a82b0a69cbaf131357eaf96fa +P c41ff2358e8af0fe2186ab4173b81fba204a57ab +R 038c75157e031b60cfa85be2f04c19c6 U shaneh -Z e448ef64d054580e4db4bcfd141ad84b +Z 4af569247c03e0c4e633f1be2df20cf9 diff --git a/manifest.uuid b/manifest.uuid index 78855b3796..661c0bd7e0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c41ff2358e8af0fe2186ab4173b81fba204a57ab \ No newline at end of file +36e364a3fe7d3a9a521189ff0262611a492c21dc \ No newline at end of file diff --git a/src/test_multiplex.c b/src/test_multiplex.c index a1768f0c4b..ff3be68509 100644 --- a/src/test_multiplex.c +++ b/src/test_multiplex.c @@ -25,6 +25,11 @@ #include "sqliteInt.h" #include "test_multiplex.h" +#ifndef SQLITE_CORE + #define SQLITE_CORE 1 /* Disable the API redefinition in sqlite3ext.h */ +#endif +#include "sqlite3ext.h" + /* ** For a build without mutexes, no-op the mutex calls. */ @@ -44,9 +49,10 @@ #define SQLITE_MULTIPLEX_VFS_NAME "multiplex" /* This is the limit on the chunk size. It may be changed by calling -** the xFileControl() interface. +** the xFileControl() interface. It will be rounded up to a +** multiple of SQLITE_MAX_PAGE_SIZE. */ -#define SQLITE_MULTIPLEX_CHUNK_SIZE 0x40000000 +#define SQLITE_MULTIPLEX_CHUNK_SIZE (SQLITE_MAX_PAGE_SIZE*32) /* Default limit on number of chunks. Care should be taken ** so that values for chunks numbers fit in the SQLITE_MULTIPLEX_EXT_FMT ** format specifier. It may be changed by calling @@ -199,12 +205,28 @@ static void multiplexControlFunc( ){ extern const char *sqlite3TestErrorName(int); extern int multiplexFileControl(sqlite3_file *, int, void *); - sqlite3_file *db = (sqlite3_file *)sqlite3_user_data(context); + // pPager->fd + sqlite3 *db = (sqlite3 *)sqlite3_user_data(context); int op = sqlite3_value_int(argv[0]); int iVal = sqlite3_value_int(argv[1]); - int rc = multiplexFileControl(db, op, &iVal); - if( rc== 0 ){ - sqlite3_result_text(context, (char *)sqlite3TestErrorName(rc), -1, SQLITE_TRANSIENT); + int rc = SQLITE_OK; + switch( op ){ + case 1: + op = MULTIPLEX_CTRL_ENABLE; + break; + case 2: + op = MULTIPLEX_CTRL_SET_CHUNK_SIZE; + break; + case 3: + op = MULTIPLEX_CTRL_SET_MAX_CHUNKS; + break; + default: + rc = SQLITE_ERROR; + break; + } + if( rc==SQLITE_OK ){ + sqlite3_file *f = (sqlite3_file *)db; + rc = multiplexFileControl(f, op, &iVal); } sqlite3_result_text(context, (char *)sqlite3TestErrorName(rc), -1, SQLITE_TRANSIENT); } @@ -213,7 +235,9 @@ static void multiplexControlFunc( ** This is the entry point to register the extension for the multiplex_control() function. */ static int multiplexFuncInit( - sqlite3 *db + sqlite3 *db, + char **pzErrMsg, + const sqlite3_api_routines *pApi ){ int rc; rc = sqlite3_create_function(db, "multiplex_control", 2, SQLITE_ANY, @@ -663,9 +687,12 @@ static int multiplexFileControl(sqlite3_file *pConn, int op, void *pArg){ case MULTIPLEX_CTRL_SET_CHUNK_SIZE: if( pArg ) { int nChunkSize = *(int *)pArg; - if( nChunkSize<32 ){ + if( nChunkSize<1 ){ rc = SQLITE_MISUSE; }else{ + /* Round up to nearest multiple of SQLITE_MAX_PAGE_SIZE. */ + nChunkSize = (nChunkSize + (SQLITE_MAX_PAGE_SIZE-1)); + nChunkSize &= ~(SQLITE_MAX_PAGE_SIZE-1); pGroup->nChunkSize = nChunkSize; rc = SQLITE_OK; } @@ -674,7 +701,7 @@ static int multiplexFileControl(sqlite3_file *pConn, int op, void *pArg){ case MULTIPLEX_CTRL_SET_MAX_CHUNKS: if( pArg ) { int nMaxChunks = *(int *)pArg; - if(( nMaxChunks<1 ) || ( nMaxChunks>99 )){ + if(( nMaxChunks<1 ) || ( nMaxChunks>SQLITE_MULTIPLEX_MAX_CHUNKS )){ rc = SQLITE_MISUSE; }else{ pGroup->nMaxChunks = nMaxChunks; @@ -781,9 +808,10 @@ static int multiplexShmUnmap(sqlite3_file *pConn, int deleteFlag){ /************************** Public Interfaces *****************************/ /* -** Initialize the multiplex VFS shim. Use the VFS named zOrigVfsName -** as the VFS that does the actual work. Use the default if -** zOrigVfsName==NULL. +** CAPI: Initialize the multiplex VFS shim - sqlite3_multiplex_initialize() +** +** Use the VFS named zOrigVfsName as the VFS that does the actual work. +** Use the default if zOrigVfsName==NULL. ** ** The multiplex VFS shim is named "multiplex". It will become the default ** VFS if makeDefault is non-zero. @@ -853,7 +881,7 @@ int sqlite3_multiplex_initialize(const char *zOrigVfsName, int makeDefault){ } /* -** Shutdown the multiplex system. +** CAPI: Shutdown the multiplex system - sqlite3_multiplex_shutdown() ** ** All SQLite database connections must be closed before calling this ** routine. diff --git a/src/test_multiplex.h b/src/test_multiplex.h index cc56ee92e4..a277e7afdb 100644 --- a/src/test_multiplex.h +++ b/src/test_multiplex.h @@ -34,7 +34,9 @@ ** ** MULTIPLEX_CTRL_SET_CHUNK_SIZE: ** This file control is used to set the maximum allowed chunk -** size for a multiplex file set. +** size for a multiplex file set. The chunk size should be +** a multiple of SQLITE_MAX_PAGE_SIZE, and will be rounded up +** if not. ** ** MULTIPLEX_CTRL_SET_MAX_CHUNKS: ** This file control is used to set the maximum number of chunks @@ -44,5 +46,46 @@ #define MULTIPLEX_CTRL_SET_CHUNK_SIZE 214015 #define MULTIPLEX_CTRL_SET_MAX_CHUNKS 214016 +/* +** CAPI: Initialize the multiplex VFS shim - sqlite3_multiplex_initialize() +** +** Use the VFS named zOrigVfsName as the VFS that does the actual work. +** Use the default if zOrigVfsName==NULL. +** +** The multiplex VFS shim is named "multiplex". It will become the default +** VFS if makeDefault is non-zero. +** +** An auto-extension is registered which will make the function +** multiplex_control() available to open database connections. This +** function gives access to the xFileControl interface of the +** multiplex VFS shim. +** +** multiplex_control(,) +** +** =1 MULTIPLEX_CTRL_ENABLE +** =1 enable +** =2 disable +** +** =1 MULTIPLEX_CTRL_SET_CHUNK_SIZE +** int, chunk size +** +** =1 MULTIPLEX_CTRL_SET_MAX_CHUNKS +** int, max chunks +** +** THIS ROUTINE IS NOT THREADSAFE. Call this routine exactly once +** during start-up. +*/ +extern int sqlite3_multiplex_initialize(const char *zOrigVfsName, int makeDefault); + +/* +** CAPI: Shutdown the multiplex system - sqlite3_multiplex_shutdown() +** +** All SQLite database connections must be closed before calling this +** routine. +** +** THIS ROUTINE IS NOT THREADSAFE. Call this routine exactly once while +** shutting down in order to free all remaining multiplex groups. +*/ +extern int sqlite3_multiplex_shutdown(void); #endif diff --git a/test/multiplex.test b/test/multiplex.test index ce76fdfeab..ab84c1e72c 100644 --- a/test/multiplex.test +++ b/test/multiplex.test @@ -36,7 +36,7 @@ proc multiplex_name {name chunk} { proc multiplex_set {db name chunk_size max_chunks} { global g_chunk_size global g_max_chunks - set g_chunk_size $chunk_size + set g_chunk_size [ expr (($chunk_size+($::SQLITE_MAX_PAGE_SIZE-1)) & ~($::SQLITE_MAX_PAGE_SIZE-1)) ] set g_max_chunks $max_chunks set rc [catch {sqlite3_multiplex_control $db $name chunk_size $chunk_size} msg] if { $rc==0 } { @@ -74,15 +74,27 @@ do_test multiplex-1.6 { sqlite3_multiplex_shutdown } {SQLITE_OK} do_test multiplex-1.7 { sqlite3_multiplex_initialize "" 1 } {SQLITE_OK} do_test multiplex-1.8 { sqlite3_multiplex_shutdown } {SQLITE_OK} -do_test multiplex-1.9 { sqlite3_multiplex_initialize "" 1 } {SQLITE_OK} -sqlite3 db test.db -do_test multiplex-1.10.1 { multiplex_set db main 32768 16 } {SQLITE_OK} -do_test multiplex-1.10.2 { multiplex_set db main 32768 -1 } {SQLITE_MISUSE} -do_test multiplex-1.10.3 { multiplex_set db main -1 16 } {SQLITE_MISUSE} -do_test multiplex-1.10.4 { multiplex_set db main 31 16 } {SQLITE_MISUSE} -do_test multiplex-1.10.5 { multiplex_set db main 32768 100 } {SQLITE_MISUSE} -db close -do_test multiplex-1.11 { sqlite3_multiplex_shutdown } {SQLITE_OK} +do_test multiplex-1.9.1 { sqlite3_multiplex_initialize "" 1 } {SQLITE_OK} +do_test multiplex-1.9.2 { sqlite3 db test.db } {} +do_test multiplex-1.9.3 { multiplex_set db main 32768 16 } {SQLITE_OK} +do_test multiplex-1.9.4 { multiplex_set db main 32768 -1 } {SQLITE_MISUSE} +do_test multiplex-1.9.5 { multiplex_set db main -1 16 } {SQLITE_MISUSE} +do_test multiplex-1.9.6 { multiplex_set db main 31 16 } {SQLITE_OK} +do_test multiplex-1.9.7 { multiplex_set db main 32768 100 } {SQLITE_MISUSE} +do_test multiplex-1.9.8 { db close } {} +do_test multiplex-1.9.9 { sqlite3_multiplex_shutdown } {SQLITE_OK} + +do_test multiplex-1.10.1 { sqlite3_multiplex_initialize "" 1 } {SQLITE_OK} +do_test multiplex-1.10.2 { sqlite3 db test.db } {} +if { 0 } { +do_test multiplex-1.10.3 { execsql { SELECT multiplex_control(2, 32768); } } {SQLITE_OK} +do_test multiplex-1.10.4 { execsql { SELECT multiplex_control(3, -1); } } {SQLITE_MISUSE} +do_test multiplex-1.10.5 { execsql { SELECT multiplex_control(2, -1); } } {SQLITE_MISUSE} +do_test multiplex-1.10.6 { execsql { SELECT multiplex_control(2, 31); } } {SQLITE_OK} +do_test multiplex-1.10.7 { execsql { SELECT multiplex_control(3, 100); } } {SQLITE_MISUSE} +} +do_test multiplex-1.10.8 { db close } {} +do_test multiplex-1.10.9 { sqlite3_multiplex_shutdown } {SQLITE_OK} #------------------------------------------------------------------------- # Some simple warm-body tests with a single database file in rollback @@ -171,7 +183,9 @@ do_test multiplex-2.5.3 { INSERT INTO t1 VALUES(2, randomblob(4000)); INSERT INTO t1 VALUES(3, 'three'); INSERT INTO t1 VALUES(4, randomblob(4000)); - INSERT INTO t1 VALUES(5, 'five') + INSERT INTO t1 VALUES(5, 'five'); + INSERT INTO t1 VALUES(6, randomblob($g_chunk_size)); + INSERT INTO t1 VALUES(7, randomblob($g_chunk_size)); } } {} @@ -479,11 +493,11 @@ if {0==[info exists ::G(perm:presql)] || $::G(perm:presql) == ""} { do_test multiplex-5.6.2.$jmode { execsql { CREATE TABLE t1(a, b); - INSERT INTO t1 VALUES(1, randomblob(1100)); - INSERT INTO t1 VALUES(2, randomblob(1100)); - INSERT INTO t1 VALUES(3, randomblob(1100)); - INSERT INTO t1 VALUES(4, randomblob(1100)); - INSERT INTO t1 VALUES(5, randomblob(1100)); + INSERT INTO t1 VALUES(1, randomblob(15000)); + INSERT INTO t1 VALUES(2, randomblob(15000)); + INSERT INTO t1 VALUES(3, randomblob(15000)); + INSERT INTO t1 VALUES(4, randomblob(15000)); + INSERT INTO t1 VALUES(5, randomblob(15000)); } db close sqlite3_multiplex_initialize "" 1 @@ -492,7 +506,7 @@ if {0==[info exists ::G(perm:presql)] || $::G(perm:presql) == ""} { } {SQLITE_OK} do_test multiplex-5.6.3.$jmode { catchsql { - INSERT INTO t1 VALUES(6, randomblob(1100)); + INSERT INTO t1 VALUES(6, randomblob(15000)); } } {1 {disk I/O error}} do_test multiplex-5.6.4.$jmode { From d8ce22bbb7cb52e8bd3c19e4cddbc98821525217 Mon Sep 17 00:00:00 2001 From: shaneh Date: Thu, 31 Mar 2011 13:14:12 +0000 Subject: [PATCH 5/7] Tests and bug fixes for SELECT multiplex_control(op, val); Add tests and fixes for SELECT multiplex_control(op, val); FossilOrigin-Name: fee9734c193a8bec9599e02e16938179e642bf5e --- manifest | 16 +++++++-------- manifest.uuid | 2 +- src/test_multiplex.c | 49 +++++++++++++++++++++++++------------------- src/test_multiplex.h | 6 +++--- test/multiplex.test | 2 -- 5 files changed, 40 insertions(+), 35 deletions(-) diff --git a/manifest b/manifest index 266e9254d8..d4d42b146b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Additional\stest\scases;\s\sRound\schunk\ssize\sup\sto\sa\smultiple\sof\smax\spage\ssize; -D 2011-03-31T05:31:24.274 +C Tests\sand\sbug\sfixes\sfor\sSELECT\smultiplex_control(op,\sval);\nAdd\stests\sand\sfixes\sfor\sSELECT\smultiplex_control(op,\sval); +D 2011-03-31T13:14:12.476 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -209,8 +209,8 @@ F src/test_intarray.h 489edb9068bb926583445cb02589344961054207 F src/test_journal.c 785edd54f963aefb3c1628124170a56697c68c70 F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e F src/test_malloc.c fd6188b1501c0010fb4241ddc9f0d5ac402c688d -F src/test_multiplex.c 6edf785c1ca9468f7d5ead21e73aeec350931588 -F src/test_multiplex.h 7bb4e7505e38996125d346177eab7ac4f8a2cbef +F src/test_multiplex.c 07dff88008c801899680eec3b9b0ea30be9fba62 +F src/test_multiplex.h bf7b2d303688c32cdd1cee3ffdc377f13391e311 F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec F src/test_osinst.c f408c6a181f2fb04c56273afd5c3e1e82f60392c @@ -576,7 +576,7 @@ F test/misc5.test 45b2e3ed5f79af2b4f38ae362eaf4c49674575bd F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91 F test/misc7.test 29032efcd3d826fbd409e2a7af873e7939f4a4e3 F test/misuse.test 30b3a458e5a70c31e74c291937b6c82204c59f33 -F test/multiplex.test e58dbe5b5a3b84a1f5b96408e29efdcd6f833f16 +F test/multiplex.test 74009eeb9b1186855a56ad522f5daf9bcf6ee134 F test/mutex1.test 78b2b9bb320e51d156c4efdb71b99b051e7a4b41 F test/mutex2.test bfeaeac2e73095b2ac32285d2756e3a65e681660 F test/nan.test a44e04df1486fcfb02d32468cbcd3c8e1e433723 @@ -914,7 +914,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P c41ff2358e8af0fe2186ab4173b81fba204a57ab -R 038c75157e031b60cfa85be2f04c19c6 +P 36e364a3fe7d3a9a521189ff0262611a492c21dc +R 139c8e5f53872b2a8fa7c9d64e54233c U shaneh -Z 4af569247c03e0c4e633f1be2df20cf9 +Z 22cc15d919103b40af9da38b0122d8bd diff --git a/manifest.uuid b/manifest.uuid index 661c0bd7e0..eb27bb55e1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -36e364a3fe7d3a9a521189ff0262611a492c21dc \ No newline at end of file +fee9734c193a8bec9599e02e16938179e642bf5e \ No newline at end of file diff --git a/src/test_multiplex.c b/src/test_multiplex.c index ff3be68509..214cddcaf1 100644 --- a/src/test_multiplex.c +++ b/src/test_multiplex.c @@ -205,34 +205,41 @@ static void multiplexControlFunc( ){ extern const char *sqlite3TestErrorName(int); extern int multiplexFileControl(sqlite3_file *, int, void *); - // pPager->fd - sqlite3 *db = (sqlite3 *)sqlite3_user_data(context); - int op = sqlite3_value_int(argv[0]); - int iVal = sqlite3_value_int(argv[1]); int rc = SQLITE_OK; - switch( op ){ - case 1: - op = MULTIPLEX_CTRL_ENABLE; - break; - case 2: - op = MULTIPLEX_CTRL_SET_CHUNK_SIZE; - break; - case 3: - op = MULTIPLEX_CTRL_SET_MAX_CHUNKS; - break; - default: - rc = SQLITE_ERROR; - break; + sqlite3 *db = sqlite3_context_db_handle(context); + int op; + int iVal; + + if( !db || argc!=2 ){ + rc = SQLITE_ERROR; + }else{ + /* extract params */ + op = sqlite3_value_int(argv[0]); + iVal = sqlite3_value_int(argv[1]); + /* map function op to file_control op */ + switch( op ){ + case 1: + op = MULTIPLEX_CTRL_ENABLE; + break; + case 2: + op = MULTIPLEX_CTRL_SET_CHUNK_SIZE; + break; + case 3: + op = MULTIPLEX_CTRL_SET_MAX_CHUNKS; + break; + default: + rc = SQLITE_ERROR; + break; + } } if( rc==SQLITE_OK ){ - sqlite3_file *f = (sqlite3_file *)db; - rc = multiplexFileControl(f, op, &iVal); + rc = sqlite3_file_control(db, 0, op, &iVal); } sqlite3_result_text(context, (char *)sqlite3TestErrorName(rc), -1, SQLITE_TRANSIENT); } /* -** This is the entry point to register the extension for the multiplex_control() function. +** This is the entry point to register the auto-extension for the multiplex_control() function. */ static int multiplexFuncInit( sqlite3 *db, @@ -241,7 +248,7 @@ static int multiplexFuncInit( ){ int rc; rc = sqlite3_create_function(db, "multiplex_control", 2, SQLITE_ANY, - db, multiplexControlFunc, 0, 0); + 0, multiplexControlFunc, 0, 0); return rc; } diff --git a/src/test_multiplex.h b/src/test_multiplex.h index a277e7afdb..1a574c1a87 100644 --- a/src/test_multiplex.h +++ b/src/test_multiplex.h @@ -56,15 +56,15 @@ ** VFS if makeDefault is non-zero. ** ** An auto-extension is registered which will make the function -** multiplex_control() available to open database connections. This +** multiplex_control() available to database connections. This ** function gives access to the xFileControl interface of the ** multiplex VFS shim. ** -** multiplex_control(,) +** SELECT multiplex_control(,) ; ** ** =1 MULTIPLEX_CTRL_ENABLE +** =0 disable ** =1 enable -** =2 disable ** ** =1 MULTIPLEX_CTRL_SET_CHUNK_SIZE ** int, chunk size diff --git a/test/multiplex.test b/test/multiplex.test index ab84c1e72c..2d6642e243 100644 --- a/test/multiplex.test +++ b/test/multiplex.test @@ -86,13 +86,11 @@ do_test multiplex-1.9.9 { sqlite3_multiplex_shutdown } {SQLITE_OK} do_test multiplex-1.10.1 { sqlite3_multiplex_initialize "" 1 } {SQLITE_OK} do_test multiplex-1.10.2 { sqlite3 db test.db } {} -if { 0 } { do_test multiplex-1.10.3 { execsql { SELECT multiplex_control(2, 32768); } } {SQLITE_OK} do_test multiplex-1.10.4 { execsql { SELECT multiplex_control(3, -1); } } {SQLITE_MISUSE} do_test multiplex-1.10.5 { execsql { SELECT multiplex_control(2, -1); } } {SQLITE_MISUSE} do_test multiplex-1.10.6 { execsql { SELECT multiplex_control(2, 31); } } {SQLITE_OK} do_test multiplex-1.10.7 { execsql { SELECT multiplex_control(3, 100); } } {SQLITE_MISUSE} -} do_test multiplex-1.10.8 { db close } {} do_test multiplex-1.10.9 { sqlite3_multiplex_shutdown } {SQLITE_OK} From c27fa4b074777f6ca61a568e2c758909e7b75a6e Mon Sep 17 00:00:00 2001 From: shaneh Date: Thu, 31 Mar 2011 15:11:53 +0000 Subject: [PATCH 6/7] Enable/disable support. FossilOrigin-Name: b3c6d9aa9e2124a2f2a1a5f9dbbd7db3b1d01a31 --- manifest | 14 +-- manifest.uuid | 2 +- src/test_multiplex.c | 231 ++++++++++++++++++++++++------------------- test/multiplex.test | 88 +++++++++++++---- 4 files changed, 205 insertions(+), 130 deletions(-) diff --git a/manifest b/manifest index d4d42b146b..43d10d3845 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Tests\sand\sbug\sfixes\sfor\sSELECT\smultiplex_control(op,\sval);\nAdd\stests\sand\sfixes\sfor\sSELECT\smultiplex_control(op,\sval); -D 2011-03-31T13:14:12.476 +C Enable/disable\ssupport. +D 2011-03-31T15:11:53.959 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -209,7 +209,7 @@ F src/test_intarray.h 489edb9068bb926583445cb02589344961054207 F src/test_journal.c 785edd54f963aefb3c1628124170a56697c68c70 F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e F src/test_malloc.c fd6188b1501c0010fb4241ddc9f0d5ac402c688d -F src/test_multiplex.c 07dff88008c801899680eec3b9b0ea30be9fba62 +F src/test_multiplex.c c0d9450b63b0f785795e4873ce90002414921a61 F src/test_multiplex.h bf7b2d303688c32cdd1cee3ffdc377f13391e311 F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec @@ -576,7 +576,7 @@ F test/misc5.test 45b2e3ed5f79af2b4f38ae362eaf4c49674575bd F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91 F test/misc7.test 29032efcd3d826fbd409e2a7af873e7939f4a4e3 F test/misuse.test 30b3a458e5a70c31e74c291937b6c82204c59f33 -F test/multiplex.test 74009eeb9b1186855a56ad522f5daf9bcf6ee134 +F test/multiplex.test 5373b2c3b0f3e262e746652d8f93b6f6297b15ba F test/mutex1.test 78b2b9bb320e51d156c4efdb71b99b051e7a4b41 F test/mutex2.test bfeaeac2e73095b2ac32285d2756e3a65e681660 F test/nan.test a44e04df1486fcfb02d32468cbcd3c8e1e433723 @@ -914,7 +914,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 36e364a3fe7d3a9a521189ff0262611a492c21dc -R 139c8e5f53872b2a8fa7c9d64e54233c +P fee9734c193a8bec9599e02e16938179e642bf5e +R 9ef3873d6c48b9ead5e6ba118b2bc91f U shaneh -Z 22cc15d919103b40af9da38b0122d8bd +Z 53dc1c2b6709916c1194488b48f81a5e diff --git a/manifest.uuid b/manifest.uuid index eb27bb55e1..1ae76db767 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fee9734c193a8bec9599e02e16938179e642bf5e \ No newline at end of file +b3c6d9aa9e2124a2f2a1a5f9dbbd7db3b1d01a31 \ No newline at end of file diff --git a/src/test_multiplex.c b/src/test_multiplex.c index 214cddcaf1..a49825717e 100644 --- a/src/test_multiplex.c +++ b/src/test_multiplex.c @@ -50,9 +50,10 @@ /* This is the limit on the chunk size. It may be changed by calling ** the xFileControl() interface. It will be rounded up to a -** multiple of SQLITE_MAX_PAGE_SIZE. +** multiple of SQLITE_MAX_PAGE_SIZE. We default it here to 1GB. */ -#define SQLITE_MULTIPLEX_CHUNK_SIZE (SQLITE_MAX_PAGE_SIZE*32) +#define SQLITE_MULTIPLEX_CHUNK_SIZE (SQLITE_MAX_PAGE_SIZE*16384) + /* Default limit on number of chunks. Care should be taken ** so that values for chunks numbers fit in the SQLITE_MULTIPLEX_EXT_FMT ** format specifier. It may be changed by calling @@ -305,6 +306,7 @@ static int multiplexOpen( char *p = (char *)&pGroup[1]; pMultiplexOpen->pGroup = pGroup; memset(pGroup, 0, sz); + pGroup->bEnabled = -1; pGroup->nChunkSize = SQLITE_MULTIPLEX_CHUNK_SIZE; pGroup->nMaxChunks = SQLITE_MULTIPLEX_MAX_CHUNKS; pGroup->pReal = (sqlite3_file **)p; @@ -323,6 +325,14 @@ static int multiplexOpen( pGroup->flags = flags; pSubOpen = multiplexSubOpen(pMultiplexOpen, 0, &rc, pOutFlags); if( pSubOpen ){ + /* if this file is already larger than chunk size, disable + ** the multiplex feature. + */ + sqlite3_int64 sz; + int rc2 = pSubOpen->pMethods->xFileSize(pSubOpen, &sz); + if( (rc2==SQLITE_OK) && (sz>pGroup->nChunkSize) ){ + pGroup->bEnabled = 0; + } if( pSubOpen->pMethods->iVersion==1 ){ pMultiplexOpen->base.pMethods = &gMultiplex.sIoMethodsV1; }else{ @@ -465,21 +475,26 @@ static int multiplexRead( multiplexGroup *pGroup = p->pGroup; int rc = SQLITE_OK; multiplexEnter(); - while( iAmt > 0 ){ - int i = (int)(iOfst / pGroup->nChunkSize); - sqlite3_file *pSubOpen = multiplexSubOpen(p, i, &rc, NULL); - if( pSubOpen ){ - int extra = ((int)(iOfst % pGroup->nChunkSize) + iAmt) - pGroup->nChunkSize; - if( extra<0 ) extra = 0; - iAmt -= extra; - rc = pSubOpen->pMethods->xRead(pSubOpen, pBuf, iAmt, iOfst % pGroup->nChunkSize); - if( rc!=SQLITE_OK ) break; - pBuf = (char *)pBuf + iAmt; - iOfst += iAmt; - iAmt = extra; - }else{ - rc = SQLITE_IOERR_READ; - break; + if( !pGroup->bEnabled ){ + sqlite3_file *pSubOpen = multiplexSubOpen(p, 0, &rc, NULL); + rc = ( !pSubOpen ) ? SQLITE_IOERR_READ : pSubOpen->pMethods->xRead(pSubOpen, pBuf, iAmt, iOfst); + }else{ + while( iAmt > 0 ){ + int i = (int)(iOfst / pGroup->nChunkSize); + sqlite3_file *pSubOpen = multiplexSubOpen(p, i, &rc, NULL); + if( pSubOpen ){ + int extra = ((int)(iOfst % pGroup->nChunkSize) + iAmt) - pGroup->nChunkSize; + if( extra<0 ) extra = 0; + iAmt -= extra; + rc = pSubOpen->pMethods->xRead(pSubOpen, pBuf, iAmt, iOfst % pGroup->nChunkSize); + if( rc!=SQLITE_OK ) break; + pBuf = (char *)pBuf + iAmt; + iOfst += iAmt; + iAmt = extra; + }else{ + rc = SQLITE_IOERR_READ; + break; + } } } multiplexLeave(); @@ -500,21 +515,26 @@ static int multiplexWrite( multiplexGroup *pGroup = p->pGroup; int rc = SQLITE_OK; multiplexEnter(); - while( iAmt > 0 ){ - int i = (int)(iOfst / pGroup->nChunkSize); - sqlite3_file *pSubOpen = multiplexSubOpen(p, i, &rc, NULL); - if( pSubOpen ){ - int extra = ((int)(iOfst % pGroup->nChunkSize) + iAmt) - pGroup->nChunkSize; - if( extra<0 ) extra = 0; - iAmt -= extra; - rc = pSubOpen->pMethods->xWrite(pSubOpen, pBuf, iAmt, iOfst % pGroup->nChunkSize); - if( rc!=SQLITE_OK ) break; - pBuf = (char *)pBuf + iAmt; - iOfst += iAmt; - iAmt = extra; - }else{ - rc = SQLITE_IOERR_WRITE; - break; + if( !pGroup->bEnabled ){ + sqlite3_file *pSubOpen = multiplexSubOpen(p, 0, &rc, NULL); + rc = ( !pSubOpen ) ? SQLITE_IOERR_WRITE : pSubOpen->pMethods->xWrite(pSubOpen, pBuf, iAmt, iOfst); + }else{ + while( iAmt > 0 ){ + int i = (int)(iOfst / pGroup->nChunkSize); + sqlite3_file *pSubOpen = multiplexSubOpen(p, i, &rc, NULL); + if( pSubOpen ){ + int extra = ((int)(iOfst % pGroup->nChunkSize) + iAmt) - pGroup->nChunkSize; + if( extra<0 ) extra = 0; + iAmt -= extra; + rc = pSubOpen->pMethods->xWrite(pSubOpen, pBuf, iAmt, iOfst % pGroup->nChunkSize); + if( rc!=SQLITE_OK ) break; + pBuf = (char *)pBuf + iAmt; + iOfst += iAmt; + iAmt = extra; + }else{ + rc = SQLITE_IOERR_WRITE; + break; + } } } multiplexLeave(); @@ -529,35 +549,40 @@ static int multiplexTruncate(sqlite3_file *pConn, sqlite3_int64 size){ multiplexConn *p = (multiplexConn*)pConn; multiplexGroup *pGroup = p->pGroup; int rc = SQLITE_OK; - int rc2; - int i; - sqlite3_file *pSubOpen; - sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs; /* Real VFS */ multiplexEnter(); - memcpy(gMultiplex.zName, pGroup->zName, pGroup->nName+1); - /* delete the chunks above the truncate limit */ - for(i=(int)(size / pGroup->nChunkSize)+1; inMaxChunks; i++){ - /* close any open chunks before deleting them */ - if( pGroup->bOpen[i] ){ - pSubOpen = pGroup->pReal[i]; - rc2 = pSubOpen->pMethods->xClose(pSubOpen); - if( rc2!=SQLITE_OK ) rc = SQLITE_IOERR_TRUNCATE; - pGroup->bOpen[i] = 0; - } -#ifdef SQLITE_MULTIPLEX_EXT_OVWR - sqlite3_snprintf(SQLITE_MULTIPLEX_EXT_SZ+1, gMultiplex.zName+pGroup->nName-SQLITE_MULTIPLEX_EXT_SZ, SQLITE_MULTIPLEX_EXT_FMT, i); -#else - sqlite3_snprintf(SQLITE_MULTIPLEX_EXT_SZ+1, gMultiplex.zName+pGroup->nName, SQLITE_MULTIPLEX_EXT_FMT, i); -#endif - rc2 = pOrigVfs->xDelete(pOrigVfs, gMultiplex.zName, 0); - if( rc2!=SQLITE_OK ) rc = SQLITE_IOERR_TRUNCATE; - } - pSubOpen = multiplexSubOpen(p, (int)(size / pGroup->nChunkSize), &rc2, NULL); - if( pSubOpen ){ - rc2 = pSubOpen->pMethods->xTruncate(pSubOpen, size % pGroup->nChunkSize); - if( rc2!=SQLITE_OK ) rc = rc2; + if( !pGroup->bEnabled ){ + sqlite3_file *pSubOpen = multiplexSubOpen(p, 0, &rc, NULL); + rc = ( !pSubOpen ) ? SQLITE_IOERR_TRUNCATE : pSubOpen->pMethods->xTruncate(pSubOpen, size); }else{ - rc = SQLITE_IOERR_TRUNCATE; + int rc2; + int i; + sqlite3_file *pSubOpen; + sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs; /* Real VFS */ + memcpy(gMultiplex.zName, pGroup->zName, pGroup->nName+1); + /* delete the chunks above the truncate limit */ + for(i=(int)(size / pGroup->nChunkSize)+1; inMaxChunks; i++){ + /* close any open chunks before deleting them */ + if( pGroup->bOpen[i] ){ + pSubOpen = pGroup->pReal[i]; + rc2 = pSubOpen->pMethods->xClose(pSubOpen); + if( rc2!=SQLITE_OK ) rc = SQLITE_IOERR_TRUNCATE; + pGroup->bOpen[i] = 0; + } +#ifdef SQLITE_MULTIPLEX_EXT_OVWR + sqlite3_snprintf(SQLITE_MULTIPLEX_EXT_SZ+1, gMultiplex.zName+pGroup->nName-SQLITE_MULTIPLEX_EXT_SZ, SQLITE_MULTIPLEX_EXT_FMT, i); +#else + sqlite3_snprintf(SQLITE_MULTIPLEX_EXT_SZ+1, gMultiplex.zName+pGroup->nName, SQLITE_MULTIPLEX_EXT_FMT, i); +#endif + rc2 = pOrigVfs->xDelete(pOrigVfs, gMultiplex.zName, 0); + if( rc2!=SQLITE_OK ) rc = SQLITE_IOERR_TRUNCATE; + } + pSubOpen = multiplexSubOpen(p, (int)(size / pGroup->nChunkSize), &rc2, NULL); + if( pSubOpen ){ + rc2 = pSubOpen->pMethods->xTruncate(pSubOpen, size % pGroup->nChunkSize); + if( rc2!=SQLITE_OK ) rc = rc2; + }else{ + rc = SQLITE_IOERR_TRUNCATE; + } } multiplexLeave(); return rc; @@ -593,46 +618,51 @@ static int multiplexFileSize(sqlite3_file *pConn, sqlite3_int64 *pSize){ int rc2; int i; multiplexEnter(); - *pSize = 0; - for(i=0; inMaxChunks; i++){ - sqlite3_file *pSubOpen = NULL; - /* if not opened already, check to see if the chunk exists */ - if( pGroup->bOpen[i] ){ - pSubOpen = pGroup->pReal[i]; - }else{ - sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs; /* Real VFS */ - int exists = 0; - memcpy(gMultiplex.zName, pGroup->zName, pGroup->nName+1); - if( i ){ -#ifdef SQLITE_MULTIPLEX_EXT_OVWR - sqlite3_snprintf(SQLITE_MULTIPLEX_EXT_SZ+1, gMultiplex.zName+pGroup->nName-SQLITE_MULTIPLEX_EXT_SZ, SQLITE_MULTIPLEX_EXT_FMT, i); -#else - sqlite3_snprintf(SQLITE_MULTIPLEX_EXT_SZ+1, gMultiplex.zName+pGroup->nName, SQLITE_MULTIPLEX_EXT_FMT, i); -#endif - } - rc2 = pOrigVfs->xAccess(pOrigVfs, gMultiplex.zName, SQLITE_ACCESS_EXISTS, &exists); - if( rc2==SQLITE_OK && exists){ - /* if it exists, open it */ - pSubOpen = multiplexSubOpen(p, i, &rc, NULL); + if( !pGroup->bEnabled ){ + sqlite3_file *pSubOpen = multiplexSubOpen(p, 0, &rc, NULL); + rc = ( !pSubOpen ) ? SQLITE_IOERR_FSTAT : pSubOpen->pMethods->xFileSize(pSubOpen, pSize); + }else{ + *pSize = 0; + for(i=0; inMaxChunks; i++){ + sqlite3_file *pSubOpen = NULL; + /* if not opened already, check to see if the chunk exists */ + if( pGroup->bOpen[i] ){ + pSubOpen = pGroup->pReal[i]; + }else{ + sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs; /* Real VFS */ + int exists = 0; + memcpy(gMultiplex.zName, pGroup->zName, pGroup->nName+1); + if( i ){ +#ifdef SQLITE_MULTIPLEX_EXT_OVWR + sqlite3_snprintf(SQLITE_MULTIPLEX_EXT_SZ+1, gMultiplex.zName+pGroup->nName-SQLITE_MULTIPLEX_EXT_SZ, SQLITE_MULTIPLEX_EXT_FMT, i); +#else + sqlite3_snprintf(SQLITE_MULTIPLEX_EXT_SZ+1, gMultiplex.zName+pGroup->nName, SQLITE_MULTIPLEX_EXT_FMT, i); +#endif + } + rc2 = pOrigVfs->xAccess(pOrigVfs, gMultiplex.zName, SQLITE_ACCESS_EXISTS, &exists); + if( rc2==SQLITE_OK && exists){ + /* if it exists, open it */ + pSubOpen = multiplexSubOpen(p, i, &rc, NULL); + }else{ + /* stop at first "gap" */ + break; + } + } + if( pSubOpen ){ + sqlite3_int64 sz; + rc2 = pSubOpen->pMethods->xFileSize(pSubOpen, &sz); + if( rc2!=SQLITE_OK ){ + rc = rc2; + }else{ + if( sz>pGroup->nChunkSize ){ + rc = SQLITE_IOERR_FSTAT; + } + *pSize += sz; + } }else{ - /* stop at first "gap" */ break; } } - if( pSubOpen ){ - sqlite3_int64 sz; - rc2 = pSubOpen->pMethods->xFileSize(pSubOpen, &sz); - if( rc2!=SQLITE_OK ){ - rc = rc2; - }else{ - if( sz>pGroup->nChunkSize ){ - rc = SQLITE_IOERR_FSTAT; - } - *pSize += sz; - } - }else{ - break; - } } multiplexLeave(); return rc; @@ -674,7 +704,8 @@ static int multiplexCheckReservedLock(sqlite3_file *pConn, int *pResOut){ return SQLITE_IOERR_CHECKRESERVEDLOCK; } -/* Pass xFileControl requests through to the original VFS unchanged. +/* Pass xFileControl requests through to the original VFS unchanged, +** except for any MULTIPLEX_CTRL_* requests here. */ static int multiplexFileControl(sqlite3_file *pConn, int op, void *pArg){ multiplexConn *p = (multiplexConn*)pConn; @@ -1046,8 +1077,8 @@ static int test_multiplex_control( { 0, 0, 0 } }; - if( objc!=4 && objc!=5 ){ - Tcl_WrongNumArgs(interp, 1, objv, "HANDLE DBNAME SUB-COMMAND ?INT-VALUE?"); + if( objc!=5 ){ + Tcl_WrongNumArgs(interp, 1, objv, "HANDLE DBNAME SUB-COMMAND INT-VALUE"); return TCL_ERROR; } @@ -1066,10 +1097,6 @@ static int test_multiplex_control( switch( aSub[idx].argtype ){ case 1: - if( objc!=5 ){ - Tcl_WrongNumArgs(interp, 4, objv, "INT-VALUE"); - return TCL_ERROR; - } if( Tcl_GetIntFromObj(interp, objv[4], &iValue) ){ return TCL_ERROR; } diff --git a/test/multiplex.test b/test/multiplex.test index 2d6642e243..c76cee71a0 100644 --- a/test/multiplex.test +++ b/test/multiplex.test @@ -14,7 +14,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/malloc_common.tcl -set g_chunk_size 2147483648 +set g_chunk_size [ expr ($::SQLITE_MAX_PAGE_SIZE*16384) ] set g_max_chunks 32 # This handles appending the chunk number @@ -74,25 +74,44 @@ do_test multiplex-1.6 { sqlite3_multiplex_shutdown } {SQLITE_OK} do_test multiplex-1.7 { sqlite3_multiplex_initialize "" 1 } {SQLITE_OK} do_test multiplex-1.8 { sqlite3_multiplex_shutdown } {SQLITE_OK} -do_test multiplex-1.9.1 { sqlite3_multiplex_initialize "" 1 } {SQLITE_OK} -do_test multiplex-1.9.2 { sqlite3 db test.db } {} -do_test multiplex-1.9.3 { multiplex_set db main 32768 16 } {SQLITE_OK} -do_test multiplex-1.9.4 { multiplex_set db main 32768 -1 } {SQLITE_MISUSE} -do_test multiplex-1.9.5 { multiplex_set db main -1 16 } {SQLITE_MISUSE} -do_test multiplex-1.9.6 { multiplex_set db main 31 16 } {SQLITE_OK} -do_test multiplex-1.9.7 { multiplex_set db main 32768 100 } {SQLITE_MISUSE} -do_test multiplex-1.9.8 { db close } {} -do_test multiplex-1.9.9 { sqlite3_multiplex_shutdown } {SQLITE_OK} -do_test multiplex-1.10.1 { sqlite3_multiplex_initialize "" 1 } {SQLITE_OK} -do_test multiplex-1.10.2 { sqlite3 db test.db } {} -do_test multiplex-1.10.3 { execsql { SELECT multiplex_control(2, 32768); } } {SQLITE_OK} -do_test multiplex-1.10.4 { execsql { SELECT multiplex_control(3, -1); } } {SQLITE_MISUSE} -do_test multiplex-1.10.5 { execsql { SELECT multiplex_control(2, -1); } } {SQLITE_MISUSE} -do_test multiplex-1.10.6 { execsql { SELECT multiplex_control(2, 31); } } {SQLITE_OK} -do_test multiplex-1.10.7 { execsql { SELECT multiplex_control(3, 100); } } {SQLITE_MISUSE} -do_test multiplex-1.10.8 { db close } {} -do_test multiplex-1.10.9 { sqlite3_multiplex_shutdown } {SQLITE_OK} +do_test multiplex-1.9.1 { sqlite3_multiplex_initialize "" 1 } {SQLITE_OK} +do_test multiplex-1.9.2 { sqlite3 db test.db } {} +do_test multiplex-1.9.3 { multiplex_set db main 32768 16 } {SQLITE_OK} +do_test multiplex-1.9.4 { multiplex_set db main 32768 -1 } {SQLITE_MISUSE} +do_test multiplex-1.9.5 { multiplex_set db main -1 16 } {SQLITE_MISUSE} +do_test multiplex-1.9.6 { multiplex_set db main 31 16 } {SQLITE_OK} +do_test multiplex-1.9.7 { multiplex_set db main 32768 100 } {SQLITE_MISUSE} +do_test multiplex-1.9.8 { multiplex_set db main 1073741824 1 } {SQLITE_OK} +do_test multiplex-1.9.9 { db close } {} +do_test multiplex-1.9.10 { sqlite3_multiplex_shutdown } {SQLITE_OK} + +do_test multiplex-1.10.1 { sqlite3_multiplex_initialize "" 1 } {SQLITE_OK} +do_test multiplex-1.10.2 { sqlite3 db test.db } {} +do_test multiplex-1.10.3 { execsql { SELECT multiplex_control(2, 32768); } } {SQLITE_OK} +do_test multiplex-1.10.4 { execsql { SELECT multiplex_control(3, -1); } } {SQLITE_MISUSE} +do_test multiplex-1.10.5 { execsql { SELECT multiplex_control(2, -1); } } {SQLITE_MISUSE} +do_test multiplex-1.10.6 { execsql { SELECT multiplex_control(2, 31); } } {SQLITE_OK} +do_test multiplex-1.10.7 { execsql { SELECT multiplex_control(3, 100); } } {SQLITE_MISUSE} +do_test multiplex-1.10.8 { execsql { SELECT multiplex_control(2, 1073741824); } } {SQLITE_OK} +do_test multiplex-1.10.9 { db close } {} +do_test multiplex-1.10.10 { sqlite3_multiplex_shutdown } {SQLITE_OK} + +do_test multiplex-1.11.1 { sqlite3_multiplex_initialize "" 1 } {SQLITE_OK} +do_test multiplex-1.11.2 { sqlite3 db test.db } {} +do_test multiplex-1.11.3 { sqlite3_multiplex_control db main enable 0 } {SQLITE_OK} +do_test multiplex-1.11.4 { sqlite3_multiplex_control db main enable 1 } {SQLITE_OK} +do_test multiplex-1.11.5 { sqlite3_multiplex_control db main enable -1 } {SQLITE_OK} +do_test multiplex-1.11.6 { db close } {} +do_test multiplex-1.11.7 { sqlite3_multiplex_shutdown } {SQLITE_OK} + +do_test multiplex-1.12.1 { sqlite3_multiplex_initialize "" 1 } {SQLITE_OK} +do_test multiplex-1.12.2 { sqlite3 db test.db } {} +do_test multiplex-1.12.3 { execsql { SELECT multiplex_control(1, 0); } } {SQLITE_OK} +do_test multiplex-1.12.4 { execsql { SELECT multiplex_control(1, 1); } } {SQLITE_OK} +do_test multiplex-1.12.5 { execsql { SELECT multiplex_control(1, -1); } } {SQLITE_OK} +do_test multiplex-1.12.6 { db close } {} +do_test multiplex-1.12.7 { sqlite3_multiplex_shutdown } {SQLITE_OK} #------------------------------------------------------------------------- # Some simple warm-body tests with a single database file in rollback @@ -104,7 +123,7 @@ do_test multiplex-1.10.9 { sqlite3_multiplex_shutdown } {S # # multiplex-2.3.*: Open and close a second db. # -# multiplex-2.4.*: Try to shutdown the multiplex system befor e closing the db +# multiplex-2.4.*: Try to shutdown the multiplex system before closing the db # file. Check that this fails and the multiplex system still works # afterwards. Then close the database and successfully shut # down the multiplex system. @@ -113,6 +132,9 @@ do_test multiplex-1.10.9 { sqlite3_multiplex_shutdown } {S # # multiplex-2.6.*: More reading/writing with varying small chunk sizes, as # well as varying journal mode. +# +# multiplex-2.7.*: Disable/enable tests. +# sqlite3_multiplex_initialize "" 1 multiplex_set db main 32768 16 @@ -261,6 +283,32 @@ foreach jmode $all_journal_modes { } } +do_test multiplex-2.7.1 { multiplex_delete test.db } {} +do_test multiplex-2.7.2 { sqlite3_multiplex_initialize "" 1 } {SQLITE_OK} +do_test multiplex-2.7.3 { sqlite3 db test.db } {} +do_test multiplex-2.7.4 { execsql { SELECT multiplex_control(2, 65536); } } {SQLITE_OK} +do_test multiplex-2.7.5 { execsql { SELECT multiplex_control(1, 0); } } {SQLITE_OK} +do_test multiplex-2.7.6 { + execsql { + CREATE TABLE t1(a PRIMARY KEY, b); + INSERT INTO t1 VALUES(1, randomblob(1000)); + } +} {} +# verify only one file, and file size is less than chunks size +do_test multiplex-2.7.7 { expr ([file size [multiplex_name test.db 0]] < 65536) } {1} +do_test multiplex-2.7.8 { file exists [multiplex_name test.db 1] } {0} +do_test multiplex-2.7.9 { + execsql { + INSERT INTO t1 VALUES(1, randomblob(65536)); + } +} {} +# verify only one file, and file size exceeds chunks size +do_test multiplex-2.7.10 { expr ([file size [multiplex_name test.db 0]] > 65536) } {1} +do_test multiplex-2.7.11 { file exists [multiplex_name test.db 1] } {0} +do_test multiplex-2.7.12 { db close } {} +do_test multiplex-2.7.13 { sqlite3_multiplex_shutdown } {SQLITE_OK} + + #------------------------------------------------------------------------- # Try some tests with more than one connection to a database file. Still # in rollback mode. From 3801b65d62a9d3f04c55988520aa700aab5cd00f Mon Sep 17 00:00:00 2001 From: shaneh Date: Fri, 1 Apr 2011 14:22:46 +0000 Subject: [PATCH 7/7] Removed dependency on sqliteInt.h so that multiplex VFS shim can be compiled as loadable module. FossilOrigin-Name: 718f1ad7df9115871ba6159012d3183183fc40a1 --- manifest | 16 ++++---- manifest.uuid | 2 +- src/test_multiplex.c | 97 +++++++++++++++++++++++++++++++------------- src/test_multiplex.h | 6 +-- test/multiplex.test | 68 +++++++++++++++++-------------- 5 files changed, 118 insertions(+), 71 deletions(-) diff --git a/manifest b/manifest index 43d10d3845..1e425354d0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enable/disable\ssupport. -D 2011-03-31T15:11:53.959 +C Removed\sdependency\son\ssqliteInt.h\sso\sthat\smultiplex\sVFS\sshim\scan\sbe\scompiled\sas\sloadable\smodule. +D 2011-04-01T14:22:46.544 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -209,8 +209,8 @@ F src/test_intarray.h 489edb9068bb926583445cb02589344961054207 F src/test_journal.c 785edd54f963aefb3c1628124170a56697c68c70 F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e F src/test_malloc.c fd6188b1501c0010fb4241ddc9f0d5ac402c688d -F src/test_multiplex.c c0d9450b63b0f785795e4873ce90002414921a61 -F src/test_multiplex.h bf7b2d303688c32cdd1cee3ffdc377f13391e311 +F src/test_multiplex.c fdabd793ee7a9642c5a8a470def2347144c46d05 +F src/test_multiplex.h e99c571bc4968b7a9363b661481f3934bfead61d F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec F src/test_osinst.c f408c6a181f2fb04c56273afd5c3e1e82f60392c @@ -576,7 +576,7 @@ F test/misc5.test 45b2e3ed5f79af2b4f38ae362eaf4c49674575bd F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91 F test/misc7.test 29032efcd3d826fbd409e2a7af873e7939f4a4e3 F test/misuse.test 30b3a458e5a70c31e74c291937b6c82204c59f33 -F test/multiplex.test 5373b2c3b0f3e262e746652d8f93b6f6297b15ba +F test/multiplex.test a88f3e2c16e567e72be7296195c59fbdd6a8d3d4 F test/mutex1.test 78b2b9bb320e51d156c4efdb71b99b051e7a4b41 F test/mutex2.test bfeaeac2e73095b2ac32285d2756e3a65e681660 F test/nan.test a44e04df1486fcfb02d32468cbcd3c8e1e433723 @@ -914,7 +914,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P fee9734c193a8bec9599e02e16938179e642bf5e -R 9ef3873d6c48b9ead5e6ba118b2bc91f +P b3c6d9aa9e2124a2f2a1a5f9dbbd7db3b1d01a31 +R 5fdb22cfeb915ca0348434fc3aeb88a3 U shaneh -Z 53dc1c2b6709916c1194488b48f81a5e +Z c6a6d5930d83831b14cb5982ae50977b diff --git a/manifest.uuid b/manifest.uuid index 1ae76db767..6c14b08a21 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b3c6d9aa9e2124a2f2a1a5f9dbbd7db3b1d01a31 \ No newline at end of file +718f1ad7df9115871ba6159012d3183183fc40a1 \ No newline at end of file diff --git a/src/test_multiplex.c b/src/test_multiplex.c index a49825717e..d8a7db86e1 100644 --- a/src/test_multiplex.c +++ b/src/test_multiplex.c @@ -22,7 +22,6 @@ #include "sqlite3.h" #include #include -#include "sqliteInt.h" #include "test_multiplex.h" #ifndef SQLITE_CORE @@ -30,6 +29,16 @@ #endif #include "sqlite3ext.h" +/* +** These should be defined to be the same as the values in +** sqliteInt.h. They are defined seperately here so that +** the multiplex VFS shim can be built as a loadable +** module. +*/ +#define UNUSED_PARAMETER(x) (void)(x) +#define MAX_PAGE_SIZE 0x10000 +#define DEFAULT_SECTOR_SIZE 0x1000 + /* ** For a build without mutexes, no-op the mutex calls. */ @@ -50,9 +59,9 @@ /* This is the limit on the chunk size. It may be changed by calling ** the xFileControl() interface. It will be rounded up to a -** multiple of SQLITE_MAX_PAGE_SIZE. We default it here to 1GB. +** multiple of MAX_PAGE_SIZE. We default it here to 1GB. */ -#define SQLITE_MULTIPLEX_CHUNK_SIZE (SQLITE_MAX_PAGE_SIZE*16384) +#define SQLITE_MULTIPLEX_CHUNK_SIZE (MAX_PAGE_SIZE*16384) /* Default limit on number of chunks. Care should be taken ** so that values for chunks numbers fit in the SQLITE_MULTIPLEX_EXT_FMT @@ -168,6 +177,21 @@ static struct { static void multiplexEnter(void){ sqlite3_mutex_enter(gMultiplex.pMutex); } static void multiplexLeave(void){ sqlite3_mutex_leave(gMultiplex.pMutex); } +/* +** Compute a string length that is limited to what can be stored in +** lower 30 bits of a 32-bit signed integer. +** +** The value returned will never be negative. Nor will it ever be greater +** than the actual length of the string. For very long strings (greater +** than 1GiB) the value returned might be less than the true string length. +*/ +int multiplexStrlen30(const char *z){ + const char *z2 = z; + if( z==0 ) return 0; + while( *z2 ){ z2++; } + return 0x3fffffff & (int)(z2 - z); +} + /* Translate an sqlite3_file* that is really a multiplexGroup* into ** the sqlite3_file* for the underlying original VFS. */ @@ -199,13 +223,14 @@ static sqlite3_file *multiplexSubOpen(multiplexConn *pConn, int iChunk, int *rc, return NULL; } +/* +** This is the implementation of the multiplex_control() SQL function. +*/ static void multiplexControlFunc( sqlite3_context *context, int argc, sqlite3_value **argv ){ - extern const char *sqlite3TestErrorName(int); - extern int multiplexFileControl(sqlite3_file *, int, void *); int rc = SQLITE_OK; sqlite3 *db = sqlite3_context_db_handle(context); int op; @@ -229,18 +254,19 @@ static void multiplexControlFunc( op = MULTIPLEX_CTRL_SET_MAX_CHUNKS; break; default: - rc = SQLITE_ERROR; + rc = SQLITE_NOTFOUND; break; } } if( rc==SQLITE_OK ){ rc = sqlite3_file_control(db, 0, op, &iVal); } - sqlite3_result_text(context, (char *)sqlite3TestErrorName(rc), -1, SQLITE_TRANSIENT); + sqlite3_result_error_code(context, rc); } /* -** This is the entry point to register the auto-extension for the multiplex_control() function. +** This is the entry point to register the auto-extension for the +** multiplex_control() function. */ static int multiplexFuncInit( sqlite3 *db, @@ -249,7 +275,7 @@ static int multiplexFuncInit( ){ int rc; rc = sqlite3_create_function(db, "multiplex_control", 2, SQLITE_ANY, - 0, multiplexControlFunc, 0, 0); + 0, multiplexControlFunc, 0, 0); return rc; } @@ -274,7 +300,7 @@ static int multiplexOpen( multiplexGroup *pGroup; /* Corresponding multiplexGroup object */ sqlite3_file *pSubOpen; /* Real file descriptor */ sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs; /* Real VFS */ - int nName = sqlite3Strlen30(zName); + int nName = multiplexStrlen30(zName); int i; int sz; @@ -286,11 +312,11 @@ static int multiplexOpen( multiplexEnter(); pMultiplexOpen = (multiplexConn*)pConn; /* allocate space for group */ - sz = sizeof(multiplexGroup) /* multiplexGroup */ - + (sizeof(sqlite3_file *)*SQLITE_MULTIPLEX_MAX_CHUNKS) /* pReal[] */ - + (pOrigVfs->szOsFile*SQLITE_MULTIPLEX_MAX_CHUNKS) /* *pReal */ - + SQLITE_MULTIPLEX_MAX_CHUNKS /* bOpen[] */ - + nName + 1; /* zName */ + sz = sizeof(multiplexGroup) /* multiplexGroup */ + + (sizeof(sqlite3_file *)*SQLITE_MULTIPLEX_MAX_CHUNKS) /* pReal[] */ + + (pOrigVfs->szOsFile*SQLITE_MULTIPLEX_MAX_CHUNKS) /* *pReal */ + + SQLITE_MULTIPLEX_MAX_CHUNKS /* bOpen[] */ + + nName + 1; /* zName */ #ifndef SQLITE_MULTIPLEX_EXT_OVWR sz += SQLITE_MULTIPLEX_EXT_SZ; assert(nName+SQLITE_MULTIPLEX_EXT_SZ < pOrigVfs->mxPathname); @@ -362,7 +388,7 @@ static int multiplexDelete( ){ sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs; /* Real VFS */ int rc = SQLITE_OK; - int nName = sqlite3Strlen30(zName); + int nName = multiplexStrlen30(zName); int i; UNUSED_PARAMETER(pVfs); @@ -374,12 +400,17 @@ static int multiplexDelete( int exists = 0; if( i ){ #ifdef SQLITE_MULTIPLEX_EXT_OVWR - sqlite3_snprintf(SQLITE_MULTIPLEX_EXT_SZ+1, gMultiplex.zName+nName-SQLITE_MULTIPLEX_EXT_SZ, SQLITE_MULTIPLEX_EXT_FMT, i); + sqlite3_snprintf(SQLITE_MULTIPLEX_EXT_SZ+1, + gMultiplex.zName+nName-SQLITE_MULTIPLEX_EXT_SZ, + SQLITE_MULTIPLEX_EXT_FMT, i); #else - sqlite3_snprintf(SQLITE_MULTIPLEX_EXT_SZ+1, gMultiplex.zName+nName, SQLITE_MULTIPLEX_EXT_FMT, i); + sqlite3_snprintf(SQLITE_MULTIPLEX_EXT_SZ+1, + gMultiplex.zName+nName, + SQLITE_MULTIPLEX_EXT_FMT, i); #endif } - rc2 = pOrigVfs->xAccess(pOrigVfs, gMultiplex.zName, SQLITE_ACCESS_EXISTS, &exists); + rc2 = pOrigVfs->xAccess(pOrigVfs, gMultiplex.zName, + SQLITE_ACCESS_EXISTS, &exists); if( rc2==SQLITE_OK && exists){ /* if it exists, delete it */ rc2 = pOrigVfs->xDelete(pOrigVfs, gMultiplex.zName, syncDir); @@ -569,9 +600,13 @@ static int multiplexTruncate(sqlite3_file *pConn, sqlite3_int64 size){ pGroup->bOpen[i] = 0; } #ifdef SQLITE_MULTIPLEX_EXT_OVWR - sqlite3_snprintf(SQLITE_MULTIPLEX_EXT_SZ+1, gMultiplex.zName+pGroup->nName-SQLITE_MULTIPLEX_EXT_SZ, SQLITE_MULTIPLEX_EXT_FMT, i); + sqlite3_snprintf(SQLITE_MULTIPLEX_EXT_SZ+1, + gMultiplex.zName+pGroup->nName-SQLITE_MULTIPLEX_EXT_SZ, + SQLITE_MULTIPLEX_EXT_FMT, i); #else - sqlite3_snprintf(SQLITE_MULTIPLEX_EXT_SZ+1, gMultiplex.zName+pGroup->nName, SQLITE_MULTIPLEX_EXT_FMT, i); + sqlite3_snprintf(SQLITE_MULTIPLEX_EXT_SZ+1, + gMultiplex.zName+pGroup->nName, + SQLITE_MULTIPLEX_EXT_FMT, i); #endif rc2 = pOrigVfs->xDelete(pOrigVfs, gMultiplex.zName, 0); if( rc2!=SQLITE_OK ) rc = SQLITE_IOERR_TRUNCATE; @@ -634,12 +669,17 @@ static int multiplexFileSize(sqlite3_file *pConn, sqlite3_int64 *pSize){ memcpy(gMultiplex.zName, pGroup->zName, pGroup->nName+1); if( i ){ #ifdef SQLITE_MULTIPLEX_EXT_OVWR - sqlite3_snprintf(SQLITE_MULTIPLEX_EXT_SZ+1, gMultiplex.zName+pGroup->nName-SQLITE_MULTIPLEX_EXT_SZ, SQLITE_MULTIPLEX_EXT_FMT, i); + sqlite3_snprintf(SQLITE_MULTIPLEX_EXT_SZ+1, + gMultiplex.zName+pGroup->nName-SQLITE_MULTIPLEX_EXT_SZ, + SQLITE_MULTIPLEX_EXT_FMT, i); #else - sqlite3_snprintf(SQLITE_MULTIPLEX_EXT_SZ+1, gMultiplex.zName+pGroup->nName, SQLITE_MULTIPLEX_EXT_FMT, i); + sqlite3_snprintf(SQLITE_MULTIPLEX_EXT_SZ+1, + gMultiplex.zName+pGroup->nName, + SQLITE_MULTIPLEX_EXT_FMT, i); #endif } - rc2 = pOrigVfs->xAccess(pOrigVfs, gMultiplex.zName, SQLITE_ACCESS_EXISTS, &exists); + rc2 = pOrigVfs->xAccess(pOrigVfs, gMultiplex.zName, + SQLITE_ACCESS_EXISTS, &exists); if( rc2==SQLITE_OK && exists){ /* if it exists, open it */ pSubOpen = multiplexSubOpen(p, i, &rc, NULL); @@ -728,9 +768,9 @@ static int multiplexFileControl(sqlite3_file *pConn, int op, void *pArg){ if( nChunkSize<1 ){ rc = SQLITE_MISUSE; }else{ - /* Round up to nearest multiple of SQLITE_MAX_PAGE_SIZE. */ - nChunkSize = (nChunkSize + (SQLITE_MAX_PAGE_SIZE-1)); - nChunkSize &= ~(SQLITE_MAX_PAGE_SIZE-1); + /* Round up to nearest multiple of MAX_PAGE_SIZE. */ + nChunkSize = (nChunkSize + (MAX_PAGE_SIZE-1)); + nChunkSize &= ~(MAX_PAGE_SIZE-1); pGroup->nChunkSize = nChunkSize; rc = SQLITE_OK; } @@ -771,7 +811,7 @@ static int multiplexSectorSize(sqlite3_file *pConn){ if( pSubOpen ){ return pSubOpen->pMethods->xSectorSize(pSubOpen); } - return SQLITE_DEFAULT_SECTOR_SIZE; + return DEFAULT_SECTOR_SIZE; } /* Pass xDeviceCharacteristics requests through to the original VFS unchanged. @@ -941,6 +981,7 @@ int sqlite3_multiplex_shutdown(void){ /***************************** Test Code ***********************************/ #ifdef SQLITE_TEST #include +extern const char *sqlite3TestErrorName(int); /* diff --git a/src/test_multiplex.h b/src/test_multiplex.h index 1a574c1a87..ec1ba9bb21 100644 --- a/src/test_multiplex.h +++ b/src/test_multiplex.h @@ -60,16 +60,16 @@ ** function gives access to the xFileControl interface of the ** multiplex VFS shim. ** -** SELECT multiplex_control(,) ; +** SELECT multiplex_control(,); ** ** =1 MULTIPLEX_CTRL_ENABLE ** =0 disable ** =1 enable ** -** =1 MULTIPLEX_CTRL_SET_CHUNK_SIZE +** =2 MULTIPLEX_CTRL_SET_CHUNK_SIZE ** int, chunk size ** -** =1 MULTIPLEX_CTRL_SET_MAX_CHUNKS +** =3 MULTIPLEX_CTRL_SET_MAX_CHUNKS ** int, max chunks ** ** THIS ROUTINE IS NOT THREADSAFE. Call this routine exactly once diff --git a/test/multiplex.test b/test/multiplex.test index c76cee71a0..518cbe37a0 100644 --- a/test/multiplex.test +++ b/test/multiplex.test @@ -86,32 +86,39 @@ do_test multiplex-1.9.8 { multiplex_set db main 1073741824 1 } {SQLITE_OK} do_test multiplex-1.9.9 { db close } {} do_test multiplex-1.9.10 { sqlite3_multiplex_shutdown } {SQLITE_OK} -do_test multiplex-1.10.1 { sqlite3_multiplex_initialize "" 1 } {SQLITE_OK} -do_test multiplex-1.10.2 { sqlite3 db test.db } {} -do_test multiplex-1.10.3 { execsql { SELECT multiplex_control(2, 32768); } } {SQLITE_OK} -do_test multiplex-1.10.4 { execsql { SELECT multiplex_control(3, -1); } } {SQLITE_MISUSE} -do_test multiplex-1.10.5 { execsql { SELECT multiplex_control(2, -1); } } {SQLITE_MISUSE} -do_test multiplex-1.10.6 { execsql { SELECT multiplex_control(2, 31); } } {SQLITE_OK} -do_test multiplex-1.10.7 { execsql { SELECT multiplex_control(3, 100); } } {SQLITE_MISUSE} -do_test multiplex-1.10.8 { execsql { SELECT multiplex_control(2, 1073741824); } } {SQLITE_OK} -do_test multiplex-1.10.9 { db close } {} -do_test multiplex-1.10.10 { sqlite3_multiplex_shutdown } {SQLITE_OK} +do_test multiplex-1.10.1 { sqlite3_multiplex_initialize "" 1 } {SQLITE_OK} +do_test multiplex-1.10.2 { sqlite3 db test.db } {} +do_test multiplex-1.10.3 { lindex [ catchsql { SELECT multiplex_control(2, 32768); } ] 0 } {0} +do_test multiplex-1.10.4 { lindex [ catchsql { SELECT multiplex_control(3, -1); } ] 0 } {1} +do_test multiplex-1.10.5 { lindex [ catchsql { SELECT multiplex_control(2, -1); } ] 0 } {1} +do_test multiplex-1.10.6 { lindex [ catchsql { SELECT multiplex_control(2, 31); } ] 0 } {0} +do_test multiplex-1.10.7 { lindex [ catchsql { SELECT multiplex_control(3, 100); } ] 0 } {1} +do_test multiplex-1.10.8 { lindex [ catchsql { SELECT multiplex_control(2, 1073741824); } ] 0 } {0} +do_test multiplex-1.10.9 { db close } {} +do_test multiplex-1.10.10 { sqlite3_multiplex_shutdown } {SQLITE_OK} -do_test multiplex-1.11.1 { sqlite3_multiplex_initialize "" 1 } {SQLITE_OK} -do_test multiplex-1.11.2 { sqlite3 db test.db } {} -do_test multiplex-1.11.3 { sqlite3_multiplex_control db main enable 0 } {SQLITE_OK} -do_test multiplex-1.11.4 { sqlite3_multiplex_control db main enable 1 } {SQLITE_OK} -do_test multiplex-1.11.5 { sqlite3_multiplex_control db main enable -1 } {SQLITE_OK} -do_test multiplex-1.11.6 { db close } {} -do_test multiplex-1.11.7 { sqlite3_multiplex_shutdown } {SQLITE_OK} +do_test multiplex-1.11.1 { sqlite3_multiplex_initialize "" 1 } {SQLITE_OK} +do_test multiplex-1.11.2 { sqlite3 db test.db } {} +do_test multiplex-1.11.3 { sqlite3_multiplex_control db main enable 0 } {SQLITE_OK} +do_test multiplex-1.11.4 { sqlite3_multiplex_control db main enable 1 } {SQLITE_OK} +do_test multiplex-1.11.5 { sqlite3_multiplex_control db main enable -1 } {SQLITE_OK} +do_test multiplex-1.11.6 { db close } {} +do_test multiplex-1.11.7 { sqlite3_multiplex_shutdown } {SQLITE_OK} -do_test multiplex-1.12.1 { sqlite3_multiplex_initialize "" 1 } {SQLITE_OK} -do_test multiplex-1.12.2 { sqlite3 db test.db } {} -do_test multiplex-1.12.3 { execsql { SELECT multiplex_control(1, 0); } } {SQLITE_OK} -do_test multiplex-1.12.4 { execsql { SELECT multiplex_control(1, 1); } } {SQLITE_OK} -do_test multiplex-1.12.5 { execsql { SELECT multiplex_control(1, -1); } } {SQLITE_OK} -do_test multiplex-1.12.6 { db close } {} -do_test multiplex-1.12.7 { sqlite3_multiplex_shutdown } {SQLITE_OK} +do_test multiplex-1.12.1 { sqlite3_multiplex_initialize "" 1 } {SQLITE_OK} +do_test multiplex-1.12.2 { sqlite3 db test.db } {} +do_test multiplex-1.12.3 { lindex [ catchsql { SELECT multiplex_control(1, 0); } ] 0 } {0} +do_test multiplex-1.12.4 { lindex [ catchsql { SELECT multiplex_control(1, 1); } ] 0 } {0} +do_test multiplex-1.12.5 { lindex [ catchsql { SELECT multiplex_control(1, -1); } ] 0 } {0} +do_test multiplex-1.12.6 { db close } {} +do_test multiplex-1.12.7 { sqlite3_multiplex_shutdown } {SQLITE_OK} + +do_test multiplex-1.13.1 { sqlite3_multiplex_initialize "" 1 } {SQLITE_OK} +do_test multiplex-1.13.2 { sqlite3 db test.db } {} +do_test multiplex-1.13.3 { lindex [ catchsql { SELECT multiplex_control(-1, 0); } ] 0 } {1} +do_test multiplex-1.13.4 { lindex [ catchsql { SELECT multiplex_control(4, 1); } ] 0 } {1} +do_test multiplex-1.13.6 { db close } {} +do_test multiplex-1.13.7 { sqlite3_multiplex_shutdown } {SQLITE_OK} #------------------------------------------------------------------------- # Some simple warm-body tests with a single database file in rollback @@ -283,11 +290,11 @@ foreach jmode $all_journal_modes { } } -do_test multiplex-2.7.1 { multiplex_delete test.db } {} -do_test multiplex-2.7.2 { sqlite3_multiplex_initialize "" 1 } {SQLITE_OK} -do_test multiplex-2.7.3 { sqlite3 db test.db } {} -do_test multiplex-2.7.4 { execsql { SELECT multiplex_control(2, 65536); } } {SQLITE_OK} -do_test multiplex-2.7.5 { execsql { SELECT multiplex_control(1, 0); } } {SQLITE_OK} +do_test multiplex-2.7.1 { multiplex_delete test.db } {} +do_test multiplex-2.7.2 { sqlite3_multiplex_initialize "" 1 } {SQLITE_OK} +do_test multiplex-2.7.3 { sqlite3 db test.db } {} +do_test multiplex-2.7.4 { lindex [ catchsql { SELECT multiplex_control(2, 65536); } ] 0 } {0} +do_test multiplex-2.7.5 { lindex [ catchsql { SELECT multiplex_control(1, 0); } ] 0 } {0} do_test multiplex-2.7.6 { execsql { CREATE TABLE t1(a PRIMARY KEY, b); @@ -299,7 +306,7 @@ do_test multiplex-2.7.7 { expr ([file size [multiplex_name test.db 0]] < 65536) do_test multiplex-2.7.8 { file exists [multiplex_name test.db 1] } {0} do_test multiplex-2.7.9 { execsql { - INSERT INTO t1 VALUES(1, randomblob(65536)); + INSERT INTO t1 VALUES(2, randomblob(65536)); } } {} # verify only one file, and file size exceeds chunks size @@ -308,7 +315,6 @@ do_test multiplex-2.7.11 { file exists [multiplex_name test.db 1] } do_test multiplex-2.7.12 { db close } {} do_test multiplex-2.7.13 { sqlite3_multiplex_shutdown } {SQLITE_OK} - #------------------------------------------------------------------------- # Try some tests with more than one connection to a database file. Still # in rollback mode.