From 4d453cc2eda12164bb14ab9e773101919f85aac7 Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 6 Jul 2025 15:01:44 +0000 Subject: [PATCH 1/8] Experimentally add sqlite3.oo1.DB/Stmt.wrapHandle(), which allow DB/Stmt instances to wrap a (sqlite3*)/(sqlite3_stmt*) optionally with or without taking ownership of it. The intent is to enable mix-and-match use of the C API, the oo1 API, and any other hypothetical API which exposes those pointers. oo1.Stmt.parameterCount is now a property access interceptor like Stmt.columnCount is, but that doesn't change how it's used. FossilOrigin-Name: 1227543b87c3320d6b80e0f61b88ea53b68779966a0295c4d6a1db6369c48207 --- ext/wasm/api/sqlite3-api-oo1.c-pp.js | 321 ++++++++++++++++++++------- ext/wasm/tester1.c-pp.js | 90 +++++++- manifest | 17 +- manifest.uuid | 2 +- 4 files changed, 346 insertions(+), 84 deletions(-) diff --git a/ext/wasm/api/sqlite3-api-oo1.c-pp.js b/ext/wasm/api/sqlite3-api-oo1.c-pp.js index 06f9160021..91d8bc544d 100644 --- a/ext/wasm/api/sqlite3-api-oo1.c-pp.js +++ b/ext/wasm/api/sqlite3-api-oo1.c-pp.js @@ -37,6 +37,16 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ it. */ const __ptrMap = new WeakMap(); + /** + A Set of oo1.DB objects which are proxies for (A) (sqlite3*) or + another oo1.DB object or (B) oo1.Stmt objects which are proxies + for (sqlite3_stmt*) pointers. Such objects do not own their + underlying handle and that handle must be guaranteed (by the + client) to outlive the proxy. These proxies are primarily + intended as a way to briefly wrap an (sqlite3[_stmt]*) object as + an oo1.DB/Stmt without taking over ownership. + */ + const __doesNotOwnHandle = new Set(); /** Map of DB instances to objects, each object being a map of Stmt wasm pointers to Stmt objects. @@ -234,73 +244,89 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ }; } const opt = ctor.normalizeArgs(...args); - let fn = opt.filename, vfsName = opt.vfs, flagsStr = opt.flags; - if(('string'!==typeof fn && 'number'!==typeof fn) - || 'string'!==typeof flagsStr - || (vfsName && ('string'!==typeof vfsName && 'number'!==typeof vfsName))){ - sqlite3.config.error("Invalid DB ctor args",opt,arguments); - toss3("Invalid arguments for DB constructor."); - } - let fnJs = ('number'===typeof fn) ? wasm.cstrToJs(fn) : fn; - const vfsCheck = ctor._name2vfs[fnJs]; - if(vfsCheck){ - vfsName = vfsCheck.vfs; - fn = fnJs = vfsCheck.filename(fnJs); - } - let pDb, oflags = 0; - if( flagsStr.indexOf('c')>=0 ){ - oflags |= capi.SQLITE_OPEN_CREATE | capi.SQLITE_OPEN_READWRITE; - } - if( flagsStr.indexOf('w')>=0 ) oflags |= capi.SQLITE_OPEN_READWRITE; - if( 0===oflags ) oflags |= capi.SQLITE_OPEN_READONLY; - oflags |= capi.SQLITE_OPEN_EXRESCODE; - const stack = wasm.pstack.pointer; - try { - const pPtr = wasm.pstack.allocPtr() /* output (sqlite3**) arg */; - let rc = capi.sqlite3_open_v2(fn, pPtr, oflags, vfsName || 0); - pDb = wasm.peekPtr(pPtr); - checkSqlite3Rc(pDb, rc); - capi.sqlite3_extended_result_codes(pDb, 1); - if(flagsStr.indexOf('t')>=0){ - capi.sqlite3_trace_v2(pDb, capi.SQLITE_TRACE_STMT, - __dbTraceToConsole, pDb); + //sqlite3.config.debug("DB ctor",opt); + let pDb; + if( (pDb = opt['sqlite3*']) ){ + /* This property ^^^^^ is very specifically NOT DOCUMENTED and + NOT part of the public API. This is a back door for functions + like DB.wrapDbHandle(). */ + //sqlite3.config.debug("creating proxy db from",opt); + if( !opt['sqlite3*:takeOwnership'] ){ + /* This is object does not own its handle. */ + __doesNotOwnHandle.add(this); } - }catch( e ){ - if( pDb ) capi.sqlite3_close_v2(pDb); - throw e; - }finally{ - wasm.pstack.restore(stack); + this.filename = capi.sqlite3_db_filename(pDb,'main'); + }else{ + let fn = opt.filename, vfsName = opt.vfs, flagsStr = opt.flags; + if(('string'!==typeof fn && 'number'!==typeof fn) + || 'string'!==typeof flagsStr + || (vfsName && ('string'!==typeof vfsName && 'number'!==typeof vfsName))){ + sqlite3.config.error("Invalid DB ctor args",opt,arguments); + toss3("Invalid arguments for DB constructor."); + } + let fnJs = ('number'===typeof fn) ? wasm.cstrToJs(fn) : fn; + const vfsCheck = ctor._name2vfs[fnJs]; + if(vfsCheck){ + vfsName = vfsCheck.vfs; + fn = fnJs = vfsCheck.filename(fnJs); + } + let oflags = 0; + if( flagsStr.indexOf('c')>=0 ){ + oflags |= capi.SQLITE_OPEN_CREATE | capi.SQLITE_OPEN_READWRITE; + } + if( flagsStr.indexOf('w')>=0 ) oflags |= capi.SQLITE_OPEN_READWRITE; + if( 0===oflags ) oflags |= capi.SQLITE_OPEN_READONLY; + oflags |= capi.SQLITE_OPEN_EXRESCODE; + const stack = wasm.pstack.pointer; + try { + const pPtr = wasm.pstack.allocPtr() /* output (sqlite3**) arg */; + let rc = capi.sqlite3_open_v2(fn, pPtr, oflags, vfsName || 0); + pDb = wasm.peekPtr(pPtr); + checkSqlite3Rc(pDb, rc); + capi.sqlite3_extended_result_codes(pDb, 1); + if(flagsStr.indexOf('t')>=0){ + capi.sqlite3_trace_v2(pDb, capi.SQLITE_TRACE_STMT, + __dbTraceToConsole, pDb); + } + }catch( e ){ + if( pDb ) capi.sqlite3_close_v2(pDb); + throw e; + }finally{ + wasm.pstack.restore(stack); + } + this.filename = fnJs; } - this.filename = fnJs; __ptrMap.set(this, pDb); __stmtMap.set(this, Object.create(null)); - try{ + if( !opt['sqlite3*'] ){ + try{ //#if enable-see - dbCtorApplySEEKey(this,opt); + dbCtorApplySEEKey(this,opt); //#endif - // Check for per-VFS post-open SQL/callback... - const pVfs = capi.sqlite3_js_db_vfs(pDb) - || toss3("Internal error: cannot get VFS for new db handle."); - const postInitSql = __vfsPostOpenCallback[pVfs]; - if(postInitSql){ - /** - Reminder: if this db is encrypted and the client did _not_ pass - in the key, any init code will fail, causing the ctor to throw. - We don't actually know whether the db is encrypted, so we cannot - sensibly apply any heuristics which skip the init code only for - encrypted databases for which no key has yet been supplied. - */ - if(postInitSql instanceof Function){ - postInitSql(this, sqlite3); - }else{ - checkSqlite3Rc( - pDb, capi.sqlite3_exec(pDb, postInitSql, 0, 0, 0) - ); + // Check for per-VFS post-open SQL/callback... + const pVfs = capi.sqlite3_js_db_vfs(pDb) + || toss3("Internal error: cannot get VFS for new db handle."); + const postInitSql = __vfsPostOpenCallback[pVfs]; + if(postInitSql){ + /** + Reminder: if this db is encrypted and the client did _not_ pass + in the key, any init code will fail, causing the ctor to throw. + We don't actually know whether the db is encrypted, so we cannot + sensibly apply any heuristics which skip the init code only for + encrypted databases for which no key has yet been supplied. + */ + if(postInitSql instanceof Function){ + postInitSql(this, sqlite3); + }else{ + checkSqlite3Rc( + pDb, capi.sqlite3_exec(pDb, postInitSql, 0, 0, 0) + ); + } } + }catch(e){ + this.close(); + throw e; } - }catch(e){ - this.close(); - throw e; } }; @@ -486,26 +512,30 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ - `db`: the DB object which created the statement. - `columnCount`: the number of result columns in the query, or 0 - for queries which cannot return results. This property is a proxy - for sqlite3_column_count() and its use in loops should be avoided - because of the call overhead associated with that. The - `columnCount` is not cached when the Stmt is created because a - schema change made via a separate db connection between this - statement's preparation and when it is stepped may invalidate it. + for queries which cannot return results. This property is a + read-only proxy for sqlite3_column_count() and its use in loops + should be avoided because of the call overhead associated with + that. The `columnCount` is not cached when the Stmt is created + because a schema change made between this statement's preparation + and when it is stepped may invalidate it. - - `parameterCount`: the number of bindable parameters in the query. + - `parameterCount`: the number of bindable parameters in the + query. Like `columnCount`, this property is ready-only and is a + proxy for a C API call. As a general rule, most methods of this class will throw if called on an instance which has been finalized. For brevity's sake, the method docs do not all repeat this warning. */ - const Stmt = function(){ + const Stmt = function(/*oo1db, stmtPtr, BindTypes [,takeOwnership=true] */){ if(BindTypes!==arguments[2]){ toss3(capi.SQLITE_MISUSE, "Do not call the Stmt constructor directly. Use DB.prepare()."); } this.db = arguments[0]; __ptrMap.set(this, arguments[1]); - this.parameterCount = capi.sqlite3_bind_parameter_count(this.pointer); + if( arguments.length>3 && false===arguments[3] ){ + __doesNotOwnHandle.add(this); + } }; /** Throws if the given DB has been closed, else it is returned. */ @@ -723,12 +753,12 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ a db. */ close: function(){ - if(this.pointer){ + const pDb = this.pointer; + if(pDb){ if(this.onclose && (this.onclose.before instanceof Function)){ try{this.onclose.before(this)} catch(e){/*ignore*/} } - const pDb = this.pointer; Object.keys(__stmtMap.get(this)).forEach((k,s)=>{ if(s && s.pointer){ try{s.finalize()} @@ -737,7 +767,9 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ }); __ptrMap.delete(this); __stmtMap.delete(this); - capi.sqlite3_close_v2(pDb); + if( !__doesNotOwnHandle.delete(this) ){ + capi.sqlite3_close_v2(pDb); + } if(this.onclose && (this.onclose.after instanceof Function)){ try{this.onclose.after(this)} catch(e){/*ignore*/} @@ -1450,9 +1482,87 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ */ checkRc: function(resultCode){ return checkSqlite3Rc(this, resultCode); - } + }, }/*DB.prototype*/; + /** + Returns a new oo1.DB instance which wraps the given db. + + The first argument must be either a non-NULL (sqlite3*) WASM + pointer or a non-close()d instance of oo1.DB. + + The second argument only applies if the first argument is a + (sqlite3*). If it is, the returned object will pass that pointer + to sqlite3_close() when its close() method is called, otherwise + it will not. + + If the first argument is a oo1.DB object, the second argument is + disregarded and the returned object will be created as a + sqlite3.oo1.DB object (as opposed to the concrete derived DB + subclass from the first argument), so will not include any + derived-type behaviors, + e.g. JsStorageDb.prototype.clearStorage(). + + Throws if db cannot be resolved to one of the legal options. + + The caller MUST GUARANTEE that the passed-in handle will outlive + the returned object, i.e. that it will not be closed. If it is closed, + this object will hold a stale pointer and results are undefined. + + Aside from its lifetime, the proxy is to be treated as any other + DB instance, including the requirement of calling close() on + it. close() will free up internal resources owned by the proxy, + and disassociate the proxy from that handle, but will not + actually close the proxied db handle. + + The following quirks and requirements apply when proxying another + DB instance, as opposed to a (sqlite3*): + + - DO NOT call close() on the being-proxied instance while a proxy + is active. + + - ALWAYS eventually call close() on the returned object BEFORE + the being-proxied handle is closed. + + - For historical reasons, the filename property of the returned + object is captured at the time of this call, as opposed to being + dynamically proxied. e.g., if the filename property of the + being-proxied object is changed, this object will not reflect + that change. There is no good reason to ever modify that + property, so this distinction is not truly significant but it's + noted here because it's a client-visible discrepancy between the + proxy and its partner. (Sidebar: the filename property _should_ + be a property access interceptor for sqlite3_db_filename(), + but making it so now may break existing code.) + */ + DB.wrapHandle = function(db, takeOwnership=false){ + let ptr, ctor = DB; + const oo1db = (db instanceof DB) ? db : undefined; + if( wasm.isPtr(db) ){ + ptr = db; + }else if( oo1db ){ + takeOwnership = false; + ptr = db.pointer; + //ctor = db.constructor; + // ^^^ that doesn't work, resulting in an Object-type value + } + //sqlite3.config.debug("wrapHandle()",'db',db,'ctor',ctor, + //'arguments',arguments,'db.constructor',db.constructor); + if( !ptr ){ + throw new sqlite3.SQLite3Error(sqlite3.SQLITE_MISUSE, + "Argument must be a WASM sqlite3 "+ + "pointer or an sqlite3.oo1.DB instance"); + } + const dc = new ctor({ + "sqlite3*": ptr, + "sqlite3*:takeOwnership": !!takeOwnership + }); + if( oo1db ){ + dc.filename = oo1db.filename; + }//else dc.filename was captured by the ctor for legacy consistency + //sqlite3.config.debug("wrapHandle() dc",dc); + return dc; + }/*DB.wrapHandle()*/; /** Throws if the given Stmt has been finalized, else stmt is returned. */ @@ -1641,12 +1751,19 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ This method always throws if called when it is illegal to do so. Namely, when triggered via a per-row callback handler of a DB.exec() call. + + If Stmt does not own its underlying (sqlite3_stmt*) (see + Stmt.wrapHandle()) then this function will not pass it to + sqlite3_finalize(). */ finalize: function(){ - if(this.pointer){ + const ptr = this.pointer; + if(ptr){ affirmNotLockedByExec(this,'finalize()'); - const rc = capi.sqlite3_finalize(this.pointer); - delete __stmtMap.get(this.db)[this.pointer]; + const rc = (__doesNotOwnHandle.delete(this) + ? 0 + : capi.sqlite3_finalize(ptr)); + delete __stmtMap.get(this.db)[ptr]; __ptrMap.delete(this); __execLock.delete(this); __stmtMayGet.delete(this); @@ -2134,6 +2251,60 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ set: ()=>toss3("The columnCount property is read-only.") }); + Object.defineProperty(Stmt.prototype, 'parameterCount', { + enumerable: false, + get: function(){return capi.sqlite3_bind_parameter_count(this.pointer)}, + set: ()=>toss3("The parameterCount property is read-only.") + }); + + /** + The Stmt counterpart of oo1.DB.wrapHandle(), this creates a Stmt + instance which wraps a WASM (sqlite3_stmt*) in the oo1 API with + or without taking over ownership of that pointer. + + The first argument must be an oo1.DB instance[^1]. + + The second argument must be a valid WASM (sqlite3_stmt*), as + produced by sqlite3_prepare_v2() and sqlite3_prepare_v3(). + + The third argument specifies whether the returned Stmt object + takes over ownership of the underlying (sqlite3_stmt*). If true, + the returned object's finalize() method will finalize that + handle, else it will not. If it is false, ownership of stmtPtr is + unchanged and stmtPtr MUST outlive the returned object or results + are undefined. + + This function throws if the arguments are invalid. On success it + returns a new Stmt object which wraps the given statement + pointer. + + Like all Stmt objects, the finalize() method must eventually be + called on the returned object to free up internal resources, + regardless of whether this function's third argument is true or + not. + + [^1]: The first argument cannot be a (sqlite3*) because the + resulting Stmt object requires a parent DB object. It is not yet + determined whether it would be of general benefit to refactor the + DB/Stmt pair internals to communicate in terms of the underlying + (sqlite3*) rather than a DB object. If so, we could laxen the + first argument's requirement and allow an (sqlite3*). + */ + Stmt.wrapHandle = function(oo1db, stmtPtr, takeOwnership=false){ + let ctor = Stmt; + if( !(oo1db instanceof DB) || !oo1db.pointer ){ + throw new sqlite3.SQLite3Error(sqlite3.SQLITE_MISUSE, + "First argument must be an opened "+ + "sqlite3.oo1.DB instance"); + } + if( !stmtPtr || !wasm.isPtr(stmtPtr) ){ + throw new sqlite3.SQLite3Error(sqlite3.SQLITE_MISUSE, + "Second argument must be a WASM "+ + "sqlite3_stmt pointer"); + } + return new Stmt(oo1db, stmtPtr, BindTypes, !!takeOwnership); + } + /** The OO API's public namespace. */ sqlite3.oo1 = { DB, diff --git a/ext/wasm/tester1.c-pp.js b/ext/wasm/tester1.c-pp.js index 5b94c7c05e..446437eef8 100644 --- a/ext/wasm/tester1.c-pp.js +++ b/ext/wasm/tester1.c-pp.js @@ -41,7 +41,7 @@ ES6 worker module build: - ./c-pp -f tester1.c-pp.js -o tester1-esm.js -Dtarget=es6-module + ./c-pp -f tester1.c-pp.js -o tester1-esm.mjs -Dtarget=es6-module */ //#if target=es6-module import {default as sqlite3InitModule} from './jswasm/sqlite3.mjs'; @@ -1209,6 +1209,94 @@ globalThis.sqlite3InitModule = sqlite3InitModule; } } }) + + //////////////////////////////////////////////////////////////////// + .t({ + name: "oo1.DB/Stmt.wrapDbHandle()", + test: function(sqlite3){ + /* Maintenance reminder: this function is early in the list to + demonstrate that the wrappers for this.db created by this + function do not interfere with downstream tests, e.g. by + closing this.db.pointer. */ + sqlite3.config.debug("Proxying",this.db); + let dw = sqlite3.oo1.DB.wrapHandle(this.db); + sqlite3.config.debug('dw',dw); + T.assert( dw, '!!dw' ) + .assert( dw instanceof sqlite3.oo1.DB, 'dw is-a oo1.DB' ) + .assert( dw.pointer, 'dw.pointer' ) + .assert( dw.pointer === this.db.pointer, 'dw.pointer===db.pointer' ) + .assert( dw.filename === this.db.filename, 'dw.filename===db.filename' ); + + T.assert( dw === dw.exec("select 1") ); + let q; + try { + q = dw.prepare("select 1"); + T.assert( q.step() ) + .assert( !q.step() ); + }finally{ + if( q ) q.finalize(); + } + dw.close(); + T.assert( !dw.pointer ) + .assert( this.db === this.db.exec("select 1") ); + dw = undefined; + + let pDb = 0, pStmt = 0; + const stack = wasm.pstack.pointer; + try { + const ppOut = wasm.pstack.allocPtr(); + T.assert( 0===wasm.peekPtr(ppOut) ); + let rc = capi.sqlite3_open_v2( ":memory:", ppOut, + capi.SQLITE_OPEN_CREATE + | capi.SQLITE_OPEN_READWRITE, + 0); + T.assert( 0===rc, 'open_v2()' ); + pDb = wasm.peekPtr(ppOut); + wasm.pokePtr(ppOut, 0); + T.assert( pDb>0, 'pDb>0' ); + const pTmp = pDb; + dw = sqlite3.oo1.DB.wrapHandle(pDb, true); + pDb = 0; + //sqlite3.config.debug("dw",dw); + T.assert( pTmp===dw.pointer, 'pDb===dw.pointer' ); + T.assert( dw.filename === "", "dw.filename == "+dw.filename ); + let q = dw.prepare("select 1"); + try { + T.assert( q.step(), "step()" ); + T.assert( !q.step(), "!step()" ); + }finally{ + q.finalize(); + q = undefined; + } + T.assert( dw===dw.exec("select 1") ); + dw.affirmOpen(); + rc = capi.sqlite3_prepare_v2( dw, "select 1", -1, ppOut, 0 ); + T.assert( 0===rc, 'prepare_v2() rc='+rc ); + pStmt = wasm.peekPtr(ppOut); + try { + q = sqlite3.oo1.Stmt.wrapHandle(dw, pStmt, false); + T.assert( q.step(), "step()" ) + .assert( !q.step(), "!step()" ); + q.finalize(); + q = undefined; + q = sqlite3.oo1.Stmt.wrapHandle(dw, pStmt, true); + pStmt = 0; + q.reset(); + T.assert( q.step(), "step()" ) + .assert( !q.step(), "!step()" ); + }finally{ + if( pStmt ) capi.sqlite3_finalize(pStmt) + if( q ) q.finalize(); + } + + }finally{ + wasm.pstack.restore(stack); + if( pDb ){ capi.sqlite3_close_v2(pDb); } + else if( dw ){ dw.close(); } + } + } + })/*oo1.DB/Stmt.wrapHandle()*/ + //////////////////////////////////////////////////////////////////// .t('sqlite3_db_config() and sqlite3_db_status()', function(sqlite3){ let rc = capi.sqlite3_db_config(this.db, capi.SQLITE_DBCONFIG_LEGACY_ALTER_TABLE, 0, 0); diff --git a/manifest b/manifest index 423c865285..b818c61644 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\s'reconfigure'\starget\sto\sMakefile.in\sto\sre-run\sthe\sconfigure\sscript\swith\sthe\ssame\sflags\sit\swas\sgenerated\swith. -D 2025-07-04T18:32:18.912 +C Experimentally\sadd\ssqlite3.oo1.DB/Stmt.wrapHandle(),\swhich\sallow\sDB/Stmt\sinstances\sto\swrap\sa\s(sqlite3*)/(sqlite3_stmt*)\soptionally\swith\sor\swithout\staking\sownership\sof\sit.\sThe\sintent\sis\sto\senable\smix-and-match\suse\sof\sthe\sC\sAPI,\sthe\soo1\sAPI,\sand\sany\sother\shypothetical\sAPI\swhich\sexposes\sthose\spointers.\soo1.Stmt.parameterCount\sis\snow\sa\sproperty\saccess\sinterceptor\slike\sStmt.columnCount\sis,\sbut\sthat\sdoesn't\schange\show\sit's\sused. +D 2025-07-06T15:01:44.333 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -641,7 +641,7 @@ F ext/wasm/api/post-js-header.js 53740d824e5d9027eb1e6fd59e216abbd2136740ce260ea F ext/wasm/api/pre-js.c-pp.js a614a2c82b12c4d96d8e3ba77330329efc53c4d56a8a7e60ade900f341866cfb F ext/wasm/api/sqlite3-api-cleanup.js 3ac1786e461ada63033143be8c3b00b26b939540661f3e839515bb92f2e35359 F ext/wasm/api/sqlite3-api-glue.c-pp.js 0b76510f3650053bac67ca8947cb6ab9d050ad2218118a2e7796dd37be832ffa -F ext/wasm/api/sqlite3-api-oo1.c-pp.js c68d6da0088c2527156fca9163a721abe08e7bd077b15404fd8d292f4612adc1 +F ext/wasm/api/sqlite3-api-oo1.c-pp.js 44d122b6d22ba9caa644193357a03bf5d2678a7815f1e2bbbdb086b14db11b7e F ext/wasm/api/sqlite3-api-prologue.js 8708570165f5b4bce9a78ccd91bc9ddf8735970ac1c4d659e36c9a7d9a644bb4 F ext/wasm/api/sqlite3-api-worker1.c-pp.js f646a65257973b8c4481f8a6a216370b85644f23e64b126e7ae113570587c0ab F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89 @@ -698,7 +698,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555 F ext/wasm/test-opfs-vfs.js 1618670e466f424aa289859fe0ec8ded223e42e9e69b5c851f809baaaca1a00c F ext/wasm/tester1-worker.html ebc4b820a128963afce328ecf63ab200bd923309eb939f4110510ab449e9814c F ext/wasm/tester1.c-pp.html 1c1bc78b858af2019e663b1a31e76657b73dc24bede28ca92fbe917c3a972af2 -F ext/wasm/tester1.c-pp.js 766a2ba51a2619d41a49be7c6a1ad014c1d23fc97b67496e4f103038203eb17d +F ext/wasm/tester1.c-pp.js e7176b2bc1228cf9a87833be7e53e20cb82dec2f104525f5cdd6cb1a53998ad6 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 @@ -2208,8 +2208,11 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 64f5f14322349b47451b8cac03bf8cd6f1ae45a8822e7f1ddee3d0b265047501 -R 2e84b390408477c8e70efdd22e84c169 +P c60907e77b32824aaaf024d299cdaf161b5f64fc927ffe5d5455eeb5754e6b01 +R 23984087c5c98e4f1ed7d33ca211546f +T *branch * oo1-unowned-handles +T *sym-oo1-unowned-handles * +T -sym-trunk * Cancelled\sby\sbranch. U stephan -Z a6be9728f4a0aec0de70108286e76b7e +Z 3bad3f183e619bbd50d1bebd9118b331 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 08e4c43bce..f6dbdc594c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c60907e77b32824aaaf024d299cdaf161b5f64fc927ffe5d5455eeb5754e6b01 +1227543b87c3320d6b80e0f61b88ea53b68779966a0295c4d6a1db6369c48207 From 787f4c3f09d00e79c04822a99fd9a03f7878e959 Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 6 Jul 2025 15:13:06 +0000 Subject: [PATCH 2/8] JS doc additions. FossilOrigin-Name: 7933505f0c1d25c6ee81ead8edc5ea649a84ec0582321bcf5ed4a17232750f90 --- ext/wasm/api/sqlite3-api-oo1.c-pp.js | 35 ++++++++++++++++------------ manifest | 15 +++++------- manifest.uuid | 2 +- 3 files changed, 27 insertions(+), 25 deletions(-) diff --git a/ext/wasm/api/sqlite3-api-oo1.c-pp.js b/ext/wasm/api/sqlite3-api-oo1.c-pp.js index 91d8bc544d..13ca9a4bdf 100644 --- a/ext/wasm/api/sqlite3-api-oo1.c-pp.js +++ b/ext/wasm/api/sqlite3-api-oo1.c-pp.js @@ -533,7 +533,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ } this.db = arguments[0]; __ptrMap.set(this, arguments[1]); - if( arguments.length>3 && false===arguments[3] ){ + if( arguments.length>3 && !!arguments[3] ){ __doesNotOwnHandle.add(this); } }; @@ -728,10 +728,10 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ }, /** Finalizes all open statements and closes this database - connection. This is a no-op if the db has already been - closed. After calling close(), `this.pointer` will resolve to - `undefined`, so that can be used to check whether the db - instance is still opened. + connection (with one exception noted below). This is a no-op if + the db has already been closed. After calling close(), + `this.pointer` will resolve to `undefined`, and that can be + used to check whether the db instance is still opened. If this.onclose.before is a function then it is called before any close-related cleanup. @@ -751,6 +751,11 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ all, will never trigger close(), so onclose handlers are not a reliable way to implement close-time cleanup or maintenance of a db. + + If this instance was created using DB.wrapHandle() and does not + own this.pointer then it does not close the db handle but it + does perform all other work, such as calling onclose callbacks + and disassociating this object from this.pointer. */ close: function(){ const pDb = this.pointer; @@ -1491,10 +1496,10 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ The first argument must be either a non-NULL (sqlite3*) WASM pointer or a non-close()d instance of oo1.DB. - The second argument only applies if the first argument is a - (sqlite3*). If it is, the returned object will pass that pointer - to sqlite3_close() when its close() method is called, otherwise - it will not. + The second argument, defaulting to false, only applies if the + first argument is a (sqlite3*). If it is, the returned object + will pass that pointer to sqlite3_close() when its close() method + is called, otherwise it will not. If the first argument is a oo1.DB object, the second argument is disregarded and the returned object will be created as a @@ -2267,12 +2272,12 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ The second argument must be a valid WASM (sqlite3_stmt*), as produced by sqlite3_prepare_v2() and sqlite3_prepare_v3(). - The third argument specifies whether the returned Stmt object - takes over ownership of the underlying (sqlite3_stmt*). If true, - the returned object's finalize() method will finalize that - handle, else it will not. If it is false, ownership of stmtPtr is - unchanged and stmtPtr MUST outlive the returned object or results - are undefined. + The third argument, defaulting to false, specifies whether the + returned Stmt object takes over ownership of the underlying + (sqlite3_stmt*). If true, the returned object's finalize() method + will finalize that handle, else it will not. If it is false, + ownership of stmtPtr is unchanged and stmtPtr MUST outlive the + returned object or results are undefined. This function throws if the arguments are invalid. On success it returns a new Stmt object which wraps the given statement diff --git a/manifest b/manifest index b818c61644..5299e9d5a5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Experimentally\sadd\ssqlite3.oo1.DB/Stmt.wrapHandle(),\swhich\sallow\sDB/Stmt\sinstances\sto\swrap\sa\s(sqlite3*)/(sqlite3_stmt*)\soptionally\swith\sor\swithout\staking\sownership\sof\sit.\sThe\sintent\sis\sto\senable\smix-and-match\suse\sof\sthe\sC\sAPI,\sthe\soo1\sAPI,\sand\sany\sother\shypothetical\sAPI\swhich\sexposes\sthose\spointers.\soo1.Stmt.parameterCount\sis\snow\sa\sproperty\saccess\sinterceptor\slike\sStmt.columnCount\sis,\sbut\sthat\sdoesn't\schange\show\sit's\sused. -D 2025-07-06T15:01:44.333 +C JS\sdoc\sadditions. +D 2025-07-06T15:13:06.902 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -641,7 +641,7 @@ F ext/wasm/api/post-js-header.js 53740d824e5d9027eb1e6fd59e216abbd2136740ce260ea F ext/wasm/api/pre-js.c-pp.js a614a2c82b12c4d96d8e3ba77330329efc53c4d56a8a7e60ade900f341866cfb F ext/wasm/api/sqlite3-api-cleanup.js 3ac1786e461ada63033143be8c3b00b26b939540661f3e839515bb92f2e35359 F ext/wasm/api/sqlite3-api-glue.c-pp.js 0b76510f3650053bac67ca8947cb6ab9d050ad2218118a2e7796dd37be832ffa -F ext/wasm/api/sqlite3-api-oo1.c-pp.js 44d122b6d22ba9caa644193357a03bf5d2678a7815f1e2bbbdb086b14db11b7e +F ext/wasm/api/sqlite3-api-oo1.c-pp.js dc3b30cefa93e6dd9f2b827e31acacbfc2acd522d5ca4d46e977dacc4261398f F ext/wasm/api/sqlite3-api-prologue.js 8708570165f5b4bce9a78ccd91bc9ddf8735970ac1c4d659e36c9a7d9a644bb4 F ext/wasm/api/sqlite3-api-worker1.c-pp.js f646a65257973b8c4481f8a6a216370b85644f23e64b126e7ae113570587c0ab F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89 @@ -2208,11 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P c60907e77b32824aaaf024d299cdaf161b5f64fc927ffe5d5455eeb5754e6b01 -R 23984087c5c98e4f1ed7d33ca211546f -T *branch * oo1-unowned-handles -T *sym-oo1-unowned-handles * -T -sym-trunk * Cancelled\sby\sbranch. +P 1227543b87c3320d6b80e0f61b88ea53b68779966a0295c4d6a1db6369c48207 +R cef3ddc9e77c9bf23d0de246f8a430aa U stephan -Z 3bad3f183e619bbd50d1bebd9118b331 +Z 86c577d4430c4b03afa5e02f4812dc59 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index f6dbdc594c..a50c65454f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1227543b87c3320d6b80e0f61b88ea53b68779966a0295c4d6a1db6369c48207 +7933505f0c1d25c6ee81ead8edc5ea649a84ec0582321bcf5ed4a17232750f90 From 240319decde8af8fc4d0896d7138c7ca282627ea Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 6 Jul 2025 15:36:28 +0000 Subject: [PATCH 3/8] Remove some dead JS code and some extraneous debug output from test code. FossilOrigin-Name: 6e73770a7f3845055e0130012d844c32c4a1bfdb87e8379c161e1a266a808143 --- ext/wasm/api/sqlite3-api-oo1.c-pp.js | 10 +++------- ext/wasm/tester1.c-pp.js | 4 ++-- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 13 insertions(+), 17 deletions(-) diff --git a/ext/wasm/api/sqlite3-api-oo1.c-pp.js b/ext/wasm/api/sqlite3-api-oo1.c-pp.js index 13ca9a4bdf..cc4c9bb287 100644 --- a/ext/wasm/api/sqlite3-api-oo1.c-pp.js +++ b/ext/wasm/api/sqlite3-api-oo1.c-pp.js @@ -429,7 +429,6 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ - `vfs`: the VFS fname //#if enable-see - SEE-capable builds optionally support ONE of the following additional options: @@ -455,7 +454,6 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ is supplied and the database is encrypted, execution of the post-initialization SQL will fail, causing the constructor to throw. - //#endif enable-see The `filename` and `vfs` arguments may be either JS strings or @@ -483,8 +481,8 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ /** Internal-use enum for mapping JS types to DB-bindable types. These do not (and need not) line up with the SQLITE_type - values. All values in this enum must be truthy and distinct - but they need not be numbers. + values. All values in this enum must be truthy and (mostly) + distinct but they need not be numbers. */ const BindTypes = { null: 1, @@ -493,7 +491,6 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ boolean: 4, blob: 5 }; - BindTypes['undefined'] == BindTypes.null; if(wasm.bigIntEnabled){ BindTypes.bigint = BindTypes.number; } @@ -1589,8 +1586,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ case BindTypes.string: return t; case BindTypes.bigint: - if(wasm.bigIntEnabled) return t; - /* else fall through */ + return wasm.bigIntEnabled ? t : undefined; default: return util.isBindableTypedArray(v) ? BindTypes.blob : undefined; } diff --git a/ext/wasm/tester1.c-pp.js b/ext/wasm/tester1.c-pp.js index 446437eef8..824b6081da 100644 --- a/ext/wasm/tester1.c-pp.js +++ b/ext/wasm/tester1.c-pp.js @@ -1218,9 +1218,9 @@ globalThis.sqlite3InitModule = sqlite3InitModule; demonstrate that the wrappers for this.db created by this function do not interfere with downstream tests, e.g. by closing this.db.pointer. */ - sqlite3.config.debug("Proxying",this.db); + //sqlite3.config.debug("Proxying",this.db); let dw = sqlite3.oo1.DB.wrapHandle(this.db); - sqlite3.config.debug('dw',dw); + //sqlite3.config.debug('dw',dw); T.assert( dw, '!!dw' ) .assert( dw instanceof sqlite3.oo1.DB, 'dw is-a oo1.DB' ) .assert( dw.pointer, 'dw.pointer' ) diff --git a/manifest b/manifest index 5299e9d5a5..7a3bb87723 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C JS\sdoc\sadditions. -D 2025-07-06T15:13:06.902 +C Remove\ssome\sdead\sJS\scode\sand\ssome\sextraneous\sdebug\soutput\sfrom\stest\scode. +D 2025-07-06T15:36:28.567 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -641,7 +641,7 @@ F ext/wasm/api/post-js-header.js 53740d824e5d9027eb1e6fd59e216abbd2136740ce260ea F ext/wasm/api/pre-js.c-pp.js a614a2c82b12c4d96d8e3ba77330329efc53c4d56a8a7e60ade900f341866cfb F ext/wasm/api/sqlite3-api-cleanup.js 3ac1786e461ada63033143be8c3b00b26b939540661f3e839515bb92f2e35359 F ext/wasm/api/sqlite3-api-glue.c-pp.js 0b76510f3650053bac67ca8947cb6ab9d050ad2218118a2e7796dd37be832ffa -F ext/wasm/api/sqlite3-api-oo1.c-pp.js dc3b30cefa93e6dd9f2b827e31acacbfc2acd522d5ca4d46e977dacc4261398f +F ext/wasm/api/sqlite3-api-oo1.c-pp.js 33203352e067d3dbb569c5ec3c247b356f61a8d320bf8551fdf18ff25c0ff862 F ext/wasm/api/sqlite3-api-prologue.js 8708570165f5b4bce9a78ccd91bc9ddf8735970ac1c4d659e36c9a7d9a644bb4 F ext/wasm/api/sqlite3-api-worker1.c-pp.js f646a65257973b8c4481f8a6a216370b85644f23e64b126e7ae113570587c0ab F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89 @@ -698,7 +698,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555 F ext/wasm/test-opfs-vfs.js 1618670e466f424aa289859fe0ec8ded223e42e9e69b5c851f809baaaca1a00c F ext/wasm/tester1-worker.html ebc4b820a128963afce328ecf63ab200bd923309eb939f4110510ab449e9814c F ext/wasm/tester1.c-pp.html 1c1bc78b858af2019e663b1a31e76657b73dc24bede28ca92fbe917c3a972af2 -F ext/wasm/tester1.c-pp.js e7176b2bc1228cf9a87833be7e53e20cb82dec2f104525f5cdd6cb1a53998ad6 +F ext/wasm/tester1.c-pp.js b99d18fe8803215664a3b53af451d11e2573682a2c8973bcd28ce574c497393b 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 @@ -2208,8 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 1227543b87c3320d6b80e0f61b88ea53b68779966a0295c4d6a1db6369c48207 -R cef3ddc9e77c9bf23d0de246f8a430aa +P 7933505f0c1d25c6ee81ead8edc5ea649a84ec0582321bcf5ed4a17232750f90 +R 7f815f9b4c7a2aabd4a38289c5be858a U stephan -Z 86c577d4430c4b03afa5e02f4812dc59 +Z d14be01d18ce30e04a958bfca48cc223 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a50c65454f..eee638be6b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7933505f0c1d25c6ee81ead8edc5ea649a84ec0582321bcf5ed4a17232750f90 +6e73770a7f3845055e0130012d844c32c4a1bfdb87e8379c161e1a266a808143 From 6276637075213c3735108d4a9d5a03eeda1e72e5 Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 9 Jul 2025 13:13:01 +0000 Subject: [PATCH 4/8] wasm: add a few tests demonstrating that oo1.Stmt.paramaterCount's new impl does not change visible behaviors. Add the c-pp-filtered files to 'make clean'. FossilOrigin-Name: 3fe61545967f82190011edb90b1be6a448b590555c7ba5f8e96494aeea8f88ce --- ext/wasm/GNUmakefile | 2 +- ext/wasm/tester1.c-pp.js | 4 ++++ manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/ext/wasm/GNUmakefile b/ext/wasm/GNUmakefile index bf1a49111c..4296b6305e 100644 --- a/ext/wasm/GNUmakefile +++ b/ext/wasm/GNUmakefile @@ -429,7 +429,7 @@ define SQLITE.CALL.C-PP.FILTER $(2): $(1) $$(MAKEFILE_LIST) $$(bin.c-pp) @mkdir -p $$(dir $$@) $$(bin.c-pp) -f $(1) -o $$@ $(3) $(SQLITE.CALL.C-PP.FILTER.global) -#CLEAN_FILES += $(2) +CLEAN_FILES += $(2) endef # /end SQLITE.CALL.C-PP.FILTER ######################################################################## diff --git a/ext/wasm/tester1.c-pp.js b/ext/wasm/tester1.c-pp.js index 824b6081da..aafe4d7f3f 100644 --- a/ext/wasm/tester1.c-pp.js +++ b/ext/wasm/tester1.c-pp.js @@ -1356,6 +1356,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule; /columnCount property is read-only/) .assert(1===st.columnCount) .assert(0===st.parameterCount) + .assert(0===capi.sqlite3_bind_parameter_count(st)) .mustThrow(()=>st.bind(1,null)) .assert(true===st.step()) .assert(3 === st.get(0)) @@ -1578,6 +1579,8 @@ globalThis.sqlite3InitModule = sqlite3InitModule; let st = db.prepare("update t set b=:b where a='blob'"); try { T.assert(0===st.columnCount) + .assert(1===st.parameterCount) + .assert(1===capi.sqlite3_bind_parameter_count(st)) .assert( false===st.isReadOnly() ); const ndx = st.getParamIndex(':b'); T.assert(1===ndx); @@ -3417,6 +3420,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule; db.exec("create table t(a)"); const stmt = db.prepare("insert into t(a) values($a)"); T.assert( 1===capi.sqlite3_bind_parameter_count(stmt) ) + .assert( 1===stmt.parameterCount ) .assert( 1===capi.sqlite3_bind_parameter_index(stmt, "$a") ) .assert( 0===capi.sqlite3_bind_parameter_index(stmt, ":a") ) .assert( 1===stmt.getParamIndex("$a") ) diff --git a/manifest b/manifest index 7a3bb87723..da6bf18ef5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\ssome\sdead\sJS\scode\sand\ssome\sextraneous\sdebug\soutput\sfrom\stest\scode. -D 2025-07-06T15:36:28.567 +C wasm:\sadd\sa\sfew\stests\sdemonstrating\sthat\soo1.Stmt.paramaterCount's\snew\simpl\sdoes\snot\schange\svisible\sbehaviors.\sAdd\sthe\sc-pp-filtered\sfiles\sto\s'make\sclean'. +D 2025-07-09T13:13:01.736 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -621,7 +621,7 @@ F ext/session/sqlite3session.c 6b0877fe1ab832aa4b85eaca72606dfd1630a1363a1be7af1 F ext/session/sqlite3session.h 9bb1a6687b467764b35178dc29bbd2c57ab8cd3acdc8a62f088c34ad17e4fe2b F ext/session/test_session.c 2ddff73ea368d827028c32851b291416e1008845832feb27b751d15e57e13cc3 F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c -F ext/wasm/GNUmakefile a05bb1766f97c88cb42fbfe9e349c799c691f8ae0dc959e9d9469f0bcee89350 +F ext/wasm/GNUmakefile 4d329d89ffb701847abadff9a7e8ec59aaa26a6a2b8ddc2677514154248a2871 F ext/wasm/README-dist.txt f01081a850ce38a56706af6b481e3a7878e24e42b314cfcd4b129f0f8427066a F ext/wasm/README.md b89605f65661cf35bf034ff6d43e448cc169b8017fc105d498e33b81218b482c F ext/wasm/SQLTester/GNUmakefile e0794f676d55819951bbfae45cc5e8d7818dc460492dc317ce7f0d2eca15caff @@ -698,7 +698,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555 F ext/wasm/test-opfs-vfs.js 1618670e466f424aa289859fe0ec8ded223e42e9e69b5c851f809baaaca1a00c F ext/wasm/tester1-worker.html ebc4b820a128963afce328ecf63ab200bd923309eb939f4110510ab449e9814c F ext/wasm/tester1.c-pp.html 1c1bc78b858af2019e663b1a31e76657b73dc24bede28ca92fbe917c3a972af2 -F ext/wasm/tester1.c-pp.js b99d18fe8803215664a3b53af451d11e2573682a2c8973bcd28ce574c497393b +F ext/wasm/tester1.c-pp.js 1c4fdb32e10c92e2595939b1b6f6588cd3a30a2691ba2dc4a42893db99e0648b 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 @@ -2208,8 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 7933505f0c1d25c6ee81ead8edc5ea649a84ec0582321bcf5ed4a17232750f90 -R 7f815f9b4c7a2aabd4a38289c5be858a +P 6e73770a7f3845055e0130012d844c32c4a1bfdb87e8379c161e1a266a808143 +R 275bf35e86e01e823d3a78eac9fe64ed U stephan -Z d14be01d18ce30e04a958bfca48cc223 +Z 5ade71be55c22a5952ee210feb5c3747 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index eee638be6b..dbc806e8f1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6e73770a7f3845055e0130012d844c32c4a1bfdb87e8379c161e1a266a808143 +3fe61545967f82190011edb90b1be6a448b590555c7ba5f8e96494aeea8f88ce From 2ba5a93e8f6f42e617fad7b840d0720bb1dfbe26 Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 9 Jul 2025 13:43:53 +0000 Subject: [PATCH 5/8] wasm: DB.wrapHandle() no longer accepts a DB object as its first argument, as there's no apparent use case for proxying one DB object with another. Doc improvements for the new code. FossilOrigin-Name: 0ee19db02a9b9320681d4393d9ba52889d149eac8ee114fc7b7f52a57271c139 --- ext/wasm/api/sqlite3-api-oo1.c-pp.js | 117 ++++++++++++--------------- ext/wasm/tester1.c-pp.js | 7 +- manifest | 14 ++-- manifest.uuid | 2 +- 4 files changed, 63 insertions(+), 77 deletions(-) diff --git a/ext/wasm/api/sqlite3-api-oo1.c-pp.js b/ext/wasm/api/sqlite3-api-oo1.c-pp.js index cc4c9bb287..27176c0264 100644 --- a/ext/wasm/api/sqlite3-api-oo1.c-pp.js +++ b/ext/wasm/api/sqlite3-api-oo1.c-pp.js @@ -38,13 +38,15 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ */ const __ptrMap = new WeakMap(); /** - A Set of oo1.DB objects which are proxies for (A) (sqlite3*) or - another oo1.DB object or (B) oo1.Stmt objects which are proxies - for (sqlite3_stmt*) pointers. Such objects do not own their - underlying handle and that handle must be guaranteed (by the - client) to outlive the proxy. These proxies are primarily - intended as a way to briefly wrap an (sqlite3[_stmt]*) object as - an oo1.DB/Stmt without taking over ownership. + A Set of oo1.DB or oo1.Stmt objects which are proxies for + (sqlite3*) resp. (sqlite3_stmt*) pointers. Such objects + optionally do not own their underlying handle and that handle + must be guaranteed (by the client) to outlive the proxy. These + proxies are primarily intended as a way to briefly wrap an + (sqlite3[_stmt]*) object as an oo1.DB/Stmt without taking over + ownership. + + See DB.wrapHandle() and Stmt.wrapHandle(). */ const __doesNotOwnHandle = new Set(); /** @@ -1488,22 +1490,17 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ }/*DB.prototype*/; /** - Returns a new oo1.DB instance which wraps the given db. + Returns a new oo1.DB instance which wraps the given (sqlite3*) + WASM pointer, optionally with or without taking over ownership of + that pointer. The first argument must be either a non-NULL (sqlite3*) WASM - pointer or a non-close()d instance of oo1.DB. + pointer. - The second argument, defaulting to false, only applies if the - first argument is a (sqlite3*). If it is, the returned object - will pass that pointer to sqlite3_close() when its close() method - is called, otherwise it will not. - - If the first argument is a oo1.DB object, the second argument is - disregarded and the returned object will be created as a - sqlite3.oo1.DB object (as opposed to the concrete derived DB - subclass from the first argument), so will not include any - derived-type behaviors, - e.g. JsStorageDb.prototype.clearStorage(). + The second argument, defaulting to false, specifies ownership of + the first argument. If it is truthy, the returned object will + pass that pointer to sqlite3_close() when its close() method is + called, otherwise it will not. Throws if db cannot be resolved to one of the legal options. @@ -1515,56 +1512,38 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ DB instance, including the requirement of calling close() on it. close() will free up internal resources owned by the proxy, and disassociate the proxy from that handle, but will not - actually close the proxied db handle. + actually close the proxied db handle unless this function is + passed a thruthy second argument. The following quirks and requirements apply when proxying another DB instance, as opposed to a (sqlite3*): - - DO NOT call close() on the being-proxied instance while a proxy - is active. + - DO NOT call sqlite3_close() (or similar) on the being-proxied + instance while a proxy is active. - - ALWAYS eventually call close() on the returned object BEFORE - the being-proxied handle is closed. + - ALWAYS eventually call close() on the returned object. If the + proxy does not own the underlying handle then its MUST be + closed BEFORE the being-proxied handle is closed. - - For historical reasons, the filename property of the returned - object is captured at the time of this call, as opposed to being - dynamically proxied. e.g., if the filename property of the - being-proxied object is changed, this object will not reflect - that change. There is no good reason to ever modify that - property, so this distinction is not truly significant but it's - noted here because it's a client-visible discrepancy between the - proxy and its partner. (Sidebar: the filename property _should_ - be a property access interceptor for sqlite3_db_filename(), - but making it so now may break existing code.) + Design notes: + + - wrapHandle() "could" accept a DB object instance as its first + argument and proxy thatDb.pointer but there is currently no use + case where doing so would be useful, so it does not allow + that. That restriction may be lifted in a future version. */ - DB.wrapHandle = function(db, takeOwnership=false){ - let ptr, ctor = DB; - const oo1db = (db instanceof DB) ? db : undefined; - if( wasm.isPtr(db) ){ - ptr = db; - }else if( oo1db ){ - takeOwnership = false; - ptr = db.pointer; - //ctor = db.constructor; - // ^^^ that doesn't work, resulting in an Object-type value + DB.wrapHandle = function(pDb, takeOwnership=false){ + if( !pDb || !wasm.isPtr(pDb) ){ + throw new sqlite3.SQLite3Error(capi.SQLITE_MISUSE, + "Argument must be a WASM sqlite3 pointer"); } - //sqlite3.config.debug("wrapHandle()",'db',db,'ctor',ctor, - //'arguments',arguments,'db.constructor',db.constructor); - if( !ptr ){ - throw new sqlite3.SQLite3Error(sqlite3.SQLITE_MISUSE, - "Argument must be a WASM sqlite3 "+ - "pointer or an sqlite3.oo1.DB instance"); - } - const dc = new ctor({ - "sqlite3*": ptr, + return new DB({ + /* This ctor call style is very specifically internal-use-only. + It is not documented and may change at any time. */ + "sqlite3*": pDb, "sqlite3*:takeOwnership": !!takeOwnership }); - if( oo1db ){ - dc.filename = oo1db.filename; - }//else dc.filename was captured by the ctor for legacy consistency - //sqlite3.config.debug("wrapHandle() dc",dc); - return dc; - }/*DB.wrapHandle()*/; + }; /** Throws if the given Stmt has been finalized, else stmt is returned. */ @@ -2260,8 +2239,8 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ /** The Stmt counterpart of oo1.DB.wrapHandle(), this creates a Stmt - instance which wraps a WASM (sqlite3_stmt*) in the oo1 API with - or without taking over ownership of that pointer. + instance which wraps a WASM (sqlite3_stmt*) in the oo1 API, + optionally with or without taking over ownership of that pointer. The first argument must be an oo1.DB instance[^1]. @@ -2272,7 +2251,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ returned Stmt object takes over ownership of the underlying (sqlite3_stmt*). If true, the returned object's finalize() method will finalize that handle, else it will not. If it is false, - ownership of stmtPtr is unchanged and stmtPtr MUST outlive the + ownership of pStmt is unchanged and pStmt MUST outlive the returned object or results are undefined. This function throws if the arguments are invalid. On success it @@ -2289,21 +2268,25 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ determined whether it would be of general benefit to refactor the DB/Stmt pair internals to communicate in terms of the underlying (sqlite3*) rather than a DB object. If so, we could laxen the - first argument's requirement and allow an (sqlite3*). + first argument's requirement and allow an (sqlite3*). Because + DB.wrapHandle() enables multiple DB objects to proxy the same + (sqlite3*), we cannot unambiguously translate the first arugment + from (sqlite3*) to DB instances for us with this function's first + argument. */ - Stmt.wrapHandle = function(oo1db, stmtPtr, takeOwnership=false){ + Stmt.wrapHandle = function(oo1db, pStmt, takeOwnership=false){ let ctor = Stmt; if( !(oo1db instanceof DB) || !oo1db.pointer ){ throw new sqlite3.SQLite3Error(sqlite3.SQLITE_MISUSE, "First argument must be an opened "+ "sqlite3.oo1.DB instance"); } - if( !stmtPtr || !wasm.isPtr(stmtPtr) ){ + if( !pStmt || !wasm.isPtr(pStmt) ){ throw new sqlite3.SQLite3Error(sqlite3.SQLITE_MISUSE, "Second argument must be a WASM "+ "sqlite3_stmt pointer"); } - return new Stmt(oo1db, stmtPtr, BindTypes, !!takeOwnership); + return new Stmt(oo1db, pStmt, BindTypes, !!takeOwnership); } /** The OO API's public namespace. */ diff --git a/ext/wasm/tester1.c-pp.js b/ext/wasm/tester1.c-pp.js index aafe4d7f3f..f2fdeebed6 100644 --- a/ext/wasm/tester1.c-pp.js +++ b/ext/wasm/tester1.c-pp.js @@ -221,7 +221,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule; else if(filter instanceof Function) pass = filter(err); else if('string' === typeof filter) pass = (err.message === filter); if(!pass){ - throw new Error(msg || ("Filter rejected this exception: "+err.message)); + throw new Error(msg || ("Filter rejected this exception: <<"+err.message+">>")); } return this; }, @@ -1219,7 +1219,10 @@ globalThis.sqlite3InitModule = sqlite3InitModule; function do not interfere with downstream tests, e.g. by closing this.db.pointer. */ //sqlite3.config.debug("Proxying",this.db); - let dw = sqlite3.oo1.DB.wrapHandle(this.db); + const misuseMsg = "SQLITE_MISUSE: Argument must be a WASM sqlite3 pointer"; + T.mustThrowMatching(()=>sqlite3.oo1.DB.wrapHandle(this.db), misuseMsg) + .mustThrowMatching(()=>sqlite3.oo1.DB.wrapHandle(0), misuseMsg); + let dw = sqlite3.oo1.DB.wrapHandle(this.db.pointer); //sqlite3.config.debug('dw',dw); T.assert( dw, '!!dw' ) .assert( dw instanceof sqlite3.oo1.DB, 'dw is-a oo1.DB' ) diff --git a/manifest b/manifest index da6bf18ef5..abeec3b372 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C wasm:\sadd\sa\sfew\stests\sdemonstrating\sthat\soo1.Stmt.paramaterCount's\snew\simpl\sdoes\snot\schange\svisible\sbehaviors.\sAdd\sthe\sc-pp-filtered\sfiles\sto\s'make\sclean'. -D 2025-07-09T13:13:01.736 +C wasm:\sDB.wrapHandle()\sno\slonger\saccepts\sa\sDB\sobject\sas\sits\sfirst\sargument,\sas\sthere's\sno\sapparent\suse\scase\sfor\sproxying\sone\sDB\sobject\swith\sanother.\sDoc\simprovements\sfor\sthe\snew\scode. +D 2025-07-09T13:43:53.471 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -641,7 +641,7 @@ F ext/wasm/api/post-js-header.js 53740d824e5d9027eb1e6fd59e216abbd2136740ce260ea F ext/wasm/api/pre-js.c-pp.js a614a2c82b12c4d96d8e3ba77330329efc53c4d56a8a7e60ade900f341866cfb F ext/wasm/api/sqlite3-api-cleanup.js 3ac1786e461ada63033143be8c3b00b26b939540661f3e839515bb92f2e35359 F ext/wasm/api/sqlite3-api-glue.c-pp.js 0b76510f3650053bac67ca8947cb6ab9d050ad2218118a2e7796dd37be832ffa -F ext/wasm/api/sqlite3-api-oo1.c-pp.js 33203352e067d3dbb569c5ec3c247b356f61a8d320bf8551fdf18ff25c0ff862 +F ext/wasm/api/sqlite3-api-oo1.c-pp.js 972e0aa2f6f3ad9d9530edfc5c18a56e55ab5bec728ce6ca9b89ce1df463f740 F ext/wasm/api/sqlite3-api-prologue.js 8708570165f5b4bce9a78ccd91bc9ddf8735970ac1c4d659e36c9a7d9a644bb4 F ext/wasm/api/sqlite3-api-worker1.c-pp.js f646a65257973b8c4481f8a6a216370b85644f23e64b126e7ae113570587c0ab F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89 @@ -698,7 +698,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555 F ext/wasm/test-opfs-vfs.js 1618670e466f424aa289859fe0ec8ded223e42e9e69b5c851f809baaaca1a00c F ext/wasm/tester1-worker.html ebc4b820a128963afce328ecf63ab200bd923309eb939f4110510ab449e9814c F ext/wasm/tester1.c-pp.html 1c1bc78b858af2019e663b1a31e76657b73dc24bede28ca92fbe917c3a972af2 -F ext/wasm/tester1.c-pp.js 1c4fdb32e10c92e2595939b1b6f6588cd3a30a2691ba2dc4a42893db99e0648b +F ext/wasm/tester1.c-pp.js 830749ee21bde538f52e150878c0078a3f6d294ba183900efd8488a9e6debf4f 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 @@ -2208,8 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 6e73770a7f3845055e0130012d844c32c4a1bfdb87e8379c161e1a266a808143 -R 275bf35e86e01e823d3a78eac9fe64ed +P 3fe61545967f82190011edb90b1be6a448b590555c7ba5f8e96494aeea8f88ce +R 7d3270f820abddff176885a6dceb6626 U stephan -Z 5ade71be55c22a5952ee210feb5c3747 +Z 4ed976109c5d88084cce8c9c03b32258 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index dbc806e8f1..b2ae9d924e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3fe61545967f82190011edb90b1be6a448b590555c7ba5f8e96494aeea8f88ce +0ee19db02a9b9320681d4393d9ba52889d149eac8ee114fc7b7f52a57271c139 From 6fd9469a3281ae67929bfc518d0e80674ec15378 Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 10 Jul 2025 09:25:57 +0000 Subject: [PATCH 6/8] Minor JS doc tweaks. FossilOrigin-Name: 34d893b4837be8bb679e9809befd98201dd79c8d2054f41429b18793b77e840f --- ext/wasm/api/sqlite3-api-oo1.c-pp.js | 11 +++++------ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/ext/wasm/api/sqlite3-api-oo1.c-pp.js b/ext/wasm/api/sqlite3-api-oo1.c-pp.js index 27176c0264..1473e4e45e 100644 --- a/ext/wasm/api/sqlite3-api-oo1.c-pp.js +++ b/ext/wasm/api/sqlite3-api-oo1.c-pp.js @@ -1502,7 +1502,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ pass that pointer to sqlite3_close() when its close() method is called, otherwise it will not. - Throws if db cannot be resolved to one of the legal options. + Throws if pDb is not a non-0 WASM pointer. The caller MUST GUARANTEE that the passed-in handle will outlive the returned object, i.e. that it will not be closed. If it is closed, @@ -1510,16 +1510,15 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ Aside from its lifetime, the proxy is to be treated as any other DB instance, including the requirement of calling close() on - it. close() will free up internal resources owned by the proxy, - and disassociate the proxy from that handle, but will not + it. close() will free up internal resources owned by the proxy + and disassociate the proxy from that handle but will not actually close the proxied db handle unless this function is passed a thruthy second argument. - The following quirks and requirements apply when proxying another - DB instance, as opposed to a (sqlite3*): + To stress: - DO NOT call sqlite3_close() (or similar) on the being-proxied - instance while a proxy is active. + pointer while a proxy is active. - ALWAYS eventually call close() on the returned object. If the proxy does not own the underlying handle then its MUST be diff --git a/manifest b/manifest index abeec3b372..20cc623889 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C wasm:\sDB.wrapHandle()\sno\slonger\saccepts\sa\sDB\sobject\sas\sits\sfirst\sargument,\sas\sthere's\sno\sapparent\suse\scase\sfor\sproxying\sone\sDB\sobject\swith\sanother.\sDoc\simprovements\sfor\sthe\snew\scode. -D 2025-07-09T13:43:53.471 +C Minor\sJS\sdoc\stweaks. +D 2025-07-10T09:25:57.652 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -641,7 +641,7 @@ F ext/wasm/api/post-js-header.js 53740d824e5d9027eb1e6fd59e216abbd2136740ce260ea F ext/wasm/api/pre-js.c-pp.js a614a2c82b12c4d96d8e3ba77330329efc53c4d56a8a7e60ade900f341866cfb F ext/wasm/api/sqlite3-api-cleanup.js 3ac1786e461ada63033143be8c3b00b26b939540661f3e839515bb92f2e35359 F ext/wasm/api/sqlite3-api-glue.c-pp.js 0b76510f3650053bac67ca8947cb6ab9d050ad2218118a2e7796dd37be832ffa -F ext/wasm/api/sqlite3-api-oo1.c-pp.js 972e0aa2f6f3ad9d9530edfc5c18a56e55ab5bec728ce6ca9b89ce1df463f740 +F ext/wasm/api/sqlite3-api-oo1.c-pp.js bc472af6c3aada06ad94b332bf23cef2407932e5bb4c0c34c12a6ced343c2e51 F ext/wasm/api/sqlite3-api-prologue.js 8708570165f5b4bce9a78ccd91bc9ddf8735970ac1c4d659e36c9a7d9a644bb4 F ext/wasm/api/sqlite3-api-worker1.c-pp.js f646a65257973b8c4481f8a6a216370b85644f23e64b126e7ae113570587c0ab F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89 @@ -2208,8 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 3fe61545967f82190011edb90b1be6a448b590555c7ba5f8e96494aeea8f88ce -R 7d3270f820abddff176885a6dceb6626 +P 0ee19db02a9b9320681d4393d9ba52889d149eac8ee114fc7b7f52a57271c139 +R 9671bcb7870e122ad1976f1fae21a064 U stephan -Z 4ed976109c5d88084cce8c9c03b32258 +Z adaaff03d3b0b893bc2eaac10b306778 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b2ae9d924e..963b157be5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0ee19db02a9b9320681d4393d9ba52889d149eac8ee114fc7b7f52a57271c139 +34d893b4837be8bb679e9809befd98201dd79c8d2054f41429b18793b77e840f From c493e4516aa4b45f98c29e546bb424974839846a Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 11 Jul 2025 19:34:30 +0000 Subject: [PATCH 7/8] Correct a one-too-many-exclamation-points bug which caused the opposite of intended semantics in oo1.Stmt.pointer ownership. FossilOrigin-Name: 91e709f36d36174534b4cf4ff548a558e66cca5e23a6c8c106bc43375fc3ce72 --- ext/wasm/api/sqlite3-api-oo1.c-pp.js | 2 +- ext/wasm/tester1.c-pp.js | 9 ++++++++- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/ext/wasm/api/sqlite3-api-oo1.c-pp.js b/ext/wasm/api/sqlite3-api-oo1.c-pp.js index 1473e4e45e..f92dde48a7 100644 --- a/ext/wasm/api/sqlite3-api-oo1.c-pp.js +++ b/ext/wasm/api/sqlite3-api-oo1.c-pp.js @@ -532,7 +532,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ } this.db = arguments[0]; __ptrMap.set(this, arguments[1]); - if( arguments.length>3 && !!arguments[3] ){ + if( arguments.length>3 && !arguments[3] ){ __doesNotOwnHandle.add(this); } }; diff --git a/ext/wasm/tester1.c-pp.js b/ext/wasm/tester1.c-pp.js index f2fdeebed6..dd70024abb 100644 --- a/ext/wasm/tester1.c-pp.js +++ b/ext/wasm/tester1.c-pp.js @@ -1273,15 +1273,22 @@ globalThis.sqlite3InitModule = sqlite3InitModule; } T.assert( dw===dw.exec("select 1") ); dw.affirmOpen(); - rc = capi.sqlite3_prepare_v2( dw, "select 1", -1, ppOut, 0 ); + const select1 = "select 1"; + rc = capi.sqlite3_prepare_v2( dw, select1, -1, ppOut, 0 ); T.assert( 0===rc, 'prepare_v2() rc='+rc ); pStmt = wasm.peekPtr(ppOut); + T.assert( pStmt && wasm.isPtr(pStmt), 'pStmt is valid?' ); try { + //log( "capi.sqlite3_sql() =",capi.sqlite3_sql(pStmt)); + T.assert( select1 === capi.sqlite3_sql(pStmt), 'SQL mismatch' ); q = sqlite3.oo1.Stmt.wrapHandle(dw, pStmt, false); + //log("q@"+pStmt+" does not own handle"); T.assert( q.step(), "step()" ) .assert( !q.step(), "!step()" ); q.finalize(); q = undefined; + T.assert( select1 === capi.sqlite3_sql(pStmt), 'SQL mismatch' + /* This will fail if we've mismanaged pStmt's lifetime */); q = sqlite3.oo1.Stmt.wrapHandle(dw, pStmt, true); pStmt = 0; q.reset(); diff --git a/manifest b/manifest index 20cc623889..cc57a87555 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\sJS\sdoc\stweaks. -D 2025-07-10T09:25:57.652 +C Correct\sa\sone-too-many-exclamation-points\sbug\swhich\scaused\sthe\sopposite\sof\sintended\ssemantics\sin\soo1.Stmt.pointer\sownership. +D 2025-07-11T19:34:30.706 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -641,7 +641,7 @@ F ext/wasm/api/post-js-header.js 53740d824e5d9027eb1e6fd59e216abbd2136740ce260ea F ext/wasm/api/pre-js.c-pp.js a614a2c82b12c4d96d8e3ba77330329efc53c4d56a8a7e60ade900f341866cfb F ext/wasm/api/sqlite3-api-cleanup.js 3ac1786e461ada63033143be8c3b00b26b939540661f3e839515bb92f2e35359 F ext/wasm/api/sqlite3-api-glue.c-pp.js 0b76510f3650053bac67ca8947cb6ab9d050ad2218118a2e7796dd37be832ffa -F ext/wasm/api/sqlite3-api-oo1.c-pp.js bc472af6c3aada06ad94b332bf23cef2407932e5bb4c0c34c12a6ced343c2e51 +F ext/wasm/api/sqlite3-api-oo1.c-pp.js 19067fa3939d355db7bb5b02ee79dbb5e7ca4a8bd24216e24a2b4320b81ebb8d F ext/wasm/api/sqlite3-api-prologue.js 8708570165f5b4bce9a78ccd91bc9ddf8735970ac1c4d659e36c9a7d9a644bb4 F ext/wasm/api/sqlite3-api-worker1.c-pp.js f646a65257973b8c4481f8a6a216370b85644f23e64b126e7ae113570587c0ab F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89 @@ -698,7 +698,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555 F ext/wasm/test-opfs-vfs.js 1618670e466f424aa289859fe0ec8ded223e42e9e69b5c851f809baaaca1a00c F ext/wasm/tester1-worker.html ebc4b820a128963afce328ecf63ab200bd923309eb939f4110510ab449e9814c F ext/wasm/tester1.c-pp.html 1c1bc78b858af2019e663b1a31e76657b73dc24bede28ca92fbe917c3a972af2 -F ext/wasm/tester1.c-pp.js 830749ee21bde538f52e150878c0078a3f6d294ba183900efd8488a9e6debf4f +F ext/wasm/tester1.c-pp.js 0abba4bd54f6b22adaadf836c04d3163399f7a8a490fd60f20daac5f9c42b47d 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 @@ -2208,8 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 0ee19db02a9b9320681d4393d9ba52889d149eac8ee114fc7b7f52a57271c139 -R 9671bcb7870e122ad1976f1fae21a064 +P 34d893b4837be8bb679e9809befd98201dd79c8d2054f41429b18793b77e840f +R 3857d6c93e170f8a2978e6a4274a481e U stephan -Z adaaff03d3b0b893bc2eaac10b306778 +Z 42d47a808b11dbced254adeb3041a5ca # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 963b157be5..2eca880dc5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -34d893b4837be8bb679e9809befd98201dd79c8d2054f41429b18793b77e840f +91e709f36d36174534b4cf4ff548a558e66cca5e23a6c8c106bc43375fc3ce72 From 1f68085849b247a6a1773603cd56d915a1c5ce92 Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 11 Jul 2025 19:44:42 +0000 Subject: [PATCH 8/8] Clearer docs for the unowned db/stmt handle mechanism. FossilOrigin-Name: 53401b5435e30c4b47b6e203976b714d616246d734b5876a34f53f6388f872f8 --- ext/wasm/api/sqlite3-api-oo1.c-pp.js | 15 +++++++++------ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/ext/wasm/api/sqlite3-api-oo1.c-pp.js b/ext/wasm/api/sqlite3-api-oo1.c-pp.js index f92dde48a7..62c44fa9d0 100644 --- a/ext/wasm/api/sqlite3-api-oo1.c-pp.js +++ b/ext/wasm/api/sqlite3-api-oo1.c-pp.js @@ -39,12 +39,15 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ const __ptrMap = new WeakMap(); /** A Set of oo1.DB or oo1.Stmt objects which are proxies for - (sqlite3*) resp. (sqlite3_stmt*) pointers. Such objects - optionally do not own their underlying handle and that handle - must be guaranteed (by the client) to outlive the proxy. These - proxies are primarily intended as a way to briefly wrap an - (sqlite3[_stmt]*) object as an oo1.DB/Stmt without taking over - ownership. + (sqlite3*) resp. (sqlite3_stmt*) pointers which themselves are + owned elsewhere. Objects in this Set do not own their underlying + handle and that handle must be guaranteed (by the client) to + outlive the proxy. DB.close()/Stmt.finalize() methods will remove + the object from this Set _instead_ of closing/finalizing the + pointer. These proxies are primarily intended as a way to briefly + wrap an (sqlite3[_stmt]*) object as an oo1.DB/Stmt without taking + over ownership, to take advantage of simplifies usage compared to + the C API while not imposing any change of ownership. See DB.wrapHandle() and Stmt.wrapHandle(). */ diff --git a/manifest b/manifest index cc57a87555..cc2bf20443 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Correct\sa\sone-too-many-exclamation-points\sbug\swhich\scaused\sthe\sopposite\sof\sintended\ssemantics\sin\soo1.Stmt.pointer\sownership. -D 2025-07-11T19:34:30.706 +C Clearer\sdocs\sfor\sthe\sunowned\sdb/stmt\shandle\smechanism. +D 2025-07-11T19:44:42.921 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -641,7 +641,7 @@ F ext/wasm/api/post-js-header.js 53740d824e5d9027eb1e6fd59e216abbd2136740ce260ea F ext/wasm/api/pre-js.c-pp.js a614a2c82b12c4d96d8e3ba77330329efc53c4d56a8a7e60ade900f341866cfb F ext/wasm/api/sqlite3-api-cleanup.js 3ac1786e461ada63033143be8c3b00b26b939540661f3e839515bb92f2e35359 F ext/wasm/api/sqlite3-api-glue.c-pp.js 0b76510f3650053bac67ca8947cb6ab9d050ad2218118a2e7796dd37be832ffa -F ext/wasm/api/sqlite3-api-oo1.c-pp.js 19067fa3939d355db7bb5b02ee79dbb5e7ca4a8bd24216e24a2b4320b81ebb8d +F ext/wasm/api/sqlite3-api-oo1.c-pp.js f59e59f0d94ba5835c6b7fc9b800a4aa5084e1224721a07e3cd6cc7fef1789c2 F ext/wasm/api/sqlite3-api-prologue.js 8708570165f5b4bce9a78ccd91bc9ddf8735970ac1c4d659e36c9a7d9a644bb4 F ext/wasm/api/sqlite3-api-worker1.c-pp.js f646a65257973b8c4481f8a6a216370b85644f23e64b126e7ae113570587c0ab F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89 @@ -2208,8 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 34d893b4837be8bb679e9809befd98201dd79c8d2054f41429b18793b77e840f -R 3857d6c93e170f8a2978e6a4274a481e +P 91e709f36d36174534b4cf4ff548a558e66cca5e23a6c8c106bc43375fc3ce72 +R e5c4d3b625713e6da11932841f2fcce9 U stephan -Z 42d47a808b11dbced254adeb3041a5ca +Z 9fc18e96946cc270569853caeaa690c0 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 2eca880dc5..6fca69ff3a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -91e709f36d36174534b4cf4ff548a558e66cca5e23a6c8c106bc43375fc3ce72 +53401b5435e30c4b47b6e203976b714d616246d734b5876a34f53f6388f872f8