picovolt 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # PicoVolt (PVDB)
2
2
 
3
3
  [![CI](https://github.com/MiniJe/picovolt/actions/workflows/ci.yml/badge.svg)](https://github.com/MiniJe/picovolt/actions/workflows/ci.yml)
4
- [![Version](https://img.shields.io/badge/version-0.7.0-blue.svg)](CHANGELOG.md)
4
+ [![Version](https://img.shields.io/badge/version-0.8.0-blue.svg)](CHANGELOG.md)
5
5
  [![License: Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)
6
6
  ![Status: experimental](https://img.shields.io/badge/status-experimental-orange.svg)
7
7
 
@@ -143,6 +143,15 @@ For native languages, the `capi` feature builds a shared library exposing a C AB
143
143
  (ctypes); both return query results as the same JSON shape as the JavaScript
144
144
  binding. The bindings suit embedded use, not a concurrent server's primary store.
145
145
 
146
+ All bindings accept positional `?` parameters
147
+ (`db.query("... WHERE id = ?", [1])`), bound as safely-escaped SQL literals. For
148
+ a familiar surface, drop-in adapters are provided: a `better-sqlite3`-style
149
+ JavaScript API (`import Database from "picovolt/sqlite"`), a Python DB-API 2.0
150
+ module (`import picovolt.dbapi2 as sqlite`), and the Go `database/sql` driver
151
+ ([`bindings/go/pvsql`](bindings/go/pvsql)). Shared limits across all of them:
152
+ positional `?` only, no SQL transactions, no JOINs, and `CREATE TABLE` takes
153
+ column names only.
154
+
146
155
  ## Extending PicoVolt
147
156
 
148
157
  There are two extension paths: sandboxed WebAssembly user-defined functions, and
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "picovolt",
3
3
  "type": "module",
4
4
  "description": "PicoVolt (PVDB): a polymorphic embedded database engine in Rust.",
5
- "version": "0.7.0",
5
+ "version": "0.8.0",
6
6
  "license": "Apache-2.0",
7
7
  "repository": {
8
8
  "type": "git",
@@ -12,7 +12,8 @@
12
12
  "picovolt_bg.wasm",
13
13
  "picovolt.js",
14
14
  "picovolt_bg.js",
15
- "picovolt.d.ts"
15
+ "picovolt.d.ts",
16
+ "sqlite.js"
16
17
  ],
17
18
  "main": "picovolt.js",
18
19
  "types": "picovolt.d.ts",
@@ -26,5 +27,9 @@
26
27
  "storage-engine",
27
28
  "mvcc",
28
29
  "columnar"
29
- ]
30
- }
30
+ ],
31
+ "exports": {
32
+ ".": "./picovolt.js",
33
+ "./sqlite": "./sqlite.js"
34
+ }
35
+ }
package/picovolt_bg.wasm CHANGED
Binary file
package/sqlite.js ADDED
@@ -0,0 +1,104 @@
1
+ // A better-sqlite3-style synchronous API over PicoVolt's WebAssembly engine, so
2
+ // code written for better-sqlite3 can use PicoVolt with minimal change:
3
+ //
4
+ // import Database from "picovolt/sqlite";
5
+ // const db = new Database();
6
+ // db.exec("CREATE TABLE t (id, name)");
7
+ // db.prepare("INSERT INTO t VALUES (?, ?)").run(1, "alice");
8
+ // const rows = db.prepare("SELECT * FROM t WHERE id = ?").all(1);
9
+ // // [ { id: 1, name: "alice" } ]
10
+ //
11
+ // Limitations: parameters are positional `?` only (named `:id` params are not
12
+ // supported); there are no transactions; blob parameters are unsupported.
13
+
14
+ import { Db } from "./picovolt.js";
15
+
16
+ function rowToObject(columns, row) {
17
+ const obj = {};
18
+ for (let i = 0; i < columns.length; i++) obj[columns[i]] = row[i];
19
+ return obj;
20
+ }
21
+
22
+ // better-sqlite3 accepts bind values either positionally (`run(1, "a")`) or as a
23
+ // single array (`run([1, "a"])`); normalize both to one array.
24
+ function normalizeParams(args) {
25
+ if (args.length === 1 && Array.isArray(args[0])) return args[0];
26
+ return args;
27
+ }
28
+
29
+ class Statement {
30
+ constructor(db, sql) {
31
+ this._db = db;
32
+ this.source = sql;
33
+ }
34
+
35
+ _exec(args) {
36
+ const params = normalizeParams(args);
37
+ const json = params.length ? this._db._db.query(this.source, params) : this._db._db.query(this.source);
38
+ return JSON.parse(json);
39
+ }
40
+
41
+ run(...args) {
42
+ const r = this._exec(args);
43
+ return { changes: typeof r.mutated === "number" ? r.mutated : 0 };
44
+ }
45
+
46
+ get(...args) {
47
+ const r = this._exec(args);
48
+ if (!r.columns || !r.rows.length) return undefined;
49
+ return rowToObject(r.columns, r.rows[0]);
50
+ }
51
+
52
+ all(...args) {
53
+ const r = this._exec(args);
54
+ if (!r.columns) return [];
55
+ return r.rows.map((row) => rowToObject(r.columns, row));
56
+ }
57
+
58
+ *iterate(...args) {
59
+ yield* this.all(...args);
60
+ }
61
+ }
62
+
63
+ class Database {
64
+ constructor() {
65
+ this._db = new Db();
66
+ }
67
+
68
+ prepare(sql) {
69
+ return new Statement(this, sql);
70
+ }
71
+
72
+ // Run one or more `;`-separated statements with no bound parameters.
73
+ exec(sql) {
74
+ for (const stmt of sql.split(";").map((s) => s.trim()).filter(Boolean)) {
75
+ this._db.query(stmt);
76
+ }
77
+ return this;
78
+ }
79
+
80
+ // The most recent committed transaction id (upper bound for `... BEFORE tx`).
81
+ get currentTx() {
82
+ return this._db.currentTx();
83
+ }
84
+
85
+ // Export the database as a `.pvdb` byte image (Uint8Array).
86
+ serialize() {
87
+ return this._db.export();
88
+ }
89
+
90
+ pragma() {
91
+ throw new Error("picovolt: pragma is not supported");
92
+ }
93
+
94
+ transaction() {
95
+ throw new Error("picovolt: transactions are not supported");
96
+ }
97
+
98
+ close() {
99
+ /* the WebAssembly instance is reclaimed by the GC */
100
+ }
101
+ }
102
+
103
+ export default Database;
104
+ export { Database, Statement };