@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.
- package/android/CMakeLists.txt +26 -15
- package/android/build.gradle +10 -1
- package/android/cpp-adapter.cpp +4 -0
- package/android/jniLibs/arm64-v8a/libsql_experimental.a +0 -0
- package/android/jniLibs/armeabi-v7a/libsql_experimental.a +0 -0
- package/android/jniLibs/x86/libsql_experimental.a +0 -0
- package/android/jniLibs/x86_64/libsql_experimental.a +0 -0
- package/cpp/DBHostObject.cpp +882 -0
- package/cpp/DBHostObject.h +61 -0
- package/cpp/PreparedStatementHostObject.cpp +29 -15
- package/cpp/PreparedStatementHostObject.h +18 -14
- package/cpp/bindings.cpp +24 -616
- package/cpp/bindings.h +5 -2
- package/cpp/bridge.cpp +55 -16
- package/cpp/bridge.h +5 -1
- package/cpp/libsql/bridge.cpp +629 -0
- package/cpp/libsql/bridge.h +88 -0
- package/cpp/libsql/libsql.h +133 -0
- package/cpp/sqlite3.h +0 -1
- package/cpp/types.h +5 -0
- package/cpp/utils.cpp +68 -6
- package/cpp/utils.h +5 -5
- package/ios/libsql.xcframework/Info.plist +48 -0
- package/ios/libsql.xcframework/ios-arm64/Headers/libsql.h +133 -0
- package/ios/libsql.xcframework/ios-arm64/libsql_experimental.a +0 -0
- package/ios/libsql.xcframework/ios-arm64_x86_64-simulator/Headers/libsql.h +133 -0
- package/ios/libsql.xcframework/ios-arm64_x86_64-simulator/libsql_experimental.a +0 -0
- package/lib/commonjs/index.js +143 -153
- package/lib/commonjs/index.js.map +1 -1
- package/lib/module/index.js +141 -152
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/src/index.d.ts +28 -39
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/op-sqlite.podspec +20 -3
- package/package.json +1 -1
- package/src/index.ts +203 -272
- package/cpp/sqlbatchexecutor.cpp +0 -93
- 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
|
|
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
|
-
|
|
149
|
-
|
|
150
|
-
|
|
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
|
-
|
|
165
|
-
|
|
166
|
-
) =>
|
|
167
|
-
|
|
168
|
-
|
|
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: (
|
|
191
|
-
rollbackHook: (
|
|
192
|
-
prepareStatement: (
|
|
193
|
-
loadExtension: (
|
|
194
|
-
executeRawAsync: (
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
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
|
|
225
|
-
OPSQLite.open = (options: {
|
|
222
|
+
export const open = (options: {
|
|
226
223
|
name: string;
|
|
227
224
|
location?: string;
|
|
228
225
|
encryptionKey?: string;
|
|
229
|
-
}) => {
|
|
230
|
-
|
|
226
|
+
}): DB => {
|
|
227
|
+
const db = OPSQLite.open(options);
|
|
231
228
|
|
|
232
|
-
|
|
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
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
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
|
-
|
|
256
|
-
|
|
240
|
+
if (lock.queue.length) {
|
|
241
|
+
lock.inProgress = true;
|
|
242
|
+
const tx = lock.queue.shift();
|
|
257
243
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
};
|
|
244
|
+
if (!tx) {
|
|
245
|
+
throw new Error('Could not get a operation on database');
|
|
246
|
+
}
|
|
262
247
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
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
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
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
|
-
|
|
283
|
-
|
|
284
|
-
const stmt = _prepareStatement(dbName, query);
|
|
280
|
+
return p;
|
|
281
|
+
});
|
|
285
282
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
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
|
-
|
|
299
|
+
const result = await db.executeAsync(query, sanitizedParams);
|
|
300
|
+
enhanceQueryResult(result);
|
|
301
|
+
return result;
|
|
297
302
|
},
|
|
298
|
-
|
|
299
|
-
const
|
|
300
|
-
|
|
301
|
-
return
|
|
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
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
):
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
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
|
-
|
|
369
|
-
commit();
|
|
370
|
-
}
|
|
371
|
-
} catch (executionError) {
|
|
372
|
-
if (!isFinalized) {
|
|
371
|
+
async function run() {
|
|
373
372
|
try {
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
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
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
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
|
-
|
|
415
|
-
|
|
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
|
+
};
|
package/cpp/sqlbatchexecutor.cpp
DELETED
|
@@ -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
|
package/cpp/sqlbatchexecutor.h
DELETED
|
@@ -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
|