flatsql 2.0.2 → 3.0.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/LICENSE +1 -1
- package/README.md +76 -64
- package/dist/artifacts/index.d.ts +1 -3
- package/dist/artifacts/index.d.ts.map +1 -1
- package/dist/artifacts/index.js +1 -3
- package/dist/artifacts/index.js.map +1 -1
- package/dist/response/artifact.d.ts +1 -2
- package/dist/response/artifact.d.ts.map +1 -1
- package/dist/response/artifact.js.map +1 -1
- package/dist/response/types.d.ts +6 -0
- package/dist/response/types.d.ts.map +1 -1
- package/dist/stress/index.d.ts +0 -1
- package/dist/stress/index.d.ts.map +1 -1
- package/dist/stress/index.js +0 -1
- package/dist/stress/index.js.map +1 -1
- package/dist/stress/native-publish-event-workload.d.ts.map +1 -1
- package/dist/stress/native-publish-event-workload.js +14 -4
- package/dist/stress/native-publish-event-workload.js.map +1 -1
- package/dist/stress/smoke-runner.d.ts.map +1 -1
- package/dist/stress/smoke-runner.js +6 -5
- package/dist/stress/smoke-runner.js.map +1 -1
- package/docs/PARTITION-STORE-WASM.md +241 -0
- package/docs/PARTITION-STORE.md +635 -0
- package/package.json +61 -22
- package/wasm/flatsql-io.js +4 -1
- package/wasm/flatsql-ps-threads.wasm +0 -0
- package/wasm/flatsql-wasi-noeh.wasm +0 -0
- package/wasm/flatsql-wasi.wasm +0 -0
- package/wasm/flatsql.js +1 -1
- package/wasm/flatsql.wasm +0 -0
- package/wasm/index.d.ts +2 -0
- package/wasm/index.js +16 -1
- package/wasm/integrity.json +28 -0
- package/wasm/ps-node-fault.d.mts +23 -0
- package/wasm/ps-node-fault.mjs +381 -0
- package/wasm/ps-node-guest.mjs +156 -0
- package/wasm/ps-node-host.d.mts +86 -0
- package/wasm/ps-node-host.mjs +431 -0
- package/wasm/ps-node-imports.mjs +847 -0
- package/wasm/ps.d.ts +21 -0
- package/wasm/ps.js +75 -0
- package/dist/artifacts/builder.d.ts +0 -31
- package/dist/artifacts/builder.d.ts.map +0 -1
- package/dist/artifacts/builder.js +0 -514
- package/dist/artifacts/builder.js.map +0 -1
- package/dist/artifacts/demo-extractors.d.ts +0 -15
- package/dist/artifacts/demo-extractors.d.ts.map +0 -1
- package/dist/artifacts/demo-extractors.js +0 -238
- package/dist/artifacts/demo-extractors.js.map +0 -1
- package/dist/artifacts/standalone-builder.d.ts +0 -62
- package/dist/artifacts/standalone-builder.d.ts.map +0 -1
- package/dist/artifacts/standalone-builder.js +0 -144
- package/dist/artifacts/standalone-builder.js.map +0 -1
- package/dist/artifacts/worker-client.d.ts +0 -32
- package/dist/artifacts/worker-client.d.ts.map +0 -1
- package/dist/artifacts/worker-client.js +0 -415
- package/dist/artifacts/worker-client.js.map +0 -1
- package/dist/core/database.d.ts +0 -86
- package/dist/core/database.d.ts.map +0 -1
- package/dist/core/database.js +0 -900
- package/dist/core/database.js.map +0 -1
- package/dist/core/index.d.ts +0 -3
- package/dist/core/index.d.ts.map +0 -1
- package/dist/core/index.js +0 -3
- package/dist/core/index.js.map +0 -1
- package/dist/core/table-store.d.ts +0 -30
- package/dist/core/table-store.d.ts.map +0 -1
- package/dist/core/table-store.js +0 -187
- package/dist/core/table-store.js.map +0 -1
- package/dist/flatbuffer-accessor.d.ts +0 -35
- package/dist/flatbuffer-accessor.d.ts.map +0 -1
- package/dist/flatbuffer-accessor.js +0 -114
- package/dist/flatbuffer-accessor.js.map +0 -1
- package/dist/index.d.ts +0 -15
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -22
- package/dist/index.js.map +0 -1
- package/dist/stress/publish-event-workload.d.ts +0 -3
- package/dist/stress/publish-event-workload.d.ts.map +0 -1
- package/dist/stress/publish-event-workload.js +0 -467
- package/dist/stress/publish-event-workload.js.map +0 -1
- package/wasm/flatsql-artifact.worker.js +0 -847
- package/wasm/standalone.d.ts +0 -122
- package/wasm/standalone.js +0 -914
package/wasm/standalone.js
DELETED
|
@@ -1,914 +0,0 @@
|
|
|
1
|
-
import { createFlatSqlIoImports, createMemoryBackend } from './flatsql-io.js';
|
|
2
|
-
|
|
3
|
-
const DEFAULT_STANDALONE_URL = new URL('./flatsql-wasi.wasm', import.meta.url);
|
|
4
|
-
|
|
5
|
-
const PARAM_NULL = 0;
|
|
6
|
-
const PARAM_BOOL = 1;
|
|
7
|
-
const PARAM_INT64 = 2;
|
|
8
|
-
const PARAM_FLOAT64 = 3;
|
|
9
|
-
const PARAM_STRING = 4;
|
|
10
|
-
const PARAM_BYTES = 5;
|
|
11
|
-
|
|
12
|
-
const textEncoder = new TextEncoder();
|
|
13
|
-
const textDecoder = new TextDecoder();
|
|
14
|
-
|
|
15
|
-
export function getFlatSQLStandaloneWasmURL() {
|
|
16
|
-
return DEFAULT_STANDALONE_URL;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
async function readViaFsPath(path) {
|
|
20
|
-
const fs = await import('node:fs/promises');
|
|
21
|
-
return new Uint8Array(await fs.readFile(path));
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
async function loadWasmBytes(options = {}) {
|
|
25
|
-
if (options.bytes instanceof Uint8Array) {
|
|
26
|
-
return options.bytes;
|
|
27
|
-
}
|
|
28
|
-
if (options.bytes instanceof ArrayBuffer) {
|
|
29
|
-
return new Uint8Array(options.bytes);
|
|
30
|
-
}
|
|
31
|
-
if (ArrayBuffer.isView(options.bytes)) {
|
|
32
|
-
return new Uint8Array(options.bytes.buffer, options.bytes.byteOffset, options.bytes.byteLength);
|
|
33
|
-
}
|
|
34
|
-
if (options.path) {
|
|
35
|
-
return readViaFsPath(options.path);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const wasmUrl = options.url ? new URL(options.url, import.meta.url) : DEFAULT_STANDALONE_URL;
|
|
39
|
-
if (wasmUrl.protocol === 'file:') {
|
|
40
|
-
const { fileURLToPath } = await import('node:url');
|
|
41
|
-
return readViaFsPath(fileURLToPath(wasmUrl));
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const response = await fetch(wasmUrl);
|
|
45
|
-
if (!response.ok) {
|
|
46
|
-
throw new Error(`Failed to load flatsql-wasi.wasm: ${response.status}`);
|
|
47
|
-
}
|
|
48
|
-
return new Uint8Array(await response.arrayBuffer());
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function makeWasiImports(state, options = {}) {
|
|
52
|
-
const stdout = options.stdout ?? (() => {});
|
|
53
|
-
const stderr = options.stderr ?? (() => {});
|
|
54
|
-
const stdin = options.stdin instanceof Uint8Array ? options.stdin : new Uint8Array();
|
|
55
|
-
let stdinOffset = 0;
|
|
56
|
-
|
|
57
|
-
function view() {
|
|
58
|
-
return new DataView(state.memory.buffer);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
function heap() {
|
|
62
|
-
return new Uint8Array(state.memory.buffer);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
function writeUint64(ptr, value) {
|
|
66
|
-
view().setBigUint64(ptr, BigInt(value), true);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
function readIov(iovPtr, iovIndex) {
|
|
70
|
-
const base = iovPtr + iovIndex * 8;
|
|
71
|
-
return {
|
|
72
|
-
ptr: view().getUint32(base, true),
|
|
73
|
-
length: view().getUint32(base + 4, true),
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
function writeFd(fd, iovPtr, iovCount, bytesWrittenPtr) {
|
|
78
|
-
let written = 0;
|
|
79
|
-
const chunks = [];
|
|
80
|
-
const memory = heap();
|
|
81
|
-
for (let index = 0; index < iovCount; index++) {
|
|
82
|
-
const iov = readIov(iovPtr, index);
|
|
83
|
-
chunks.push(memory.slice(iov.ptr, iov.ptr + iov.length));
|
|
84
|
-
written += iov.length;
|
|
85
|
-
}
|
|
86
|
-
view().setUint32(bytesWrittenPtr, written, true);
|
|
87
|
-
|
|
88
|
-
if (chunks.length > 0) {
|
|
89
|
-
const total = new Uint8Array(written);
|
|
90
|
-
let offset = 0;
|
|
91
|
-
for (const chunk of chunks) {
|
|
92
|
-
total.set(chunk, offset);
|
|
93
|
-
offset += chunk.length;
|
|
94
|
-
}
|
|
95
|
-
const text = textDecoder.decode(total);
|
|
96
|
-
if (fd === 2) {
|
|
97
|
-
stderr(text);
|
|
98
|
-
} else {
|
|
99
|
-
stdout(text);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
return 0;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
function readFd(fd, iovPtr, iovCount, bytesReadPtr) {
|
|
106
|
-
if (fd !== 0 || stdinOffset >= stdin.length) {
|
|
107
|
-
view().setUint32(bytesReadPtr, 0, true);
|
|
108
|
-
return 0;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
let read = 0;
|
|
112
|
-
const memory = heap();
|
|
113
|
-
for (let index = 0; index < iovCount && stdinOffset < stdin.length; index++) {
|
|
114
|
-
const iov = readIov(iovPtr, index);
|
|
115
|
-
const length = Math.min(iov.length, stdin.length - stdinOffset);
|
|
116
|
-
memory.set(stdin.subarray(stdinOffset, stdinOffset + length), iov.ptr);
|
|
117
|
-
stdinOffset += length;
|
|
118
|
-
read += length;
|
|
119
|
-
}
|
|
120
|
-
view().setUint32(bytesReadPtr, read, true);
|
|
121
|
-
return 0;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
function randomGet(ptr, length) {
|
|
125
|
-
const target = heap().subarray(ptr, ptr + length);
|
|
126
|
-
const cryptoApi = globalThis.crypto;
|
|
127
|
-
if (cryptoApi?.getRandomValues) {
|
|
128
|
-
cryptoApi.getRandomValues(target);
|
|
129
|
-
return 0;
|
|
130
|
-
}
|
|
131
|
-
for (let index = 0; index < target.length; index++) {
|
|
132
|
-
target[index] = Math.floor(Math.random() * 256);
|
|
133
|
-
}
|
|
134
|
-
return 0;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
return {
|
|
138
|
-
wasi_snapshot_preview1: {
|
|
139
|
-
clock_time_get(clockId, _precision, timePtr) {
|
|
140
|
-
const millis = clockId === 0 ? Date.now() : performance.now();
|
|
141
|
-
writeUint64(timePtr, Math.round(millis * 1_000_000));
|
|
142
|
-
return 0;
|
|
143
|
-
},
|
|
144
|
-
fd_write: writeFd,
|
|
145
|
-
fd_read: readFd,
|
|
146
|
-
environ_sizes_get(environCountPtr, environBufferSizePtr) {
|
|
147
|
-
view().setUint32(environCountPtr, 0, true);
|
|
148
|
-
view().setUint32(environBufferSizePtr, 0, true);
|
|
149
|
-
return 0;
|
|
150
|
-
},
|
|
151
|
-
environ_get() {
|
|
152
|
-
return 0;
|
|
153
|
-
},
|
|
154
|
-
random_get: randomGet,
|
|
155
|
-
},
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
function encodeQueryParams(params) {
|
|
160
|
-
const parts = [];
|
|
161
|
-
let total = 0;
|
|
162
|
-
|
|
163
|
-
for (const value of params) {
|
|
164
|
-
let tag;
|
|
165
|
-
let payload;
|
|
166
|
-
|
|
167
|
-
if (value === null) {
|
|
168
|
-
tag = PARAM_NULL;
|
|
169
|
-
payload = new Uint8Array(0);
|
|
170
|
-
} else if (typeof value === 'boolean') {
|
|
171
|
-
tag = PARAM_BOOL;
|
|
172
|
-
payload = Uint8Array.of(value ? 1 : 0);
|
|
173
|
-
} else if (typeof value === 'number' && Number.isInteger(value)) {
|
|
174
|
-
if (!Number.isSafeInteger(value)) {
|
|
175
|
-
throw new TypeError('Integer query parameters must be safe integers');
|
|
176
|
-
}
|
|
177
|
-
tag = PARAM_INT64;
|
|
178
|
-
payload = new Uint8Array(8);
|
|
179
|
-
new DataView(payload.buffer).setBigInt64(0, BigInt(value), true);
|
|
180
|
-
} else if (typeof value === 'number') {
|
|
181
|
-
tag = PARAM_FLOAT64;
|
|
182
|
-
payload = new Uint8Array(8);
|
|
183
|
-
new DataView(payload.buffer).setFloat64(0, value, true);
|
|
184
|
-
} else if (typeof value === 'string') {
|
|
185
|
-
tag = PARAM_STRING;
|
|
186
|
-
payload = textEncoder.encode(value);
|
|
187
|
-
} else if (value instanceof Uint8Array) {
|
|
188
|
-
tag = PARAM_BYTES;
|
|
189
|
-
payload = value;
|
|
190
|
-
} else {
|
|
191
|
-
throw new TypeError(`Unsupported query parameter type: ${typeof value}`);
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
const header = new Uint8Array(5);
|
|
195
|
-
const headerView = new DataView(header.buffer);
|
|
196
|
-
headerView.setUint8(0, tag);
|
|
197
|
-
headerView.setUint32(1, payload.length, true);
|
|
198
|
-
parts.push(header, payload);
|
|
199
|
-
total += header.length + payload.length;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
const encoded = new Uint8Array(total);
|
|
203
|
-
let offset = 0;
|
|
204
|
-
for (const part of parts) {
|
|
205
|
-
encoded.set(part, offset);
|
|
206
|
-
offset += part.length;
|
|
207
|
-
}
|
|
208
|
-
return encoded;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
function encodeQueryRequests(queries) {
|
|
212
|
-
const parts = [];
|
|
213
|
-
let total = 0;
|
|
214
|
-
|
|
215
|
-
for (const query of queries) {
|
|
216
|
-
const sqlBytes = textEncoder.encode(query.sql);
|
|
217
|
-
const params = query.params ?? [];
|
|
218
|
-
const paramBytes = encodeQueryParams(params);
|
|
219
|
-
const header = new Uint8Array(12);
|
|
220
|
-
const headerView = new DataView(header.buffer);
|
|
221
|
-
headerView.setUint32(0, sqlBytes.length, true);
|
|
222
|
-
headerView.setUint32(4, params.length, true);
|
|
223
|
-
headerView.setUint32(8, paramBytes.length, true);
|
|
224
|
-
parts.push(header, sqlBytes, paramBytes);
|
|
225
|
-
total += header.length + sqlBytes.length + paramBytes.length;
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
const encoded = new Uint8Array(total);
|
|
229
|
-
let offset = 0;
|
|
230
|
-
for (const part of parts) {
|
|
231
|
-
encoded.set(part, offset);
|
|
232
|
-
offset += part.length;
|
|
233
|
-
}
|
|
234
|
-
return encoded;
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
function buildSizePrefixedStream(buffers) {
|
|
238
|
-
let total = 0;
|
|
239
|
-
for (const buffer of buffers) {
|
|
240
|
-
total += 4 + buffer.length;
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
const stream = new Uint8Array(total);
|
|
244
|
-
let offset = 0;
|
|
245
|
-
for (const buffer of buffers) {
|
|
246
|
-
new DataView(stream.buffer, offset, 4).setUint32(0, buffer.length, true);
|
|
247
|
-
offset += 4;
|
|
248
|
-
stream.set(buffer, offset);
|
|
249
|
-
offset += buffer.length;
|
|
250
|
-
}
|
|
251
|
-
return stream;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
function createRuntime(exports) {
|
|
255
|
-
const memory = exports.memory;
|
|
256
|
-
if (!(memory instanceof WebAssembly.Memory)) {
|
|
257
|
-
throw new Error('Standalone FlatSQL artifact does not export WebAssembly.Memory as memory.');
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
function heap() {
|
|
261
|
-
return new Uint8Array(memory.buffer);
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
function malloc(size) {
|
|
265
|
-
const ptr = exports.malloc(size);
|
|
266
|
-
if (!ptr) {
|
|
267
|
-
throw new Error(`FlatSQL standalone allocation failed for ${size} bytes`);
|
|
268
|
-
}
|
|
269
|
-
return ptr;
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
function free(ptr) {
|
|
273
|
-
if (ptr) {
|
|
274
|
-
exports.free(ptr);
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
function readCString(ptr) {
|
|
279
|
-
if (!ptr) {
|
|
280
|
-
return '';
|
|
281
|
-
}
|
|
282
|
-
const memoryBytes = heap();
|
|
283
|
-
if (ptr < 0 || ptr >= memoryBytes.length) {
|
|
284
|
-
throw new Error(`FlatSQL standalone string pointer is outside memory: ${ptr}`);
|
|
285
|
-
}
|
|
286
|
-
let end = ptr;
|
|
287
|
-
while (end < memoryBytes.length && memoryBytes[end] !== 0) {
|
|
288
|
-
end++;
|
|
289
|
-
}
|
|
290
|
-
if (end === memoryBytes.length) {
|
|
291
|
-
throw new Error(`FlatSQL standalone string is not null-terminated at pointer ${ptr}`);
|
|
292
|
-
}
|
|
293
|
-
return textDecoder.decode(memoryBytes.subarray(ptr, end));
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
function withCString(value, callback) {
|
|
297
|
-
const bytes = textEncoder.encode(String(value));
|
|
298
|
-
const ptr = malloc(bytes.length + 1);
|
|
299
|
-
try {
|
|
300
|
-
heap().set(bytes, ptr);
|
|
301
|
-
heap()[ptr + bytes.length] = 0;
|
|
302
|
-
return callback(ptr);
|
|
303
|
-
} finally {
|
|
304
|
-
free(ptr);
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
function withBytes(bytes, callback) {
|
|
309
|
-
if (bytes.length === 0) {
|
|
310
|
-
return callback(0);
|
|
311
|
-
}
|
|
312
|
-
const ptr = malloc(bytes.length);
|
|
313
|
-
try {
|
|
314
|
-
heap().set(bytes, ptr);
|
|
315
|
-
return callback(ptr);
|
|
316
|
-
} finally {
|
|
317
|
-
free(ptr);
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
function check(success) {
|
|
322
|
-
if (!success) {
|
|
323
|
-
throw new Error(readCString(exports.flatsql_get_error()));
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
function readCellValue(row, column) {
|
|
328
|
-
const type = exports.flatsql_result_cell_type(row, column);
|
|
329
|
-
switch (type) {
|
|
330
|
-
case 0:
|
|
331
|
-
return null;
|
|
332
|
-
case 1:
|
|
333
|
-
return exports.flatsql_result_cell_number(row, column) !== 0;
|
|
334
|
-
case 2:
|
|
335
|
-
case 3:
|
|
336
|
-
case 4:
|
|
337
|
-
return exports.flatsql_result_cell_number(row, column);
|
|
338
|
-
case 5:
|
|
339
|
-
return readCString(exports.flatsql_result_cell_string(row, column));
|
|
340
|
-
case 6: {
|
|
341
|
-
const ptr = exports.flatsql_result_cell_blob(row, column);
|
|
342
|
-
const size = exports.flatsql_result_cell_blob_size(row, column);
|
|
343
|
-
return ptr && size > 0 ? Array.from(heap().slice(ptr, ptr + size)) : [];
|
|
344
|
-
}
|
|
345
|
-
default:
|
|
346
|
-
return null;
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
function readQueryResult() {
|
|
351
|
-
const columnCount = exports.flatsql_result_column_count();
|
|
352
|
-
const rowCount = exports.flatsql_result_row_count();
|
|
353
|
-
const columns = [];
|
|
354
|
-
const rows = [];
|
|
355
|
-
|
|
356
|
-
for (let column = 0; column < columnCount; column++) {
|
|
357
|
-
columns.push(readCString(exports.flatsql_result_column_name(column)));
|
|
358
|
-
}
|
|
359
|
-
for (let row = 0; row < rowCount; row++) {
|
|
360
|
-
const values = [];
|
|
361
|
-
for (let column = 0; column < columnCount; column++) {
|
|
362
|
-
values.push(readCellValue(row, column));
|
|
363
|
-
}
|
|
364
|
-
rows.push(values);
|
|
365
|
-
}
|
|
366
|
-
return { columns, rows };
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
return {
|
|
370
|
-
exports,
|
|
371
|
-
memory,
|
|
372
|
-
readCString,
|
|
373
|
-
withCString,
|
|
374
|
-
withBytes,
|
|
375
|
-
check,
|
|
376
|
-
readQueryResult,
|
|
377
|
-
readBytes(ptr, size) {
|
|
378
|
-
return heap().slice(ptr, ptr + size);
|
|
379
|
-
},
|
|
380
|
-
};
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
export async function loadFlatSQLStandalone(options = {}) {
|
|
384
|
-
const wasmBytes = await loadWasmBytes(options);
|
|
385
|
-
const state = { memory: null };
|
|
386
|
-
const imports = makeWasiImports(state, options.wasi ?? options);
|
|
387
|
-
|
|
388
|
-
// The seven-import host I/O contract (cpp/include/flatsql/flatsql_io.h).
|
|
389
|
-
// The module imports these unconditionally, so they are always supplied: with
|
|
390
|
-
// no backend the default is in-memory, which keeps the historical ephemeral
|
|
391
|
-
// behaviour byte-for-byte and never pretends a path is durable.
|
|
392
|
-
const io = options.io ?? createMemoryBackend();
|
|
393
|
-
imports.env = {
|
|
394
|
-
...createFlatSqlIoImports(io, () => state.memory),
|
|
395
|
-
...(imports.env ?? {}),
|
|
396
|
-
};
|
|
397
|
-
|
|
398
|
-
const mergedImports = options.imports
|
|
399
|
-
? {
|
|
400
|
-
...imports,
|
|
401
|
-
...options.imports,
|
|
402
|
-
env: {
|
|
403
|
-
...imports.env,
|
|
404
|
-
...(options.imports.env ?? {}),
|
|
405
|
-
},
|
|
406
|
-
wasi_snapshot_preview1: {
|
|
407
|
-
...imports.wasi_snapshot_preview1,
|
|
408
|
-
...(options.imports.wasi_snapshot_preview1 ?? {}),
|
|
409
|
-
},
|
|
410
|
-
}
|
|
411
|
-
: imports;
|
|
412
|
-
const { instance, module } = await WebAssembly.instantiate(wasmBytes, mergedImports);
|
|
413
|
-
state.memory = instance.exports.memory;
|
|
414
|
-
|
|
415
|
-
if (typeof instance.exports._initialize === 'function') {
|
|
416
|
-
instance.exports._initialize();
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
return new FlatSQLStandalone(createRuntime(instance.exports), module, io);
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
export const createStandaloneFlatSQL = loadFlatSQLStandalone;
|
|
423
|
-
|
|
424
|
-
export class FlatSQLStandalone {
|
|
425
|
-
constructor(runtime, module, io) {
|
|
426
|
-
this._runtime = runtime;
|
|
427
|
-
this.module = module;
|
|
428
|
-
this.memory = runtime.memory;
|
|
429
|
-
// The I/O backend this instance was wired to. Callers await io.hydrate()
|
|
430
|
-
// before opening a disk-backed database and io.flush() after
|
|
431
|
-
// flushIndex(); on synchronous backends both are no-ops.
|
|
432
|
-
this.io = io ?? null;
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
/**
|
|
436
|
-
* Disk-backed open. `path` is a name in the backend's namespace — a real
|
|
437
|
-
* path under a WASI preopen, a key prefix in a browser store. The module
|
|
438
|
-
* never learns which, and that is the point.
|
|
439
|
-
*
|
|
440
|
-
* journalMode: 0 DELETE, 1 WAL (unavailable on wasm), 2 TRUNCATE, 3 MEMORY.
|
|
441
|
-
* TRUNCATE is the wasm default because WAL needs xShmMap shared memory that
|
|
442
|
-
* neither lane provides (docs/STORAGE-DURABILITY.md §3.5).
|
|
443
|
-
*/
|
|
444
|
-
openDatabase(schema, dbName = 'default', path = '', journalMode = 2) {
|
|
445
|
-
const handle = this._runtime.withCString(schema, (schemaPtr) =>
|
|
446
|
-
this._runtime.withCString(dbName, (namePtr) =>
|
|
447
|
-
this._runtime.withCString(path ?? '', (pathPtr) =>
|
|
448
|
-
this._runtime.exports.flatsql_open_db(schemaPtr, namePtr, pathPtr, journalMode)
|
|
449
|
-
)
|
|
450
|
-
)
|
|
451
|
-
);
|
|
452
|
-
if (!handle) {
|
|
453
|
-
const errPtr = this._runtime.exports.flatsql_get_error();
|
|
454
|
-
const message = errPtr ? this._runtime.readCString(errPtr) : 'unknown error';
|
|
455
|
-
throw new Error(`Failed to open FlatSQL database at "${path}": ${message}`);
|
|
456
|
-
}
|
|
457
|
-
return new FlatSQLStandaloneDatabase(this._runtime, handle);
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
createDatabase(schema, dbName = 'default') {
|
|
461
|
-
const handle = this._runtime.withCString(schema, (schemaPtr) =>
|
|
462
|
-
this._runtime.withCString(dbName, (namePtr) =>
|
|
463
|
-
this._runtime.exports.flatsql_create_db(schemaPtr, namePtr)
|
|
464
|
-
)
|
|
465
|
-
);
|
|
466
|
-
if (!handle) {
|
|
467
|
-
throw new Error('Failed to create FlatSQL standalone database.');
|
|
468
|
-
}
|
|
469
|
-
return new FlatSQLStandaloneDatabase(this._runtime, handle);
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
createTestUser(id, name, email, age) {
|
|
473
|
-
const ptr = this._runtime.withCString(name, (namePtr) =>
|
|
474
|
-
this._runtime.withCString(email, (emailPtr) =>
|
|
475
|
-
this._runtime.exports.flatsql_create_test_user(id, namePtr, emailPtr, age)
|
|
476
|
-
)
|
|
477
|
-
);
|
|
478
|
-
const size = this._runtime.exports.flatsql_test_buffer_size();
|
|
479
|
-
return this._runtime.readBytes(ptr, size);
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
createTestPost(id, userId, title) {
|
|
483
|
-
const ptr = this._runtime.withCString(title, (titlePtr) =>
|
|
484
|
-
this._runtime.exports.flatsql_create_test_post(id, userId, titlePtr)
|
|
485
|
-
);
|
|
486
|
-
const size = this._runtime.exports.flatsql_test_buffer_size();
|
|
487
|
-
return this._runtime.readBytes(ptr, size);
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
createTestPublishEvent(fileId, recordId, eventIndex, payloadSize) {
|
|
491
|
-
const ptr = this._runtime.withCString(fileId, (fileIdPtr) =>
|
|
492
|
-
this._runtime.withCString(recordId, (recordIdPtr) =>
|
|
493
|
-
this._runtime.exports.flatsql_create_test_publish_event(
|
|
494
|
-
fileIdPtr,
|
|
495
|
-
recordIdPtr,
|
|
496
|
-
eventIndex,
|
|
497
|
-
payloadSize
|
|
498
|
-
)
|
|
499
|
-
)
|
|
500
|
-
);
|
|
501
|
-
const size = this._runtime.exports.flatsql_test_buffer_size();
|
|
502
|
-
return this._runtime.readBytes(ptr, size);
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
buildQueryCacheKey(dataset, artifactVersion, queryId, params = []) {
|
|
506
|
-
const paramBytes = encodeQueryParams(params);
|
|
507
|
-
const keyPtr = this._runtime.withCString(dataset, (datasetPtr) =>
|
|
508
|
-
this._runtime.withCString(artifactVersion, (versionPtr) =>
|
|
509
|
-
this._runtime.withCString(queryId, (queryIdPtr) =>
|
|
510
|
-
this._runtime.withBytes(paramBytes, (paramPtr) =>
|
|
511
|
-
this._runtime.exports.flatsql_build_query_cache_key(
|
|
512
|
-
datasetPtr,
|
|
513
|
-
versionPtr,
|
|
514
|
-
queryIdPtr,
|
|
515
|
-
paramPtr,
|
|
516
|
-
paramBytes.length,
|
|
517
|
-
params.length
|
|
518
|
-
)
|
|
519
|
-
)
|
|
520
|
-
)
|
|
521
|
-
)
|
|
522
|
-
);
|
|
523
|
-
const key = this._runtime.readCString(keyPtr);
|
|
524
|
-
if (!key) {
|
|
525
|
-
throw new Error(this._runtime.readCString(this._runtime.exports.flatsql_get_error()));
|
|
526
|
-
}
|
|
527
|
-
return key;
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
buildResponseArtifactCacheKey(schemaName, schemaVersion, sql, options = {}) {
|
|
531
|
-
const format = options.format ?? 'json';
|
|
532
|
-
const publishEventKey = options.publishEventKey ?? '';
|
|
533
|
-
const projectionList = (options.projection ?? []).join('\n');
|
|
534
|
-
const params = options.params ?? [];
|
|
535
|
-
const paramBytes = encodeQueryParams(params);
|
|
536
|
-
const keyPtr = this._runtime.withCString(schemaName, (schemaPtr) =>
|
|
537
|
-
this._runtime.withCString(schemaVersion, (versionPtr) =>
|
|
538
|
-
this._runtime.withCString(sql, (sqlPtr) =>
|
|
539
|
-
this._runtime.withCString(format, (formatPtr) =>
|
|
540
|
-
this._runtime.withCString(publishEventKey, (eventPtr) =>
|
|
541
|
-
this._runtime.withCString(projectionList, (projectionPtr) =>
|
|
542
|
-
this._runtime.withBytes(paramBytes, (paramPtr) =>
|
|
543
|
-
this._runtime.exports.flatsql_build_response_artifact_cache_key(
|
|
544
|
-
schemaPtr,
|
|
545
|
-
versionPtr,
|
|
546
|
-
sqlPtr,
|
|
547
|
-
formatPtr,
|
|
548
|
-
eventPtr,
|
|
549
|
-
projectionPtr,
|
|
550
|
-
paramPtr,
|
|
551
|
-
paramBytes.length,
|
|
552
|
-
params.length
|
|
553
|
-
)
|
|
554
|
-
)
|
|
555
|
-
)
|
|
556
|
-
)
|
|
557
|
-
)
|
|
558
|
-
)
|
|
559
|
-
)
|
|
560
|
-
);
|
|
561
|
-
const key = this._runtime.readCString(keyPtr);
|
|
562
|
-
if (!key) {
|
|
563
|
-
throw new Error(this._runtime.readCString(this._runtime.exports.flatsql_get_error()));
|
|
564
|
-
}
|
|
565
|
-
return key;
|
|
566
|
-
}
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
export class FlatSQLStandaloneDatabase {
|
|
570
|
-
constructor(runtime, handle) {
|
|
571
|
-
this._runtime = runtime;
|
|
572
|
-
this._handle = handle;
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
destroy() {
|
|
576
|
-
if (this._handle) {
|
|
577
|
-
this._runtime.exports.flatsql_destroy_db(this._handle);
|
|
578
|
-
this._handle = 0;
|
|
579
|
-
}
|
|
580
|
-
}
|
|
581
|
-
|
|
582
|
-
// ---- Durable state (docs/STORAGE-DURABILITY.md §3.3) --------------------
|
|
583
|
-
// Codes are values, never throws:
|
|
584
|
-
// >=0 record count / OK -1 absent -2 format or schema -3 corrupt
|
|
585
|
-
// -4 torn pair -5 no filesystem
|
|
586
|
-
// EVERY negative is recoverable with reindexAll(); none means data loss.
|
|
587
|
-
|
|
588
|
-
isDiskBacked() {
|
|
589
|
-
return this._runtime.exports.flatsql_is_disk_backed(this._handle) === 1;
|
|
590
|
-
}
|
|
591
|
-
|
|
592
|
-
openState() {
|
|
593
|
-
return this._runtime.exports.flatsql_open_state(this._handle);
|
|
594
|
-
}
|
|
595
|
-
|
|
596
|
-
reindexAll() {
|
|
597
|
-
return this._runtime.exports.flatsql_reindex_all(this._handle);
|
|
598
|
-
}
|
|
599
|
-
|
|
600
|
-
reindexStep(maxRecords = 4096) {
|
|
601
|
-
if (!Number.isSafeInteger(maxRecords) || maxRecords <= 0 || maxRecords > 0x7fffffff) {
|
|
602
|
-
throw new RangeError('maxRecords must be a positive 32-bit integer');
|
|
603
|
-
}
|
|
604
|
-
return this._runtime.exports.flatsql_reindex_step(this._handle, maxRecords);
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
flushIndex() {
|
|
608
|
-
return this._runtime.exports.flatsql_flush_index(this._handle);
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
flushedOffset() {
|
|
612
|
-
return this._runtime.exports.flatsql_flushed_offset(this._handle);
|
|
613
|
-
}
|
|
614
|
-
|
|
615
|
-
streamPath() {
|
|
616
|
-
const ptr = this._runtime.exports.flatsql_stream_path(this._handle);
|
|
617
|
-
return ptr ? this._runtime.readCString(ptr) : '';
|
|
618
|
-
}
|
|
619
|
-
|
|
620
|
-
registerFileId(fileId, tableName) {
|
|
621
|
-
this._runtime.withCString(fileId, (filePtr) =>
|
|
622
|
-
this._runtime.withCString(tableName, (tablePtr) =>
|
|
623
|
-
this._runtime.exports.flatsql_register_file_id(this._handle, filePtr, tablePtr)
|
|
624
|
-
)
|
|
625
|
-
);
|
|
626
|
-
}
|
|
627
|
-
|
|
628
|
-
enableDemoExtractors() {
|
|
629
|
-
this._runtime.exports.flatsql_enable_demo_extractors(this._handle);
|
|
630
|
-
}
|
|
631
|
-
|
|
632
|
-
// Source partitions. The artifact has always exported these; the shim did
|
|
633
|
-
// not wrap them, so the wasm lane could ingest WITH a source but never
|
|
634
|
-
// declare one, and could not see what a reopen restored. Same three calls,
|
|
635
|
-
// same names, same order as wasm/index.js — one engine, one surface.
|
|
636
|
-
registerSource(sourceName) {
|
|
637
|
-
this._runtime.withCString(sourceName, (ptr) =>
|
|
638
|
-
this._runtime.exports.flatsql_register_source(this._handle, ptr)
|
|
639
|
-
);
|
|
640
|
-
}
|
|
641
|
-
|
|
642
|
-
createUnifiedViews() {
|
|
643
|
-
this._runtime.exports.flatsql_create_unified_views(this._handle);
|
|
644
|
-
}
|
|
645
|
-
|
|
646
|
-
listSources() {
|
|
647
|
-
const count = this._runtime.exports.flatsql_get_sources_count(this._handle);
|
|
648
|
-
const sources = [];
|
|
649
|
-
for (let i = 0; i < count; i++) {
|
|
650
|
-
const ptr = this._runtime.exports.flatsql_get_source_name(i);
|
|
651
|
-
sources.push(ptr ? this._runtime.readCString(ptr) : '');
|
|
652
|
-
}
|
|
653
|
-
return sources;
|
|
654
|
-
}
|
|
655
|
-
|
|
656
|
-
ingest(data, source = null) {
|
|
657
|
-
const result = this._runtime.withBytes(data, (ptr) => {
|
|
658
|
-
if (source) {
|
|
659
|
-
return this._runtime.withCString(source, (sourcePtr) =>
|
|
660
|
-
this._runtime.exports.flatsql_ingest_with_source(this._handle, ptr, data.length, sourcePtr)
|
|
661
|
-
);
|
|
662
|
-
}
|
|
663
|
-
return this._runtime.exports.flatsql_ingest(this._handle, ptr, data.length);
|
|
664
|
-
});
|
|
665
|
-
if (result < 0) throw new Error(this._runtime.readCString(this._runtime.exports.flatsql_get_error()));
|
|
666
|
-
return result;
|
|
667
|
-
}
|
|
668
|
-
|
|
669
|
-
ingestBuffers(buffers, source = null) {
|
|
670
|
-
return this.ingest(buildSizePrefixedStream(buffers), source);
|
|
671
|
-
}
|
|
672
|
-
|
|
673
|
-
ingestOne(data, source = null) {
|
|
674
|
-
const result = this._runtime.withBytes(data, (ptr) => {
|
|
675
|
-
if (source) {
|
|
676
|
-
return this._runtime.withCString(source, (sourcePtr) =>
|
|
677
|
-
this._runtime.exports.flatsql_ingest_one_with_source(this._handle, ptr, data.length, sourcePtr)
|
|
678
|
-
);
|
|
679
|
-
}
|
|
680
|
-
return this._runtime.exports.flatsql_ingest_one(this._handle, ptr, data.length);
|
|
681
|
-
});
|
|
682
|
-
if (result < 0) throw new Error(this._runtime.readCString(this._runtime.exports.flatsql_get_error()));
|
|
683
|
-
return result;
|
|
684
|
-
}
|
|
685
|
-
|
|
686
|
-
query(sql, params = undefined) {
|
|
687
|
-
const success = this._runtime.withCString(sql, (sqlPtr) => {
|
|
688
|
-
if (params === undefined) {
|
|
689
|
-
return this._runtime.exports.flatsql_query(this._handle, sqlPtr);
|
|
690
|
-
}
|
|
691
|
-
const paramBytes = encodeQueryParams(params);
|
|
692
|
-
return this._runtime.withBytes(paramBytes, (paramPtr) =>
|
|
693
|
-
this._runtime.exports.flatsql_query_params(
|
|
694
|
-
this._handle,
|
|
695
|
-
sqlPtr,
|
|
696
|
-
paramPtr,
|
|
697
|
-
paramBytes.length,
|
|
698
|
-
params.length
|
|
699
|
-
)
|
|
700
|
-
);
|
|
701
|
-
});
|
|
702
|
-
this._runtime.check(success);
|
|
703
|
-
return this._runtime.readQueryResult();
|
|
704
|
-
}
|
|
705
|
-
|
|
706
|
-
queryMany(queries) {
|
|
707
|
-
if (queries.length === 0) {
|
|
708
|
-
return [];
|
|
709
|
-
}
|
|
710
|
-
const requestBytes = encodeQueryRequests(queries);
|
|
711
|
-
const success = this._runtime.withBytes(requestBytes, (ptr) =>
|
|
712
|
-
this._runtime.exports.flatsql_query_many(this._handle, ptr, requestBytes.length, queries.length)
|
|
713
|
-
);
|
|
714
|
-
this._runtime.check(success);
|
|
715
|
-
|
|
716
|
-
const count = this._runtime.exports.flatsql_batch_result_count();
|
|
717
|
-
const results = [];
|
|
718
|
-
for (let index = 0; index < count; index++) {
|
|
719
|
-
this._runtime.check(this._runtime.exports.flatsql_select_batch_result(index));
|
|
720
|
-
results.push(this._runtime.readQueryResult());
|
|
721
|
-
}
|
|
722
|
-
return results;
|
|
723
|
-
}
|
|
724
|
-
|
|
725
|
-
queryRawFlatBufferStream(sql, params = []) {
|
|
726
|
-
const paramBytes = encodeQueryParams(params);
|
|
727
|
-
const success = this._runtime.withCString(sql, (sqlPtr) =>
|
|
728
|
-
this._runtime.withBytes(paramBytes, (paramPtr) =>
|
|
729
|
-
this._runtime.exports.flatsql_query_raw_flatbuffer_stream(
|
|
730
|
-
this._handle,
|
|
731
|
-
sqlPtr,
|
|
732
|
-
paramPtr,
|
|
733
|
-
paramBytes.length,
|
|
734
|
-
params.length
|
|
735
|
-
)
|
|
736
|
-
)
|
|
737
|
-
);
|
|
738
|
-
this._runtime.check(success);
|
|
739
|
-
|
|
740
|
-
const ptr = this._runtime.exports.flatsql_response_artifact_data();
|
|
741
|
-
const size = this._runtime.exports.flatsql_response_artifact_size();
|
|
742
|
-
return ptr && size > 0 ? this._runtime.readBytes(ptr, size) : new Uint8Array();
|
|
743
|
-
}
|
|
744
|
-
|
|
745
|
-
// Sandboxed public query (gateway loop G.5): one read-only SELECT under
|
|
746
|
-
// the engine authorizer (record tables / shadow tables / unified views
|
|
747
|
-
// only), single-statement, statement timeout, row/byte caps. options:
|
|
748
|
-
// { mode: "stream" | "json", maxRows, maxBytes, timeoutMs }. Returns
|
|
749
|
-
// { payload: Uint8Array, rows, columns } — payload is the aligned frame
|
|
750
|
-
// stream (mode "stream") or UTF-8 bare-array JSON bytes (mode "json").
|
|
751
|
-
// Sandbox rejections throw with the engine's "sandbox: <code>: ..." text.
|
|
752
|
-
querySandboxed(sql, params = [], options = {}) {
|
|
753
|
-
const paramBytes = encodeQueryParams(params);
|
|
754
|
-
const mode = options.mode === "json" ? 1 : 0;
|
|
755
|
-
const success = this._runtime.withCString(sql, (sqlPtr) =>
|
|
756
|
-
this._runtime.withBytes(paramBytes, (paramPtr) =>
|
|
757
|
-
this._runtime.exports.flatsql_query_sandboxed(
|
|
758
|
-
this._handle,
|
|
759
|
-
sqlPtr,
|
|
760
|
-
paramPtr,
|
|
761
|
-
paramBytes.length,
|
|
762
|
-
params.length,
|
|
763
|
-
mode,
|
|
764
|
-
options.maxRows > 0 ? options.maxRows : 0,
|
|
765
|
-
options.maxBytes > 0 ? options.maxBytes : 0,
|
|
766
|
-
options.timeoutMs > 0 ? options.timeoutMs : 0
|
|
767
|
-
)
|
|
768
|
-
)
|
|
769
|
-
);
|
|
770
|
-
this._runtime.check(success);
|
|
771
|
-
|
|
772
|
-
const ptr = this._runtime.exports.flatsql_response_artifact_data();
|
|
773
|
-
const size = this._runtime.exports.flatsql_response_artifact_size();
|
|
774
|
-
return {
|
|
775
|
-
payload: ptr && size > 0 ? this._runtime.readBytes(ptr, size) : new Uint8Array(),
|
|
776
|
-
rows: this._runtime.exports.flatsql_response_artifact_row_count(),
|
|
777
|
-
columns: this._runtime.exports.flatsql_response_artifact_column_count(),
|
|
778
|
-
};
|
|
779
|
-
}
|
|
780
|
-
|
|
781
|
-
// True when the last queryRawFlatBufferStream call was served from the
|
|
782
|
-
// engine's response-artifact cache (no SQL re-execution).
|
|
783
|
-
lastRawStreamCacheHit() {
|
|
784
|
-
return this._runtime.exports.flatsql_response_artifact_cache_hit() !== 0;
|
|
785
|
-
}
|
|
786
|
-
|
|
787
|
-
configureRawStreamCache(maxEntries, maxTotalBytes) {
|
|
788
|
-
const ok = this._runtime.exports.flatsql_configure_raw_stream_cache(
|
|
789
|
-
this._handle,
|
|
790
|
-
maxEntries,
|
|
791
|
-
maxTotalBytes
|
|
792
|
-
);
|
|
793
|
-
this._runtime.check(ok);
|
|
794
|
-
}
|
|
795
|
-
|
|
796
|
-
getRawStreamCacheStats() {
|
|
797
|
-
return {
|
|
798
|
-
hits: this._runtime.exports.flatsql_raw_stream_cache_hits(this._handle),
|
|
799
|
-
misses: this._runtime.exports.flatsql_raw_stream_cache_misses(this._handle),
|
|
800
|
-
entries: this._runtime.exports.flatsql_raw_stream_cache_size(this._handle),
|
|
801
|
-
totalBytes: this._runtime.exports.flatsql_raw_stream_cache_total_bytes(this._handle),
|
|
802
|
-
};
|
|
803
|
-
}
|
|
804
|
-
|
|
805
|
-
registerQueryTemplate(queryId, sql, cacheable = true) {
|
|
806
|
-
const success = this._runtime.withCString(queryId, (queryIdPtr) =>
|
|
807
|
-
this._runtime.withCString(sql, (sqlPtr) =>
|
|
808
|
-
this._runtime.exports.flatsql_register_query_template(
|
|
809
|
-
this._handle,
|
|
810
|
-
queryIdPtr,
|
|
811
|
-
sqlPtr,
|
|
812
|
-
cacheable ? 1 : 0
|
|
813
|
-
)
|
|
814
|
-
)
|
|
815
|
-
);
|
|
816
|
-
this._runtime.check(success);
|
|
817
|
-
}
|
|
818
|
-
|
|
819
|
-
queryTemplate(queryId, params = []) {
|
|
820
|
-
const paramBytes = encodeQueryParams(params);
|
|
821
|
-
const success = this._runtime.withCString(queryId, (queryIdPtr) =>
|
|
822
|
-
this._runtime.withBytes(paramBytes, (paramPtr) =>
|
|
823
|
-
this._runtime.exports.flatsql_query_template(
|
|
824
|
-
this._handle,
|
|
825
|
-
queryIdPtr,
|
|
826
|
-
paramPtr,
|
|
827
|
-
paramBytes.length,
|
|
828
|
-
params.length
|
|
829
|
-
)
|
|
830
|
-
)
|
|
831
|
-
);
|
|
832
|
-
this._runtime.check(success);
|
|
833
|
-
return this._runtime.readQueryResult();
|
|
834
|
-
}
|
|
835
|
-
|
|
836
|
-
clearQueryCache() {
|
|
837
|
-
this._runtime.exports.flatsql_clear_query_cache(this._handle);
|
|
838
|
-
}
|
|
839
|
-
|
|
840
|
-
configureQueryCache({ maxEntries, maxRows }) {
|
|
841
|
-
if (!Number.isSafeInteger(maxEntries) || maxEntries <= 0) {
|
|
842
|
-
throw new TypeError(`maxEntries must be a positive safe integer, received: ${maxEntries}`);
|
|
843
|
-
}
|
|
844
|
-
if (!Number.isSafeInteger(maxRows) || maxRows <= 0) {
|
|
845
|
-
throw new TypeError(`maxRows must be a positive safe integer, received: ${maxRows}`);
|
|
846
|
-
}
|
|
847
|
-
this._runtime.check(
|
|
848
|
-
this._runtime.exports.flatsql_configure_query_cache(this._handle, maxEntries, maxRows)
|
|
849
|
-
);
|
|
850
|
-
}
|
|
851
|
-
|
|
852
|
-
getQueryCacheStats() {
|
|
853
|
-
return {
|
|
854
|
-
hits: this._runtime.exports.flatsql_query_cache_hits(this._handle),
|
|
855
|
-
misses: this._runtime.exports.flatsql_query_cache_misses(this._handle),
|
|
856
|
-
size: this._runtime.exports.flatsql_query_cache_size(this._handle),
|
|
857
|
-
generation: this._runtime.exports.flatsql_query_cache_generation(this._handle),
|
|
858
|
-
maxEntries: this._runtime.exports.flatsql_query_cache_max_entries(this._handle),
|
|
859
|
-
maxRows: this._runtime.exports.flatsql_query_cache_max_rows(this._handle),
|
|
860
|
-
};
|
|
861
|
-
}
|
|
862
|
-
|
|
863
|
-
exportData() {
|
|
864
|
-
const ptr = this._runtime.exports.flatsql_export_data(this._handle);
|
|
865
|
-
const error = this._runtime.readCString(this._runtime.exports.flatsql_get_error());
|
|
866
|
-
if (error) throw new Error(error);
|
|
867
|
-
const size = this._runtime.exports.flatsql_export_size();
|
|
868
|
-
return this._runtime.readBytes(ptr, size);
|
|
869
|
-
}
|
|
870
|
-
|
|
871
|
-
loadAndRebuild(data) {
|
|
872
|
-
this._runtime.withBytes(data, (ptr) =>
|
|
873
|
-
this._runtime.exports.flatsql_load_and_rebuild(this._handle, ptr, data.length)
|
|
874
|
-
);
|
|
875
|
-
}
|
|
876
|
-
|
|
877
|
-
reserveStorageBytes(bytes) {
|
|
878
|
-
this._runtime.exports.flatsql_reserve_storage(this._handle, bytes);
|
|
879
|
-
}
|
|
880
|
-
|
|
881
|
-
loadAndRebuildFrom(sourceDb) {
|
|
882
|
-
if (!sourceDb?._handle) {
|
|
883
|
-
throw new TypeError('loadAndRebuildFrom requires a FlatSQL standalone database.');
|
|
884
|
-
}
|
|
885
|
-
this._runtime.exports.flatsql_load_from_db(this._handle, sourceDb._handle);
|
|
886
|
-
}
|
|
887
|
-
|
|
888
|
-
getFlatBufferByIndex(tableName, indexName, keyParams = []) {
|
|
889
|
-
const paramBytes = encodeQueryParams(keyParams);
|
|
890
|
-
const ptr = this._runtime.withCString(tableName, (tablePtr) =>
|
|
891
|
-
this._runtime.withCString(indexName, (indexPtr) =>
|
|
892
|
-
this._runtime.withBytes(paramBytes, (paramPtr) =>
|
|
893
|
-
this._runtime.exports.flatsql_get_flatbuffer_by_index(
|
|
894
|
-
this._handle,
|
|
895
|
-
tablePtr,
|
|
896
|
-
indexPtr,
|
|
897
|
-
paramPtr,
|
|
898
|
-
paramBytes.length,
|
|
899
|
-
keyParams.length
|
|
900
|
-
)
|
|
901
|
-
)
|
|
902
|
-
)
|
|
903
|
-
);
|
|
904
|
-
const size = this._runtime.exports.flatsql_get_raw_flatbuffer_size();
|
|
905
|
-
return ptr && size > 0 ? this._runtime.readBytes(ptr, size) : null;
|
|
906
|
-
}
|
|
907
|
-
|
|
908
|
-
getStorageInfo() {
|
|
909
|
-
return {
|
|
910
|
-
ptr: this._runtime.exports.flatsql_get_storage_buffer(this._handle),
|
|
911
|
-
size: this._runtime.exports.flatsql_get_storage_size(this._handle),
|
|
912
|
-
};
|
|
913
|
-
}
|
|
914
|
-
}
|