xref: /sqlite-3.40.0/ext/wasm/test-opfs-vfs.js (revision ef9cd12e)
1/*
2  2022-09-17
3
4  The author disclaims copyright to this source code.  In place of a
5  legal notice, here is a blessing:
6
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.
10
11  ***********************************************************************
12
13  A testing ground for the OPFS VFS.
14
15  Summary of how this works:
16
17  This file uses the sqlite3.StructBinder-created struct wrappers for
18  sqlite3_vfs, sqlite3_io_methods, ans sqlite3_file to set up a
19  conventional sqlite3_vfs (except that it's implemented in JS). The
20  methods which require OPFS APIs use a separate worker (hereafter called the
21  OPFS worker) to access that functionality. This worker and that one
22  use SharedArrayBuffer.
23*/
24'use strict';
25const tryOpfsVfs = function(sqlite3){
26  const toss = function(...args){throw new Error(args.join(' '))};
27  const logPrefix = "OPFS tester:";
28  const log = (...args)=>console.log(logPrefix,...args);
29  const warn =  (...args)=>console.warn(logPrefix,...args);
30  const error =  (...args)=>console.error(logPrefix,...args);
31  const opfs = sqlite3.opfs;
32  log("tryOpfsVfs()");
33  if(!sqlite3.opfs){
34    const e = toss("OPFS is not available.");
35    error(e);
36    throw e;
37  }
38  const capi = sqlite3.capi;
39  const pVfs = capi.sqlite3_vfs_find("opfs") || toss("Missing 'opfs' VFS.");
40  const oVfs = capi.sqlite3_vfs.instanceForPointer(pVfs) || toss("Unexpected instanceForPointer() result.");;
41  log("OPFS VFS:",pVfs, oVfs);
42
43  const urlArgs = new URL(self.location.href).searchParams;
44  const dbFile = "my-persistent.db";
45  if(urlArgs.has('delete')) sqlite3.opfs.deleteEntry(dbFile);
46
47  const db = new opfs.OpfsDb(dbFile);
48  log("db file:",db.filename);
49  try{
50    if(opfs.entryExists(dbFile)){
51      let n = db.selectValue("select count(*) from sqlite_schema");
52      log("Persistent data found. sqlite_schema entry count =",n);
53    }
54    db.transaction((db)=>{
55      db.exec({
56        sql:[
57          "create table if not exists t(a);",
58          "insert into t(a) values(?),(?),(?);",
59        ],
60        bind: [performance.now() | 0,
61               (performance.now() |0) / 2,
62               (performance.now() |0) / 4]
63      });
64    });
65    log("count(*) from t =",db.selectValue("select count(*) from t"));
66
67    // Some sanity checks of the opfs utility functions...
68    const testDir = '/sqlite3-opfs-'+opfs.randomFilename(12);
69    const aDir = testDir+'/test/dir';
70    opfs.mkdir(aDir) || toss("mkdir failed");
71    opfs.mkdir(aDir) || toss("mkdir must pass if the dir exists");
72    opfs.deleteEntry(testDir+'/test') && toss("delete 1 should have failed (dir not empty)");
73    opfs.deleteEntry(testDir+'/test/dir') || toss("delete 2 failed");
74    opfs.deleteEntry(testDir+'/test/dir') && toss("delete 2b should have failed (dir already deleted)");
75    opfs.deleteEntry(testDir,true) || toss("delete 3 failed");
76    opfs.entryExists(testDir) && toss("entryExists(",testDir,") should have failed");
77  }finally{
78    db.close();
79  }
80
81  log("Done!");
82}/*tryOpfsVfs()*/;
83
84importScripts('sqlite3.js');
85self.sqlite3InitModule()
86  .then((sqlite3)=>tryOpfsVfs(sqlite3))
87  .catch((e)=>{
88    console.error("Error initializing module:",e);
89  });
90