-C Take\sout\sthe\sspecial\shandling\sof\snolock=true\sin\sos_win.c\sand\sadd\sit\sto\npager.c,\sso\sthat\sit\sworks\sfor\sall\sVFSes.\s\sAdd\sthe\spPager->noLock\sboolean\nfor\sclarity.
-D 2014-05-01T01:49:22.279
+C Add\stest\scases\sand\sdocumentation\sfor\sthe\snolock\sand\simmutable\squery\nparameters.
+D 2014-05-07T15:09:24.618
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F src/rowset.c a9c9aae3234b44a6d7c6f5a3cadf90dce1e627be
F src/select.c ed459f7f478a1e533d19c4b953693b3ffa2efd15
F src/shell.c 2afe7a7154e97be0c74c5feacf09626bda8493be
-F src/sqlite.h.in ad2bbeb6a41c228f6a9dbf24df62e4d3eff79ee5
+F src/sqlite.h.in 564fc23db33870b5096b20d72df7491ce0b8b74f
F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e
F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
F src/sqliteInt.h b2947801eccefd7ba3e5f14e1353289351a83cf3
F src/test_syscall.c 2e21ca7f7dc54a028f1967b63f1e76155c356f9b
F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa
F src/test_thread.c 1e133a40b50e9c035b00174035b846e7eef481cb
-F src/test_vfs.c e72f555ef7a59080f898fcf1a233deb9eb704ea9
+F src/test_vfs.c f84075a388527892ff184988f43b69ce69b8083c
F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/tokenize.c 6da2de6e12218ccb0aea5184b56727d011f4bee7
F test/mutex1.test 78b2b9bb320e51d156c4efdb71b99b051e7a4b41
F test/mutex2.test bfeaeac2e73095b2ac32285d2756e3a65e681660
F test/nan.test e9648b9d007c7045242af35e11a984d4b169443a
+F test/nolock.test 77b278317fa765b1ada5f88d59219cdeb8364f8f
F test/notify1.test 669b2b743618efdc18ca4b02f45423d5d2304abf
F test/notify2.test ce23eb522c9e1fff6443f96376fe67872202061c
F test/notify3.test 10ff25cde502e72a92053a2f215d64bece4ef934
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
-P 1829c38c3233c8cb194fae6d560d35a8916b1348
-R 9585bcff14fbe775451a3a647d896079
+P 725c1c14be331bce9bf074960dbfa7b6d4c1ba87
+R 89db3fd7a34cc009fbfa4be31d82927f
U drh
-Z 3dae204f6c4a7be4483961b87ae0c17a
+Z 2af631f996ea658459fe7078e363eaf4
-725c1c14be331bce9bf074960dbfa7b6d4c1ba87
\ No newline at end of file
+19d56cbaca222b32e2e354063149cccd89441d73
\ No newline at end of file
** ^If sqlite3_open_v2() is used and the "cache" parameter is present in
** a URI filename, its value overrides any behavior requested by setting
** SQLITE_OPEN_PRIVATECACHE or SQLITE_OPEN_SHAREDCACHE flag.
+**
+** <li> <b>psow</b>: ^The psow parameter may be "true" (or "on" or "yes" or
+** "1") or "false" (or "off" or "no" or "0") to indicate that the
+** [powersafe overwrite] property does or does not apply to the
+** storage media on which the database file resides. ^The psow query
+** parameter only works for the built-in unix and Windows VFSes.
+**
+** <li> <b>nolock</b>: ^The nolock parameter is a boolean query parameter
+** which if set disables file locking in rollback journal modes. This
+** is useful for accessing a database on a filesystem that does not
+** support locking. Caution: Database corruption might result if two
+** or more processes write to the same database and any one of those
+** processes uses nolock=1.
+**
+** <li> <b>immutable</b>: ^The immutable parameter is a boolean query
+** parameter that indicates that the database file is stored on
+** read-only media. ^When immutable is set, SQLite assumes that the
+** database file cannot be changed, even by a process with higher
+** privilege, and so the database is opened read-only and all locking
+** and change detection is disabled. Caution: Setting the immutable
+** property on a database file that does in fact change can result
+** in incorrect query results and/or [SQLITE_CORRUPT] errors.
+** See also: [SQLITE_IOCAP_IMMUTABLE].
+**
** </ul>
**
** ^Specifying an unknown parameter in the query component of a URI is not an
** Open file "data.db" in the current directory for read-only access.
** Regardless of whether or not shared-cache mode is enabled by
** default, use a private cache.
-** <tr><td> file:/home/fred/data.db?vfs=unix-nolock <td>
-** Open file "/home/fred/data.db". Use the special VFS "unix-nolock".
+** <tr><td> file:/home/fred/data.db?vfs=unix-dotfile <td>
+** Open file "/home/fred/data.db". Use the special VFS "unix-dotfile"
+** that uses dot-files in place of posix advisory locking.
** <tr><td> file:data.db?mode=readonly <td>
** An error. "readonly" is not a valid option for the "mode" parameter.
** </table>
#define TESTVFS_FULLPATHNAME_MASK 0x00008000
#define TESTVFS_READ_MASK 0x00010000
#define TESTVFS_UNLOCK_MASK 0x00020000
+#define TESTVFS_LOCK_MASK 0x00040000
+#define TESTVFS_CKLOCK_MASK 0x00080000
-#define TESTVFS_ALL_MASK 0x0003FFFF
+#define TESTVFS_ALL_MASK 0x000FFFFF
#define TESTVFS_MAX_PAGES 1024
** Lock an tvfs-file.
*/
static int tvfsLock(sqlite3_file *pFile, int eLock){
- TestvfsFd *p = tvfsGetFd(pFile);
- return sqlite3OsLock(p->pReal, eLock);
+ TestvfsFd *pFd = tvfsGetFd(pFile);
+ Testvfs *p = (Testvfs *)pFd->pVfs->pAppData;
+ if( p->pScript && p->mask&TESTVFS_LOCK_MASK ){
+ char zLock[30];
+ sqlite3_snprintf(sizeof(zLock),zLock,"%d",eLock);
+ tvfsExecTcl(p, "xLock", Tcl_NewStringObj(pFd->zFilename, -1),
+ Tcl_NewStringObj(zLock, -1), 0, 0);
+ }
+ return sqlite3OsLock(pFd->pReal, eLock);
}
/*
static int tvfsUnlock(sqlite3_file *pFile, int eLock){
TestvfsFd *pFd = tvfsGetFd(pFile);
Testvfs *p = (Testvfs *)pFd->pVfs->pAppData;
+ if( p->pScript && p->mask&TESTVFS_UNLOCK_MASK ){
+ char zLock[30];
+ sqlite3_snprintf(sizeof(zLock),zLock,"%d",eLock);
+ tvfsExecTcl(p, "xUnlock", Tcl_NewStringObj(pFd->zFilename, -1),
+ Tcl_NewStringObj(zLock, -1), 0, 0);
+ }
if( p->mask&TESTVFS_WRITE_MASK && tvfsInjectIoerr(p) ){
return SQLITE_IOERR_UNLOCK;
}
** Check if another file-handle holds a RESERVED lock on an tvfs-file.
*/
static int tvfsCheckReservedLock(sqlite3_file *pFile, int *pResOut){
- TestvfsFd *p = tvfsGetFd(pFile);
- return sqlite3OsCheckReservedLock(p->pReal, pResOut);
+ TestvfsFd *pFd = tvfsGetFd(pFile);
+ Testvfs *p = (Testvfs *)pFd->pVfs->pAppData;
+ if( p->pScript && p->mask&TESTVFS_CKLOCK_MASK ){
+ tvfsExecTcl(p, "xCheckReservedLock", Tcl_NewStringObj(pFd->zFilename, -1),
+ 0, 0, 0);
+ }
+ return sqlite3OsCheckReservedLock(pFd->pReal, pResOut);
}
/*
break;
}
+ /* TESTVFS filter METHOD-LIST
+ **
+ ** Activate special processing for those methods contained in the list
+ */
case CMD_FILTER: {
static struct VfsMethod {
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 },
- { "xRead", TESTVFS_READ_MASK },
- { "xTruncate", TESTVFS_TRUNCATE_MASK },
- { "xOpen", TESTVFS_OPEN_MASK },
- { "xClose", TESTVFS_CLOSE_MASK },
- { "xAccess", TESTVFS_ACCESS_MASK },
- { "xFullPathname", TESTVFS_FULLPATHNAME_MASK },
- { "xUnlock", TESTVFS_UNLOCK_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 },
+ { "xRead", TESTVFS_READ_MASK },
+ { "xTruncate", TESTVFS_TRUNCATE_MASK },
+ { "xOpen", TESTVFS_OPEN_MASK },
+ { "xClose", TESTVFS_CLOSE_MASK },
+ { "xAccess", TESTVFS_ACCESS_MASK },
+ { "xFullPathname", TESTVFS_FULLPATHNAME_MASK },
+ { "xUnlock", TESTVFS_UNLOCK_MASK },
+ { "xLock", TESTVFS_LOCK_MASK },
+ { "xCheckReservedLock", TESTVFS_CKLOCK_MASK },
};
Tcl_Obj **apElem = 0;
int nElem = 0;
break;
}
+ /*
+ ** TESTVFS script ?SCRIPT?
+ **
+ ** Query or set the script to be run when filtered VFS events
+ ** occur.
+ */
case CMD_SCRIPT: {
if( objc==3 ){
int nByte;
{ "safe_append", SQLITE_IOCAP_SAFE_APPEND },
{ "undeletable_when_open", SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN },
{ "powersafe_overwrite", SQLITE_IOCAP_POWERSAFE_OVERWRITE },
+ { "immutable", SQLITE_IOCAP_IMMUTABLE },
{ 0, 0 }
};
Tcl_Obj *pRet;
--- /dev/null
+# 2014-05-07
+#
+# 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 implements regression tests for SQLite library. The
+# focus of this file is testing the nolock=1 and immutable=1 query
+# parameters and the SQLITE_IOCAP_IMMUTABLE device characteristic.
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+
+unset -nocomplain tvfs_calls
+proc tvfs_reset {} {
+ global tvfs_calls
+ array set tvfs_calls {xLock 0 xUnlock 0 xCheckReservedLock 0 xAccess 0}
+}
+proc tvfs_callback {op args} {
+ global tvfs_calls
+ incr tvfs_calls($op)
+ return SQLITE_OK
+}
+tvfs_reset
+
+testvfs tvfs
+tvfs script tvfs_callback
+tvfs filter {xLock xUnlock xCheckReservedLock xAccess}
+
+############################################################################
+# Verify that the nolock=1 query parameter for URI filenames disables all
+# calls to xLock and xUnlock for rollback databases.
+#
+do_test nolock-1.0 {
+ db close
+ forcedelete test.db
+ tvfs_reset
+ sqlite db test.db -vfs tvfs
+ db eval {CREATE TABLE t1(a,b,c); INSERT INTO t1 VALUES(1,2,3);}
+ list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \
+ xCheckReservedLock $::tvfs_calls(xCheckReservedLock)
+} {xLock 7 xUnlock 5 xCheckReservedLock 0}
+
+do_test nolock-1.1 {
+ db close
+ forcedelete test.db
+ tvfs_reset
+ sqlite db file:test.db?nolock=0 -vfs tvfs -uri 1
+ db eval {CREATE TABLE t1(a,b,c); INSERT INTO t1 VALUES(1,2,3);}
+ list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \
+ xCheckReservedLock $::tvfs_calls(xCheckReservedLock)
+} {xLock 7 xUnlock 5 xCheckReservedLock 0}
+
+do_test nolock-1.2 {
+ db close
+ forcedelete test.db
+ tvfs_reset
+ sqlite db file:test.db?nolock=1 -vfs tvfs -uri 1
+ db eval {CREATE TABLE t1(a,b,c); INSERT INTO t1 VALUES(1,2,3);}
+ list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \
+ xCheckReservedLock $::tvfs_calls(xCheckReservedLock)
+} {xLock 0 xUnlock 0 xCheckReservedLock 0}
+
+#############################################################################
+# Verify that immutable=1 disables both locking and xAccess calls to the
+# journal files.
+#
+do_test nolock-2.0 {
+ db close
+ forcedelete test.db
+ # begin by creating a test database
+ sqlite3 db test.db
+ db eval {
+ CREATE TABLE t1(a,b);
+ INSERT INTO t1 VALUES('hello','world');
+ CREATE TABLE t2(x,y);
+ INSERT INTO t2 VALUES(12345,67890);
+ SELECT * FROM t1, t2;
+ }
+} {hello world 12345 67890}
+do_test nolock-2.1 {
+ tvfs_reset
+ sqlite3 db2 test.db -vfs tvfs
+ db2 eval {SELECT * FROM t1, t2}
+} {hello world 12345 67890}
+do_test nolock-2.2 {
+ list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \
+ xCheckReservedLock $::tvfs_calls(xCheckReservedLock) \
+ xAccess $::tvfs_calls(xAccess)
+} {xLock 2 xUnlock 2 xCheckReservedLock 0 xAccess 4}
+
+
+do_test nolock-2.11 {
+ db2 close
+ tvfs_reset
+ sqlite3 db2 file:test.db?immutable=0 -vfs tvfs -uri 1
+ db2 eval {SELECT * FROM t1, t2}
+} {hello world 12345 67890}
+do_test nolock-2.12 {
+ list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \
+ xCheckReservedLock $::tvfs_calls(xCheckReservedLock) \
+ xAccess $::tvfs_calls(xAccess)
+} {xLock 2 xUnlock 2 xCheckReservedLock 0 xAccess 4}
+
+
+do_test nolock-2.21 {
+ db2 close
+ tvfs_reset
+ sqlite3 db2 file:test.db?immutable=1 -vfs tvfs -uri 1
+ db2 eval {SELECT * FROM t1, t2}
+} {hello world 12345 67890}
+do_test nolock-2.22 {
+ list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \
+ xCheckReservedLock $::tvfs_calls(xCheckReservedLock) \
+ xAccess $::tvfs_calls(xAccess)
+} {xLock 0 xUnlock 0 xCheckReservedLock 0 xAccess 0}
+
+############################################################################
+# Verify that the SQLITE_IOCAP_IMMUTABLE flag works
+#
+do_test nolock-3.1 {
+ db2 close
+ tvfs devchar immutable
+ tvfs_reset
+ sqlite3 db2 test.db -vfs tvfs
+ db2 eval {SELECT * FROM t1, t2}
+} {hello world 12345 67890}
+do_test nolock-3.2 {
+ list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \
+ xCheckReservedLock $::tvfs_calls(xCheckReservedLock) \
+ xAccess $::tvfs_calls(xAccess)
+} {xLock 0 xUnlock 0 xCheckReservedLock 0 xAccess 0}
+
+db2 close
+db close
+tvfs delete
+finish_test