Snapshot of upstream SQLite 3.43.2
[sqlcipher.git] / ext / wasm / demo-worker1-promiser.js
blobc2d24623a3908742dcaf6ce948b986f218a5b4cc
1 /*
2 2022-08-23
4 The author disclaims copyright to this source code. In place of a
5 legal notice, here is a blessing:
7 * May you do good and not evil.
8 * May you find forgiveness for yourself and forgive others.
9 * May you share freely, never taking more than you give.
11 ***********************************************************************
13 Demonstration of the sqlite3 Worker API #1 Promiser: a Promise-based
14 proxy for for the sqlite3 Worker #1 API.
16 'use strict';
17 (function(){
18 const T = self.SqliteTestUtil;
19 const eOutput = document.querySelector('#test-output');
20 const warn = console.warn.bind(console);
21 const error = console.error.bind(console);
22 const log = console.log.bind(console);
23 const logHtml = async function(cssClass,...args){
24 log.apply(this, args);
25 const ln = document.createElement('div');
26 if(cssClass) ln.classList.add(cssClass);
27 ln.append(document.createTextNode(args.join(' ')));
28 eOutput.append(ln);
31 let startTime;
32 const testCount = async ()=>{
33 logHtml("","Total test count:",T.counter+". Total time =",(performance.now() - startTime),"ms");
36 //why is this triggered even when we catch() a Promise?
37 //window.addEventListener('unhandledrejection', function(event) {
38 // warn('unhandledrejection',event);
39 //});
41 const promiserConfig = {
42 worker: ()=>{
43 const w = new Worker("jswasm/sqlite3-worker1.js");
44 w.onerror = (event)=>error("worker.onerror",event);
45 return w;
47 debug: 1 ? undefined : (...args)=>console.debug('worker debug',...args),
48 onunhandled: function(ev){
49 error("Unhandled worker message:",ev.data);
51 onready: function(){
52 self.sqlite3TestModule.setStatus(null)/*hide the HTML-side is-loading spinner*/;
53 runTests();
55 onerror: function(ev){
56 error("worker1 error:",ev);
59 const workerPromise = self.sqlite3Worker1Promiser(promiserConfig);
60 delete self.sqlite3Worker1Promiser;
62 const wtest = async function(msgType, msgArgs, callback){
63 if(2===arguments.length && 'function'===typeof msgArgs){
64 callback = msgArgs;
65 msgArgs = undefined;
67 const p = 1
68 ? workerPromise({type: msgType, args:msgArgs})
69 : workerPromise(msgType, msgArgs);
70 return callback ? p.then(callback).finally(testCount) : p;
73 let sqConfig;
74 const runTests = async function(){
75 const dbFilename = '/testing2.sqlite3';
76 startTime = performance.now();
78 await wtest('config-get', (ev)=>{
79 const r = ev.result;
80 log('sqlite3.config subset:', r);
81 T.assert('boolean' === typeof r.bigIntEnabled);
82 sqConfig = r;
83 });
84 logHtml('',
85 "Sending 'open' message and waiting for its response before continuing...");
87 await wtest('open', {
88 filename: dbFilename,
89 simulateError: 0 /* if true, fail the 'open' */,
90 }, function(ev){
91 const r = ev.result;
92 log("then open result",r);
93 T.assert(ev.dbId === r.dbId)
94 .assert(ev.messageId)
95 .assert('string' === typeof r.vfs);
96 promiserConfig.dbId = ev.dbId;
97 }).then(runTests2);
100 const runTests2 = async function(){
101 const mustNotReach = ()=>toss("This is not supposed to be reached.");
103 await wtest('exec',{
104 sql: ["create table t(a,b)",
105 "insert into t(a,b) values(1,2),(3,4),(5,6)"
106 ].join(';'),
107 resultRows: [], columnNames: [],
108 countChanges: sqConfig.bigIntEnabled ? 64 : true
109 }, function(ev){
110 ev = ev.result;
111 T.assert(0===ev.resultRows.length)
112 .assert(0===ev.columnNames.length)
113 .assert(sqConfig.bigIntEnabled
114 ? (3n===ev.changeCount)
115 : (3===ev.changeCount));
118 await wtest('exec',{
119 sql: 'select a a, b b from t order by a',
120 resultRows: [], columnNames: [],
121 }, function(ev){
122 ev = ev.result;
123 T.assert(3===ev.resultRows.length)
124 .assert(1===ev.resultRows[0][0])
125 .assert(6===ev.resultRows[2][1])
126 .assert(2===ev.columnNames.length)
127 .assert('b'===ev.columnNames[1]);
130 await wtest('exec',{
131 sql: 'select a a, b b from t order by a',
132 resultRows: [], columnNames: [],
133 rowMode: 'object',
134 countChanges: true
135 }, function(ev){
136 ev = ev.result;
137 T.assert(3===ev.resultRows.length)
138 .assert(1===ev.resultRows[0].a)
139 .assert(6===ev.resultRows[2].b)
140 .assert(0===ev.changeCount);
143 await wtest(
144 'exec',
145 {sql:'intentional_error'},
146 mustNotReach
147 ).catch((e)=>{
148 warn("Intentional error:",e);
151 await wtest('exec',{
152 sql:'select 1 union all select 3',
153 resultRows: []
154 }, function(ev){
155 ev = ev.result;
156 T.assert(2 === ev.resultRows.length)
157 .assert(1 === ev.resultRows[0][0])
158 .assert(3 === ev.resultRows[1][0])
159 .assert(undefined === ev.changeCount);
162 const resultRowTest1 = function f(ev){
163 if(undefined === f.counter) f.counter = 0;
164 if(null === ev.rowNumber){
165 /* End of result set. */
166 T.assert(undefined === ev.row)
167 .assert(2===ev.columnNames.length)
168 .assert('a'===ev.columnNames[0])
169 .assert('B'===ev.columnNames[1]);
170 }else{
171 T.assert(ev.rowNumber > 0);
172 ++f.counter;
174 log("exec() result row:",ev);
175 T.assert(null === ev.rowNumber || 'number' === typeof ev.row.B);
177 await wtest('exec',{
178 sql: 'select a a, b B from t order by a limit 3',
179 callback: resultRowTest1,
180 rowMode: 'object'
181 }, function(ev){
182 T.assert(3===resultRowTest1.counter);
183 resultRowTest1.counter = 0;
186 const resultRowTest2 = function f(ev){
187 if(null === ev.rowNumber){
188 /* End of result set. */
189 T.assert(undefined === ev.row)
190 .assert(1===ev.columnNames.length)
191 .assert('a'===ev.columnNames[0])
192 }else{
193 T.assert(ev.rowNumber > 0);
194 f.counter = ev.rowNumber;
196 log("exec() result row:",ev);
197 T.assert(null === ev.rowNumber || 'number' === typeof ev.row);
199 await wtest('exec',{
200 sql: 'select a a from t limit 3',
201 callback: resultRowTest2,
202 rowMode: 0
203 }, function(ev){
204 T.assert(3===resultRowTest2.counter);
207 const resultRowTest3 = function f(ev){
208 if(null === ev.rowNumber){
209 T.assert(3===ev.columnNames.length)
210 .assert('foo'===ev.columnNames[0])
211 .assert('bar'===ev.columnNames[1])
212 .assert('baz'===ev.columnNames[2]);
213 }else{
214 f.counter = ev.rowNumber;
215 T.assert('number' === typeof ev.row);
218 await wtest('exec',{
219 sql: "select 'foo' foo, a bar, 'baz' baz from t limit 2",
220 callback: resultRowTest3,
221 columnNames: [],
222 rowMode: '$bar'
223 }, function(ev){
224 log("exec() result row:",ev);
225 T.assert(2===resultRowTest3.counter);
228 await wtest('exec',{
229 sql:[
230 'pragma foreign_keys=0;',
231 // ^^^ arbitrary query with no result columns
232 'select a, b from t order by a desc; select a from t;'
233 // exec() only honors SELECT results from the first
234 // statement with result columns (regardless of whether
235 // it has any rows).
237 rowMode: 1,
238 resultRows: []
239 },function(ev){
240 const rows = ev.result.resultRows;
241 T.assert(3===rows.length).
242 assert(6===rows[0]);
245 await wtest('exec',{sql: 'delete from t where a>3'});
247 await wtest('exec',{
248 sql: 'select count(a) from t',
249 resultRows: []
250 },function(ev){
251 ev = ev.result;
252 T.assert(1===ev.resultRows.length)
253 .assert(2===ev.resultRows[0][0]);
256 await wtest('export', function(ev){
257 ev = ev.result;
258 T.assert('string' === typeof ev.filename)
259 .assert(ev.byteArray instanceof Uint8Array)
260 .assert(ev.byteArray.length > 1024)
261 .assert('application/x-sqlite3' === ev.mimetype);
264 /***** close() tests must come last. *****/
265 await wtest('close',{},function(ev){
266 T.assert('string' === typeof ev.result.filename);
269 await wtest('close', (ev)=>{
270 T.assert(undefined === ev.result.filename);
271 }).finally(()=>logHtml('',"That's all, folks!"));
272 }/*runTests2()*/;
274 log("Init complete, but async init bits may still be running.");
275 })();