picovolt 0.7.0 → 0.9.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 +10 -1
- package/package.json +9 -4
- package/picovolt_bg.wasm +0 -0
- package/sqlite.js +104 -0
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# PicoVolt (PVDB)
|
|
2
2
|
|
|
3
3
|
[](https://github.com/MiniJe/picovolt/actions/workflows/ci.yml)
|
|
4
|
-
[](CHANGELOG.md)
|
|
5
5
|
[](LICENSE)
|
|
6
6
|

|
|
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.
|
|
5
|
+
"version": "0.9.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 };
|