Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Only open a db in server-mode if there is a directory named "db-journal" in the file-system and the VFS is an exclusive locking VFS. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | server-process-edition |
Files: | files | file ages | folders |
SHA3-256: |
e77d29f64480179d7aae7d88adab2ba9 |
User & Date: | dan 2017-07-24 19:23:20.202 |
Context
2017-07-24
| ||
19:43 | Update this branch with latest changes from trunk. (check-in: d0719ad757 user: dan tags: server-process-edition) | |
19:23 | Only open a db in server-mode if there is a directory named "db-journal" in the file-system and the VFS is an exclusive locking VFS. (check-in: e77d29f644 user: dan tags: server-process-edition) | |
2017-07-19
| ||
18:54 | Merge latest trunk changes with this branch. (check-in: be0df0a65f user: dan tags: server-process-edition) | |
Changes
Changes to src/os_unix.c.
︙ | ︙ | |||
3773 3774 3775 3776 3777 3778 3779 3780 | /* ** Information and control of an open file handle. */ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ unixFile *pFile = (unixFile*)id; switch( op ){ case SQLITE_FCNTL_FILEID: { | > > > > > > > > > > > > > > > > > > > > | | 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 | /* ** Information and control of an open file handle. */ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ unixFile *pFile = (unixFile*)id; switch( op ){ case SQLITE_FCNTL_SERVER_MODE: { int rc = SQLITE_OK; int eServer = 0; if( pFile->ctrlFlags | UNIXFILE_EXCL ){ char *zJrnl = sqlite3_mprintf("%s-journal", pFile->zPath); if( zJrnl==0 ){ rc = SQLITE_NOMEM; }else{ struct stat buf; /* Used to hold return values of stat() */ if( osStat(zJrnl, &buf) ){ rc = SQLITE_IOERR_FSTAT; }else{ eServer = ((buf.st_mode & S_IFDIR) ? 1 : 0); } } sqlite3_free(zJrnl); } *((int*)pArg) = eServer; return rc; } case SQLITE_FCNTL_FILEID: { i64 *aId = (i64*)pArg; aId[0] = (i64)(pFile->pInode->fileId.dev); aId[1] = (i64)(pFile->pInode->fileId.ino); return SQLITE_OK; } case SQLITE_FCNTL_LOCKSTATE: { *(int*)pArg = pFile->eFileLock; return SQLITE_OK; |
︙ | ︙ | |||
5626 5627 5628 5629 5630 5631 5632 5633 5634 5635 5636 5637 5638 5639 | #endif nDb--; } memcpy(zDb, zPath, nDb); zDb[nDb] = '\0'; rc = getFileMode(zDb, pMode, pUid, pGid); }else if( flags & SQLITE_OPEN_DELETEONCLOSE ){ *pMode = 0600; }else if( flags & SQLITE_OPEN_URI ){ /* If this is a main database file and the file was opened using a URI ** filename, check for the "modeof" parameter. If present, interpret ** its value as a filename and try to copy the mode, uid and gid from ** that file. */ | > > > > > > > > > | 5646 5647 5648 5649 5650 5651 5652 5653 5654 5655 5656 5657 5658 5659 5660 5661 5662 5663 5664 5665 5666 5667 5668 | #endif nDb--; } memcpy(zDb, zPath, nDb); zDb[nDb] = '\0'; rc = getFileMode(zDb, pMode, pUid, pGid); #ifdef SQLITE_SERVER_EDITION if( rc==SQLITE_IOERR_FSTAT ){ while( nDb && zDb[nDb]!='/' ) nDb--; if( nDb>8 && memcmp("-journal/", &zDb[nDb-8], 9)==0 ){ zDb[nDb-8] = '\0'; rc = getFileMode(zDb, pMode, pUid, pGid); } } #endif }else if( flags & SQLITE_OPEN_DELETEONCLOSE ){ *pMode = 0600; }else if( flags & SQLITE_OPEN_URI ){ /* If this is a main database file and the file was opened using a URI ** filename, check for the "modeof" parameter. If present, interpret ** its value as a filename and try to copy the mode, uid and gid from ** that file. */ |
︙ | ︙ |
Changes to src/pager.c.
︙ | ︙ | |||
5062 5063 5064 5065 5066 5067 5068 | ** ** If a hot-journal file is found to exist, *pExists is set to 1 and ** SQLITE_OK returned. If no hot-journal file is present, *pExists is ** set to 0 and SQLITE_OK returned. If an IO error occurs while trying ** to determine whether or not a hot-journal file exists, the IO error ** code is returned and the value of *pExists is undefined. */ | | > > > > > > > | 5062 5063 5064 5065 5066 5067 5068 5069 5070 5071 5072 5073 5074 5075 5076 5077 5078 5079 5080 5081 5082 5083 5084 5085 5086 5087 5088 5089 5090 5091 5092 5093 5094 5095 5096 5097 5098 5099 5100 5101 5102 | ** ** If a hot-journal file is found to exist, *pExists is set to 1 and ** SQLITE_OK returned. If no hot-journal file is present, *pExists is ** set to 0 and SQLITE_OK returned. If an IO error occurs while trying ** to determine whether or not a hot-journal file exists, the IO error ** code is returned and the value of *pExists is undefined. */ static int hasHotJournal(Pager *pPager, int *pExists, int *peServer){ sqlite3_vfs * const pVfs = pPager->pVfs; int rc = SQLITE_OK; /* Return code */ int exists = 1; /* True if a journal file is present */ int jrnlOpen = !!isOpen(pPager->jfd); assert( pPager->useJournal ); assert( isOpen(pPager->fd) ); assert( pPager->eState==PAGER_OPEN ); assert( jrnlOpen==0 || ( sqlite3OsDeviceCharacteristics(pPager->jfd) & SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN )); *pExists = 0; if( !jrnlOpen ){ rc = sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS, &exists); } if( rc==SQLITE_OK && exists ){ int locked = 0; /* True if some process holds a RESERVED lock */ #ifdef SQLITE_SERVER_EDITION rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SERVER_MODE, peServer); if( rc!=SQLITE_NOTFOUND ){ if( rc!=SQLITE_OK || *peServer ) return rc; } #endif /* Race condition here: Another process might have been holding the ** the RESERVED lock and have a journal open at the sqlite3OsAccess() ** call above, but then delete the journal and drop the lock before ** we get to the following sqlite3OsCheckReservedLock() call. If that ** is the case, this routine might think there is a hot journal when ** in fact there is none. This results in a false-positive which will |
︙ | ︙ | |||
5196 5197 5198 5199 5200 5201 5202 | } void sqlite3PagerServerJournal( Pager *pPager, sqlite3_file *jfd, const char *zJournal ){ | | < < < | 5203 5204 5205 5206 5207 5208 5209 5210 5211 5212 5213 5214 5215 5216 5217 5218 5219 | } void sqlite3PagerServerJournal( Pager *pPager, sqlite3_file *jfd, const char *zJournal ){ pPager->zJournal = (char*)zJournal; pPager->jfd = jfd; } #endif /* ** This function is called to obtain a shared lock on the database file. ** It is illegal to call sqlite3PagerGet() until after this function ** has been successfully called. If a shared-lock is already held when |
︙ | ︙ | |||
5234 5235 5236 5237 5238 5239 5240 5241 5242 5243 5244 5245 5246 5247 | ** ** If everything is successful, SQLITE_OK is returned. If an IO error ** occurs while locking the database, checking for a hot-journal file or ** rolling back a journal file, the IO error code is returned. */ int sqlite3PagerSharedLock(Pager *pPager, int bReadonly){ int rc = SQLITE_OK; /* Return code */ /* This routine is only called from b-tree and only when there are no ** outstanding pages. This implies that the pager state should either ** be OPEN or READER. READER is only possible if the pager is or was in ** exclusive access mode. */ assert( sqlite3PcacheRefCount(pPager->pPCache)==0 ); assert( assert_pager_state(pPager) ); | > > > | 5238 5239 5240 5241 5242 5243 5244 5245 5246 5247 5248 5249 5250 5251 5252 5253 5254 | ** ** If everything is successful, SQLITE_OK is returned. If an IO error ** occurs while locking the database, checking for a hot-journal file or ** rolling back a journal file, the IO error code is returned. */ int sqlite3PagerSharedLock(Pager *pPager, int bReadonly){ int rc = SQLITE_OK; /* Return code */ #ifdef SQLITE_SERVER_EDITION int eServer = 0; #endif /* This routine is only called from b-tree and only when there are no ** outstanding pages. This implies that the pager state should either ** be OPEN or READER. READER is only possible if the pager is or was in ** exclusive access mode. */ assert( sqlite3PcacheRefCount(pPager->pPCache)==0 ); assert( assert_pager_state(pPager) ); |
︙ | ︙ | |||
5262 5263 5264 5265 5266 5267 5268 | goto failed; } /* If a journal file exists, and there is no RESERVED lock on the ** database file, then it either needs to be played back or deleted. */ if( pPager->eLock<=SHARED_LOCK ){ | | > | 5269 5270 5271 5272 5273 5274 5275 5276 5277 5278 5279 5280 5281 5282 5283 5284 | goto failed; } /* If a journal file exists, and there is no RESERVED lock on the ** database file, then it either needs to be played back or deleted. */ if( pPager->eLock<=SHARED_LOCK ){ rc = hasHotJournal(pPager, &bHotJournal, &eServer); assert( bHotJournal==0 || eServer==0 ); } if( rc!=SQLITE_OK ){ goto failed; } if( bHotJournal ){ if( pPager->readOnly ){ rc = SQLITE_READONLY_ROLLBACK; |
︙ | ︙ | |||
5395 5396 5397 5398 5399 5400 5401 5402 5403 5404 5405 5406 5407 5408 5409 5410 5411 5412 5413 5414 5415 5416 5417 5418 5419 | IOTRACE(("CKVERS %p %d\n", pPager, sizeof(dbFileVers))); rc = sqlite3OsRead(pPager->fd, &dbFileVers, sizeof(dbFileVers), 24); if( rc!=SQLITE_OK ){ if( rc!=SQLITE_IOERR_SHORT_READ ){ goto failed; } memset(dbFileVers, 0, sizeof(dbFileVers)); } if( memcmp(pPager->dbFileVers, dbFileVers, sizeof(dbFileVers))!=0 ){ pager_reset(pPager); /* Unmap the database file. It is possible that external processes ** may have truncated the database file and then extended it back ** to its original size while this process was not holding a lock. ** In this case there may exist a Pager.pMap mapping that appears ** to be the right size but is not actually valid. Avoid this ** possibility by unmapping the db here. */ if( USEFETCH(pPager) ){ sqlite3OsUnfetch(pPager->fd, 0, 0); } } } | > > > | > > > | 5403 5404 5405 5406 5407 5408 5409 5410 5411 5412 5413 5414 5415 5416 5417 5418 5419 5420 5421 5422 5423 5424 5425 5426 5427 5428 5429 5430 5431 5432 5433 5434 5435 5436 5437 5438 5439 5440 5441 5442 5443 5444 5445 5446 5447 5448 5449 5450 5451 5452 5453 5454 5455 5456 5457 | IOTRACE(("CKVERS %p %d\n", pPager, sizeof(dbFileVers))); rc = sqlite3OsRead(pPager->fd, &dbFileVers, sizeof(dbFileVers), 24); if( rc!=SQLITE_OK ){ if( rc!=SQLITE_IOERR_SHORT_READ ){ goto failed; } rc = SQLITE_OK; memset(dbFileVers, 0, sizeof(dbFileVers)); } if( memcmp(pPager->dbFileVers, dbFileVers, sizeof(dbFileVers))!=0 ){ pager_reset(pPager); /* Unmap the database file. It is possible that external processes ** may have truncated the database file and then extended it back ** to its original size while this process was not holding a lock. ** In this case there may exist a Pager.pMap mapping that appears ** to be the right size but is not actually valid. Avoid this ** possibility by unmapping the db here. */ if( USEFETCH(pPager) ){ sqlite3OsUnfetch(pPager->fd, 0, 0); } } } #ifdef SQLITE_SERVER_EDITION if( eServer ){ rc = pagerServerConnect(pPager); } #endif /* If there is a WAL file in the file-system, open this database in WAL ** mode. Otherwise, the following function call is a no-op. */ if( rc==SQLITE_OK ){ rc = pagerOpenWalIfPresent(pPager); } #ifndef SQLITE_OMIT_WAL assert( pPager->pWal==0 || rc==SQLITE_OK ); #endif } #ifdef SQLITE_SERVER_EDITION if( pagerIsServer(pPager) ){ assert( rc==SQLITE_OK ); assert( sqlite3PagerRefcount(pPager)==0 ); assert( pagerUseWal(pPager)==0 ); pager_reset(pPager); rc = sqlite3ServerBegin(pPager->pServer, bReadonly); if( rc==SQLITE_OK ){ rc = sqlite3ServerLock(pPager->pServer, 1, 0, 0); } } #endif |
︙ | ︙ | |||
7730 7731 7732 7733 7734 7735 7736 7737 7738 7739 7740 7741 | #endif #ifdef SQLITE_SERVER_EDITION int sqlite3PagerIsServer(Pager *pPager){ return pagerIsServer(pPager); } int sqlite3PagerPagelock(Pager *pPager, Pgno pgno, int bWrite){ return sqlite3ServerLock(pPager->pServer, pgno, bWrite, 0); } #endif #endif /* SQLITE_OMIT_DISKIO */ | > | 7744 7745 7746 7747 7748 7749 7750 7751 7752 7753 7754 7755 7756 | #endif #ifdef SQLITE_SERVER_EDITION int sqlite3PagerIsServer(Pager *pPager){ return pagerIsServer(pPager); } int sqlite3PagerPagelock(Pager *pPager, Pgno pgno, int bWrite){ if( pagerIsServer(pPager)==0 ) return SQLITE_OK; return sqlite3ServerLock(pPager->pServer, pgno, bWrite, 0); } #endif #endif /* SQLITE_OMIT_DISKIO */ |
Changes to src/server.c.
︙ | ︙ | |||
243 244 245 246 247 248 249 | }else{ u8 *a = pDb->aJrnlFdSpace; int i; for(i=0; rc==SQLITE_OK && i<HMA_MAX_TRANSACTIONID; i++){ int bExists = 0; ServerJournal *pJ = &pDb->aJrnl[i]; pJ->jfd = (sqlite3_file*)&a[ROUND8(pVfs->szOsFile)*i]; | | | 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 | }else{ u8 *a = pDb->aJrnlFdSpace; int i; for(i=0; rc==SQLITE_OK && i<HMA_MAX_TRANSACTIONID; i++){ int bExists = 0; ServerJournal *pJ = &pDb->aJrnl[i]; pJ->jfd = (sqlite3_file*)&a[ROUND8(pVfs->szOsFile)*i]; pJ->zJournal = sqlite3_mprintf("%s-journal/%d-journal", zFilename, i); if( pJ->zJournal==0 ){ rc = SQLITE_NOMEM_BKPT; break; } rc = sqlite3OsAccess(pVfs, pJ->zJournal, SQLITE_ACCESS_EXISTS, &bExists); if( rc==SQLITE_OK && bExists ){ |
︙ | ︙ |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 | #define SQLITE_FCNTL_ZIPVFS 25 #define SQLITE_FCNTL_RBU 26 #define SQLITE_FCNTL_VFS_POINTER 27 #define SQLITE_FCNTL_JOURNAL_POINTER 28 #define SQLITE_FCNTL_WIN32_GET_HANDLE 29 #define SQLITE_FCNTL_PDB 30 #define SQLITE_FCNTL_FILEID 31 /* deprecated names */ #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE #define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE #define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO | > | 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 | #define SQLITE_FCNTL_ZIPVFS 25 #define SQLITE_FCNTL_RBU 26 #define SQLITE_FCNTL_VFS_POINTER 27 #define SQLITE_FCNTL_JOURNAL_POINTER 28 #define SQLITE_FCNTL_WIN32_GET_HANDLE 29 #define SQLITE_FCNTL_PDB 30 #define SQLITE_FCNTL_FILEID 31 #define SQLITE_FCNTL_SERVER_MODE 32 /* deprecated names */ #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE #define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE #define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO |
︙ | ︙ |
Changes to src/test_config.c.
︙ | ︙ | |||
721 722 723 724 725 726 727 728 729 730 731 732 733 734 | #endif #ifdef SQLITE_ENABLE_URI_00_ERROR Tcl_SetVar2(interp, "sqlite_options", "uri_00_error", "1", TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp, "sqlite_options", "uri_00_error", "0", TCL_GLOBAL_ONLY); #endif #define LINKVAR(x) { \ static const int cv_ ## x = SQLITE_ ## x; \ Tcl_LinkVar(interp, "SQLITE_" #x, (char *)&(cv_ ## x), \ TCL_LINK_INT | TCL_LINK_READ_ONLY); } LINKVAR( MAX_LENGTH ); | > > > > > > | 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 | #endif #ifdef SQLITE_ENABLE_URI_00_ERROR Tcl_SetVar2(interp, "sqlite_options", "uri_00_error", "1", TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp, "sqlite_options", "uri_00_error", "0", TCL_GLOBAL_ONLY); #endif #ifdef SQLITE_SERVER_EDITION Tcl_SetVar2(interp, "sqlite_options", "server", "1", TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp, "sqlite_options", "server", "0", TCL_GLOBAL_ONLY); #endif #define LINKVAR(x) { \ static const int cv_ ## x = SQLITE_ ## x; \ Tcl_LinkVar(interp, "SQLITE_" #x, (char *)&(cv_ ## x), \ TCL_LINK_INT | TCL_LINK_READ_ONLY); } LINKVAR( MAX_LENGTH ); |
︙ | ︙ |
Changes to test/permutations.test.
︙ | ︙ | |||
274 275 276 277 278 279 280 | All FTS5 tests. } -files [glob -nocomplain $::testdir/../ext/fts5/test/*.test] test_suite "server" -prefix "" -description { All server-edition tests. } -files [ test_set \ | | | 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 | All FTS5 tests. } -files [glob -nocomplain $::testdir/../ext/fts5/test/*.test] test_suite "server" -prefix "" -description { All server-edition tests. } -files [ test_set \ select1.test server2.test server3.test server4.test server5.test ] test_suite "fts5-light" -prefix "" -description { All FTS5 tests. } -files [ test_set \ [glob -nocomplain $::testdir/../ext/fts5/test/*.test] \ |
︙ | ︙ |
Changes to test/server2.test.
︙ | ︙ | |||
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix server2 db close foreach f [glob -nocomplain test.db*] { forcedelete $f } #------------------------------------------------------------------------- # Check that the *-journal* files are deleted correctly. # | > > > | | | | | | | | | | | | | | | | | | | | | | | | < | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix server2 source $testdir/server_common.tcl return_if_no_server db close foreach f [glob -nocomplain test.db*] { forcedelete $f } #------------------------------------------------------------------------- # Check that the *-journal* files are deleted correctly. # server_reset_db do_execsql_test 1.0 { CREATE TABLE t1(a, b); } {} do_test 1.1 { lsort [glob -nocomplain test.db-journal/*] } {test.db-journal/0-journal} do_test 1.2 { db close lsort [glob -nocomplain test.db-journal/*] } {} server_sqlite3 db test.db do_execsql_test 1.3 { CREATE TABLE t2(a, b); } {} server_sqlite3 db2 test.db do_test 1.4 { db eval { BEGIN; INSERT INTO t1 VALUES(1, 2); } db2 eval { BEGIN; INSERT INTO t2 VALUES(3, 4); } } {} do_test 1.5 { db2 eval COMMIT db eval COMMIT lsort [glob -nocomplain test.db-journal/*] } {test.db-journal/0-journal test.db-journal/1-journal} do_test 1.6 { db close lsort [glob -nocomplain test.db-journal/*] } {test.db-journal/0-journal test.db-journal/1-journal} do_test 1.7 { db2 close lsort [glob -nocomplain test.db-journal/*] } {} #------------------------------------------------------------------------- # server_reset_db server_sqlite3 db2 test.db do_execsql_test 2.0 { CREATE TABLE t1(a, b); CREATE TABLE t2(c, d); } # Two concurrent transactions committed. # do_test 2.1 { db eval { BEGIN; INSERT INTO t1 VALUES(1, 2); } db2 eval { BEGIN; INSERT INTO t2 VALUES(3, 4); } } {} do_test 2.2 { lsort [glob -nocomplain test.db-journal/*] } {test.db-journal/0-journal test.db-journal/1-journal} do_test 2.3.1 { db eval COMMIT } {} do_test 2.3.2 { db2 eval COMMIT } {} do_execsql_test 2.4 {SELECT * FROM t1, t2} {1 2 3 4} do_test 2.5 { lsort [glob -nocomplain test.db-journal/*] } {test.db-journal/0-journal test.db-journal/1-journal} do_test 2.6 { execsql {BEGIN} execsql {INSERT INTO t1 VALUES(5, 6)} execsql {BEGIN} db2 catchsql {INSERT INTO t1 VALUES(7, 8)} db2 } {1 {database is locked}} do_test 2.7 { # Transaction is automatically rolled back in this case. sqlite3_get_autocommit db2 } {1} do_test 2.8 { execsql COMMIT execsql { SELECT * FROM t1 } db2 } {1 2 5 6} db2 close #------------------------------------------------------------------------- # server_reset_db do_execsql_test 3.0 { CREATE TABLE t1(a, b); } do_test 3.1 { lsort [glob -nocomplain test.db-journal/*] } {test.db-journal/0-journal} do_test 3.2 { db close lsort [glob -nocomplain test.db-journal/*] } {} finish_test |
Changes to test/server3.test.
︙ | ︙ | |||
14 15 16 17 18 19 20 | set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/lock_common.tcl set testprefix server3 | > | > | < | | | | | | | | | | | > | | | | | | > > > | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/lock_common.tcl set testprefix server3 source $testdir/server_common.tcl return_if_no_server server_reset_db server_sqlite3 db2 test.db do_test 1.1 { db eval { CREATE TABLE t1(a, b) } db2 eval { CREATE TABLE t2(a, b) } } {} do_test 1.2 { db eval { INSERT INTO t2 VALUES(1, 2); BEGIN; INSERT INTO t1 VALUES(1, 2); } } {} do_test 1.3 { list [catch { db2 eval { SELECT * FROM t1 } } msg] $msg } {1 {database is locked}} do_test 1.4 { list [catch { db2 eval { SELECT * FROM t1 } } msg] $msg } {1 {database is locked}} do_test 1.4 { db2 eval { SELECT * FROM t2 } } {1 2} finish_test |
Changes to test/server4.test.
︙ | ︙ | |||
15 16 17 18 19 20 21 | # transaction. # set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/lock_common.tcl | | > > > > | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | # transaction. # set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/lock_common.tcl set testprefix server4 source $testdir/server_common.tcl return_if_no_server server_reset_db server_sqlite3 db2 test.db do_execsql_test 1.0 { CREATE TABLE t1(x); INSERT INTO t1 VALUES(1); CREATE TABLE t2(x); INSERT INTO t2 VALUES(1); BEGIN; |
︙ | ︙ | |||
52 53 54 55 56 57 58 | SELECT * FROM t2; } {1} do_execsql_test -db db2 1.4 { ROLLBACK; SELECT * FROM t1; } {1 2 3} | < | 56 57 58 59 60 61 62 63 64 65 | SELECT * FROM t2; } {1} do_execsql_test -db db2 1.4 { ROLLBACK; SELECT * FROM t1; } {1 2 3} finish_test |
Changes to test/server5.test.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 2017 July 09 # # 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 script is testing the server mode of SQLite. | | < < < < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | # 2017 July 09 # # 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 script is testing the server mode of SQLite. # Specifically, that "PRAGMA freelist_format" works. # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix server5 do_execsql_test 1.0 { PRAGMA freelist_format; } {1} do_execsql_test 1.1 { PRAGMA freelist_format = 2; } {2} do_execsql_test 1.2 { PRAGMA freelist_format; } {2} |
︙ | ︙ | |||
52 53 54 55 56 57 58 | do_execsql_test 1.6 { CREATE TABLE t2(y); } do_execsql_test 1.6 { PRAGMA freelist_format = 1; } {2} | < < | 47 48 49 50 51 52 53 54 55 56 | do_execsql_test 1.6 { CREATE TABLE t2(y); } do_execsql_test 1.6 { PRAGMA freelist_format = 1; } {2} finish_test |
Added test/server_common.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | # 2017 July 25 # # 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. # #*********************************************************************** # # ifcapable !server { proc return_if_no_server {} { finish_test return -code return } return } else { proc return_if_no_server {} {} } proc server_sqlite3 {cmd file} { sqlite3 $cmd $file -vfs unix-excl } proc server_reset_db {} { catch {db close} forcedelete test.db test.db-journal test.db-wal file mkdir test.db-journal server_sqlite3 db test.db } |
Deleted test/serverwal.test.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |