@@ -206,6 +206,8 @@ class InnerDatabaseFile : public SQLiteVFS::File {
206206
207207 // reset the outer database cursor; should be done when it otherwise might go stale.
208208 virtual void ResetCursor () {
209+ src = nullptr ;
210+ src_size = 0 ;
209211 if (cursor_pageno > 0 ) {
210212 cursor.reset ();
211213 cursor_pageno = 0 ;
@@ -241,18 +243,23 @@ class InnerDatabaseFile : public SQLiteVFS::File {
241243 }
242244 cursor_pageno = pageno;
243245 }
244- SQLite::Column data = cursor.getColumn (1 );
246+ auto data = cursor.getColumn (1 );
245247 assert (data.getName () == std::string (" data" ));
246248 src = data.getBlob ();
247249 src_size = data.getBytes ();
248250 if (src_size && (!src || !data.isBlob ())) {
249251 throw SQLite::Exception (" corrupt page " + std::to_string (pageno), SQLITE_CORRUPT);
250252 }
253+ FinishSeek ();
251254#ifndef NDEBUG
252255 t_seek += std::chrono::high_resolution_clock::now () - t0;
253256#endif
254257 }
255258
259+ // Override to add additional logic after seeking cursor (still under the seek lock), such
260+ // as reading the meta columns.
261+ virtual void FinishSeek () {}
262+
256263 // Decode one page from the blob stored in the outer db. Override me!
257264 // May parallelize with other jobs.
258265 virtual void DecodePage () {
@@ -702,7 +709,7 @@ class InnerDatabaseFile : public SQLiteVFS::File {
702709 // into a special row with pageno = -100.
703710 upsert->reset ();
704711 upsert->bindNoCopy (1 , job->encoded_page ,
705- std::min (job->encoded_page_size , size_t (100 )));
712+ std::min (job->encoded_page_size , size_t (100 )));
706713 // keep meta1 & meta2 bindings, if any
707714 upsert->bind (4 , (sqlite_int64)-100 );
708715 if (upsert->exec () != 1 ) {
@@ -1035,10 +1042,11 @@ class VFS : public SQLiteVFS::Wrapper {
10351042 if (zName && zName[0 ]) {
10361043 std::string sName (zName);
10371044 if (flags & SQLITE_OPEN_MAIN_DB) {
1038- // strip inner_db_filename_suffix_ to get filename of outer database
10391045 std::string outer_db_filename = sName ;
10401046 bool web = sName == " /__web__" ;
10411047 if (!web) {
1048+ // strip inner_db_filename_suffix_ to get filename of outer database (see
1049+ // FullPathname below)
10421050 if (sName .size () > inner_db_filename_suffix_.size ()) {
10431051 outer_db_filename =
10441052 sName .substr (0 , sName .size () - inner_db_filename_suffix_.size ());
@@ -1057,6 +1065,7 @@ class VFS : public SQLiteVFS::Wrapper {
10571065 std::string outer_db_uri = " file:" + urlencode (outer_db_filename, true );
10581066 bool unsafe = sqlite3_uri_boolean (zName, " outer_unsafe" , 0 );
10591067 if (web) {
1068+ // use sqlite_web_vfs, passing through configuration
10601069 outer_db_uri += " ?immutable=1" ;
10611070 for (const char *passthrough : {" web_log" , " web_insecure" , " web_url" }) {
10621071 if (sqlite3_uri_parameter (zName, passthrough)) {
@@ -1154,10 +1163,12 @@ class VFS : public SQLiteVFS::Wrapper {
11541163
11551164 // Given user-provided db filename, use it as the outer db on the host filesystem, and
11561165 // append a suffix as the inner db's filename (which won't actually exist on the host
1157- // filesystem, but xOpen() will recognize).
1166+ // filesystem, but xOpen() will recognize). This ensures the inner & outer journals will have
1167+ // distinct filenames.
11581168 int FullPathname (const char *zName, int nPathOut, char *zPathOut) override {
11591169 std::string zName2 (zName);
11601170 if (zName2 == " /__web__" ) {
1171+ // unnecessary for read-only web access
11611172 strncpy (zPathOut, zName, nPathOut);
11621173 return SQLITE_OK;
11631174 }
0 commit comments