Skip to content

Commit 1e201fd

Browse files
himself65aduh95
authored andcommitted
sqlite: support TypedArray and DataView in StatementSync
Co-authored-by: Antoine du Hamel <[email protected]> PR-URL: #56385 Fixes: #56384 Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Yagiz Nizipli <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Antoine du Hamel <[email protected]>
1 parent 839a06e commit 1e201fd

File tree

3 files changed

+83
-6
lines changed

3 files changed

+83
-6
lines changed

doc/api/sqlite.md

+20-4
Original file line numberDiff line numberDiff line change
@@ -329,11 +329,15 @@ over hand-crafted SQL strings when handling user input.
329329

330330
<!-- YAML
331331
added: v22.5.0
332+
changes:
333+
- version: REPLACEME
334+
pr-url: https://github.com/nodejs/node/pull/56385
335+
description: Add support for `DataView` and typed array objects for `anonymousParameters`.
332336
-->
333337

334338
* `namedParameters` {Object} An optional object used to bind named parameters.
335339
The keys of this object are used to configure the mapping.
336-
* `...anonymousParameters` {null|number|bigint|string|Buffer|Uint8Array} Zero or
340+
* `...anonymousParameters` {null|number|bigint|string|Buffer|TypedArray|DataView} Zero or
337341
more values to bind to anonymous parameters.
338342
* Returns: {Array} An array of objects. Each object corresponds to a row
339343
returned by executing the prepared statement. The keys and values of each
@@ -361,11 +365,15 @@ execution of this prepared statement. This property is a wrapper around
361365

362366
<!-- YAML
363367
added: v22.5.0
368+
changes:
369+
- version: REPLACEME
370+
pr-url: https://github.com/nodejs/node/pull/56385
371+
description: Add support for `DataView` and typed array objects for `anonymousParameters`.
364372
-->
365373

366374
* `namedParameters` {Object} An optional object used to bind named parameters.
367375
The keys of this object are used to configure the mapping.
368-
* `...anonymousParameters` {null|number|bigint|string|Buffer|Uint8Array} Zero or
376+
* `...anonymousParameters` {null|number|bigint|string|Buffer|TypedArray|DataView} Zero or
369377
more values to bind to anonymous parameters.
370378
* Returns: {Object|undefined} An object corresponding to the first row returned
371379
by executing the prepared statement. The keys and values of the object
@@ -381,11 +389,15 @@ values in `namedParameters` and `anonymousParameters`.
381389

382390
<!-- YAML
383391
added: v23.4.0
392+
changes:
393+
- version: REPLACEME
394+
pr-url: https://github.com/nodejs/node/pull/56385
395+
description: Add support for `DataView` and typed array objects for `anonymousParameters`.
384396
-->
385397

386398
* `namedParameters` {Object} An optional object used to bind named parameters.
387399
The keys of this object are used to configure the mapping.
388-
* `...anonymousParameters` {null|number|bigint|string|Buffer|Uint8Array} Zero or
400+
* `...anonymousParameters` {null|number|bigint|string|Buffer|TypedArray|DataView} Zero or
389401
more values to bind to anonymous parameters.
390402
* Returns: {Iterator} An iterable iterator of objects. Each object corresponds to a row
391403
returned by executing the prepared statement. The keys and values of each
@@ -400,11 +412,15 @@ the values in `namedParameters` and `anonymousParameters`.
400412

401413
<!-- YAML
402414
added: v22.5.0
415+
changes:
416+
- version: REPLACEME
417+
pr-url: https://github.com/nodejs/node/pull/56385
418+
description: Add support for `DataView` and typed array objects for `anonymousParameters`.
403419
-->
404420

405421
* `namedParameters` {Object} An optional object used to bind named parameters.
406422
The keys of this object are used to configure the mapping.
407-
* `...anonymousParameters` {null|number|bigint|string|Buffer|Uint8Array} Zero or
423+
* `...anonymousParameters` {null|number|bigint|string|Buffer|TypedArray|DataView} Zero or
408424
more values to bind to anonymous parameters.
409425
* Returns: {Object}
410426
* `changes`: {number|bigint} The number of rows modified, inserted, or deleted

src/node_sqlite.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -960,7 +960,7 @@ bool StatementSync::BindParams(const FunctionCallbackInfo<Value>& args) {
960960
int anon_idx = 1;
961961
int anon_start = 0;
962962

963-
if (args[0]->IsObject() && !args[0]->IsUint8Array()) {
963+
if (args[0]->IsObject() && !args[0]->IsArrayBufferView()) {
964964
Local<Object> obj = args[0].As<Object>();
965965
Local<Context> context = obj->GetIsolate()->GetCurrentContext();
966966
Local<Array> keys;
@@ -1065,7 +1065,7 @@ bool StatementSync::BindValue(const Local<Value>& value, const int index) {
10651065
statement_, index, *val, val.length(), SQLITE_TRANSIENT);
10661066
} else if (value->IsNull()) {
10671067
r = sqlite3_bind_null(statement_, index);
1068-
} else if (value->IsUint8Array()) {
1068+
} else if (value->IsArrayBufferView()) {
10691069
ArrayBufferViewContents<uint8_t> buf(value);
10701070
r = sqlite3_bind_blob(
10711071
statement_, index, buf.data(), buf.length(), SQLITE_TRANSIENT);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
'use strict';
2+
require('../common');
3+
const tmpdir = require('../common/tmpdir');
4+
const { join } = require('node:path');
5+
const { DatabaseSync } = require('node:sqlite');
6+
const { suite, test } = require('node:test');
7+
let cnt = 0;
8+
9+
tmpdir.refresh();
10+
11+
function nextDb() {
12+
return join(tmpdir.path, `database-${cnt++}.db`);
13+
}
14+
15+
const arrayBuffer = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]).buffer;
16+
const TypedArrays = [
17+
['Int8Array', Int8Array],
18+
['Uint8Array', Uint8Array],
19+
['Uint8ClampedArray', Uint8ClampedArray],
20+
['Int16Array', Int16Array],
21+
['Uint16Array', Uint16Array],
22+
['Int32Array', Int32Array],
23+
['Uint32Array', Uint32Array],
24+
['Float32Array', Float32Array],
25+
['Float64Array', Float64Array],
26+
['BigInt64Array', BigInt64Array],
27+
['BigUint64Array', BigUint64Array],
28+
['DataView', DataView],
29+
];
30+
31+
suite('StatementSync with TypedArray/DataView', () => {
32+
for (const [displayName, TypedArray] of TypedArrays) {
33+
test(displayName, (t) => {
34+
const db = new DatabaseSync(nextDb());
35+
t.after(() => { db.close(); });
36+
db.exec('CREATE TABLE test (data BLOB)');
37+
// insert
38+
{
39+
const stmt = db.prepare('INSERT INTO test VALUES (?)');
40+
stmt.run(new TypedArray(arrayBuffer));
41+
}
42+
// select all
43+
{
44+
const stmt = db.prepare('SELECT * FROM test');
45+
const row = stmt.get();
46+
t.assert.ok(row.data instanceof Uint8Array);
47+
t.assert.strictEqual(row.data.length, 8);
48+
t.assert.deepStrictEqual(row.data, new Uint8Array(arrayBuffer));
49+
}
50+
// query
51+
{
52+
const stmt = db.prepare('SELECT * FROM test WHERE data = ?');
53+
const rows = stmt.all(new TypedArray(arrayBuffer));
54+
t.assert.strictEqual(rows.length, 1);
55+
t.assert.ok(rows[0].data instanceof Uint8Array);
56+
t.assert.strictEqual(rows[0].data.length, 8);
57+
t.assert.deepStrictEqual(rows[0].data, new Uint8Array(arrayBuffer));
58+
}
59+
});
60+
}
61+
});

0 commit comments

Comments
 (0)