Skip to content

Commit 89c8807

Browse files
authored
Merge pull request #318 from OP-Engineering/oscar/trigger-hooks-in-executeBatch
Trigger hooks on executeBatch
2 parents 8105e91 + bbc98bd commit 89c8807

File tree

9 files changed

+130
-24
lines changed

9 files changed

+130
-24
lines changed

cpp/DBHostObject.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ void DBHostObject::create_jsi_functions() {
361361

362362
return create_js_rows(rt, status);
363363
});
364-
364+
365365
function_map["executeRawSync"] = HOSTFN("executeRawSync") {
366366
const std::string query = args[0].asString(rt).utf8(rt);
367367
std::vector<JSVariant> params = count == 2 && args[1].isObject()

cpp/bridge.cpp

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -855,15 +855,12 @@ opsqlite_execute_batch(sqlite3 *db,
855855
const auto &command = commands->at(i);
856856
// We do not provide a datastructure to receive query data because we
857857
// don't need/want to handle this results in a batch execution
858-
try {
859-
auto result = opsqlite_execute(db, command.sql, &command.params);
860-
affectedRows += result.affectedRows;
861-
} catch (std::exception &exc) {
862-
opsqlite_execute(db, "ROLLBACK", nullptr);
863-
throw exc;
864-
}
858+
// There is also no need to commit/catch this transaction, this is done
859+
// in the JS code
860+
auto result = opsqlite_execute(db, command.sql, &command.params);
861+
affectedRows += result.affectedRows;
865862
}
866-
// opsqlite_execute(db, "COMMIT", nullptr);
863+
867864
return BatchResult{
868865
.affectedRows = affectedRows,
869866
.commands = static_cast<int>(commandCount),

example/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"build:ios": "cd ios && xcodebuild -workspace OPSQLiteExample.xcworkspace -scheme debug -configuration Debug -sdk iphonesimulator CC=clang CPLUSPLUS=clang++ LD=clang LDPLUSPLUS=clang++ GCC_OPTIMIZATION_LEVEL=0 GCC_PRECOMPILE_PREFIX_HEADER=YES ASSETCATALOG_COMPILER_OPTIMIZATION=time DEBUG_INFORMATION_FORMAT=dwarf COMPILER_INDEX_STORE_ENABLE=NO"
1616
},
1717
"dependencies": {
18-
"@op-engineering/op-test": "^0.2.3",
18+
"@op-engineering/op-test": "^0.2.4",
1919
"chance": "^1.1.9",
2020
"clsx": "^2.0.0",
2121
"events": "^3.3.0",

example/src/tests/hooks.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,41 @@ describe('Hooks', () => {
7575
db.updateHook(null);
7676
});
7777

78+
it('Execute batch should trigger update hook', async () => {
79+
const id = chance.integer();
80+
const name = chance.name();
81+
const age = chance.integer();
82+
const networth = chance.floating();
83+
84+
db.executeSync(
85+
'INSERT INTO "User" (id, name, age, networth) VALUES(?, ?, ?, ?)',
86+
[id, name, age, networth],
87+
);
88+
89+
let promiseResolve: any;
90+
let promise = new Promise<{
91+
rowId: number;
92+
row?: any;
93+
operation: string;
94+
table: string;
95+
}>(resolve => {
96+
promiseResolve = resolve;
97+
});
98+
99+
db.updateHook(data => {
100+
promiseResolve(data);
101+
});
102+
103+
await db.executeBatch([
104+
['UPDATE "User" SET name = ? WHERE id = ?', ['foo', id]],
105+
]);
106+
107+
const data = await promise;
108+
109+
expect(data.operation).toEqual('UPDATE');
110+
expect(data.rowId).toEqual(1);
111+
});
112+
78113
it('remove update hook', async () => {
79114
const hookRes: string[] = [];
80115

example/src/tests/queries.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,7 @@ describe('Queries tests', () => {
579579
expect(ranCallback).toEqual(true);
580580
});
581581

582-
it('Batch execute', async () => {
582+
it('executeBatch', async () => {
583583
const id1 = chance.integer();
584584
const name1 = chance.name();
585585
const age1 = chance.integer();

example/src/tests/reactive.ts

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,77 @@ describe('Reactive queries', () => {
202202
unsubscribe3();
203203
});
204204

205+
it('Row reactive query with executeBatch', async () => {
206+
let firstReactiveRan = false;
207+
let secondReactiveRan = false;
208+
let emittedUser = null;
209+
210+
const unsubscribe = db.reactiveExecute({
211+
query: 'SELECT * FROM User;',
212+
arguments: [],
213+
fireOn: [
214+
{
215+
table: 'User',
216+
ids: [2],
217+
},
218+
],
219+
callback: () => {
220+
firstReactiveRan = true;
221+
},
222+
});
223+
224+
const unsubscribe2 = db.reactiveExecute({
225+
query: 'SELECT * FROM User;',
226+
arguments: [],
227+
fireOn: [
228+
{
229+
table: 'Foo',
230+
},
231+
],
232+
callback: () => {
233+
secondReactiveRan = true;
234+
},
235+
});
236+
237+
const unsubscribe3 = db.reactiveExecute({
238+
query: 'SELECT name FROM User;',
239+
arguments: [],
240+
fireOn: [
241+
{
242+
table: 'User',
243+
ids: [1],
244+
},
245+
],
246+
callback: data => {
247+
emittedUser = data.rows[0];
248+
},
249+
});
250+
251+
await db.executeBatch([
252+
[
253+
'INSERT INTO User (id, name, age, networth, nickname) VALUES (?, ?, ?, ?, ?);',
254+
[1, 'John', 30, 1000, 'Johnny'],
255+
],
256+
]);
257+
258+
await sleep(0);
259+
260+
await db.transaction(async tx => {
261+
await tx.execute('UPDATE User SET name = ? WHERE id = ?;', ['Foo', 1]);
262+
});
263+
264+
await sleep(0);
265+
266+
expect(!!firstReactiveRan).toBe(false);
267+
expect(!!secondReactiveRan).toBe(false);
268+
expect(emittedUser).toDeepEqual({
269+
name: 'Foo',
270+
});
271+
unsubscribe();
272+
unsubscribe2();
273+
unsubscribe3();
274+
});
275+
205276
it('Update hook and reactive queries work at the same time', async () => {
206277
let promiseResolve: any;
207278
let promise = new Promise(resolve => {

src/functions.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -97,22 +97,24 @@ function enhanceDB(db: _InternalDB, options: DBParams): DB {
9797
executeBatch: async (
9898
commands: SQLBatchTuple[]
9999
): Promise<BatchQueryResult> => {
100-
const sanitizedCommands = commands.map(([query, params]) => {
101-
if (params) {
102-
return [query, sanitizeArrayBuffersInArray(params)];
100+
// Do normal for loop and replace in place for performance
101+
for (let i = 0; i < commands.length; i++) {
102+
// [1] is the params arg
103+
if (commands[i]![1]) {
104+
commands[i]![1] = sanitizeArrayBuffersInArray(commands[i]![1]) as any;
103105
}
104-
105-
return [query];
106-
});
106+
}
107107

108108
async function run() {
109109
try {
110110
enhancedDb.executeSync('BEGIN TRANSACTION;');
111111

112-
let res = await db.executeBatch(sanitizedCommands as any[]);
112+
let res = await db.executeBatch(commands as any[]);
113113

114114
enhancedDb.executeSync('COMMIT;');
115115

116+
await db.flushPendingReactiveQueries();
117+
116118
return res;
117119
} catch (executionError) {
118120
try {

src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ export type ColumnMetadata = {
5757
*/
5858
export type SQLBatchTuple =
5959
| [string]
60-
| [string, Array<Scalar> | Array<Array<Scalar>>];
60+
| [string, Scalar[]]
61+
| [string, Scalar[][]];
6162

6263
export type UpdateHookOperation = 'INSERT' | 'DELETE' | 'UPDATE';
6364

yarn.lock

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3262,15 +3262,15 @@ __metadata:
32623262
languageName: unknown
32633263
linkType: soft
32643264

3265-
"@op-engineering/op-test@npm:^0.2.3":
3266-
version: 0.2.3
3267-
resolution: "@op-engineering/op-test@npm:0.2.3"
3265+
"@op-engineering/op-test@npm:^0.2.4":
3266+
version: 0.2.4
3267+
resolution: "@op-engineering/op-test@npm:0.2.4"
32683268
dependencies:
32693269
react-native-safe-area-context: "npm:^5.6.1"
32703270
peerDependencies:
32713271
react: "*"
32723272
react-native: "*"
3273-
checksum: 10c0/a256568acef2d72b739cbb33ac4e7d7541b028ad49ad5512a6e806eec3dc3bff485b9251a22f6148a0fa46f7a2d2e25c981b476bc65b5b48a21a7fb1aea14136
3273+
checksum: 10c0/6dacc5124b0d2e23e9c95a33d120bc5edde4fd2f6bb05e3e2b77487549856b2577a5285320472982df7b1907e9e1b43e5062484914c1f37b34b1795d8439e0c2
32743274
languageName: node
32753275
linkType: hard
32763276

@@ -7365,7 +7365,7 @@ __metadata:
73657365
"@babel/core": "npm:^7.25.2"
73667366
"@babel/preset-env": "npm:^7.25.3"
73677367
"@babel/runtime": "npm:^7.25.0"
7368-
"@op-engineering/op-test": "npm:^0.2.3"
7368+
"@op-engineering/op-test": "npm:^0.2.4"
73697369
"@react-native-community/cli": "npm:^18.0.0"
73707370
"@react-native-community/cli-platform-android": "npm:18.0.0"
73717371
"@react-native-community/cli-platform-ios": "npm:18.0.0"

0 commit comments

Comments
 (0)