1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-29 08:01:23 +03:00

Add sqlite3.oo1.DB.clearKvvfsStorage(). Add controls to kvvfs1.js demo to reset and query the db without requiring the dev console.

FossilOrigin-Name: d845c6c22bd5d3fffc66e0566df346d690dd8bd1fc1688e312161b1a1edcfd79
This commit is contained in:
stephan
2022-09-12 17:59:04 +00:00
parent 5360f5fcff
commit a002cc174f
9 changed files with 132 additions and 77 deletions

View File

@ -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 */
});

View File

@ -24,18 +24,23 @@
<div class="emscripten">
<progress value="0" max="100" id="module-progress" hidden='1'></progress>
</div><!-- /emscripten bits -->
<div>Everything on this page happens in the dev console. TODOs for this demo include,
but are not necessarily limited to:
<ul>
<li>UI controls to switch between localStorage and sessionStorage</li>
<li>Button to clear storage.</li>
<li>Button to dump the current db contents.</li>
<!--li></li-->
</ul>
</div>
<hr>
<fieldset>
<legend>Options</legend>
<div class='toolbar'>
<button id='btn-clear-log'>Clear log</button>
<button id='btn-clear-storage'>Clear storage</button>
<button id='btn-init-db'>(Re)init db</button>
<button id='btn-select1'>Select db rows</button>
</div>
</fieldset>
<div id='test-output'></div>
<style>
.toolbar {
display: flex;
}
.toolbar > * { margin: 0.25em; }
fieldset { border-radius: 0.5em; }
</style>
<script src="sqlite3-kvvfs.js"></script>
<script src="common/SqliteTestUtil.js"></script>
<script src="kvvfs1.js"></script>

View File

@ -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){