From afc8b7f0c14ba5acd6d08245e32d1a39fe96a185 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 26 May 2012 18:06:38 +0000 Subject: Enable the use of shared cache for an in-memory database, so that separate database connections can share the same in-memory database. FossilOrigin-Name: 4590e433f2a595bb80fb061024b0a3d2ca25b7b2 --- src/btree.c | 17 +++++++++++------ src/pager.c | 5 ++++- 2 files changed, 15 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/btree.c b/src/btree.c index 287652692..a59e6d10c 100644 --- a/src/btree.c +++ b/src/btree.c @@ -1757,7 +1757,7 @@ int sqlite3BtreeOpen( ** If this Btree is a candidate for shared cache, try to find an ** existing BtShared object that we can share with */ - if( isMemdb==0 && isTempDb==0 ){ + if( isTempDb==0 ){ if( vfsFlags & SQLITE_OPEN_SHAREDCACHE ){ int nFullPathname = pVfs->mxPathname+1; char *zFullPathname = sqlite3Malloc(nFullPathname); @@ -1767,11 +1767,16 @@ int sqlite3BtreeOpen( sqlite3_free(p); return SQLITE_NOMEM; } - rc = sqlite3OsFullPathname(pVfs, zFilename, nFullPathname, zFullPathname); - if( rc ){ - sqlite3_free(zFullPathname); - sqlite3_free(p); - return rc; + if( isMemdb ){ + memcpy(zFullPathname, zFilename, sqlite3Strlen30(zFilename)+1); + }else{ + rc = sqlite3OsFullPathname(pVfs, zFilename, + nFullPathname, zFullPathname); + if( rc ){ + sqlite3_free(zFullPathname); + sqlite3_free(p); + return rc; + } } #if SQLITE_THREADSAFE mutexOpen = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_OPEN); diff --git a/src/pager.c b/src/pager.c index b93e0aa86..43c00c7ec 100644 --- a/src/pager.c +++ b/src/pager.c @@ -4360,6 +4360,8 @@ int sqlite3PagerOpen( #ifndef SQLITE_OMIT_MEMORYDB if( flags & PAGER_MEMORY ){ memDb = 1; + zPathname = sqlite3DbStrDup(0, zFilename); + nPathname = sqlite3Strlen30(zPathname); zFilename = 0; } #endif @@ -6743,7 +6745,8 @@ int sqlite3PagerWalCallback(Pager *pPager){ */ int sqlite3PagerWalSupported(Pager *pPager){ const sqlite3_io_methods *pMethods = pPager->fd->pMethods; - return pPager->exclusiveMode || (pMethods->iVersion>=2 && pMethods->xShmMap); + return pPager->memDb==0 && + (pPager->exclusiveMode || (pMethods->iVersion>=2 && pMethods->xShmMap)); } /* -- cgit v1.2.3 From 7946c530091fe91c4d80a1170c3e15ad66716dfe Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 26 May 2012 18:28:14 +0000 Subject: If SQLITE_DISABLE_FTS3_UNICODE is defined, do not build the "unicode61" tokenizer. FossilOrigin-Name: e71495a817b479bc23c5403d99255e3f098eb054 --- src/test_config.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/test_config.c b/src/test_config.c index f096ebf23..6b5646060 100644 --- a/src/test_config.c +++ b/src/test_config.c @@ -307,6 +307,12 @@ static void set_options(Tcl_Interp *interp){ Tcl_SetVar2(interp, "sqlite_options", "fts3", "0", TCL_GLOBAL_ONLY); #endif +#if !defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_DISABLE_FTS3_UNICODE) + Tcl_SetVar2(interp, "sqlite_options", "fts3_unicode", "0", TCL_GLOBAL_ONLY); +#else + Tcl_SetVar2(interp, "sqlite_options", "fts3_unicode", "1", TCL_GLOBAL_ONLY); +#endif + #ifdef SQLITE_OMIT_GET_TABLE Tcl_SetVar2(interp, "sqlite_options", "gettable", "0", TCL_GLOBAL_ONLY); #else -- cgit v1.2.3 From 4ab9d254e066247855b8907d001b9994aa072f1f Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 26 May 2012 20:08:49 +0000 Subject: Only allow :memory: databases to share cache if there are created using a URI filename. This minimizes the risk of breakages in legacy applications that have shared-cache enabled but also use :memory: databases which they expect to keep separate. FossilOrigin-Name: e3ad61e0308a8442c2bdb7cdb3465576cd39ed4a --- src/btree.c | 2 +- src/main.c | 1 + src/pager.c | 9 ++++++--- 3 files changed, 8 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/btree.c b/src/btree.c index a59e6d10c..136cc196a 100644 --- a/src/btree.c +++ b/src/btree.c @@ -1757,7 +1757,7 @@ int sqlite3BtreeOpen( ** If this Btree is a candidate for shared cache, try to find an ** existing BtShared object that we can share with */ - if( isTempDb==0 ){ + if( isTempDb==0 && (isMemdb==0 || (vfsFlags&SQLITE_OPEN_URI)!=0) ){ if( vfsFlags & SQLITE_OPEN_SHAREDCACHE ){ int nFullPathname = pVfs->mxPathname+1; char *zFullPathname = sqlite3Malloc(nFullPathname); diff --git a/src/main.c b/src/main.c index d148b4b42..c8fda4787 100644 --- a/src/main.c +++ b/src/main.c @@ -2055,6 +2055,7 @@ int sqlite3ParseUri( memcpy(zFile, zUri, nUri); zFile[nUri] = '\0'; zFile[nUri+1] = '\0'; + flags &= ~SQLITE_OPEN_URI; } *ppVfs = sqlite3_vfs_find(zVfs); diff --git a/src/pager.c b/src/pager.c index 43c00c7ec..0154a5d7f 100644 --- a/src/pager.c +++ b/src/pager.c @@ -4360,9 +4360,12 @@ int sqlite3PagerOpen( #ifndef SQLITE_OMIT_MEMORYDB if( flags & PAGER_MEMORY ){ memDb = 1; - zPathname = sqlite3DbStrDup(0, zFilename); - nPathname = sqlite3Strlen30(zPathname); - zFilename = 0; + if( zFilename ){ + zPathname = sqlite3DbStrDup(0, zFilename); + if( zPathname==0 ) return SQLITE_NOMEM; + nPathname = sqlite3Strlen30(zPathname); + zFilename = 0; + } } #endif -- cgit v1.2.3 From d4e0bb0e65a9cb33ba6139152ddbe652a4ea0393 Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 27 May 2012 01:19:04 +0000 Subject: Have user interfaces report out the filename of in-memory databases as an empty string, as it always has. This simplifies the changes. FossilOrigin-Name: 595dfdbffefb2598cba89980f885289d1c5f5833 --- src/btree.c | 7 ++++--- src/pager.c | 16 +++++++++++----- src/pager.h | 2 +- src/test_btree.c | 2 +- src/vdbe.c | 2 +- 5 files changed, 18 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/btree.c b/src/btree.c index 136cc196a..58a9dce1e 100644 --- a/src/btree.c +++ b/src/btree.c @@ -1786,7 +1786,7 @@ int sqlite3BtreeOpen( #endif for(pBt=GLOBAL(BtShared*,sqlite3SharedCacheList); pBt; pBt=pBt->pNext){ assert( pBt->nRef>0 ); - if( 0==strcmp(zFullPathname, sqlite3PagerFilename(pBt->pPager)) + if( 0==strcmp(zFullPathname, sqlite3PagerFilename(pBt->pPager, 0)) && sqlite3PagerVfs(pBt->pPager)==pVfs ){ int iDb; for(iDb=db->nDb-1; iDb>=0; iDb--){ @@ -8051,14 +8051,15 @@ char *sqlite3BtreeIntegrityCheck( #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ /* -** Return the full pathname of the underlying database file. +** Return the full pathname of the underlying database file. Return +** an empty string if the database is in-memory or a TEMP database. ** ** The pager filename is invariant as long as the pager is ** open so it is safe to access without the BtShared mutex. */ const char *sqlite3BtreeGetFilename(Btree *p){ assert( p->pBt->pPager!=0 ); - return sqlite3PagerFilename(p->pBt->pPager); + return sqlite3PagerFilename(p->pBt->pPager, 1); } /* diff --git a/src/pager.c b/src/pager.c index 0154a5d7f..425fb78ce 100644 --- a/src/pager.c +++ b/src/pager.c @@ -4360,7 +4360,7 @@ int sqlite3PagerOpen( #ifndef SQLITE_OMIT_MEMORYDB if( flags & PAGER_MEMORY ){ memDb = 1; - if( zFilename ){ + if( zFilename && zFilename[0] ){ zPathname = sqlite3DbStrDup(0, zFilename); if( zPathname==0 ) return SQLITE_NOMEM; nPathname = sqlite3Strlen30(zPathname); @@ -6301,9 +6301,16 @@ int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){ /* ** Return the full pathname of the database file. +** +** Except, if the pager is in-memory only, then return an empty string if +** nullIfMemDb is true. This routine is called with nullIfMemDb==1 when +** used to report the filename to the user, for compatibility with legacy +** behavior. But when the Btree needs to know the filename for matching to +** shared cache, it uses nullIfMemDb==0 so that in-memory databases can +** participate in shared-cache. */ -const char *sqlite3PagerFilename(Pager *pPager){ - return pPager->zFilename; +const char *sqlite3PagerFilename(Pager *pPager, int nullIfMemDb){ + return (nullIfMemDb && pPager->memDb) ? "" : pPager->zFilename; } /* @@ -6748,8 +6755,7 @@ int sqlite3PagerWalCallback(Pager *pPager){ */ int sqlite3PagerWalSupported(Pager *pPager){ const sqlite3_io_methods *pMethods = pPager->fd->pMethods; - return pPager->memDb==0 && - (pPager->exclusiveMode || (pMethods->iVersion>=2 && pMethods->xShmMap)); + return pPager->exclusiveMode || (pMethods->iVersion>=2 && pMethods->xShmMap); } /* diff --git a/src/pager.h b/src/pager.h index eca8a2f07..2b60e058d 100644 --- a/src/pager.h +++ b/src/pager.h @@ -151,7 +151,7 @@ int sqlite3PagerCloseWal(Pager *pPager); u8 sqlite3PagerIsreadonly(Pager*); int sqlite3PagerRefcount(Pager*); int sqlite3PagerMemUsed(Pager*); -const char *sqlite3PagerFilename(Pager*); +const char *sqlite3PagerFilename(Pager*, int); const sqlite3_vfs *sqlite3PagerVfs(Pager*); sqlite3_file *sqlite3PagerFile(Pager*); const char *sqlite3PagerJournalname(Pager*); diff --git a/src/test_btree.c b/src/test_btree.c index 0048397e9..db72889b2 100644 --- a/src/test_btree.c +++ b/src/test_btree.c @@ -33,7 +33,7 @@ int sqlite3BtreeSharedCacheReport( BtShared *pBt; Tcl_Obj *pRet = Tcl_NewObj(); for(pBt=GLOBAL(BtShared*,sqlite3SharedCacheList); pBt; pBt=pBt->pNext){ - const char *zFile = sqlite3PagerFilename(pBt->pPager); + const char *zFile = sqlite3PagerFilename(pBt->pPager, 1); Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj(zFile, -1)); Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(pBt->nRef)); } diff --git a/src/vdbe.c b/src/vdbe.c index fa5180c9a..ec4ea2a55 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -5511,7 +5511,7 @@ case OP_JournalMode: { /* out2-prerelease */ if( !sqlite3PagerOkToChangeJournalMode(pPager) ) eNew = eOld; #ifndef SQLITE_OMIT_WAL - zFilename = sqlite3PagerFilename(pPager); + zFilename = sqlite3PagerFilename(pPager, 1); /* Do not allow a transition to journal_mode=WAL for a database ** in temporary storage or if the VFS does not support shared memory -- cgit v1.2.3 From 9c67b2aae06e8571e8c5faa8968fab8286a70672 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 28 May 2012 13:58:00 +0000 Subject: Add the mode=memory option to URI filenames, which when present forces the database to be an in-memory database. This enables named in-memory databases. FossilOrigin-Name: 651520fa84ee0c488bef660bab9865500309d5e9 --- src/btree.c | 3 ++- src/main.c | 8 ++++++-- src/sqlite.h.in | 1 + 3 files changed, 9 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/btree.c b/src/btree.c index 58a9dce1e..c16eca5f6 100644 --- a/src/btree.c +++ b/src/btree.c @@ -1721,7 +1721,8 @@ int sqlite3BtreeOpen( const int isMemdb = 0; #else const int isMemdb = (zFilename && strcmp(zFilename, ":memory:")==0) - || (isTempDb && sqlite3TempInMemory(db)); + || (isTempDb && sqlite3TempInMemory(db)) + || (vfsFlags & SQLITE_OPEN_MEMORY)!=0; #endif assert( db!=0 ); diff --git a/src/main.c b/src/main.c index c8fda4787..4e9a605f4 100644 --- a/src/main.c +++ b/src/main.c @@ -2012,10 +2012,14 @@ int sqlite3ParseUri( { "ro", SQLITE_OPEN_READONLY }, { "rw", SQLITE_OPEN_READWRITE }, { "rwc", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE }, + { "memory", + SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE + | SQLITE_OPEN_MEMORY }, { 0, 0 } }; - mask = SQLITE_OPEN_READONLY|SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE; + mask = SQLITE_OPEN_READONLY | SQLITE_OPEN_READWRITE + | SQLITE_OPEN_CREATE | SQLITE_OPEN_MEMORY; aMode = aOpenMode; limit = mask & flags; zModeType = "access"; @@ -2036,7 +2040,7 @@ int sqlite3ParseUri( rc = SQLITE_ERROR; goto parse_uri_out; } - if( mode>limit ){ + if( (mode & ~SQLITE_OPEN_MEMORY)>limit ){ *pzErrMsg = sqlite3_mprintf("%s mode not allowed: %s", zModeType, zVal); rc = SQLITE_PERM; diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 29355d770..bfaf70c79 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -473,6 +473,7 @@ int sqlite3_exec( #define SQLITE_OPEN_EXCLUSIVE 0x00000010 /* VFS only */ #define SQLITE_OPEN_AUTOPROXY 0x00000020 /* VFS only */ #define SQLITE_OPEN_URI 0x00000040 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_MEMORY 0x00000080 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_MAIN_DB 0x00000100 /* VFS only */ #define SQLITE_OPEN_TEMP_DB 0x00000200 /* VFS only */ #define SQLITE_OPEN_TRANSIENT_DB 0x00000400 /* VFS only */ -- cgit v1.2.3 From 9cb7200815baf934dff0db605a38ff675bcef40e Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 28 May 2012 17:51:53 +0000 Subject: Updates regarding URI query parameters and shared cache in the documentation derived from comments in sqlite.h.in. No changes to code. FossilOrigin-Name: bcc72d413e8db5fe8b32147ac22d406e2cd6bb60 --- src/sqlite.h.in | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/sqlite.h.in b/src/sqlite.h.in index bfaf70c79..85534870a 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -2571,18 +2571,20 @@ void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** present, then the VFS specified by the option takes precedence over ** the value passed as the fourth parameter to sqlite3_open_v2(). ** -**
  • mode: ^(The mode parameter may be set to either "ro", "rw" or -** "rwc". Attempting to set it to any other value is an error)^. +**
  • mode: ^(The mode parameter may be set to either "ro", "rw", +** "rwc", or "memory". Attempting to set it to any other value is +** an error)^. ** ^If "ro" is specified, then the database is opened for read-only ** access, just as if the [SQLITE_OPEN_READONLY] flag had been set in the ** third argument to sqlite3_prepare_v2(). ^If the mode option is set to ** "rw", then the database is opened for read-write (but not create) ** access, as if SQLITE_OPEN_READWRITE (but not SQLITE_OPEN_CREATE) had ** been set. ^Value "rwc" is equivalent to setting both -** SQLITE_OPEN_READWRITE and SQLITE_OPEN_CREATE. ^If sqlite3_open_v2() is -** used, it is an error to specify a value for the mode parameter that is -** less restrictive than that specified by the flags passed as the third -** parameter. +** SQLITE_OPEN_READWRITE and SQLITE_OPEN_CREATE. ^If the mode option is +** set to "memory" then a pure [in-memory database] that never reads or +** or writes from disk is used. ^It is an error to specify a value for +** the mode parameter that is less restrictive than that specified by +** the flags passed in the third parameter to sqlite3_open_v2(). ** **
  • cache: ^The cache parameter may be set to either "shared" or ** "private". ^Setting it to "shared" is equivalent to setting the @@ -4623,7 +4625,6 @@ void *sqlite3_update_hook( /* ** CAPI3REF: Enable Or Disable Shared Pager Cache -** KEYWORDS: {shared cache} ** ** ^(This routine enables or disables the sharing of the database cache ** and schema data structures between [database connection | connections] -- cgit v1.2.3