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:
@ -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 */
|
||||
});
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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){
|
||||
|
Reference in New Issue
Block a user