From: stephan Date: Sun, 30 Nov 2025 08:32:52 +0000 (+0000) Subject: Rename kvvfs's 'localThread' storage object to '.'. Swap kvvfs.listen()'s elideJourna... X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=316020580e78bff116122608b8ccc1fe82d86e08;p=thirdparty%2Fsqlite.git Rename kvvfs's 'localThread' storage object to '.'. Swap kvvfs.listen()'s elideJournal(=false) option with includeJournal(=false) (i.e. opt in instead of opt out). FossilOrigin-Name: 7f0eca9d0aeb49c86a785ae930d235902bbd0f15877cc8f6083daac8efb2d1c1 --- diff --git a/ext/wasm/api/sqlite3-vfs-kvvfs.c-pp.js b/ext/wasm/api/sqlite3-vfs-kvvfs.c-pp.js index 6b50be885b..bb39fe378c 100644 --- a/ext/wasm/api/sqlite3-vfs-kvvfs.c-pp.js +++ b/ext/wasm/api/sqlite3-vfs-kvvfs.c-pp.js @@ -228,12 +228,12 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ const kvvfsKeyPrefix = (v)=>kvvfsIsPersistentName(v) ? 'kvvfs-'+v+'-' : ''; /** - Throws if storage name n is not valid for use as a storage name. - Much of this goes back to kvvfs having a fixed buffer size for - its keys, and the storage name needing to be encoded in the keys - for local/session storage. We disallow non-ASCII to avoid - problems with truncated multibyte characters at the end of the - key buffer. + Throws if storage name n (JS string) is not valid for use as a + storage name. Much of this goes back to kvvfs having a fixed + buffer size for its keys, and the storage name needing to be + encoded in the keys for local/session storage. We disallow + non-ASCII to avoid problems with truncated multibyte characters + at the end of the key buffer. The second argument must only be true when called from xOpen() - it makes names with a "-journal" suffix legal. @@ -257,7 +257,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ let i; for( i = 0; i < len; ++i ){ const ch = n.codePointAt(i); - if( ch<45 || ch >126 ){ + if( ch<43 || ch >126 ){ toss3(capi.SQLITE_RANGE, "Illegal character ("+ch+"d) in storage name:",n); } @@ -344,6 +344,12 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ cache.storagePool[store.jzClass] = cache.storagePool[store.jzClass+'-journal'] = store; + /** + The public name of the current thread's transient storage + object. A storage object with this name gets preinstalled. + */ + const nameOfThisThreadStorage = '.'; + /** Map of JS-stringified KVVfsFile::zClass names to reference-counted Storage objects. These objects are created in @@ -354,7 +360,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ */ cache.storagePool = Object.assign(Object.create(null),{ /* Start off with mappings for well-known names. */ - localThread: newStorageObj('localThread') + [nameOfThisThreadStorage]: newStorageObj(nameOfThisThreadStorage) }); if( globalThis.Storage ){ @@ -432,7 +438,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ const decodePages = ear.decodePages; const f = ear.events[eventName]; if( f ){ - if( ear.elideJournal && args[0]==='jrnl' ){ + if( !ear.includeJournal && args[0]==='jrnl' ){ continue; } if( 'write'===eventName && ear.decodePages && +args[0]>0 ){ @@ -1045,7 +1051,6 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ } const store = storageForZClass(which); if( !store ) return 0; - const keyPrefix = store.keyPrefix; if( store.files.length ){ toss3(capi.SQLITE_ACCESS, "Cannot clear in-use database storage."); @@ -1057,7 +1062,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ for( i = 0; i < n; ++i ){ const k = s.key(i); //debug("kvvfs_clear ?",k); - if(!keyPrefix || k.startsWith(keyPrefix)) toRm.push(k); + if(!store.keyPrefix || k.startsWith(store.keyPrefix)) toRm.push(k); } toRm.forEach((kk)=>s.removeItem(kk)); //alertFilesToReload(store); @@ -1178,7 +1183,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ }); const pages = Object.create(null); let xpages; - const keyPrefix = kvvfsKeyPrefix(rc.name); + const keyPrefix = store.keyPrefix; const rxTail = keyPrefix ? /^kvvfs-[^-]+-(\w+)/ /* X... part of kvvfs-NAME-X... */ : undefined; @@ -1431,10 +1436,11 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ requires no extra work, we already have it in hand, and it's often smaller. It's not great for interchange, though. - - elideJournal [=false]: if true, writes and deletes of - "jrnl" records are elided (no event is sent). + - includeJournal [=false]: if true, writes and deletes of + "jrnl" records are included. If false, no events are sent + for journal updates. - Passing the same object ot sqlite3_js_kvvfs_unlisten() will + Passing the same object to sqlite3_js_kvvfs_unlisten() will remove the listener. Each one of the events callbacks will be called asynchronously @@ -1460,38 +1466,32 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ - 'write' gets a length-two array holding the key and value which were written. The key is always a string, even if it's a db page number. For db-page records, the value's type depends on - opt.decodePages. All others, including the journal, are strings - (the latter, being in a kvvfs-specific format, is delivered in - its kvvfs-native format). More details below. + opt.decodePages. All others, including the journal, are strings. + (The journal, being a kvvfs-specific format, is delivered in + that same JSON-friendly format.) More details below. - 'delete' gets the string-type key of the deleted record. - - 'sync' receives - one argument: true if it was triggered by db file's - xSync(), false if it was triggered by xFileControl() (which - triggers before the xSync() and also triggers is the DB has - PRAGMA SYNCHRONOUS=OFF. + - 'sync' gets a boolean value: true if it was triggered by db + file's xSync(), false if it was triggered by xFileControl(). The + latter triggers before the xSync() and also triggers if the DB + has PRAGMA SYNCHRONOUS=OFF (in which case xSync() is not + triggered). - The arguments to 'write', and keys to 'delete', are in one of the - following forms: + The key/value arguments to 'write', and key argument to 'delete', + are in one of the following forms: - 'sz' = the unencoded db size as a string. This specific key is key is never deleted, so is only ever passed to 'write' events. - 'jrnl' = the current db journal as a kvvfs-encoded string. This journal format is not useful anywhere except in the kvvfs - internals. These events are not fired if opt.elideJournal is - true. - - - '[1-9][0-9]*' (a db page number) = a db page. Its type depends - on opt.decodePages. These may be written and deleted in arbitrary - order. If a page is deleted, the db is shrinking. + internals. These events are not fired if opt.includeJournal is + false. - For 'local' and 'session' storage, all of those keys have a - prefix of 'kvvfs-local-' resp. 'kvvfs-session-'. This is required - both for backwards compatibility and to enable dbs in those - storage objects to coexit with client data. Other storage objects - do not have a prefix. + - '[1-9][0-9]*' (a db page number) = Its type depends on + opt.decodePages. These may be written and deleted in arbitrary + order. Design note: JS has StorageEvents but only in the main thread, which is why the listeners are not based on that. @@ -1625,7 +1625,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ DB.dbCtorHelper.call(this, opt); }; sqlite3.oo1.JsStorageDb.defaultStorageName - = cache.storagePool.session ? 'session' : 'localThread'; + = cache.storagePool.session ? 'session' : nameOfThisThreadStorage; const jdb = sqlite3.oo1.JsStorageDb; jdb.prototype = Object.create(DB.prototype); jdb.clearStorage = sqlite3_js_kvvfs_clear; diff --git a/ext/wasm/tester1.c-pp.js b/ext/wasm/tester1.c-pp.js index f42dcb2bee..3b4a7bee77 100644 --- a/ext/wasm/tester1.c-pp.js +++ b/ext/wasm/tester1.c-pp.js @@ -2973,7 +2973,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule; name: 'transient kvvfs', //predicate: ()=>false, test: function(sqlite3){ - const filename = 'localThread' /* preinstalled instance */; + const filename = '.' /* preinstalled instance */; const JDb = sqlite3.oo1.JsStorageDb; const DB = sqlite3.oo1.DB; @@ -3266,7 +3266,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule; pglog.pages = []; pglog.jrnl = undefined; pglog.size = undefined; - pglog.elideJournal = true; + pglog.includeJournal = false; pglog.decodePages = true; pglog.exception = new Error("Testing that exceptions from listeners do not interfere"); const toss = ()=>{ @@ -3280,7 +3280,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule; const listener = { storage: filename, reserve: true, - elideJournal: pglog.elideJournal, + includeJournal: pglog.includeJournal, decodePages: pglog.decodePages, events: { 'open': (ev)=>{ @@ -3303,7 +3303,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule; T.assert('string'===typeof ev.data); switch(ev.data){ case 'jrnl': - T.assert(!pglog.elideJournal); + T.assert(pglog.includeJournal); pglog.jrnl = null; break; default:{ @@ -3328,7 +3328,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule; .assert('string'===typeof key); switch( key ){ case 'jrnl': - T.assert(!pglog.elideJournal); + T.assert(pglog.includeJournal); pglog.jrnl = val; break; case 'sz':{ @@ -3368,14 +3368,14 @@ globalThis.sqlite3InitModule = sqlite3InitModule; debug("kvvfs listener counts:",counts); T.assert( counts.open ); T.assert( counts.close ); - T.assert( listener.elideJournal ? !counts.delete : counts.delete ); + T.assert( listener.includeJournal ? counts.delete : !counts.delete ); T.assert( counts.write ); T.assert( counts.xSync ); T.assert( counts.xFileControlSync>=counts.xSync ); T.assert( counts.open===counts.close ); - T.assert( pglog.elideJournal - ? (undefined===pglog.jrnl) - : (null===pglog.jrnl), + T.assert( pglog.includeJournal + ? (null===pglog.jrnl) + : (undefined===pglog.jrnl), "Unexpected pglog.jrnl value: "+pglog.jrnl ); if( 1 ){ T.assert(undefined===pglog.pages[0], "Expecting empty slot 0"); diff --git a/manifest b/manifest index 319bc9f3de..9c5ae27b7d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\ssync\sevents\sto\skvvfs.listen()\sso\sthat\sstreaming\scan\smaybe\sget\sa\sbetter\ssense\sof\swhen\sit's\sokay\sto\sprocess\sthe\sstream. -D 2025-11-30T07:08:45.236 +C Rename\skvvfs's\s'localThread'\sstorage\sobject\sto\s'.'.\sSwap\skvvfs.listen()'s\selideJournal(=false)\soption\swith\sincludeJournal(=false)\s(i.e.\sopt\sin\sinstead\sof\sopt\sout). +D 2025-11-30T08:32:52.350 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -600,7 +600,7 @@ F ext/wasm/api/sqlite3-api-worker1.c-pp.js 1041dd645e8e821c082b628cd8d9acf70c667 F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89 F ext/wasm/api/sqlite3-opfs-async-proxy.js 9654b565b346dc609b75d15337f20acfa7af7d9d558da1afeb9b6d8eaa404966 F ext/wasm/api/sqlite3-vfs-helper.c-pp.js 3f828cc66758acb40e9c5b4dcfd87fd478a14c8fb7f0630264e6c7fa0e57515d -F ext/wasm/api/sqlite3-vfs-kvvfs.c-pp.js 92e838b2b1b3039d14ab43f23a99c553df5bd967525457335e2d498f4b72f632 +F ext/wasm/api/sqlite3-vfs-kvvfs.c-pp.js 352436a4e3adf66ae68dcff58ebb5aabe9754d716b818d955bceaf2641b6f815 F ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js a2eea6442556867b589e04107796c6e1d04a472219529eeb45b7cd221d7d048b F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 88ce2078267a2d1af57525a32d896295f4a8db7664de0e17e82dc9ff006ed8d3 F ext/wasm/api/sqlite3-vtab-helper.c-pp.js 366596d8ff73d4cefb938bbe95bc839d503c3fab6c8335ce4bf52f0d8a7dee81 @@ -647,7 +647,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555 F ext/wasm/test-opfs-vfs.js 1618670e466f424aa289859fe0ec8ded223e42e9e69b5c851f809baaaca1a00c F ext/wasm/tester1-worker.c-pp.html 0e432ec2c0d99cd470484337066e8d27e7aee4641d97115338f7d962bf7b081a F ext/wasm/tester1.c-pp.html 52d88fe2c6f21a046030a36410b4839b632f4424028197a45a3d5669ea724ddb -F ext/wasm/tester1.c-pp.js cb0b1a07bd19af014e62343b973c61be312ef91f612b83db074b1542969d64e3 +F ext/wasm/tester1.c-pp.js d8fb2ae2b3aff305040f595be7e0be0fc14fac510fe8bbc92dbb48af9d124c98 F ext/wasm/tests/opfs/concurrency/index.html 657578a6e9ce1e9b8be951549ed93a6a471f4520a99e5b545928668f4285fb5e F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65ad09f510589c779b7cc6a803a88 F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 @@ -2180,8 +2180,8 @@ F tool/version-info.c 33d0390ef484b3b1cb685d59362be891ea162123cea181cb8e6d2cf6dd F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh d924598cf2f55a4ecbc2aeb055c10bd5f48114793e7ba25f9585435da29e7e98 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P b8fee839b0199d1d2714c99612ea4b4d943d8b0033d742eaa66e1575ce46f0d2 -R fb9f8ede3e2ffe33cbb590ee3d7d0cdc +P a4b6dadffa1b43aadebfa06a1de14d763efd18b16c4a3e87f1bd039fbff2524d +R f7259cd8e3b1071dcc04e1dcebc90322 U stephan -Z a9c442087c9256ab328a4323b6416791 +Z 1f9741d6046d640c682611f3b5f58d30 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 611d42e9a1..bafa50ee69 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a4b6dadffa1b43aadebfa06a1de14d763efd18b16c4a3e87f1bd039fbff2524d +7f0eca9d0aeb49c86a785ae930d235902bbd0f15877cc8f6083daac8efb2d1c1