@op-engineering/op-sqlite 6.0.1 → 6.0.2-beta3

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.
Files changed (38) hide show
  1. package/android/CMakeLists.txt +26 -15
  2. package/android/build.gradle +10 -1
  3. package/android/cpp-adapter.cpp +4 -0
  4. package/android/jniLibs/arm64-v8a/libsql_experimental.a +0 -0
  5. package/android/jniLibs/armeabi-v7a/libsql_experimental.a +0 -0
  6. package/android/jniLibs/x86/libsql_experimental.a +0 -0
  7. package/android/jniLibs/x86_64/libsql_experimental.a +0 -0
  8. package/cpp/DBHostObject.cpp +882 -0
  9. package/cpp/DBHostObject.h +61 -0
  10. package/cpp/PreparedStatementHostObject.cpp +29 -15
  11. package/cpp/PreparedStatementHostObject.h +18 -14
  12. package/cpp/bindings.cpp +24 -616
  13. package/cpp/bindings.h +5 -2
  14. package/cpp/bridge.cpp +55 -16
  15. package/cpp/bridge.h +5 -1
  16. package/cpp/libsql/bridge.cpp +629 -0
  17. package/cpp/libsql/bridge.h +88 -0
  18. package/cpp/libsql/libsql.h +133 -0
  19. package/cpp/sqlite3.h +0 -1
  20. package/cpp/types.h +5 -0
  21. package/cpp/utils.cpp +68 -6
  22. package/cpp/utils.h +5 -5
  23. package/ios/libsql.xcframework/Info.plist +48 -0
  24. package/ios/libsql.xcframework/ios-arm64/Headers/libsql.h +133 -0
  25. package/ios/libsql.xcframework/ios-arm64/libsql_experimental.a +0 -0
  26. package/ios/libsql.xcframework/ios-arm64_x86_64-simulator/Headers/libsql.h +133 -0
  27. package/ios/libsql.xcframework/ios-arm64_x86_64-simulator/libsql_experimental.a +0 -0
  28. package/lib/commonjs/index.js +143 -153
  29. package/lib/commonjs/index.js.map +1 -1
  30. package/lib/module/index.js +141 -152
  31. package/lib/module/index.js.map +1 -1
  32. package/lib/typescript/src/index.d.ts +28 -39
  33. package/lib/typescript/src/index.d.ts.map +1 -1
  34. package/op-sqlite.podspec +20 -3
  35. package/package.json +1 -1
  36. package/src/index.ts +203 -272
  37. package/cpp/sqlbatchexecutor.cpp +0 -93
  38. package/cpp/sqlbatchexecutor.h +0 -30
package/src/index.ts CHANGED
@@ -34,7 +34,7 @@ if (global.__OPSQLiteProxy == null) {
34
34
  }
35
35
 
36
36
  const proxy = global.__OPSQLiteProxy;
37
- export const OPSQLite = proxy as ISQLite;
37
+ export const OPSQLite = proxy as OPSQLiteProxy;
38
38
 
39
39
  export const {
40
40
  IOS_DOCUMENT_PATH,
@@ -145,14 +145,9 @@ export type PreparedStatementObj = {
145
145
  execute: () => QueryResult;
146
146
  };
147
147
 
148
- interface ISQLite {
149
- open: (options: {
150
- name: string;
151
- location?: string;
152
- encryptionKey?: string;
153
- }) => void;
154
- close: (dbName: string) => void;
155
- delete: (dbName: string, location?: string) => void;
148
+ export type DB = {
149
+ close: () => void;
150
+ delete: (location?: string) => void;
156
151
  attach: (
157
152
  mainDbName: string,
158
153
  dbNameToAttach: string,
@@ -160,24 +155,13 @@ interface ISQLite {
160
155
  location?: string
161
156
  ) => void;
162
157
  detach: (mainDbName: string, alias: string) => void;
163
- transaction: (
164
- dbName: string,
165
- fn: (tx: Transaction) => Promise<void>
166
- ) => Promise<void>;
167
- execute: (dbName: string, query: string, params?: any[]) => QueryResult;
168
- executeAsync: (
169
- dbName: string,
170
- query: string,
171
- params?: any[]
172
- ) => Promise<QueryResult>;
173
- executeBatch: (dbName: string, commands: SQLBatchTuple[]) => BatchQueryResult;
174
- executeBatchAsync: (
175
- dbName: string,
176
- commands: SQLBatchTuple[]
177
- ) => Promise<BatchQueryResult>;
178
- loadFile: (dbName: string, location: string) => Promise<FileLoadResult>;
158
+ transaction: (fn: (tx: Transaction) => Promise<void>) => Promise<void>;
159
+ execute: (query: string, params?: any[]) => QueryResult;
160
+ executeAsync: (query: string, params?: any[]) => Promise<QueryResult>;
161
+ executeBatch: (commands: SQLBatchTuple[]) => BatchQueryResult;
162
+ executeBatchAsync: (commands: SQLBatchTuple[]) => Promise<BatchQueryResult>;
163
+ loadFile: (location: string) => Promise<FileLoadResult>;
179
164
  updateHook: (
180
- dbName: string,
181
165
  callback?:
182
166
  | ((params: {
183
167
  table: string;
@@ -187,18 +171,32 @@ interface ISQLite {
187
171
  }) => void)
188
172
  | null
189
173
  ) => void;
190
- commitHook: (dbName: string, callback?: (() => void) | null) => void;
191
- rollbackHook: (dbName: string, callback?: (() => void) | null) => void;
192
- prepareStatement: (dbName: string, query: string) => PreparedStatementObj;
193
- loadExtension: (dbName: string, path: string, entryPoint?: string) => void;
194
- executeRawAsync: (
195
- dbName: string,
196
- query: string,
197
- params?: any[]
198
- ) => Promise<any[]>;
199
- getDbPath: (dbName: string, location?: string) => string;
174
+ commitHook: (callback?: (() => void) | null) => void;
175
+ rollbackHook: (callback?: (() => void) | null) => void;
176
+ prepareStatement: (query: string) => PreparedStatementObj;
177
+ loadExtension: (path: string, entryPoint?: string) => void;
178
+ executeRawAsync: (query: string, params?: any[]) => Promise<any[]>;
179
+ getDbPath: (location?: string) => string;
180
+ reactiveExecute: (params: {
181
+ query: string;
182
+ arguments: any[];
183
+ fireOn: {
184
+ table: string;
185
+ ids?: number[];
186
+ }[];
187
+ callback: (response: any) => void;
188
+ }) => () => void;
189
+ };
190
+
191
+ type OPSQLiteProxy = {
192
+ open: (options: {
193
+ name: string;
194
+ location?: string;
195
+ encryptionKey?: string;
196
+ }) => DB;
200
197
  isSQLCipher: () => boolean;
201
- }
198
+ isLibsql: () => boolean;
199
+ };
202
200
 
203
201
  const locks: Record<
204
202
  string,
@@ -221,71 +219,76 @@ function enhanceQueryResult(result: QueryResult): void {
221
219
  }
222
220
  }
223
221
 
224
- const _open = OPSQLite.open;
225
- OPSQLite.open = (options: {
222
+ export const open = (options: {
226
223
  name: string;
227
224
  location?: string;
228
225
  encryptionKey?: string;
229
- }) => {
230
- _open(options);
226
+ }): DB => {
227
+ const db = OPSQLite.open(options);
231
228
 
232
- locks[options.name] = {
233
- queue: [],
229
+ const lock = {
230
+ queue: [] as PendingTransaction[],
234
231
  inProgress: false,
235
232
  };
236
- };
237
-
238
- const _close = OPSQLite.close;
239
- OPSQLite.close = (dbName: string) => {
240
- _close(dbName);
241
- delete locks[dbName];
242
- };
243
233
 
244
- const _execute = OPSQLite.execute;
245
- OPSQLite.execute = (
246
- dbName: string,
247
- query: string,
248
- params?: any[] | undefined
249
- ): QueryResult => {
250
- const sanitizedParams = params?.map((p) => {
251
- if (ArrayBuffer.isView(p)) {
252
- return p.buffer;
234
+ const startNextTransaction = () => {
235
+ if (lock.inProgress) {
236
+ // Transaction is already in process bail out
237
+ return;
253
238
  }
254
239
 
255
- return p;
256
- });
240
+ if (lock.queue.length) {
241
+ lock.inProgress = true;
242
+ const tx = lock.queue.shift();
257
243
 
258
- const result = _execute(dbName, query, sanitizedParams);
259
- enhanceQueryResult(result);
260
- return result;
261
- };
244
+ if (!tx) {
245
+ throw new Error('Could not get a operation on database');
246
+ }
262
247
 
263
- const _executeAsync = OPSQLite.executeAsync;
264
- OPSQLite.executeAsync = async (
265
- dbName: string,
266
- query: string,
267
- params?: any[] | undefined
268
- ): Promise<QueryResult> => {
269
- const sanitizedParams = params?.map((p) => {
270
- if (ArrayBuffer.isView(p)) {
271
- return p.buffer;
248
+ setImmediate(() => {
249
+ tx.start();
250
+ });
272
251
  }
252
+ };
273
253
 
274
- return p;
275
- });
276
-
277
- const res = await _executeAsync(dbName, query, sanitizedParams);
278
- enhanceQueryResult(res);
279
- return res;
280
- };
254
+ // spreading the object is not working, so we need to do it manually
255
+ let enhancedDb = {
256
+ delete: db.delete,
257
+ attach: db.attach,
258
+ detach: db.detach,
259
+ executeBatch: db.executeBatch,
260
+ executeBatchAsync: db.executeBatchAsync,
261
+
262
+ loadFile: db.loadFile,
263
+ updateHook: db.updateHook,
264
+ commitHook: db.commitHook,
265
+ rollbackHook: db.rollbackHook,
266
+ loadExtension: db.loadExtension,
267
+ executeRawAsync: db.executeRawAsync,
268
+ getDbPath: db.getDbPath,
269
+ reactiveExecute: db.reactiveExecute,
270
+ close: () => {
271
+ db.close();
272
+ delete locks[options.name];
273
+ },
274
+ execute: (query: string, params?: any[] | undefined): QueryResult => {
275
+ const sanitizedParams = params?.map((p) => {
276
+ if (ArrayBuffer.isView(p)) {
277
+ return p.buffer;
278
+ }
281
279
 
282
- const _prepareStatement = OPSQLite.prepareStatement;
283
- OPSQLite.prepareStatement = (dbName: string, query: string) => {
284
- const stmt = _prepareStatement(dbName, query);
280
+ return p;
281
+ });
285
282
 
286
- return {
287
- bind: (params: any[]) => {
288
- const sanitizedParams = params.map((p) => {
283
+ const result = db.execute(query, sanitizedParams);
284
+ enhanceQueryResult(result);
285
+ return result;
286
+ },
287
+ executeAsync: async (
288
+ query: string,
289
+ params?: any[] | undefined
290
+ ): Promise<QueryResult> => {
291
+ const sanitizedParams = params?.map((p) => {
289
292
  if (ArrayBuffer.isView(p)) {
290
293
  return p.buffer;
291
294
  }
@@ -293,200 +296,124 @@ OPSQLite.prepareStatement = (dbName: string, query: string) => {
293
296
  return p;
294
297
  });
295
298
 
296
- stmt.bind(sanitizedParams);
299
+ const result = await db.executeAsync(query, sanitizedParams);
300
+ enhanceQueryResult(result);
301
+ return result;
297
302
  },
298
- execute: () => {
299
- const res = stmt.execute();
300
- enhanceQueryResult(res);
301
- return res;
303
+ prepareStatement: (query: string) => {
304
+ const stmt = db.prepareStatement(query);
305
+
306
+ return {
307
+ bind: (params: any[]) => {
308
+ const sanitizedParams = params.map((p) => {
309
+ if (ArrayBuffer.isView(p)) {
310
+ return p.buffer;
311
+ }
312
+
313
+ return p;
314
+ });
315
+
316
+ stmt.bind(sanitizedParams);
317
+ },
318
+ execute: () => {
319
+ const res = stmt.execute();
320
+ enhanceQueryResult(res);
321
+ return res;
322
+ },
323
+ };
302
324
  },
303
- };
304
- };
305
-
306
- OPSQLite.transaction = async (
307
- dbName: string,
308
- fn: (tx: Transaction) => Promise<void>
309
- ): Promise<void> => {
310
- if (!locks[dbName]) {
311
- throw Error(`SQLite Error: No lock found on db: ${dbName}`);
312
- }
313
-
314
- let isFinalized = false;
315
-
316
- // Local transaction context object implementation
317
- const execute = (query: string, params?: any[]): QueryResult => {
318
- if (isFinalized) {
319
- throw Error(
320
- `SQLite Error: Cannot execute query on finalized transaction: ${dbName}`
321
- );
322
- }
323
- return OPSQLite.execute(dbName, query, params);
324
- };
325
-
326
- const executeAsync = (query: string, params?: any[] | undefined) => {
327
- if (isFinalized) {
328
- throw Error(
329
- `SQLite Error: Cannot execute query on finalized transaction: ${dbName}`
330
- );
331
- }
332
- return OPSQLite.executeAsync(dbName, query, params);
333
- };
334
-
335
- const commit = () => {
336
- if (isFinalized) {
337
- throw Error(
338
- `SQLite Error: Cannot execute commit on finalized transaction: ${dbName}`
339
- );
340
- }
341
- const result = OPSQLite.execute(dbName, 'COMMIT');
342
- isFinalized = true;
343
- return result;
344
- };
345
-
346
- const rollback = () => {
347
- if (isFinalized) {
348
- throw Error(
349
- `SQLite Error: Cannot execute rollback on finalized transaction: ${dbName}`
350
- );
351
- }
352
- const result = OPSQLite.execute(dbName, 'ROLLBACK');
353
- isFinalized = true;
354
- return result;
355
- };
356
-
357
- async function run() {
358
- try {
359
- await OPSQLite.executeAsync(dbName, 'BEGIN TRANSACTION');
360
-
361
- await fn({
362
- commit,
363
- execute,
364
- executeAsync,
365
- rollback,
366
- });
325
+ transaction: async (
326
+ fn: (tx: Transaction) => Promise<void>
327
+ ): Promise<void> => {
328
+ let isFinalized = false;
329
+
330
+ // Local transaction context object implementation
331
+ const execute = (query: string, params?: any[]): QueryResult => {
332
+ if (isFinalized) {
333
+ throw Error(
334
+ `OP-Sqlite Error: Database: ${options.name}. Cannot execute query on finalized transaction`
335
+ );
336
+ }
337
+ return enhancedDb.execute(query, params);
338
+ };
339
+
340
+ const executeAsync = (query: string, params?: any[] | undefined) => {
341
+ if (isFinalized) {
342
+ throw Error(
343
+ `OP-Sqlite Error: Database: ${options.name}. Cannot execute query on finalized transaction`
344
+ );
345
+ }
346
+ return enhancedDb.executeAsync(query, params);
347
+ };
348
+
349
+ const commit = () => {
350
+ if (isFinalized) {
351
+ throw Error(
352
+ `OP-Sqlite Error: Database: ${options.name}. Cannot execute query on finalized transaction`
353
+ );
354
+ }
355
+ const result = enhancedDb.execute('COMMIT;');
356
+ isFinalized = true;
357
+ return result;
358
+ };
359
+
360
+ const rollback = () => {
361
+ if (isFinalized) {
362
+ throw Error(
363
+ `OP-Sqlite Error: Database: ${options.name}. Cannot execute query on finalized transaction`
364
+ );
365
+ }
366
+ const result = enhancedDb.execute('ROLLBACK;');
367
+ isFinalized = true;
368
+ return result;
369
+ };
367
370
 
368
- if (!isFinalized) {
369
- commit();
370
- }
371
- } catch (executionError) {
372
- if (!isFinalized) {
371
+ async function run() {
373
372
  try {
374
- rollback();
375
- } catch (rollbackError) {
376
- throw rollbackError;
373
+ await enhancedDb.executeAsync('BEGIN TRANSACTION;');
374
+
375
+ await fn({
376
+ commit,
377
+ execute,
378
+ executeAsync,
379
+ rollback,
380
+ });
381
+
382
+ if (!isFinalized) {
383
+ commit();
384
+ }
385
+ } catch (executionError) {
386
+ console.warn('transaction error', executionError);
387
+ if (!isFinalized) {
388
+ try {
389
+ rollback();
390
+ } catch (rollbackError) {
391
+ throw rollbackError;
392
+ }
393
+ }
394
+
395
+ throw executionError;
396
+ } finally {
397
+ lock.inProgress = false;
398
+ isFinalized = false;
399
+ startNextTransaction();
377
400
  }
378
401
  }
379
402
 
380
- throw executionError;
381
- } finally {
382
- locks[dbName]!.inProgress = false;
383
- isFinalized = false;
384
- startNextTransaction(dbName);
385
- }
386
- }
387
-
388
- return await new Promise((resolve, reject) => {
389
- const tx: PendingTransaction = {
390
- start: () => {
391
- run().then(resolve).catch(reject);
392
- },
393
- };
394
-
395
- locks[dbName]!.queue.push(tx);
396
- startNextTransaction(dbName);
397
- });
398
- };
399
-
400
- const startNextTransaction = (dbName: string) => {
401
- if (!locks[dbName]) {
402
- throw Error(`Lock not found for db: ${dbName}`);
403
- }
404
-
405
- if (locks[dbName]!.inProgress) {
406
- // Transaction is already in process bail out
407
- return;
408
- }
409
-
410
- if (locks[dbName]!.queue.length) {
411
- locks[dbName]!.inProgress = true;
412
- const tx = locks[dbName]!.queue.shift();
403
+ return await new Promise((resolve, reject) => {
404
+ const tx: PendingTransaction = {
405
+ start: () => {
406
+ run().then(resolve).catch(reject);
407
+ },
408
+ };
413
409
 
414
- if (!tx) {
415
- throw new Error('Could not get a operation on datebase');
416
- }
417
-
418
- setImmediate(() => {
419
- tx.start();
420
- });
421
- }
422
- };
423
-
424
- export type OPSQLiteConnection = {
425
- close: () => void;
426
- delete: () => void;
427
- attach: (dbNameToAttach: string, alias: string, location?: string) => void;
428
- detach: (alias: string) => void;
429
- transaction: (fn: (tx: Transaction) => Promise<void>) => Promise<void>;
430
- execute: (query: string, params?: any[]) => QueryResult;
431
- executeAsync: (query: string, params?: any[]) => Promise<QueryResult>;
432
- executeBatch: (commands: SQLBatchTuple[]) => BatchQueryResult;
433
- executeBatchAsync: (commands: SQLBatchTuple[]) => Promise<BatchQueryResult>;
434
- loadFile: (location: string) => Promise<FileLoadResult>;
435
- updateHook: (
436
- callback:
437
- | ((params: {
438
- table: string;
439
- operation: UpdateHookOperation;
440
- row?: any;
441
- rowId: number;
442
- }) => void)
443
- | null
444
- ) => void;
445
- commitHook: (callback: (() => void) | null) => void;
446
- rollbackHook: (callback: (() => void) | null) => void;
447
- prepareStatement: (query: string) => PreparedStatementObj;
448
- loadExtension: (path: string, entryPoint?: string) => void;
449
- executeRawAsync: (query: string, params?: any[]) => Promise<any[]>;
450
- getDbPath: () => string;
451
- };
452
-
453
- export const open = (options: {
454
- name: string;
455
- location?: string;
456
- encryptionKey?: string;
457
- }): OPSQLiteConnection => {
458
- OPSQLite.open(options);
459
-
460
- return {
461
- close: () => OPSQLite.close(options.name),
462
- delete: () => OPSQLite.delete(options.name, options.location),
463
- attach: (dbNameToAttach: string, alias: string, location?: string) =>
464
- OPSQLite.attach(options.name, dbNameToAttach, alias, location),
465
- detach: (alias: string) => OPSQLite.detach(options.name, alias),
466
- transaction: (fn: (tx: Transaction) => Promise<void>) =>
467
- OPSQLite.transaction(options.name, fn),
468
- execute: (query: string, params?: any[] | undefined): QueryResult =>
469
- OPSQLite.execute(options.name, query, params),
470
- executeAsync: (
471
- query: string,
472
- params?: any[] | undefined
473
- ): Promise<QueryResult> =>
474
- OPSQLite.executeAsync(options.name, query, params),
475
- executeBatch: (commands: SQLBatchTuple[]) =>
476
- OPSQLite.executeBatch(options.name, commands),
477
- executeBatchAsync: (commands: SQLBatchTuple[]) =>
478
- OPSQLite.executeBatchAsync(options.name, commands),
479
- loadFile: (location: string) => OPSQLite.loadFile(options.name, location),
480
- updateHook: (callback) => OPSQLite.updateHook(options.name, callback),
481
- commitHook: (callback) => OPSQLite.commitHook(options.name, callback),
482
- rollbackHook: (callback) => OPSQLite.rollbackHook(options.name, callback),
483
- prepareStatement: (query) => OPSQLite.prepareStatement(options.name, query),
484
- loadExtension: (path, entryPoint) =>
485
- OPSQLite.loadExtension(options.name, path, entryPoint),
486
- executeRawAsync: (query, params) =>
487
- OPSQLite.executeRawAsync(options.name, query, params),
488
- getDbPath: () => OPSQLite.getDbPath(options.name, options.location),
410
+ lock.queue.push(tx);
411
+ startNextTransaction();
412
+ });
413
+ },
489
414
  };
415
+
416
+ return enhancedDb;
490
417
  };
491
418
 
492
419
  export const moveAssetsDatabase = async (args: {
@@ -500,3 +427,7 @@ export const moveAssetsDatabase = async (args: {
500
427
  export const isSQLCipher = (): boolean => {
501
428
  return OPSQLite.isSQLCipher();
502
429
  };
430
+
431
+ export const isLibsql = (): boolean => {
432
+ return OPSQLite.isLibsql();
433
+ };
@@ -1,93 +0,0 @@
1
- #include "sqlbatchexecutor.h"
2
-
3
- namespace opsqlite {
4
-
5
- /**
6
- * Batch execution implementation
7
- */
8
-
9
- void toBatchArguments(jsi::Runtime &rt, jsi::Array const &batchParams,
10
- std::vector<BatchArguments> *commands) {
11
- for (int i = 0; i < batchParams.length(rt); i++) {
12
- const jsi::Array &command =
13
- batchParams.getValueAtIndex(rt, i).asObject(rt).asArray(rt);
14
- if (command.length(rt) == 0) {
15
- continue;
16
- }
17
-
18
- const std::string query =
19
- command.getValueAtIndex(rt, 0).asString(rt).utf8(rt);
20
- const jsi::Value &commandParams = command.length(rt) > 1
21
- ? command.getValueAtIndex(rt, 1)
22
- : jsi::Value::undefined();
23
- if (!commandParams.isUndefined() &&
24
- commandParams.asObject(rt).isArray(rt) &&
25
- commandParams.asObject(rt).asArray(rt).length(rt) > 0 &&
26
- commandParams.asObject(rt)
27
- .asArray(rt)
28
- .getValueAtIndex(rt, 0)
29
- .isObject()) {
30
- // This arguments is an array of arrays, like a batch update of a single
31
- // sql command.
32
- const jsi::Array &batchUpdateParams =
33
- commandParams.asObject(rt).asArray(rt);
34
- for (int x = 0; x < batchUpdateParams.length(rt); x++) {
35
- const jsi::Value &p = batchUpdateParams.getValueAtIndex(rt, x);
36
- auto params =
37
- std::make_shared<std::vector<JSVariant>>(toVariantVec(rt, p));
38
- commands->push_back({query, params});
39
- }
40
- } else {
41
- auto params = std::make_shared<std::vector<JSVariant>>(
42
- toVariantVec(rt, commandParams));
43
- commands->push_back({query, params});
44
- }
45
- }
46
- }
47
-
48
- BatchResult sqliteExecuteBatch(std::string dbName,
49
- std::vector<BatchArguments> *commands) {
50
- size_t commandCount = commands->size();
51
- if (commandCount <= 0) {
52
- return BatchResult{
53
- .type = SQLiteError,
54
- .message = "No SQL commands provided",
55
- };
56
- }
57
-
58
- try {
59
- int affectedRows = 0;
60
- opsqlite_execute(dbName, "BEGIN EXCLUSIVE TRANSACTION", nullptr, nullptr,
61
- nullptr);
62
- for (int i = 0; i < commandCount; i++) {
63
- auto command = commands->at(i);
64
- // We do not provide a datastructure to receive query data because we
65
- // don't need/want to handle this results in a batch execution
66
- auto result = opsqlite_execute(dbName, command.sql, command.params.get(),
67
- nullptr, nullptr);
68
- if (result.type == SQLiteError) {
69
- opsqlite_execute(dbName, "ROLLBACK", nullptr, nullptr, nullptr);
70
- return BatchResult{
71
- .type = SQLiteError,
72
- .message = result.message,
73
- };
74
- } else {
75
- affectedRows += result.affectedRows;
76
- }
77
- }
78
- opsqlite_execute(dbName, "COMMIT", nullptr, nullptr, nullptr);
79
- return BatchResult{
80
- .type = SQLiteOk,
81
- .affectedRows = affectedRows,
82
- .commands = static_cast<int>(commandCount),
83
- };
84
- } catch (std::exception &exc) {
85
- opsqlite_execute(dbName, "ROLLBACK", nullptr, nullptr, nullptr);
86
- return BatchResult{
87
- .type = SQLiteError,
88
- .message = exc.what(),
89
- };
90
- }
91
- }
92
-
93
- } // namespace opsqlite
@@ -1,30 +0,0 @@
1
- /**
2
- * SQL Batch execution implementation using default sqliteBridge implementation
3
- */
4
- #include "bridge.h"
5
- #include "types.h"
6
- #include "utils.h"
7
-
8
- namespace opsqlite {
9
-
10
- namespace jsi = facebook::jsi;
11
-
12
- struct BatchArguments {
13
- std::string sql;
14
- std::shared_ptr<std::vector<JSVariant>> params;
15
- };
16
-
17
- /**
18
- * Local Helper method to translate JSI objects BatchArguments data structure
19
- * MUST be called in the JavaScript Thread
20
- */
21
- void toBatchArguments(jsi::Runtime &rt, jsi::Array const &batchParams,
22
- std::vector<BatchArguments> *commands);
23
-
24
- /**
25
- * Execute a batch of commands in a exclusive transaction
26
- */
27
- BatchResult sqliteExecuteBatch(std::string dbName,
28
- std::vector<BatchArguments> *commands);
29
-
30
- } // namespace opsqlite