diff --git a/ext/wasm/api/sqlite3-api-oo1.js b/ext/wasm/api/sqlite3-api-oo1.js
index af179d1fe1..3dfe5bfb05 100644
--- a/ext/wasm/api/sqlite3-api-oo1.js
+++ b/ext/wasm/api/sqlite3-api-oo1.js
@@ -1581,17 +1581,30 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
}/*oo1 object*/;
if( self.window===self && 0!==capi.sqlite3_vfs_find('kvvfs') ){
- /* In the main window thread, add a couple of convenience proxies
- for localStorage and sessionStorage DBs... */
- let klass = sqlite3.oo1.LocalStorageDb = function(){
- dbCtorHelper.call(this, 'local', 'c', 'kvvfs');
+ /* Features specific to kvvfs... */
+ /**
+ Clears all storage used by the kvvfs DB backend, deleting any
+ DB(s) stored there. Its argument must be either 'session',
+ 'local', or ''. In the first two cases, only sessionStorage
+ resp. localStorage is cleared. If it's an empty string (the
+ default) then both are cleared. Only storage keys which match
+ the pattern used by kvvfs are cleared: any other client-side
+ data are retained.
+ */
+ DB.clearKvvfsStorage = function(which=''){
+ const prefix = 'kvvfs-'+which;
+ const stores = [];
+ if('session'===which || ''===which) stores.push(sessionStorage);
+ if('local'===which || ''===which) stores.push(localStorage);
+ stores.forEach(function(s){
+ const toRm = [];
+ let i = 0, k;
+ for( i = 0; (k = s.key(i)); ++i ){
+ if(k.startsWith(prefix)) toRm.push(k);
+ }
+ toRm.forEach((kk)=>s.removeItem(kk));
+ });
};
- klass.prototype = DB.prototype;
-
- klass = sqlite3.oo1.SessionStorageDb = function(){
- dbCtorHelper.call(this, 'session', 'c', 'kvvfs');
- };
- klass.prototype = DB.prototype;
- }
+ }/* main-window-only bits */
});
diff --git a/ext/wasm/kvvfs1.html b/ext/wasm/kvvfs1.html
index 773de0a603..1a5eb62cf1 100644
--- a/ext/wasm/kvvfs1.html
+++ b/ext/wasm/kvvfs1.html
@@ -24,18 +24,23 @@
-
Everything on this page happens in the dev console. TODOs for this demo include,
- but are not necessarily limited to:
-
-
-
UI controls to switch between localStorage and sessionStorage
-
Button to clear storage.
-
Button to dump the current db contents.
-
-
-
-
+
+
diff --git a/ext/wasm/kvvfs1.js b/ext/wasm/kvvfs1.js
index 169fcc8bdf..c29426fc63 100644
--- a/ext/wasm/kvvfs1.js
+++ b/ext/wasm/kvvfs1.js
@@ -19,12 +19,25 @@
const toss = function(...args){throw new Error(args.join(' '))};
const debug = console.debug.bind(console);
const eOutput = document.querySelector('#test-output');
- const log = console.log.bind(console)
- const logHtml = function(...args){
- log.apply(this, args);
+ const logC = console.log.bind(console)
+ const logE = function(domElement){
+ eOutput.append(domElement);
+ };
+ const logHtml = function(cssClass,...args){
const ln = document.createElement('div');
+ if(cssClass) ln.classList.add(cssClass);
ln.append(document.createTextNode(args.join(' ')));
- eOutput.append(ln);
+ logE(ln);
+ }
+ const log = function(...args){
+ logC(...args);
+ logHtml('',...args);
+ };
+ const warn = function(...args){
+ logHtml('warning',...args);
+ };
+ const error = function(...args){
+ logHtml('error',...args);
};
const runTests = function(Module){
@@ -34,10 +47,14 @@
oo = sqlite3.oo1,
wasm = capi.wasm;
log("Loaded module:",capi.sqlite3_libversion(), capi.sqlite3_sourceid());
- log("Build options:",wasm.compileOptionUsed());
T.assert( 0 !== capi.sqlite3_vfs_find(null) );
-
+ if(!oo.DB.clearKvvfsStorage){
+ warn("This build is not kvvfs-capable.");
+ return;
+ }
+
const dbStorage = 1 ? ':sessionStorage:' : ':localStorage:';
+ const theStore = 's'===dbStorage[1] ? sessionStorage : localStorage;
/**
The names ':sessionStorage:' and ':localStorage:' are handled
via the DB class constructor, not the C level. In the C API,
@@ -45,24 +62,52 @@
names for those keys, but that is subject to change.
*/
const db = new oo.DB( dbStorage );
- log("Storage backend:",db.filename /* note that the name was internally translated */);
- try {
- db.exec("create table if not exists t(a)");
- if(undefined===db.selectValue("select a from t limit 1")){
- log("New db. Populating. This DB will persist across page reloads.");
- db.exec("insert into t(a) values(1),(2),(3)");
- }else{
- log("Found existing table data:");
+
+ document.querySelector('#btn-clear-storage').addEventListener('click',function(){
+ oo.DB.clearKvvfsStorage();
+ log("kvvfs localStorage and sessionStorage cleared.");
+ });
+ document.querySelector('#btn-clear-log').addEventListener('click',function(){
+ eOutput.innerText = '';
+ });
+ document.querySelector('#btn-init-db').addEventListener('click',function(){
+ const saveSql = [];
+ try{
+ db.exec({
+ sql:["drop table if exists t;",
+ "create table if not exists t(a);",
+ "insert into t(a) values(?),(?),(?)"],
+ bind: [performance.now() >> 0,
+ (performance.now() * 2) >> 0,
+ (performance.now() / 2) >> 0],
+ saveSql
+ });
+ console.log("saveSql =",saveSql,theStore);
+ log("DB (re)initialized.");
+ }catch(e){
+ error(e.message);
+ }
+ });
+ const btnSelect = document.querySelector('#btn-select1');
+ btnSelect.addEventListener('click',function(){
+ log("DB rows:");
+ try{
db.exec({
sql: "select * from t order by a",
rowMode: 0,
- callback: function(v){log(v)}
+ callback: (v)=>log(v)
});
+ }catch(e){
+ error(e.message);
}
- }finally{
- db.close();
+ });
+ log("Storage backend:",db.filename /* note that the name was internally translated */);
+ if(0===db.selectValue('select count(*) from sqlite_master')){
+ log("DB is empty. Use the init button to populate it.");
+ }else{
+ log("DB contains data from a previous session. Use the Clear Ctorage button to delete it.");
+ btnSelect.click();
}
- log("End of demo.");
};
sqlite3InitModule(self.sqlite3TestModule).then(function(theModule){
diff --git a/manifest b/manifest
index c182819a97..f11a02ef2a 100644
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Merge\skv-vfs\sbranch\sinto\sfiddle-opfs\sbranch\sto\sadd\skvvfs-based\swasm\sbuild\sand\sdemo.
-D 2022-09-12T16:09:50.625
+C Add\ssqlite3.oo1.DB.clearKvvfsStorage().\sAdd\scontrols\sto\skvvfs1.js\sdemo\sto\sreset\sand\squery\sthe\sdb\swithout\srequiring\sthe\sdev\sconsole.
+D 2022-09-12T17:59:04.237
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -483,7 +483,7 @@ F ext/wasm/api/post-js-footer.js b64319261d920211b8700004d08b956a6c285f3b0bba814
F ext/wasm/api/post-js-header.js 0e853b78db83cb1c06b01663549e0e8b4f377f12f5a2d9a4a06cb776c003880b
F ext/wasm/api/sqlite3-api-cleanup.js 101919ec261644e2f6f0a59952fd9612127b69ea99b493277b2789ea478f9b6b
F ext/wasm/api/sqlite3-api-glue.js 2bf536a38cde324cf352bc2c575f8e22c6d204d667c0eda5a254ba45318914bc
-F ext/wasm/api/sqlite3-api-oo1.js a9d8892be246548a9978ace506d108954aa13eb5ce25332975c8377953804ff3
+F ext/wasm/api/sqlite3-api-oo1.js b498662748918c132aa59433ea2bd2ebb7e026549fd68506a1ae1ea94736f4f6
F ext/wasm/api/sqlite3-api-opfs.js 011799db398157cbd254264b6ebae00d7234b93d0e9e810345f213a5774993c0
F ext/wasm/api/sqlite3-api-prologue.js 9e37ce4dfd74926d0df80dd7e72e33085db4bcee48e2c21236039be416a7dff2
F ext/wasm/api/sqlite3-api-worker1.js d33062afa045fd4be01ba4abc266801807472558b862b30056211b00c9c347b4
@@ -507,8 +507,8 @@ F ext/wasm/jaccwabyt/jaccwabyt.md 447cc02b598f7792edaa8ae6853a7847b8178a18ed356a
F ext/wasm/jaccwabyt/jaccwabyt_test.c 39e4b865a33548f943e2eb9dd0dc8d619a80de05d5300668e9960fff30d0d36f
F ext/wasm/jaccwabyt/jaccwabyt_test.exports 5ff001ef975c426ffe88d7d8a6e96ec725e568d2c2307c416902059339c06f19
F ext/wasm/kvvfs.make dba616578bf91a76370a46494dd68a09c6dff5beb6d5561e2db65a27216e9630
-F ext/wasm/kvvfs1.html b8304cd5c7e7ec32c3b15521a95c322d6efdb8d22b3c4156123545dc54e07583
-F ext/wasm/kvvfs1.js a5075f98ffecd7d32348697db991fc61342d89aa20651034d1572af61890fb8b
+F ext/wasm/kvvfs1.html 83bac238d1e93ed102a461672fc58fe74e611e426708e9a5c66002c01eadb942
+F ext/wasm/kvvfs1.js 53721a42e0ec45f6978cc723e5de47f882517867d0fcff4c6ff05f4c422e27c4
F ext/wasm/scratchpad-opfs-main.html 4565cf194e66188190d35f70e82553e2e2d72b9809b73c94ab67b8cfd14d2e0c
F ext/wasm/scratchpad-opfs-main.js 69e960e9161f6412fd0c30f355d4112f1894d6609eb431e2d16d207d1380518e
F ext/wasm/scratchpad-opfs-worker.html 66c1d15d678f3bd306373d76b61c6c8aef988f61f4a8dd40185d452f9c6d2bf5
@@ -596,14 +596,14 @@ F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85
F src/os_kv.c a188e92dac693b1c1b512d93b0c4dc85c1baad11e322b01121f87057996e4d11
F src/os_setup.h 0711dbc4678f3ac52d7fe736951b6384a0615387c4ba5135a4764e4e31f4b6a6
F src/os_unix.c d6322b78130d995160bb9cfb7850678ad6838b08c1d13915461b33326a406c04
-F src/os_win.c e9454cb141908e8eef2102180bad353a36480612d5b736e4c2bd5777d9b25a34
+F src/os_win.c 8d129ae3e59e0fa900e20d0ad789e96f2e08177f0b00b53cdda65c40331e0902
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
F src/pager.c 6176d9752eb580419e8fef4592dc417a6b00ddfd43ee22f818819bf8840ceee8
F src/pager.h f82e9844166e1585f5786837ddc7709966138ced17f568c16af7ccf946c2baa3
F src/parse.y 8e67d820030d2655b9942ffe61c1e7e6b96cea2f2f72183533299393907d0564
-F src/pcache.c 22a6ebe498d1d26c85fd1e3bcb246d97b882c060027c1e1688fbea905f5ac3cf
+F src/pcache.c f4268f7f73c6a3db12ce22fd25bc68dc42315d19599414ab1207d7cf32f79197
F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586
-F src/pcache1.c 849a26ea9dc1e6a176b75dc576672a598170b0b46aeef87a981dd25e0af0ccf9
+F src/pcache1.c dee95e3cd2b61e6512dc814c5ab76d5eb36f0bfc9441dbb4260fccc0d12bbddc
F src/pragma.c 9bf7d8a2a9ad3bc36df3ec0d61817a44c38a1da527d59c26c203047f906e334a
F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7
F src/prepare.c 971d5819a4bda88038c2283d71fc0a2974ffc3dd480f9bd941341017abacfd1b
@@ -1981,7 +1981,7 @@ F tool/showstat4.c 0682ebea7abf4d3657f53c4a243f2e7eab48eab344ed36a94bb75dcd19a5c
F tool/showwal.c 0253c187ae16fdae9cde89e63e1dfcd3bb35e5416d066415f99e2f8cac6ab03d
F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe
F tool/spaceanal.tcl 1b5be34c6223cb1af06da2a10fb77863eb869b1962d055820b0a11cf2336ab45
-F tool/speed-check.sh ff74a68bb95a0341275f4d3c9a7d8a3800bd278aceecf1913295a1f0175bc3e6
+F tool/speed-check.sh 13f8e07dbfe25f3aecda33fb6068894665af61ca1360a7b654be0ad0c3f3ae0b
F tool/speedtest.tcl 06c76698485ccf597b9e7dbb1ac70706eb873355
F tool/speedtest16.c ecb6542862151c3e6509bbc00509b234562ae81e
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
@@ -2023,8 +2023,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 4e6ce329872eb733ba2f7f7879747c52761ae97790fd8ed169a25a79854cc3d9 e49682c5eac91958f143e639c5656ca54560d14f5805d514bf4aa0c206e63844
-R f15733833cf5e73dce86b4365f218581
+P a7d8b26acd3c1ae344369e4d70804c0cab45272c0983cfd32d616a0a7b28acb9
+R 984d02350bb7056e7ff7dbf797b44085
U stephan
-Z f2a01bf4c99986993a2e00b39e93be73
+Z f41406c18c315f5b1f10f4c607ad1f16
# Remove this line to create a well-formed Fossil manifest.
diff --git a/manifest.uuid b/manifest.uuid
index bde2102af8..c3f7434826 100644
--- a/manifest.uuid
+++ b/manifest.uuid
@@ -1 +1 @@
-a7d8b26acd3c1ae344369e4d70804c0cab45272c0983cfd32d616a0a7b28acb9
\ No newline at end of file
+d845c6c22bd5d3fffc66e0566df346d690dd8bd1fc1688e312161b1a1edcfd79
\ No newline at end of file
diff --git a/src/os_win.c b/src/os_win.c
index 2827b0b49b..d71fb39220 100644
--- a/src/os_win.c
+++ b/src/os_win.c
@@ -5763,7 +5763,8 @@ static int winFullPathname(
char *zFull /* Output buffer */
){
int rc;
- sqlite3_mutex *pMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR);
+ MUTEX_LOGIC( sqlite3_mutex *pMutex; )
+ MUTEX_LOGIC( pMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR); )
sqlite3_mutex_enter(pMutex);
rc = winFullPathnameNoMutex(pVfs, zRelative, nFull, zFull);
sqlite3_mutex_leave(pMutex);
diff --git a/src/pcache.c b/src/pcache.c
index 8c57f5b1eb..0407e06b2f 100644
--- a/src/pcache.c
+++ b/src/pcache.c
@@ -655,14 +655,14 @@ void sqlite3PcacheMove(PgHdr *p, Pgno newPgno){
assert( sqlite3PcachePageSanity(p) );
pcacheTrace(("%p.MOVE %d -> %d\n",pCache,p->pgno,newPgno));
pOther = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, newPgno, 0);
- sqlite3GlobalConfig.pcache2.xRekey(pCache->pCache, p->pPage, p->pgno,newPgno);
if( pOther ){
- PgHdr *pPg = (PgHdr*)pOther->pExtra;
- pPg->pgno = p->pgno;
- if( pPg->pPage==0 ){
- sqlite3GlobalConfig.pcache2.xUnpin(pCache->pCache, pOther, 0);
- }
+ PgHdr *pXPage = (PgHdr*)pOther->pExtra;
+ assert( pXPage->nRef==0 );
+ pXPage->nRef++;
+ pCache->nRefSum++;
+ sqlite3PcacheDrop(pXPage);
}
+ sqlite3GlobalConfig.pcache2.xRekey(pCache->pCache, p->pPage, p->pgno,newPgno);
p->pgno = newPgno;
if( (p->flags&PGHDR_DIRTY) && (p->flags&PGHDR_NEED_SYNC) ){
pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT);
diff --git a/src/pcache1.c b/src/pcache1.c
index a47087fa11..adbe953959 100644
--- a/src/pcache1.c
+++ b/src/pcache1.c
@@ -1125,7 +1125,7 @@ static void pcache1Rekey(
assert( iOld!=iNew ); /* The page number really is changing */
pcache1EnterMutex(pCache->pGroup);
-
+
assert( pcache1FetchNoMutex(p, iOld, 0)==pPage ); /* pPg really is iOld */
hOld = iOld%pCache->nHash;
pp = &pCache->apHash[hOld];
@@ -1134,23 +1134,8 @@ static void pcache1Rekey(
}
*pp = pPage->pNext;
+ assert( pcache1FetchNoMutex(p, iNew, 0)==0 ); /* iNew not in cache */
hNew = iNew%pCache->nHash;
- pp = &pCache->apHash[hNew];
- while( *pp ){
- if( (*pp)->iKey==iNew ){
- /* If there is already another pcache entry at iNew, change it to iOld,
- ** thus swapping the positions of iNew and iOld */
- PgHdr1 *pOld = *pp;
- *pp = pOld->pNext;
- pOld->pNext = pCache->apHash[hOld];
- pCache->apHash[hOld] = pOld;
- pOld->iKey = iOld;
- break;
- }else{
- pp = &(*pp)->pNext;
- }
- }
-
pPage->iKey = iNew;
pPage->pNext = pCache->apHash[hNew];
pCache->apHash[hNew] = pPage;
diff --git a/tool/speed-check.sh b/tool/speed-check.sh
index 6b0fbeb43a..879ffa9562 100644
--- a/tool/speed-check.sh
+++ b/tool/speed-check.sh
@@ -96,6 +96,9 @@ while test "$1" != ""; do
--cachesize)
shift; SPEEDTEST_OPTS="$SPEEDTEST_OPTS --cachesize $1"
;;
+ --stmtcache)
+ shift; SPEEDTEST_OPTS="$SPEEDTEST_OPTS --stmtcache $1"
+ ;;
--checkpoint)
SPEEDTEST_OPTS="$SPEEDTEST_OPTS --checkpoint"
;;
@@ -143,6 +146,9 @@ while test "$1" != ""; do
SPEEDTEST_OPTS="$SPEEDTEST_OPTS --testset rtree"
CC_OPTS="$CC_OPTS -DSQLITE_ENABLE_RTREE"
;;
+ --persist)
+ SPEEDTEST_OPTS="$SPEEDTEST_OPTS --persist"
+ ;;
--orm)
SPEEDTEST_OPTS="$SPEEDTEST_OPTS --testset orm"
;;