'use strict';
(function(){
let logHtml;
if(self.window === self ){
console.log("Running demo from main UI thread.");
logHtml = function(cssClass,...args){
const ln = document.createElement('div');
if(cssClass) ln.classList.add(cssClass);
ln.append(document.createTextNode(args.join(' ')));
document.body.append(ln);
};
}else{
console.log("Running demo from Worker thread.");
logHtml = function(cssClass,...args){
postMessage({
type:'log',
payload:{cssClass, args}
});
};
}
const log = (...args)=>logHtml('',...args);
const warn = (...args)=>logHtml('warning',...args);
const error = (...args)=>logHtml('error',...args);
const demo1 = function(sqlite3){
const capi = sqlite3.capi,
oo = sqlite3.oo1;
log("sqlite3 version",capi.sqlite3_libversion(), capi.sqlite3_sourceid());
const db = new oo.DB("/mydb.sqlite3",'ct');
log("transient db =",db.filename);
try {
log("Create a table...");
db.exec("CREATE TABLE IF NOT EXISTS t(a,b)");
db.exec({
sql:"CREATE TABLE IF NOT EXISTS t(a,b)"
});
log("Insert some data using exec()...");
let i;
for( i = 20; i <= 25; ++i ){
db.exec({
sql: "insert into t(a,b) values (?,?)",
bind: [i, i*2]
});
db.exec({
sql: "insert into t(a,b) values ($a,$b)",
bind: {$a: i * 10, $b: i * 20}
});
}
log("Insert using a prepared statement...");
let q = db.prepare([
"insert into t(a,b) ",
"values(?,?)"
]);
try {
for( i = 100; i < 103; ++i ){
q.bind( [i, i*2] ).step();
q.reset();
}
for( i = 103; i <= 105; ++i ){
q.bind(1, i).bind(2, i*2).stepReset();
}
}finally{
q.finalize();
}
log("Query data with exec() using rowMode 'array'...");
db.exec({
sql: "select a from t order by a limit 3",
rowMode: 'array', callback: function(row){
log("row ",++this.counter,"=",row);
}.bind({counter: 0})
});
log("Query data with exec() using rowMode 'object'...");
db.exec({
sql: "select a as aa, b as bb from t order by aa limit 3",
rowMode: 'object',
callback: function(row){
log("row ",++this.counter,"=",JSON.stringify(row));
}.bind({counter: 0})
});
log("Query data with exec() using rowMode 'stmt'...");
db.exec({
sql: "select a from t order by a limit 3",
rowMode: 'stmt',
callback: function(row){
log("row ",++this.counter,"get(0) =",row.get(0));
}.bind({counter: 0})
});
log("Query data with exec() using rowMode INTEGER (result column index)...");
db.exec({
sql: "select a, b from t order by a limit 3",
rowMode: 1, callback: function(row){
log("row ",++this.counter,"b =",row);
}.bind({counter: 0})
});
log("Query data with exec() using rowMode $COLNAME (result column name)...");
db.exec({
sql: "select a a, b from t order by a limit 3",
rowMode: '$a',
callback: function(value){
log("row ",++this.counter,"a =",value);
}.bind({counter: 0})
});
log("Query data with exec() without a callback...");
let resultRows = [];
db.exec({
sql: "select a, b from t order by a limit 3",
rowMode: 'object',
resultRows: resultRows
});
log("Result rows:",JSON.stringify(resultRows,undefined,2));
log("Create a scalar UDF...");
db.createFunction({
name: 'twice',
xFunc: function(pCx, arg){ return arg + arg;
}
});
log("Run scalar UDF and collect result column names...");
let columnNames = [];
db.exec({
sql: "select a, twice(a), twice(''||a) from t order by a desc limit 3",
columnNames: columnNames,
rowMode: 'stmt',
callback: function(row){
log("a =",row.get(0), "twice(a) =", row.get(1),
"twice(''||a) =",row.get(2));
}
});
log("Result column names:",columnNames);
try{
log("The following use of the twice() UDF will",
"fail because of incorrect arg count...");
db.exec("select twice(1,2,3)");
}catch(e){
warn("Got expected exception:",e.message);
}
try {
db.transaction( function(D) {
D.exec("delete from t");
log("In transaction: count(*) from t =",db.selectValue("select count(*) from t"));
throw new sqlite3.SQLite3Error("Demonstrating transaction() rollback");
});
}catch(e){
if(e instanceof sqlite3.SQLite3Error){
log("Got expected exception from db.transaction():",e.message);
log("count(*) from t =",db.selectValue("select count(*) from t"));
}else{
throw e;
}
}
try {
db.savepoint( function(D) {
D.exec("delete from t");
log("In savepoint: count(*) from t =",db.selectValue("select count(*) from t"));
D.savepoint(function(DD){
const rows = [];
DD.exec({
sql: ["insert into t(a,b) values(99,100);",
"select count(*) from t"],
rowMode: 0,
resultRows: rows
});
log("In nested savepoint. Row count =",rows[0]);
throw new sqlite3.SQLite3Error("Demonstrating nested savepoint() rollback");
})
});
}catch(e){
if(e instanceof sqlite3.SQLite3Error){
log("Got expected exception from nested db.savepoint():",e.message);
log("count(*) from t =",db.selectValue("select count(*) from t"));
}else{
throw e;
}
}
}finally{
db.close();
}
log("That's all, folks!");
};
log("Loading and initializing sqlite3 module...");
if(self.window!==self) {
let sqlite3Js = 'sqlite3.js';
const urlParams = new URL(self.location.href).searchParams;
if(urlParams.has('sqlite3.dir')){
sqlite3Js = urlParams.get('sqlite3.dir') + '/' + sqlite3Js;
}
importScripts(sqlite3Js);
}
self.sqlite3InitModule({
print: log,
printErr: error
}).then(function(sqlite3){
log("Done initializing. Running demo...");
try {
demo1(sqlite3);
}catch(e){
error("Exception:",e.message);
}
});
})();