--- /dev/null
+# 2015 February 16
+#
+# 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.
+#
+#***********************************************************************
+#
+
+if {![info exists testdir]} {
+ set testdir [file join [file dirname [info script]] .. .. test]
+}
+source $testdir/tester.tcl
+set ::testprefix ota11
+
+
+#--------------------------------------------------------------------
+# Test that the xAccess() method of an ota vfs handles queries other
+# than SQLITE_ACCESS_EXISTS correctly. The test code below causes
+# SQLite to call xAccess(SQLITE_ACCESS_READWRITE) on the directory
+# path argument passed to "PRAGMA temp_store_directory".
+#
+do_test 1.1 {
+ sqlite3ota_create_vfs -default ota ""
+ reset_db
+ catchsql { PRAGMA temp_store_directory = '/no/such/directory' }
+} {1 {not a writable directory}}
+
+do_test 1.2 {
+ catchsql " PRAGMA temp_store_directory = '[pwd]' "
+} {0 {}}
+
+do_test 1.3 {
+ catchsql " PRAGMA temp_store_directory = '' "
+} {0 {}}
+
+do_test 1.4 {
+ db close
+ sqlite3ota_destroy_vfs ota
+} {}
+
+#--------------------------------------------------------------------
+# Try to trick ota into operating on a database opened in wal mode.
+#
+reset_db
+do_execsql_test 2.1 {
+ CREATE TABLE t1(a PRIMARY KEY, b, c);
+ INSERT INTO t1 VALUES(1, 2, 3);
+ PRAGMA journal_mode = 'wal';
+ CREATE TABLE t2(d PRIMARY KEY, e, f);
+} {wal}
+
+do_test 2.2 {
+ db_save
+ db close
+
+ forcedelete ota.db
+ sqlite3 dbo ota.db
+ dbo eval {
+ CREATE TABLE data_t1(a, b, c, ota_control);
+ INSERT INTO data_t1 VALUES(4, 5, 6, 0);
+ INSERT INTO data_t1 VALUES(7, 8, 9, 0);
+ }
+ dbo close
+
+ db_restore
+ hexio_write test.db 18 0101
+ file exists test.db-wal
+} {1}
+
+breakpoint
+do_test 2.3 {
+ sqlite3ota ota test.db ota.db
+ ota step
+} {SQLITE_ERROR}
+
+do_test 2.4 {
+ list [catch {ota close} msg] $msg
+} {1 {SQLITE_ERROR - cannot update wal mode database}}
+
+finish_test
+
i64 iWalCksum;
int nRow;
i64 nProgress;
+ u32 iCookie;
};
/*
};
-static void otaCreateVfs(sqlite3ota*, const char*);
-static void otaDeleteVfs(sqlite3ota*);
-
/*
** Prepare the SQL statement in buffer zSql against database handle db.
** If successful, set *ppStmt to point to the new statement and return
break;
case OTA_STATE_COOKIE:
- /* At this point (p->iCookie) contains the value of the change-counter
- ** cookie (the thing that gets incremented when a transaction is
- ** committed in rollback mode) currently stored on page 1 of the
- ** database file. */
- if( pRet->eStage==OTA_STAGE_OAL
- && p->pTargetFd->iCookie!=(u32)sqlite3_column_int64(pStmt, 1)
- ){
- rc = SQLITE_BUSY;
- p->zErrmsg = sqlite3_mprintf("database modified during ota update");
- }
+ pRet->iCookie = (u32)sqlite3_column_int64(pStmt, 1);
break;
default:
sqlite3_free(zOal);
}
+static void otaCreateVfs(sqlite3ota *p){
+ int rnd;
+ char zRnd[64];
+
+ assert( p->rc==SQLITE_OK );
+ sqlite3_randomness(sizeof(int), (void*)&rnd);
+ sprintf(zRnd, "ota_vfs_%d", rnd);
+ p->rc = sqlite3ota_create_vfs(zRnd, 0);
+ if( p->rc==SQLITE_OK ){
+ sqlite3_vfs *pVfs = sqlite3_vfs_find(zRnd);
+ assert( pVfs );
+ p->zVfsName = pVfs->zName;
+ }
+}
+
+static void otaDeleteVfs(sqlite3ota *p){
+ if( p->zVfsName ){
+ sqlite3ota_destroy_vfs(p->zVfsName);
+ p->zVfsName = 0;
+ }
+}
+
/*
** Open and return a new OTA handle.
*/
/* Create the custom VFS. */
memset(p, 0, sizeof(sqlite3ota));
- otaCreateVfs(p, 0);
+ otaCreateVfs(p);
/* Open the target database */
if( p->rc==SQLITE_OK ){
** function, on the off chance that the target is a wal database for
** which the first page of the db file has been overwritten by garbage
** during an earlier failed checkpoint. */
+#if 0
if( p->rc==SQLITE_OK && p->pTargetFd->iWriteVer>1 ){
p->rc = SQLITE_ERROR;
p->zErrmsg = sqlite3_mprintf("cannot update wal mode database");
}
+#endif
if( p->rc==SQLITE_OK ){
pState = otaLoadState(p);
assert( pState || p->rc!=SQLITE_OK );
if( p->rc==SQLITE_OK ){
+
if( pState->eStage==0 ){
otaDeleteOalFile(p);
p->eStage = OTA_STAGE_OAL;
if( p->rc==SQLITE_OK ){
if( p->eStage==OTA_STAGE_OAL ){
+ if( p->pTargetFd->pWalFd ){
+ p->rc = SQLITE_ERROR;
+ p->zErrmsg = sqlite3_mprintf("cannot update wal mode database");
+ }
+
+ /* At this point (pTargetFd->iCookie) contains the value of the
+ ** change-counter cookie (the thing that gets incremented when a
+ ** transaction is committed in rollback mode) currently stored on
+ ** page 1 of the database file. */
+ else if( pState->eStage==OTA_STAGE_OAL
+ && p->pTargetFd->iCookie!=pState->iCookie
+ ){
+ p->rc = SQLITE_BUSY;
+ p->zErrmsg = sqlite3_mprintf("database modified during ota update");
+ }
/* Open the transaction */
if( p->rc==SQLITE_OK ){
for(pp=&p->pOtaVfs->pMain; *pp!=p; pp=&((*pp)->pMainNext));
*pp = p->pMainNext;
sqlite3_mutex_leave(p->pOtaVfs->mutex);
+ p->pReal->pMethods->xShmUnmap(p->pReal, 0);
}
/* Close the underlying file handle */
void sqlite3ota_destroy_vfs(const char *zName){
sqlite3_vfs *pVfs = sqlite3_vfs_find(zName);
- if( pVfs ){
+ if( pVfs && pVfs->xOpen==otaVfsOpen ){
sqlite3_vfs_unregister(pVfs);
sqlite3_free(pVfs);
}
0, 0, 0 /* Unimplemented version 3 methods */
};
- sqlite3_vfs *pParent; /* Parent VFS */
ota_vfs *pNew = 0; /* Newly allocated VFS */
int nName;
int rc = SQLITE_OK;
+ int nByte;
nName = strlen(zName);
- pParent = sqlite3_vfs_find(zParent);
- if( pParent==0 ){
- rc = SQLITE_NOTFOUND;
+ nByte = sizeof(ota_vfs) + nName + 1;
+ pNew = (ota_vfs*)sqlite3_malloc(nByte);
+ if( pNew==0 ){
+ rc = SQLITE_NOMEM;
}else{
- int nByte = sizeof(ota_vfs) + nName + 1;
- pNew = (ota_vfs*)sqlite3_malloc(nByte);
- if( pNew==0 ){
- rc = SQLITE_NOMEM;
+ sqlite3_vfs *pParent; /* Parent VFS */
+ memset(pNew, 0, nByte);
+ pParent = sqlite3_vfs_find(zParent);
+ if( pParent==0 ){
+ rc = SQLITE_NOTFOUND;
}else{
- memset(pNew, 0, nByte);
- }
- }
-
- if( rc==SQLITE_OK ){
- char *zSpace;
- memcpy(&pNew->base, &vfs_template, sizeof(sqlite3_vfs));
- pNew->base.mxPathname = pParent->mxPathname;
- pNew->base.szOsFile = sizeof(ota_file) + pParent->szOsFile;
- pNew->pRealVfs = pParent;
+ char *zSpace;
+ memcpy(&pNew->base, &vfs_template, sizeof(sqlite3_vfs));
+ pNew->base.mxPathname = pParent->mxPathname;
+ pNew->base.szOsFile = sizeof(ota_file) + pParent->szOsFile;
+ pNew->pRealVfs = pParent;
- pNew->base.zName = (const char*)(zSpace = (char*)&pNew[1]);
- memcpy(zSpace, zName, nName);
+ pNew->base.zName = (const char*)(zSpace = (char*)&pNew[1]);
+ memcpy(zSpace, zName, nName);
- /* Register the new VFS (not as the default) */
- rc = sqlite3_vfs_register(&pNew->base, 0);
- if( rc ){
- sqlite3_free(pNew);
+ /* Register the new VFS (not as the default) */
+ rc = sqlite3_vfs_register(&pNew->base, 0);
}
}
- return rc;
-}
-
-static void otaCreateVfs(sqlite3ota *p, const char *zParent){
- int rnd;
- char zRnd[64];
-
- assert( p->rc==SQLITE_OK );
- sqlite3_randomness(sizeof(int), (void*)&rnd);
- sprintf(zRnd, "ota_vfs_%d", rnd);
- p->rc = sqlite3ota_create_vfs(zRnd, zParent);
- if( p->rc==SQLITE_NOTFOUND ){
- p->zErrmsg = sqlite3_mprintf("no such vfs: %s", zParent);
- }else if( p->rc==SQLITE_OK ){
- sqlite3_vfs *pVfs = sqlite3_vfs_find(zRnd);
- assert( pVfs );
- p->zVfsName = pVfs->zName;
- }
-}
-
-static void otaDeleteVfs(sqlite3ota *p){
- if( p->zVfsName ){
- sqlite3ota_destroy_vfs(p->zVfsName);
- p->zVfsName = 0;
+ if( rc!=SQLITE_OK ){
+ sqlite3_free(pNew);
}
+ return rc;
}
-C Move\stcl\stest\scode\sfrom\ssqlite3ota.c\sto\snew\sfile\sext/ota/test_ota.c.
-D 2015-02-16T06:27:37.241
+C Add\sfurther\stests\sand\sfixes\sfor\sota.
+D 2015-02-16T11:48:34.819
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 6b9e7677829aa94b9f30949656e27312aefb9a46
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F ext/ota/ota.c c11a85af71dccc45976622fe7a51169a481caa91
F ext/ota/ota1.test dee5b852353642a243e0bf414d332b1bccd5324f
F ext/ota/ota10.test 85e0f6e7964db5007590c1b299e75211ed4240d4
-F ext/ota/ota3.test a77efbce7723332eb688d2b28bf18204fc9614d7
+F ext/ota/ota11.test 44e9ebdc1d9c23214c739f122f2b36e169e515aa
+F ext/ota/ota3.test cd654ef16fc6b3d3596894ee3f3b8fd821b969f5
F ext/ota/ota5.test ad0799daf8923ddebffe75ae8c5504ca90b7fadb
F ext/ota/ota6.test 40996b7716dee72a6c5d28c3bee436717a438d3d
F ext/ota/ota7.test 1fe2c5761705374530e29f70c39693076028221a
F ext/ota/ota8.test cd70e63a0c29c45c0906692827deafa34638feda
F ext/ota/ota9.test d3eee95dd836824d07a22e5efcdb7bf6e869358b
-F ext/ota/otaA.test 95566a8d193113867b960eadf85b310937f2fe03
+F ext/ota/otaA.test ef4bfa8cfd4ed814ae86f7457b64aa2f18c90171
F ext/ota/otafault.test 508ba87c83d632670ac0f94371a465d4bb4d49dd
-F ext/ota/sqlite3ota.c 79874bc6f31a514aebd17ab24d31e7c567e6225e
+F ext/ota/sqlite3ota.c f2ea3fe9d7fceec5efc1ad62b8bf07ec607f99c5
F ext/ota/sqlite3ota.h 1cc7201086fe65a36957740381485a24738c4077
F ext/ota/test_ota.c 5dd58e4e6eb3ae7b471566616d44b701971bce88
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P b64a11a754dc56f3406d3b703531ebe9e4af4908
-R 8813c4f37af98778b18f1d2e1e748912
+P f20779a6e890ba73bfaa904cefcf3a029b01fed4
+R d9098c0831f1564055344cfb128a3e0f
U dan
-Z ac67e9a36714c8c694cc168f5b99c0ce
+Z f0ac85428b81638540d3d3b58c8f458b