Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Defer opening a bt database until it is first read. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
d9560b73de51f4f4c085659af2c0e18d |
User & Date: | dan 2014-02-15 20:29:44.221 |
Context
2014-02-17
| ||
09:26 | Have the bt backend support "PRAGMA page_size". check-in: 5aca057cad user: dan tags: trunk | |
2014-02-15
| ||
20:29 | Defer opening a bt database until it is first read. check-in: d9560b73de user: dan tags: trunk | |
17:04 | Add some human readable text to the bt file header. Refuse to open a database (SQLITE_NOTADB) if a valid header cannot be located in the database or wal files. check-in: b942b91a3d user: dan tags: trunk | |
Changes
Changes to src/kvbt.c.
︙ | ︙ | |||
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 | typedef struct KVBtCsr KVBtCsr; /* ** An instance of an open connection to a bt_db store. A subclass of KVStore. */ struct KVBt { KVStore base; /* Base class, must be first */ bt_db *pDb; /* Database handle */ }; /* ** An instance of an open cursor pointing into an LSM store. A subclass ** of KVCursor. */ struct KVBtCsr { KVCursor base; /* Base class. Must be first */ bt_cursor *pCsr; /* LSM cursor handle */ }; /* ** Begin a transaction or subtransaction. */ static int btBegin(KVStore *pKVStore, int iLevel){ KVBt *p = (KVBt *)pKVStore; int rc; rc = sqlite4BtBegin(p->pDb, iLevel); pKVStore->iTransLevel = sqlite4BtTransactionLevel(p->pDb); return rc; } /* ** Commit a transaction or subtransaction. */ static int btCommitPhaseOne(KVStore *pKVStore, int iLevel){ return SQLITE4_OK; } static int btCommitPhaseTwo(KVStore *pKVStore, int iLevel){ KVBt *p = (KVBt *)pKVStore; int rc; rc = sqlite4BtCommit(p->pDb, iLevel); pKVStore->iTransLevel = sqlite4BtTransactionLevel(p->pDb); return rc; } /* ** Rollback a transaction or subtransaction. */ static int btRollback(KVStore *pKVStore, int iLevel){ KVBt *p = (KVBt *)pKVStore; | > > > > > > > > > > > > | > | | > | 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 | typedef struct KVBtCsr KVBtCsr; /* ** An instance of an open connection to a bt_db store. A subclass of KVStore. */ struct KVBt { KVStore base; /* Base class, must be first */ const char *zFilename; /* File to open */ int bOpen; /* See above */ int openrc; /* See above */ bt_db *pDb; /* Database handle */ }; /* ** An instance of an open cursor pointing into an LSM store. A subclass ** of KVCursor. */ struct KVBtCsr { KVCursor base; /* Base class. Must be first */ bt_cursor *pCsr; /* LSM cursor handle */ }; /* ** Begin a transaction or subtransaction. */ static int btBegin(KVStore *pKVStore, int iLevel){ KVBt *p = (KVBt *)pKVStore; int rc; if( p->openrc ) return p->openrc; if( p->bOpen==0 ){ p->openrc = rc = sqlite4BtOpen(p->pDb, p->zFilename); if( rc!=SQLITE4_OK ){ return rc; } p->bOpen = 1; } rc = sqlite4BtBegin(p->pDb, iLevel); pKVStore->iTransLevel = sqlite4BtTransactionLevel(p->pDb); return rc; } /* ** Commit a transaction or subtransaction. */ static int btCommitPhaseOne(KVStore *pKVStore, int iLevel){ return SQLITE4_OK; } static int btCommitPhaseTwo(KVStore *pKVStore, int iLevel){ KVBt *p = (KVBt *)pKVStore; int rc; assert( p->bOpen==1 ); rc = sqlite4BtCommit(p->pDb, iLevel); pKVStore->iTransLevel = sqlite4BtTransactionLevel(p->pDb); return rc; } /* ** Rollback a transaction or subtransaction. */ static int btRollback(KVStore *pKVStore, int iLevel){ KVBt *p = (KVBt *)pKVStore; int rc = SQLITE4_OK; if( p->bOpen==1 ){ rc = sqlite4BtRollback(p->pDb, iLevel); pKVStore->iTransLevel = sqlite4BtTransactionLevel(p->pDb); } return rc; } /* ** Revert a transaction back to what it was when it started. */ #if 0 |
︙ | ︙ | |||
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 | */ static int btReplace( KVStore *pKVStore, const KVByteArray *aKey, KVSize nKey, const KVByteArray *aData, KVSize nData ){ KVBt *p = (KVBt *)pKVStore; return sqlite4BtReplace(p->pDb, aKey, nKey, aData, nData); } /* ** Create a new cursor object. */ static int btOpenCursor(KVStore *pKVStore, KVCursor **ppKVCursor){ KVBt *p = (KVBt *)pKVStore; int rc = SQLITE4_OK; bt_cursor *pCsr; KVBtCsr *pBtcsr; rc = sqlite4BtCsrOpen(p->pDb, sizeof(KVBtCsr), &pCsr); if( rc!=SQLITE4_OK ){ pBtcsr = 0; }else{ pBtcsr = (KVBtCsr*)sqlite4BtCsrExtra(pCsr); memset(pBtcsr, 0, sizeof(KVBtCsr)); pBtcsr->base.pStore = pKVStore; | > > | 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 | */ static int btReplace( KVStore *pKVStore, const KVByteArray *aKey, KVSize nKey, const KVByteArray *aData, KVSize nData ){ KVBt *p = (KVBt *)pKVStore; assert( p->bOpen==1 ); return sqlite4BtReplace(p->pDb, aKey, nKey, aData, nData); } /* ** Create a new cursor object. */ static int btOpenCursor(KVStore *pKVStore, KVCursor **ppKVCursor){ KVBt *p = (KVBt *)pKVStore; int rc = SQLITE4_OK; bt_cursor *pCsr; KVBtCsr *pBtcsr; assert( p->bOpen==1 ); rc = sqlite4BtCsrOpen(p->pDb, sizeof(KVBtCsr), &pCsr); if( rc!=SQLITE4_OK ){ pBtcsr = 0; }else{ pBtcsr = (KVBtCsr*)sqlite4BtCsrExtra(pCsr); memset(pBtcsr, 0, sizeof(KVBtCsr)); pBtcsr->base.pStore = pKVStore; |
︙ | ︙ | |||
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 | } /* ** Destructor for the entire in-memory storage tree. */ static int btClose(KVStore *pKVStore){ KVBt *p = (KVBt *)pKVStore; return sqlite4BtClose(p->pDb); } static int btControl(KVStore *pKVStore, int op, void *pArg){ KVBt *p = (KVBt *)pKVStore; return sqlite4BtControl(p->pDb, op, pArg); } static int btGetMeta(KVStore *pKVStore, unsigned int *piVal){ KVBt *p = (KVBt *)pKVStore; return sqlite4BtGetCookie(p->pDb, piVal); } static int btPutMeta(KVStore *pKVStore, unsigned int iVal){ KVBt *p = (KVBt *)pKVStore; return sqlite4BtSetCookie(p->pDb, iVal); } static int btGetMethod( sqlite4_kvstore *pKVStore, const char *zMethod, void **ppArg, | > > > | 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 | } /* ** Destructor for the entire in-memory storage tree. */ static int btClose(KVStore *pKVStore){ KVBt *p = (KVBt *)pKVStore; sqlite4_free(pKVStore->pEnv, p->zFilename); return sqlite4BtClose(p->pDb); } static int btControl(KVStore *pKVStore, int op, void *pArg){ KVBt *p = (KVBt *)pKVStore; return sqlite4BtControl(p->pDb, op, pArg); } static int btGetMeta(KVStore *pKVStore, unsigned int *piVal){ KVBt *p = (KVBt *)pKVStore; assert( p->bOpen==1 ); return sqlite4BtGetCookie(p->pDb, piVal); } static int btPutMeta(KVStore *pKVStore, unsigned int iVal){ KVBt *p = (KVBt *)pKVStore; assert( p->bOpen==1 ); return sqlite4BtSetCookie(p->pDb, iVal); } static int btGetMethod( sqlite4_kvstore *pKVStore, const char *zMethod, void **ppArg, |
︙ | ︙ | |||
278 279 280 281 282 283 284 285 286 287 288 | KVBt *pNew = 0; bt_db *pDb = 0; int rc; rc = sqlite4BtNew(pEnv, sizeof(KVBt), &pDb); if( rc==SQLITE4_OK ){ pNew = (KVBt*)sqlite4BtExtra(pDb); pNew->base.pStoreVfunc = &bt_methods; pNew->base.pEnv = pEnv; pNew->pDb = pDb; | > > | | 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 | KVBt *pNew = 0; bt_db *pDb = 0; int rc; rc = sqlite4BtNew(pEnv, sizeof(KVBt), &pDb); if( rc==SQLITE4_OK ){ bt_env *pBtenv = 0; pNew = (KVBt*)sqlite4BtExtra(pDb); pNew->base.pStoreVfunc = &bt_methods; pNew->base.pEnv = pEnv; pNew->pDb = pDb; sqlite4BtControl(pDb, BT_CONTROL_GETVFS, (void*)&pBtenv); rc = pBtenv->xFullpath(pEnv, pBtenv, zFilename, &pNew->zFilename); } if( rc!=SQLITE4_OK && pDb ){ sqlite4BtClose(pDb); pNew = 0; } *ppKVStore = pNew; return rc; } |
Changes to test/attach.test.
︙ | ︙ | |||
745 746 747 748 749 750 751 | puts "\n**** Tests do not work when run as root ****" forcedelete cannot-read exit 1 } catchsql { ATTACH DATABASE 'cannot-read' AS noread; } | | | 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 | puts "\n**** Tests do not work when run as root ****" forcedelete cannot-read exit 1 } catchsql { ATTACH DATABASE 'cannot-read' AS noread; } } {1 {disk I/O error}} do_test attach-6.2.2 { db errorcode } {10} forcedelete cannot-read } # Check the error message if we try to access a database that has |
︙ | ︙ | |||
787 788 789 790 791 792 793 | do_test attach-8.1 { set fd [open test2.db w] puts $fd "This file is not a valid SQLite database" close $fd catchsql { ATTACH 'test2.db' AS t2; } | | | 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 | do_test attach-8.1 { set fd [open test2.db w] puts $fd "This file is not a valid SQLite database" close $fd catchsql { ATTACH 'test2.db' AS t2; } } {1 {file is encrypted or is not a database}} do_test attach-8.2 { db errorcode } {26} forcedelete test2.db do_test attach-8.3 { sqlite4 db2 test2.db db2 eval {CREATE TABLE t1(x); BEGIN EXCLUSIVE} |
︙ | ︙ |
Changes to test/attach3.test.
︙ | ︙ | |||
235 236 237 238 239 240 241 | # Failure to attach leaves us in a workable state. # Ticket #811 # do_test attach3-11.0 { catchsql { ATTACH DATABASE '/nodir/nofile.x' AS notadb; } | | | 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 | # Failure to attach leaves us in a workable state. # Ticket #811 # do_test attach3-11.0 { catchsql { ATTACH DATABASE '/nodir/nofile.x' AS notadb; } } {1 {disk I/O error}} do_test attach3-11.1 { catchsql { ATTACH DATABASE ':memory:' AS notadb; } } {0 {}} do_test attach3-11.2 { catchsql { |
︙ | ︙ |
Changes to test/bt1.test.
︙ | ︙ | |||
44 45 46 47 48 49 50 | execsql { SELECT * FROM t1 } } {abcd} do_test 1.3 { db close hexio_write test.db 8 55555555 | | > | 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | execsql { SELECT * FROM t1 } } {abcd} do_test 1.3 { db close hexio_write test.db 8 55555555 sqlite4 db test.db catchsql { SELECT * FROM t1 } } {1 {file is encrypted or is not a database}} #------------------------------------------------------------------------- # Test that, if there is a *-wal file that contains a valid copy of page # 1 (with the db header), it is possible to open the database even if # the header at byte offset 0 is damaged. # |
︙ | ︙ |
Changes to test/fault1.test.
︙ | ︙ | |||
11 12 13 14 15 16 17 18 19 20 21 22 23 24 | # set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/malloc_common.tcl set ::testprefix fault1 do_faultsim_test 1.0 -faults oom* -body { execsql { SELECT * FROM sqlite_master } } -test { faultsim_test_result {0 {}} } | > > | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | # set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/malloc_common.tcl set ::testprefix fault1 execsql { SELECT * FROM sqlite_master } do_faultsim_test 1.0 -faults oom* -body { execsql { SELECT * FROM sqlite_master } } -test { faultsim_test_result {0 {}} } |
︙ | ︙ |
Changes to test/permutations.test.
︙ | ︙ | |||
131 132 133 134 135 136 137 | # full # lappend ::testsuitelist xxx test_suite "bt" -prefix "bt-" -description { } -files { bt1.test | < | 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | # full # lappend ::testsuitelist xxx test_suite "bt" -prefix "bt-" -description { } -files { bt1.test aggerror.test alter.test alter3.test alter4.test analyze.test analyze3.test analyze4.test |
︙ | ︙ |