Skip to content

Commit b068075

Browse files
committed
fix: copy commands in executeBatchAsync as well
1 parent de33ded commit b068075

2 files changed

Lines changed: 66 additions & 2 deletions

File tree

example/src/tests/unit/specs/operations/execute.spec.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,45 @@ export default function registerExecuteUnitTests() {
213213
}
214214
})
215215
})
216+
217+
describe('executeBatchAsync', () => {
218+
it('stores ArrayBuffer values in BLOB columns', async () => {
219+
const dbName = 'array_buffer_batch_async'
220+
const db = createArrayBufferTestDb(dbName)
221+
222+
const originalBytes = new Uint8Array([1, 2, 3, 4, 5])
223+
const originalBuffer = originalBytes.buffer
224+
225+
try {
226+
await db.executeBatchAsync([
227+
{
228+
query: 'INSERT INTO BlobData (id, data) VALUES (?, ?)',
229+
params: [1, originalBuffer],
230+
},
231+
])
232+
233+
const result = db.execute(
234+
'SELECT data FROM BlobData WHERE id = ?',
235+
[1],
236+
)
237+
238+
expect(result.rowsAffected).to.equal(1)
239+
expect(result.rows?.length).to.equal(1)
240+
241+
const row = result.results[0]
242+
expect(row).to.not.equal(undefined)
243+
244+
const value = row?.data
245+
expect(value).to.be.instanceOf(ArrayBuffer)
246+
247+
const returnedBytes = new Uint8Array(value as ArrayBuffer)
248+
expect(Array.from(returnedBytes)).to.eql(Array.from(originalBytes))
249+
} finally {
250+
db.close()
251+
db.delete()
252+
}
253+
})
254+
})
216255
})
217256
})
218257
}

package/cpp/specs/HybridNitroSQLite.cpp

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
#include "sqliteExecuteBatch.hpp"
99
#include <iostream>
1010
#include <map>
11+
#include <optional>
1112
#include <string>
13+
#include <variant>
1214
#include <vector>
1315

1416
namespace margelo::nitro::rnnitrosqlite {
@@ -36,6 +38,24 @@ static std::optional<SQLiteQueryParams> copyArrayBufferParamsForBackground(const
3638
return copiedParams;
3739
}
3840

41+
// Overload for batch execution: copy ArrayBuffer params inside each BatchQuery.
42+
static std::vector<BatchQuery> copyArrayBufferParamsForBackground(const std::vector<BatchQuery>& commands) {
43+
std::vector<BatchQuery> copiedCommands;
44+
copiedCommands.reserve(commands.size());
45+
46+
for (const auto& command : commands) {
47+
BatchQuery copiedCommand = command;
48+
49+
if (command.params) {
50+
copiedCommand.params = copyArrayBufferParamsForBackground(command.params);
51+
}
52+
53+
copiedCommands.push_back(std::move(copiedCommand));
54+
}
55+
56+
return copiedCommands;
57+
}
58+
3959
const std::string getDocPath(const std::optional<std::string>& location) {
4060
std::string tempDocPath = std::string(HybridNitroSQLite::docPath);
4161
if (location) {
@@ -98,9 +118,14 @@ BatchQueryResult HybridNitroSQLite::executeBatch(const std::string& dbName, cons
98118

99119
std::shared_ptr<Promise<BatchQueryResult>> HybridNitroSQLite::executeBatchAsync(const std::string& dbName,
100120
const std::vector<BatchQueryCommand>& batchParams) {
121+
// Convert BatchQueryCommand objects on the JS thread and copy any JS-backed
122+
// ArrayBuffers into native buffers before going off-thread.
123+
const auto commands = batchParamsToCommands(batchParams);
124+
const auto copiedCommands = copyArrayBufferParamsForBackground(commands);
125+
101126
return Promise<BatchQueryResult>::async([=, this]() -> BatchQueryResult {
102-
auto result = executeBatch(dbName, batchParams);
103-
return result;
127+
auto result = sqliteExecuteBatch(dbName, copiedCommands);
128+
return BatchQueryResult(result.rowsAffected);
104129
});
105130
};
106131

0 commit comments

Comments
 (0)