quiverdb 0.9.11 → 0.9.13

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.
Binary file
Binary file
Binary file
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "quiverdb",
3
- "version": "0.9.11",
3
+ "version": "0.9.13",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -31,4 +31,4 @@
31
31
  "@biomejs/biome": "^2.4.6",
32
32
  "@types/bun": "latest"
33
33
  }
34
- }
34
+ }
package/src/database.ts CHANGED
@@ -88,9 +88,9 @@ export class Database {
88
88
  declare deleteElement: (collection: string, id: number) => void;
89
89
 
90
90
  // --- Reads (implemented in read.ts) ---
91
- declare readScalarIntegers: (collection: string, attribute: string) => number[];
92
- declare readScalarFloats: (collection: string, attribute: string) => number[];
93
- declare readScalarStrings: (collection: string, attribute: string) => string[];
91
+ declare readScalarIntegers: (collection: string, attribute: string) => (number | null)[];
92
+ declare readScalarFloats: (collection: string, attribute: string) => (number | null)[];
93
+ declare readScalarStrings: (collection: string, attribute: string) => (string | null)[];
94
94
  declare readScalarIntegerById: (
95
95
  collection: string,
96
96
  attribute: string,
package/src/loader.ts CHANGED
@@ -62,8 +62,8 @@ const crudSymbols = {
62
62
  } as const;
63
63
 
64
64
  const readSymbols = {
65
- quiver_database_read_scalar_integers: { args: [P, BUF, BUF, P, P], returns: I32 },
66
- quiver_database_read_scalar_floats: { args: [P, BUF, BUF, P, P], returns: I32 },
65
+ quiver_database_read_scalar_integers: { args: [P, BUF, BUF, P, P, P], returns: I32 },
66
+ quiver_database_read_scalar_floats: { args: [P, BUF, BUF, P, P, P], returns: I32 },
67
67
  quiver_database_read_scalar_strings: { args: [P, BUF, BUF, P, P], returns: I32 },
68
68
  quiver_database_read_scalar_integer_by_id: { args: [P, BUF, BUF, I64, P, P], returns: I32 },
69
69
  quiver_database_read_scalar_float_by_id: { args: [P, BUF, BUF, I64, P, P], returns: I32 },
@@ -123,7 +123,10 @@ const timeSeriesSymbols = {
123
123
  returns: I32,
124
124
  },
125
125
  quiver_database_read_time_series_row: { args: [P, BUF, BUF, BUF, BUF, P, P, P], returns: I32 },
126
- quiver_database_upsert_time_series_row: { args: [P, BUF, BUF, I64, P, P, P, USIZE], returns: I32 },
126
+ quiver_database_upsert_time_series_row: {
127
+ args: [P, BUF, BUF, I64, P, P, P, USIZE],
128
+ returns: I32,
129
+ },
127
130
  quiver_database_update_time_series_group: {
128
131
  args: [P, BUF, BUF, I64, P, P, P, P, USIZE, USIZE],
129
132
  returns: I32,
@@ -144,6 +147,7 @@ const csvSymbols = {
144
147
  const freeSymbols = {
145
148
  quiver_database_free_integer_array: { args: [P], returns: I32 },
146
149
  quiver_database_free_float_array: { args: [P], returns: I32 },
150
+ quiver_database_free_mask: { args: [P], returns: I32 },
147
151
  quiver_database_free_string_array: { args: [P, USIZE], returns: I32 },
148
152
  quiver_database_free_string: { args: [P], returns: I32 },
149
153
  quiver_database_free_integer_vectors: { args: [P, P, USIZE], returns: I32 },
package/src/lua-runner.ts CHANGED
@@ -6,11 +6,9 @@ import { getSymbols } from "./loader.ts";
6
6
 
7
7
  export class LuaRunner {
8
8
  private _ptr: NativePointer;
9
- private _db: Database;
10
9
  private _closed = false;
11
10
 
12
11
  constructor(db: Database) {
13
- this._db = db;
14
12
  const lib = getSymbols();
15
13
  const outRunner = allocPtrOut();
16
14
  check(lib.quiver_lua_runner_new(db._handle, outRunner.buf));
package/src/read.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { CString, type Pointer, toArrayBuffer } from "bun:ffi";
1
2
  import { Database } from "./database.ts";
2
3
  import { check } from "./errors.ts";
3
4
  import {
@@ -21,11 +22,12 @@ Database.prototype.readScalarIntegers = function (
21
22
  this: Database,
22
23
  collection: string,
23
24
  attribute: string,
24
- ): number[] {
25
+ ): (number | null)[] {
25
26
  const lib = getSymbols();
26
27
  const collBuf = toCString(collection);
27
28
  const attrBuf = toCString(attribute);
28
29
  const outValues = allocPtrOut();
30
+ const outMask = allocPtrOut();
29
31
  const outCount = allocUint64Out();
30
32
  check(
31
33
  lib.quiver_database_read_scalar_integers(
@@ -33,14 +35,20 @@ Database.prototype.readScalarIntegers = function (
33
35
  collBuf.buf,
34
36
  attrBuf.buf,
35
37
  outValues.buf,
38
+ outMask.buf,
36
39
  outCount.buf,
37
40
  ),
38
41
  );
39
42
  const count = readUint64Out(outCount);
40
43
  if (count === 0) return [];
41
44
  const arrPtr = readPtrOut(outValues);
42
- const result = decodeInt64Array(arrPtr, count);
45
+ const maskPtr = readPtrOut(outMask);
46
+ const vals = decodeInt64Array(arrPtr, count);
47
+ // mask[i] === 0 means SQL NULL; gate to null (never Number(placeholder)).
48
+ const mask = new Uint8Array(toArrayBuffer(maskPtr as Pointer, 0, count));
49
+ const result = vals.map((v, i) => (mask[i] ? v : null));
43
50
  lib.quiver_database_free_integer_array(arrPtr);
51
+ lib.quiver_database_free_mask(maskPtr);
44
52
  return result;
45
53
  };
46
54
 
@@ -48,11 +56,12 @@ Database.prototype.readScalarFloats = function (
48
56
  this: Database,
49
57
  collection: string,
50
58
  attribute: string,
51
- ): number[] {
59
+ ): (number | null)[] {
52
60
  const lib = getSymbols();
53
61
  const collBuf = toCString(collection);
54
62
  const attrBuf = toCString(attribute);
55
63
  const outValues = allocPtrOut();
64
+ const outMask = allocPtrOut();
56
65
  const outCount = allocUint64Out();
57
66
  check(
58
67
  lib.quiver_database_read_scalar_floats(
@@ -60,14 +69,19 @@ Database.prototype.readScalarFloats = function (
60
69
  collBuf.buf,
61
70
  attrBuf.buf,
62
71
  outValues.buf,
72
+ outMask.buf,
63
73
  outCount.buf,
64
74
  ),
65
75
  );
66
76
  const count = readUint64Out(outCount);
67
77
  if (count === 0) return [];
68
78
  const arrPtr = readPtrOut(outValues);
69
- const result = decodeFloat64Array(arrPtr, count);
79
+ const maskPtr = readPtrOut(outMask);
80
+ const vals = decodeFloat64Array(arrPtr, count);
81
+ const mask = new Uint8Array(toArrayBuffer(maskPtr as Pointer, 0, count));
82
+ const result = vals.map((v, i) => (mask[i] ? v : null));
70
83
  lib.quiver_database_free_float_array(arrPtr);
84
+ lib.quiver_database_free_mask(maskPtr);
71
85
  return result;
72
86
  };
73
87
 
@@ -75,7 +89,7 @@ Database.prototype.readScalarStrings = function (
75
89
  this: Database,
76
90
  collection: string,
77
91
  attribute: string,
78
- ): string[] {
92
+ ): (string | null)[] {
79
93
  const lib = getSymbols();
80
94
  const collBuf = toCString(collection);
81
95
  const attrBuf = toCString(attribute);
@@ -93,7 +107,11 @@ Database.prototype.readScalarStrings = function (
93
107
  const count = readUint64Out(outCount);
94
108
  if (count === 0) return [];
95
109
  const arrPtr = readPtrOut(outValues);
96
- const result = decodeStringArray(arrPtr, count);
110
+ // A NULL string is a NULL char* entry: decode the (null-guarded) pointer array and map
111
+ // NULL -> null (decodeStringArray would construct "" from a NULL pointer instead).
112
+ const result = decodePtrArray(arrPtr, count).map((p) =>
113
+ p === null ? null : new CString(p).toString(),
114
+ );
97
115
  lib.quiver_database_free_string_array(arrPtr, BigInt(count));
98
116
  return result;
99
117
  };