Skip to content

Commit 62acd48

Browse files
authored
sqlite: bind ArrayBuffer
PR-URL: #62061 Fixes: #61396 Reviewed-By: René <contact.9a5d6388@renegade334.me.uk> Reviewed-By: Edy Silva <edigleyssonsilva@gmail.com>
1 parent 02f4630 commit 62acd48

2 files changed

Lines changed: 75 additions & 3 deletions

File tree

src/node_sqlite.cc

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,8 @@ void JSValueToSQLiteResult(Isolate* isolate,
235235
} else if (value->IsString()) {
236236
Utf8Value val(isolate, value.As<String>());
237237
sqlite3_result_text(ctx, *val, val.length(), SQLITE_TRANSIENT);
238-
} else if (value->IsArrayBufferView()) {
238+
} else if (value->IsArrayBufferView() || value->IsArrayBuffer() ||
239+
value->IsSharedArrayBuffer()) {
239240
ArrayBufferViewContents<uint8_t> buf(value);
240241
sqlite3_result_blob(ctx, buf.data(), buf.length(), SQLITE_TRANSIENT);
241242
} else if (value->IsBigInt()) {
@@ -2665,7 +2666,8 @@ bool StatementSync::BindParams(const FunctionCallbackInfo<Value>& args) {
26652666
int anon_idx = 1;
26662667
int anon_start = 0;
26672668

2668-
if (args[0]->IsObject() && !args[0]->IsArrayBufferView()) {
2669+
if (args[0]->IsObject() && !args[0]->IsArrayBufferView() &&
2670+
!args[0]->IsArrayBuffer() && !args[0]->IsSharedArrayBuffer()) {
26692671
Local<Object> obj = args[0].As<Object>();
26702672
Local<Context> context = Isolate::GetCurrent()->GetCurrentContext();
26712673
Local<Array> keys;
@@ -2791,7 +2793,8 @@ bool StatementSync::BindValue(const Local<Value>& value, const int index) {
27912793
}
27922794
} else if (value->IsNull()) {
27932795
r = sqlite3_bind_null(statement_, index);
2794-
} else if (value->IsArrayBufferView()) {
2796+
} else if (value->IsArrayBufferView() || value->IsArrayBuffer() ||
2797+
value->IsSharedArrayBuffer()) {
27952798
ArrayBufferViewContents<uint8_t> buf(value);
27962799
r = sqlite3_bind_blob64(statement_,
27972800
index,

test/parallel/test-sqlite-typed-array-and-data-view.js

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ const { DatabaseSync } = require('node:sqlite');
55
const { suite, test } = require('node:test');
66

77
const arrayBuffer = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]).buffer;
8+
const sharedArrayBuffer = new SharedArrayBuffer(8);
9+
const typedArrayOnSharedArrayBuffer = new Uint8Array(sharedArrayBuffer);
10+
typedArrayOnSharedArrayBuffer.set([1, 2, 3, 4, 5, 6, 7, 8]);
11+
812
const TypedArrays = [
913
['Int8Array', Int8Array],
1014
['Uint8Array', Uint8Array],
@@ -51,3 +55,68 @@ suite('StatementSync with TypedArray/DataView', () => {
5155
});
5256
}
5357
});
58+
59+
suite('StatementSync with ArrayBuffer and SharedArrayBuffer', () => {
60+
const buffers = [
61+
['ArrayBuffer', arrayBuffer],
62+
['SharedArrayBuffer', sharedArrayBuffer],
63+
];
64+
65+
for (const [displayName, buffer] of buffers) {
66+
test(`${displayName} - anonymous binding`, (t) => {
67+
const db = new DatabaseSync(':memory:');
68+
t.after(() => { db.close(); });
69+
db.exec('CREATE TABLE test (data BLOB)');
70+
// insert
71+
{
72+
const stmt = db.prepare('INSERT INTO test VALUES (?)');
73+
stmt.run(buffer);
74+
}
75+
// select all
76+
{
77+
const stmt = db.prepare('SELECT * FROM test');
78+
const row = stmt.get();
79+
t.assert.ok(row.data instanceof Uint8Array);
80+
t.assert.strictEqual(row.data.length, 8);
81+
t.assert.deepStrictEqual(row.data, new Uint8Array(arrayBuffer));
82+
}
83+
// query
84+
{
85+
const stmt = db.prepare('SELECT * FROM test WHERE data = ?');
86+
const rows = stmt.all(buffer);
87+
t.assert.strictEqual(rows.length, 1);
88+
t.assert.ok(rows[0].data instanceof Uint8Array);
89+
t.assert.strictEqual(rows[0].data.length, 8);
90+
t.assert.deepStrictEqual(rows[0].data, new Uint8Array(arrayBuffer));
91+
}
92+
});
93+
94+
test(`${displayName} - named binding (object)`, (t) => {
95+
const db = new DatabaseSync(':memory:');
96+
t.after(() => { db.close(); });
97+
db.exec('CREATE TABLE test (data BLOB)');
98+
// insert
99+
{
100+
const stmt = db.prepare('INSERT INTO test VALUES ($data)');
101+
stmt.run({ '$data': buffer });
102+
}
103+
// select all
104+
{
105+
const stmt = db.prepare('SELECT * FROM test');
106+
const row = stmt.get();
107+
t.assert.ok(row.data instanceof Uint8Array);
108+
t.assert.strictEqual(row.data.length, 8);
109+
t.assert.deepStrictEqual(row.data, new Uint8Array(arrayBuffer));
110+
}
111+
// query
112+
{
113+
const stmt = db.prepare('SELECT * FROM test WHERE data = $data');
114+
const rows = stmt.all({ '$data': buffer });
115+
t.assert.strictEqual(rows.length, 1);
116+
t.assert.ok(rows[0].data instanceof Uint8Array);
117+
t.assert.strictEqual(rows[0].data.length, 8);
118+
t.assert.deepStrictEqual(rows[0].data, new Uint8Array(arrayBuffer));
119+
}
120+
});
121+
}
122+
});

0 commit comments

Comments
 (0)