aboutsummaryrefslogtreecommitdiff
path: root/ext/wasm/demo-oo1.js
diff options
context:
space:
mode:
Diffstat (limited to 'ext/wasm/demo-oo1.js')
-rw-r--r--ext/wasm/demo-oo1.js232
1 files changed, 232 insertions, 0 deletions
diff --git a/ext/wasm/demo-oo1.js b/ext/wasm/demo-oo1.js
new file mode 100644
index 000000000..4564fe0dd
--- /dev/null
+++ b/ext/wasm/demo-oo1.js
@@ -0,0 +1,232 @@
+/*
+ 2022-08-16
+
+ The author disclaims copyright to this source code. In place of a
+ legal notice, here is a blessing:
+
+ * May you do good and not evil.
+ * May you find forgiveness for yourself and forgive others.
+ * May you share freely, never taking more than you give.
+
+ ***********************************************************************
+
+ A basic demonstration of the SQLite3 OO API #1, shorn of assertions
+ and the like to improve readability.
+*/
+'use strict';
+(function(){
+ const toss = function(...args){throw new Error(args.join(' '))};
+ const debug = console.debug.bind(console),
+ log = console.log.bind(console),
+ warn = console.warn.bind(console),
+ error = console.error.bind(console);
+
+ const demo1 = function(sqlite3){
+ const capi = sqlite3.capi,
+ oo = sqlite3.oo1,
+ wasm = capi.wasm;
+
+ const dbName = (
+ 0 ? "" : capi.sqlite3_web_persistent_dir()
+ )+"/mydb.sqlite3"
+ if(0 && capi.sqlite3_web_persistent_dir()){
+ capi.wasm.sqlite3_wasm_vfs_unlink(dbName);
+ }
+ const db = new oo.DB(dbName);
+ log("db =",db.filename);
+ /**
+ Never(!) rely on garbage collection to clean up DBs and
+ (especially) statements. Always wrap their lifetimes in
+ try/finally construct...
+ */
+ try {
+ log("Create a table...");
+ db.exec("CREATE TABLE IF NOT EXISTS t(a,b)");
+ //Equivalent:
+ db.exec({
+ sql:"CREATE TABLE IF NOT EXISTS t(a,b)"
+ // ... numerous other options ...
+ });
+ // SQL can be either a string or a byte array
+
+ log("Insert some data using exec()...");
+ let i;
+ for( i = 1; i <= 5; ++i ){
+ db.exec({
+ sql: "insert into t(a,b) values (?,?)",
+ // bind by parameter index...
+ bind: [i, i*2]
+ });
+ db.exec({
+ sql: "insert into t(a,b) values ($a,$b)",
+ // bind by parameter name...
+ bind: {$a: i * 3, $b: i * 4}
+ });
+ }
+
+ 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();
+ }
+ // Equivalent...
+ 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', // 'array', 'object', or 'stmt' (default)
+ 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,"=",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', // stmt === the default
+ 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, // === result column 1
+ callback: function(row){
+ log("row ",++this.counter,"b =",row);
+ }.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:",resultRows);
+
+ log("Create a scalar UDF...");
+ db.createFunction({
+ name: 'twice',
+ callback: function(arg){ // note the call arg count
+ 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);
+
+ if(0){
+ warn("UDF will throw because of incorrect arg count...");
+ db.exec("select twice(1,2,3)");
+ }
+
+ 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 = [];
+ D.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();
+ }
+
+ /**
+ Misc. DB features:
+
+ - get change count (total or statement-local, 32- or 64-bit)
+ - get its file name
+ - selectValue() takes SQL and returns first column of first row.
+
+ Misc. Stmt features:
+
+ - Various forms of bind()
+ - clearBindings()
+ - reset()
+ - Various forms of step()
+ - Variants of get() for explicit type treatment/conversion,
+ e.g. getInt(), getFloat(), getBlob(), getJSON()
+ - getColumnName(ndx), getColumnNames()
+ - getParamIndex(name)
+ */
+ }/*demo1()*/;
+
+ const runDemos = function(Module){
+ //log("Module.sqlite3",Module);
+ const sqlite3 = Module.sqlite3,
+ capi = sqlite3.capi;
+ log("Loaded module:",capi.sqlite3_libversion(), capi.sqlite3_sourceid());
+ log("sqlite3 namespace:",sqlite3);
+ try {
+ demo1(sqlite3);
+ }catch(e){
+ error("Exception:",e.message);
+ throw e;
+ }
+ };
+
+ //self.sqlite3TestModule.sqlite3ApiConfig.persistentDirName = "/hi";
+ self.sqlite3TestModule.initSqlite3().then(runDemos);
+})();