From 8e98037c1b1bc9f7b838e8e01a51df8804035bd4 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 23 Apr 2011 19:06:26 +0000 Subject: [PATCH] Test that it is now possible to use different VFSs for two databases attached to a single handle. FossilOrigin-Name: 2af51f856c6203f836d8bb62b6b79b19554886e7 --- manifest | 16 ++++++------ manifest.uuid | 2 +- src/main.c | 6 ++--- src/test_vfs.c | 60 +++++++++++++++++++++++++------------------- test/uri.test | 68 +++++++++++++++++++++++++++++++++++++++++++++++++- 5 files changed, 114 insertions(+), 38 deletions(-) diff --git a/manifest b/manifest index de6aca8fbd..71007d9576 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Have\sthe\sATTACH\scommand\sdo\sURI\sinterpretation\sin\sthe\ssame\sway\sas\ssqlite3_open()\sand\ssqlite3_open_v2()\sdo. -D 2011-04-23T15:54:54.370 +C Test\sthat\sit\sis\snow\spossible\sto\suse\sdifferent\sVFSs\sfor\stwo\sdatabases\sattached\sto\sa\ssingle\shandle. +D 2011-04-23T19:06:26.760 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 7a4d9524721d40ef9ee26f93f9bd6a51dba106f2 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -143,7 +143,7 @@ F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 7f026423f4d71d989e719a743f98a1cbd4e6d99e F src/loadext.c 3ae0d52da013a6326310655be6473fd472347b85 -F src/main.c 8b4ebab18189148b702afd931efd2f40476e6e05 +F src/main.c 933d0bcf586ba7acbe2ce3f37d35c474a8306109 F src/malloc.c 74c740e8ba22b806cfb980c8c0ddea1cbd54a20e F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 00bd8265c81abb665c48fea1e0c234eb3b922206 @@ -225,7 +225,7 @@ F src/test_superlock.c 2b97936ca127d13962c3605dbc9a4ef269c424cd F src/test_syscall.c 162c4ec0137a549c009bb9ecab550527743cfc5d F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa F src/test_thread.c 361ae0a0f1cbf5a28ad0388a258b104017a370c0 -F src/test_vfs.c b6bab7382f4ed27a67b204250c0c22821c6e3ae9 +F src/test_vfs.c 0ac5b2e3da61bc385c1017890687c359746be2fd F src/test_vfstrace.c 2265c9895f350c8d3c39b079998fbe7481505cc1 F src/test_wholenumber.c 6129adfbe7c7444f2e60cc785927f3aa74e12290 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 @@ -837,7 +837,7 @@ F test/unique.test 083c7fff74695bcc27a71d75699deba3595bc9c2 F test/unixexcl.test 9d80a54d86d2261f660758928959368ffc36151e F test/unordered.test e81169ce2a8f31b2c6b66af691887e1376ab3ced F test/update.test 8bc86fd7ef1a00014f76dc6a6a7c974df4aef172 -F test/uri.test 72d31f90b982e65763541db45ef3cb16f797d9fc +F test/uri.test 062ba42524a5042985e7994dc2289259424b60bf F test/utf16align.test 54cd35a27c005a9b6e7815d887718780b6a462ae F test/vacuum.test 29b60e8cc9e573b39676df6c4a75fe9e02d04a09 F test/vacuum2.test 91a84c9b08adfc4472097d2e8deb0150214e0e76 @@ -930,7 +930,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 44f0874a95408c75a296964a04eef00341abb94a -R 72226daec7234c928303c103545adaa3 +P 68240e75e87a54cde93352b0ec364d34365a8170 +R 4f397b814ac53bbd808b171d5d8b418c U dan -Z b332a80681747acde88f379c7f0557c6 +Z 87fa4f3faa1bbb8cd013b95e032b042b diff --git a/manifest.uuid b/manifest.uuid index 7dcb2b1739..ac2253e166 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -68240e75e87a54cde93352b0ec364d34365a8170 \ No newline at end of file +2af51f856c6203f836d8bb62b6b79b19554886e7 \ No newline at end of file diff --git a/src/main.c b/src/main.c index bb1eafb9a6..313222f54b 100644 --- a/src/main.c +++ b/src/main.c @@ -1791,9 +1791,9 @@ int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){ } /* -** This function is used to parse filenames passed by the user to API -** functions sqlite3_open() or sqlite3_open_v2(), and for database filenames -** specified as part of ATTACH statements. +** This function is used to parse URIs passed by the user to API functions +** sqlite3_open() or sqlite3_open_v2(), and for database URIs specified as +** part of ATTACH statements. */ int sqlite3ParseUri( const char *zDefaultVfs, /* VFS to use if no "vfs=xxx" query option */ diff --git a/src/test_vfs.c b/src/test_vfs.c index 53bdca68c1..ba078a0f9b 100644 --- a/src/test_vfs.c +++ b/src/test_vfs.c @@ -114,20 +114,21 @@ struct Testvfs { ** + Simulating IO errors, and ** + Invoking the Tcl callback script. */ -#define TESTVFS_SHMOPEN_MASK 0x00000001 -#define TESTVFS_SHMLOCK_MASK 0x00000010 -#define TESTVFS_SHMMAP_MASK 0x00000020 -#define TESTVFS_SHMBARRIER_MASK 0x00000040 -#define TESTVFS_SHMCLOSE_MASK 0x00000080 +#define TESTVFS_SHMOPEN_MASK 0x00000001 +#define TESTVFS_SHMLOCK_MASK 0x00000010 +#define TESTVFS_SHMMAP_MASK 0x00000020 +#define TESTVFS_SHMBARRIER_MASK 0x00000040 +#define TESTVFS_SHMCLOSE_MASK 0x00000080 -#define TESTVFS_OPEN_MASK 0x00000100 -#define TESTVFS_SYNC_MASK 0x00000200 -#define TESTVFS_DELETE_MASK 0x00000400 -#define TESTVFS_CLOSE_MASK 0x00000800 -#define TESTVFS_WRITE_MASK 0x00001000 -#define TESTVFS_TRUNCATE_MASK 0x00002000 -#define TESTVFS_ACCESS_MASK 0x00004000 -#define TESTVFS_ALL_MASK 0x00007FFF +#define TESTVFS_OPEN_MASK 0x00000100 +#define TESTVFS_SYNC_MASK 0x00000200 +#define TESTVFS_DELETE_MASK 0x00000400 +#define TESTVFS_CLOSE_MASK 0x00000800 +#define TESTVFS_WRITE_MASK 0x00001000 +#define TESTVFS_TRUNCATE_MASK 0x00002000 +#define TESTVFS_ACCESS_MASK 0x00004000 +#define TESTVFS_FULLPATHNAME_MASK 0x00008000 +#define TESTVFS_ALL_MASK 0x0001FFFF #define TESTVFS_MAX_PAGES 1024 @@ -675,6 +676,14 @@ static int tvfsFullPathname( int nOut, char *zOut ){ + Testvfs *p = (Testvfs *)pVfs->pAppData; + if( p->pScript && p->mask&TESTVFS_FULLPATHNAME_MASK ){ + int rc; + tvfsExecTcl(p, "xFullPathname", Tcl_NewStringObj(zPath, -1), 0, 0); + if( tvfsResultCode(p, &rc) ){ + if( rc!=SQLITE_OK ) return rc; + } + } return sqlite3OsFullPathname(PARENTVFS(pVfs), zPath, nOut, zOut); } @@ -1040,18 +1049,19 @@ static int testvfs_obj_cmd( char *zName; int mask; } vfsmethod [] = { - { "xShmOpen", TESTVFS_SHMOPEN_MASK }, - { "xShmLock", TESTVFS_SHMLOCK_MASK }, - { "xShmBarrier", TESTVFS_SHMBARRIER_MASK }, - { "xShmUnmap", TESTVFS_SHMCLOSE_MASK }, - { "xShmMap", TESTVFS_SHMMAP_MASK }, - { "xSync", TESTVFS_SYNC_MASK }, - { "xDelete", TESTVFS_DELETE_MASK }, - { "xWrite", TESTVFS_WRITE_MASK }, - { "xTruncate", TESTVFS_TRUNCATE_MASK }, - { "xOpen", TESTVFS_OPEN_MASK }, - { "xClose", TESTVFS_CLOSE_MASK }, - { "xAccess", TESTVFS_ACCESS_MASK }, + { "xShmOpen", TESTVFS_SHMOPEN_MASK }, + { "xShmLock", TESTVFS_SHMLOCK_MASK }, + { "xShmBarrier", TESTVFS_SHMBARRIER_MASK }, + { "xShmUnmap", TESTVFS_SHMCLOSE_MASK }, + { "xShmMap", TESTVFS_SHMMAP_MASK }, + { "xSync", TESTVFS_SYNC_MASK }, + { "xDelete", TESTVFS_DELETE_MASK }, + { "xWrite", TESTVFS_WRITE_MASK }, + { "xTruncate", TESTVFS_TRUNCATE_MASK }, + { "xOpen", TESTVFS_OPEN_MASK }, + { "xClose", TESTVFS_CLOSE_MASK }, + { "xAccess", TESTVFS_ACCESS_MASK }, + { "xFullPathname", TESTVFS_FULLPATHNAME_MASK }, }; Tcl_Obj **apElem = 0; int nElem = 0; diff --git a/test/uri.test b/test/uri.test index cf4197f348..6248381f81 100644 --- a/test/uri.test +++ b/test/uri.test @@ -13,6 +13,15 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl +# Test organization: +# +# 1.*: That file names are correctly extracted from URIs. +# 2.*: That URI options (query parameters) are correctly extracted from URIs. +# 3.*: That specifying an unknown VFS causes an error. +# 4.*: Tests for specifying other options (other than "vfs"). +# 5.*: Test using a different VFS with an attached database. +# + set testprefix uri db close sqlite3_shutdown @@ -104,7 +113,9 @@ do_test 3.1 { } {1 {no such vfs: nosuchvfs}} #------------------------------------------------------------------------- -# Test the "readonly" URI option. +# Test some of the other options (other than "vfs"). +# +# TODO: Fix this after the list of options is decided. # do_test 4.0 { sqlite3 db test.db @@ -126,5 +137,60 @@ foreach {tn uri ro} { db close } +#------------------------------------------------------------------------- +# Test that things work if an ATTACHed database uses a different VFS than +# the main database. The important point is that for all operations +# involving the ATTACHed database, the correct versions of the following +# VFS are used for all operations involving the attached database. +# +# xOpen +# xDelete +# xAccess +# xFullPathname +# + +# This block of code creates two VFS - "tvfs1" and "tvfs2". Each time one +# of the above methods is called using "tvfs1", global variable ::T1(X) is +# set, where X is the file-name the method is called on. Calls to the above +# methods using "tvfs2" set entries in the global T2 array. +# +testvfs tvfs1 +tvfs1 filter {xOpen xDelete xAccess xFullPathname} +tvfs1 script tvfs1_callback +proc tvfs1_callback {method filename args} { + set ::T1([file tail $filename]) 1 +} +testvfs tvfs2 +tvfs2 filter {xOpen xDelete xAccess xFullPathname} +tvfs2 script tvfs2_callback +proc tvfs2_callback {method filename args} { + set ::T2([file tail $filename]) 1 +} + +eval forcedelete [glob test.db*] +do_test 5.1.1 { + sqlite3 db file:test.db1?vfs=tvfs1 + execsql { + ATTACH 'file:test.db2?vfs=tvfs2' AS aux; + PRAGMA main.journal_mode = PERSIST; + PRAGMA aux.journal_mode = PERSIST; + CREATE TABLE t1(a, b); + CREATE TABLE aux.t2(a, b); + PRAGMA main.journal_mode = WAL; + PRAGMA aux.journal_mode = PERSIST; + INSERT INTO t1 VALUES('x', 'y'); + INSERT INTO t2 VALUES('x', 'y'); + } + lsort [array names ::T1] +} {test.db1 test.db1-journal test.db1-wal} + +do_test 5.1.2 { + lsort [array names ::T2] +} {test.db2 test.db2-journal test.db2-wal} + +db close +tvfs1 delete +tvfs2 delete + finish_test