picovolt 1.5.0 → 1.6.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 +22 -7
- package/package.json +1 -1
- package/picovolt.d.ts +16 -0
- package/picovolt_bg.js +35 -0
- package/picovolt_bg.wasm +0 -0
- package/sqlite.js +7 -5
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
|
[](https://github.com/MiniJe/picovolt)
|
|
@@ -58,6 +58,7 @@ Linux and Windows. Changes are tracked in [CHANGELOG.md](CHANGELOG.md).
|
|
|
58
58
|
| [`engine/interp.rs`](src/engine/interp.rs) | `pv-wasm`: a from-scratch WASM interpreter (integer subset) |
|
|
59
59
|
| [`engine/query.rs`](src/engine/query.rs) | SQL front-end (CREATE/INSERT/UPDATE/DELETE/DROP, `SELECT` with projection, `AS` aliases, `DISTINCT`, aggregates, `GROUP BY`/`HAVING`, `WHERE` predicates incl. `IN`/`BETWEEN`/`IS NULL`/`LIKE`, `BEFORE`, multi-column `ORDER BY`, `LIMIT`/`OFFSET`) |
|
|
60
60
|
| [`engine/compliance.rs`](src/engine/compliance.rs) | optional, app-driven usage-policy hook (not a license requirement) |
|
|
61
|
+
| [`enterprise.rs`](src/enterprise.rs) | optional, host-owned audit events and honest capability discovery for fleet integrations |
|
|
61
62
|
| [`db.rs`](src/db.rs) | the `Database` surface that ties it together |
|
|
62
63
|
| [`ffi.rs`](src/ffi.rs) | C ABI (the `capi` feature): a panic-safe, C-callable surface wrapping the engine for Go, Python, and C bindings |
|
|
63
64
|
|
|
@@ -86,6 +87,10 @@ Linux and Windows. Changes are tracked in [CHANGELOG.md](CHANGELOG.md).
|
|
|
86
87
|
each flush `fsync` the data and commit the manifest atomically (write to a temp
|
|
87
88
|
file, `fsync`, then rename). The default `Fast` mode uses the OS cache only:
|
|
88
89
|
fast and durable on a clean exit, but not power-loss-safe.
|
|
90
|
+
- **Crash-recoverable transactions.** Explicit `BEGIN`, `COMMIT`, and
|
|
91
|
+
`ROLLBACK` group filesystem or in-memory writes. Filesystem transactions keep
|
|
92
|
+
a synced rollback image and recovery marker; reopening after interruption
|
|
93
|
+
restores the last committed state before loading the workspace.
|
|
89
94
|
- **Hardened against untrusted input.** Opening a `.pvdb` or workspace, or running
|
|
90
95
|
a WASM module, validates manifest hashes (no path traversal), bounds-checks CAS
|
|
91
96
|
offsets and page chains (no out-of-bounds reads or infinite loops on a crafted
|
|
@@ -128,8 +133,9 @@ FROM t [WHERE <pred>] [GROUP BY cols] [HAVING <pred>] [BEFORE tx]
|
|
|
128
133
|
`AND`, `OR`, and parentheses. Integer and decimal values compare by magnitude.
|
|
129
134
|
Two-table equality `INNER`/`LEFT JOIN` queries support qualified references,
|
|
130
135
|
projection, aliases, `DISTINCT`, filters, ordering, and pagination. Rust callers
|
|
131
|
-
can cache `Database::prepare(...)` templates and use
|
|
132
|
-
atomic `Database::transaction(...)` closures with
|
|
136
|
+
can cache `Database::prepare(...)` templates and use explicit transaction
|
|
137
|
+
lifecycle methods or atomic `Database::transaction(...)` closures with both
|
|
138
|
+
filesystem and in-memory databases.
|
|
133
139
|
Durability is selectable via `Database::set_durability` (`Fast` OS-cache default,
|
|
134
140
|
or crash-safe `Sync` with fsync and an atomic manifest).
|
|
135
141
|
|
|
@@ -140,8 +146,9 @@ around 33k rows/s, linear), larger-than-RAM reads through a bounded buffer pool
|
|
|
140
146
|
lookups roughly 11,000 times faster than a scan, plus range predicates), MVCC
|
|
141
147
|
time-travel, opt-in crash-safe durability (`Durability::Sync`), and a fast
|
|
142
148
|
compile-and-publish path (CAS dedup, columnar compression, memory-mappable
|
|
143
|
-
single-file artifacts). Current limits include
|
|
144
|
-
|
|
149
|
+
single-file artifacts). Current limits include full-workspace transaction
|
|
150
|
+
backups rather than an incremental WAL, only basic two-table equality joins,
|
|
151
|
+
and no concurrent writers.
|
|
145
152
|
|
|
146
153
|
## Install and distribution
|
|
147
154
|
|
|
@@ -149,7 +156,7 @@ transactions, only basic two-table equality joins, and no concurrent writers.
|
|
|
149
156
|
|--------|-----|
|
|
150
157
|
| **Rust** (crates.io) | `cargo add picovolt` |
|
|
151
158
|
| **JavaScript / npm** (WebAssembly, browser and Node) | `npm install picovolt` |
|
|
152
|
-
| **Python** (native wheels) | `python -m pip install picovolt`
|
|
159
|
+
| **Python** (native wheels) | `python -m pip install picovolt` |
|
|
153
160
|
| **C / Go** (native, via the C ABI) | `cargo build --release --features capi`, then see [`bindings/`](bindings) |
|
|
154
161
|
| **In-memory** (native, no filesystem) | `Database::open_memory()`, export with `bake_to_bytes()` |
|
|
155
162
|
|
|
@@ -172,7 +179,8 @@ JavaScript API (`import Database from "picovolt/sqlite"`), a Python DB-API 2.0
|
|
|
172
179
|
module (`import picovolt.dbapi2 as sqlite`), and the Go `database/sql` driver
|
|
173
180
|
([`bindings/go/pvsql`](bindings/go/pvsql)). Shared limits include positional `?`
|
|
174
181
|
only and the intentionally compact SQL grammar; JavaScript and in-memory Rust
|
|
175
|
-
also expose rollback-capable transaction wrappers.
|
|
182
|
+
also expose rollback-capable transaction wrappers. Native bindings expose the
|
|
183
|
+
same transaction lifecycle through the C ABI.
|
|
176
184
|
|
|
177
185
|
## Server mode
|
|
178
186
|
|
|
@@ -197,6 +205,11 @@ result rows, and response size are bounded. TLS is not built in, so network
|
|
|
197
205
|
deployments still belong behind a TLS-terminating reverse proxy. See
|
|
198
206
|
[src/bin/server.rs](src/bin/server.rs).
|
|
199
207
|
|
|
208
|
+
The HTTP API is sessionless, so each request is an atomic statement and explicit
|
|
209
|
+
transaction-control statements are rejected. Applications needing a
|
|
210
|
+
multi-statement transaction should use an embedded language binding, where the
|
|
211
|
+
transaction belongs to one database handle.
|
|
212
|
+
|
|
200
213
|
Applications accepting SQL from users can also call `Database::query_with_limits`
|
|
201
214
|
directly and choose their own scan, result, memory, and deadline budgets.
|
|
202
215
|
|
|
@@ -212,6 +225,8 @@ native modules built on the public API. Both are documented in
|
|
|
212
225
|
|--|--|
|
|
213
226
|
| Roadmap | [ROADMAP.md](ROADMAP.md) |
|
|
214
227
|
| One-million-download plan | [docs/ROADMAP_1M_DOWNLOADS.md](docs/ROADMAP_1M_DOWNLOADS.md) |
|
|
228
|
+
| Monetization thesis | [docs/MONETIZATION.md](docs/MONETIZATION.md) |
|
|
229
|
+
| Enterprise integration foundation | [docs/ENTERPRISE.md](docs/ENTERPRISE.md) |
|
|
215
230
|
| Platform and file support | [docs/SUPPORT.md](docs/SUPPORT.md) |
|
|
216
231
|
| Contributing | [CONTRIBUTING.md](CONTRIBUTING.md) |
|
|
217
232
|
| Code of conduct | [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) |
|
package/package.json
CHANGED
package/picovolt.d.ts
CHANGED
|
@@ -7,6 +7,14 @@
|
|
|
7
7
|
export class Db {
|
|
8
8
|
free(): void;
|
|
9
9
|
[Symbol.dispose](): void;
|
|
10
|
+
/**
|
|
11
|
+
* Begin an explicit multi-statement in-memory transaction.
|
|
12
|
+
*/
|
|
13
|
+
beginTransaction(): void;
|
|
14
|
+
/**
|
|
15
|
+
* Commit the active transaction.
|
|
16
|
+
*/
|
|
17
|
+
commitTransaction(): void;
|
|
10
18
|
/**
|
|
11
19
|
* The most recently committed transaction id, the upper bound for a
|
|
12
20
|
* `... BEFORE tx` time-travel query.
|
|
@@ -21,6 +29,10 @@ export class Db {
|
|
|
21
29
|
* [`export`](Db::export)). Writable, with full time-travel history intact.
|
|
22
30
|
*/
|
|
23
31
|
static fromBytes(bytes: Uint8Array): Db;
|
|
32
|
+
/**
|
|
33
|
+
* Whether an explicit transaction is active.
|
|
34
|
+
*/
|
|
35
|
+
inTransaction(): boolean;
|
|
24
36
|
/**
|
|
25
37
|
* Create a new, empty in-memory database.
|
|
26
38
|
*/
|
|
@@ -40,6 +52,10 @@ export class Db {
|
|
|
40
52
|
* `{"done":true}` otherwise. Throws the error message (a string) on failure.
|
|
41
53
|
*/
|
|
42
54
|
query(sql: string, params: any): string;
|
|
55
|
+
/**
|
|
56
|
+
* Roll back the active transaction.
|
|
57
|
+
*/
|
|
58
|
+
rollbackTransaction(): void;
|
|
43
59
|
/**
|
|
44
60
|
* A JSON array of the table names in this database (for introspecting an
|
|
45
61
|
* uploaded `.pvdb` whose schema is unknown).
|
package/picovolt_bg.js
CHANGED
|
@@ -18,6 +18,24 @@ export class Db {
|
|
|
18
18
|
const ptr = this.__destroy_into_raw();
|
|
19
19
|
wasm.__wbg_db_free(ptr, 0);
|
|
20
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* Begin an explicit multi-statement in-memory transaction.
|
|
23
|
+
*/
|
|
24
|
+
beginTransaction() {
|
|
25
|
+
const ret = wasm.db_beginTransaction(this.__wbg_ptr);
|
|
26
|
+
if (ret[1]) {
|
|
27
|
+
throw takeFromExternrefTable0(ret[0]);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Commit the active transaction.
|
|
32
|
+
*/
|
|
33
|
+
commitTransaction() {
|
|
34
|
+
const ret = wasm.db_commitTransaction(this.__wbg_ptr);
|
|
35
|
+
if (ret[1]) {
|
|
36
|
+
throw takeFromExternrefTable0(ret[0]);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
21
39
|
/**
|
|
22
40
|
* The most recently committed transaction id, the upper bound for a
|
|
23
41
|
* `... BEFORE tx` time-travel query.
|
|
@@ -55,6 +73,14 @@ export class Db {
|
|
|
55
73
|
}
|
|
56
74
|
return Db.__wrap(ret[0]);
|
|
57
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* Whether an explicit transaction is active.
|
|
78
|
+
* @returns {boolean}
|
|
79
|
+
*/
|
|
80
|
+
inTransaction() {
|
|
81
|
+
const ret = wasm.db_inTransaction(this.__wbg_ptr);
|
|
82
|
+
return ret !== 0;
|
|
83
|
+
}
|
|
58
84
|
/**
|
|
59
85
|
* Create a new, empty in-memory database.
|
|
60
86
|
*/
|
|
@@ -110,6 +136,15 @@ export class Db {
|
|
|
110
136
|
wasm.__wbindgen_free(deferred3_0, deferred3_1, 1);
|
|
111
137
|
}
|
|
112
138
|
}
|
|
139
|
+
/**
|
|
140
|
+
* Roll back the active transaction.
|
|
141
|
+
*/
|
|
142
|
+
rollbackTransaction() {
|
|
143
|
+
const ret = wasm.db_rollbackTransaction(this.__wbg_ptr);
|
|
144
|
+
if (ret[1]) {
|
|
145
|
+
throw takeFromExternrefTable0(ret[0]);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
113
148
|
/**
|
|
114
149
|
* A JSON array of the table names in this database (for introspecting an
|
|
115
150
|
* uploaded `.pvdb` whose schema is unknown).
|
package/picovolt_bg.wasm
CHANGED
|
Binary file
|
package/sqlite.js
CHANGED
|
@@ -94,19 +94,21 @@ class Database {
|
|
|
94
94
|
throw new Error("picovolt: pragma is not supported");
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
// Wrap a synchronous callback in an
|
|
98
|
-
//
|
|
97
|
+
// Wrap a synchronous callback in an engine transaction, matching
|
|
98
|
+
// better-sqlite3's common pattern.
|
|
99
99
|
transaction(fn) {
|
|
100
100
|
if (typeof fn !== "function") throw new TypeError("transaction expects a function");
|
|
101
101
|
const db = this;
|
|
102
102
|
function wrapped(...args) {
|
|
103
103
|
if (db._inTransaction) return fn(...args);
|
|
104
|
-
|
|
104
|
+
db._db.beginTransaction();
|
|
105
105
|
db._inTransaction = true;
|
|
106
106
|
try {
|
|
107
|
-
|
|
107
|
+
const value = fn(...args);
|
|
108
|
+
db._db.commitTransaction();
|
|
109
|
+
return value;
|
|
108
110
|
} catch (error) {
|
|
109
|
-
db._db
|
|
111
|
+
if (db._db.inTransaction()) db._db.rollbackTransaction();
|
|
110
112
|
throw error;
|
|
111
113
|
} finally {
|
|
112
114
|
db._inTransaction = false;
|