@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/cpp/bindings.cpp CHANGED
@@ -1,11 +1,14 @@
1
1
  #include "bindings.h"
2
+ #include "DBHostObject.h"
2
3
  #include "DumbHostObject.h"
3
- #include "PreparedStatementHostObject.h"
4
4
  #include "ThreadPool.h"
5
+ #ifdef OP_SQLITE_USE_LIBSQL
6
+ #include "libsql/bridge.h"
7
+ #else
5
8
  #include "bridge.h"
9
+ #endif
6
10
  #include "logs.h"
7
11
  #include "macros.h"
8
- #include "sqlbatchexecutor.h"
9
12
  #include "utils.h"
10
13
  #include <iostream>
11
14
  #include <string>
@@ -19,13 +22,7 @@ namespace jsi = facebook::jsi;
19
22
  std::string basePath;
20
23
  std::string crsqlitePath;
21
24
  std::shared_ptr<react::CallInvoker> invoker;
22
- ThreadPool pool;
23
- std::unordered_map<std::string, std::shared_ptr<jsi::Value>> updateHooks =
24
- std::unordered_map<std::string, std::shared_ptr<jsi::Value>>();
25
- std::unordered_map<std::string, std::shared_ptr<jsi::Value>> commitHooks =
26
- std::unordered_map<std::string, std::shared_ptr<jsi::Value>>();
27
- std::unordered_map<std::string, std::shared_ptr<jsi::Value>> rollbackHooks =
28
- std::unordered_map<std::string, std::shared_ptr<jsi::Value>>();
25
+ std::shared_ptr<ThreadPool> thread_pool = std::make_shared<ThreadPool>();
29
26
 
30
27
  // React native will try to clean the module on JS context invalidation
31
28
  // (CodePush/Hot Reload) The clearState function is called and we use this flag
@@ -35,22 +32,19 @@ bool invalidated = false;
35
32
  void clearState() {
36
33
  invalidated = true;
37
34
  // Will terminate all operations and database connections
38
- opsqlite_close_all();
35
+ // opsqlite_close_all();
39
36
  // We then join all the threads before the context gets invalidated
40
- pool.restartPool();
41
- updateHooks.clear();
42
- commitHooks.clear();
43
- rollbackHooks.clear();
37
+ thread_pool->restartPool();
44
38
  }
45
39
 
46
40
  void install(jsi::Runtime &rt,
47
- std::shared_ptr<react::CallInvoker> jsCallInvoker,
48
- const char *docPath, const char *_crsqlitePath) {
41
+ std::shared_ptr<react::CallInvoker> js_call_invoker,
42
+ const char *doc_path, const char *_crsqlitePath) {
49
43
 
50
44
  invalidated = false;
51
- basePath = std::string(docPath);
45
+ basePath = std::string(doc_path);
52
46
  crsqlitePath = std::string(_crsqlitePath);
53
- invoker = jsCallInvoker;
47
+ invoker = js_call_invoker;
54
48
 
55
49
  auto open = HOSTFN("open", 3) {
56
50
  if (count == 0) {
@@ -77,13 +71,6 @@ void install(jsi::Runtime &rt,
77
71
  throw std::runtime_error(
78
72
  "[OP SQLite] using SQLCipher encryption key is required");
79
73
  }
80
- // TODO(osp) find a way to display the yellow box from c++
81
- #else
82
- // if (!encryptionKey.empty()) {
83
- // // RCTLogWarn(@"Your message")
84
- // throw std::runtime_error("[OP SQLite] SQLCipher is not enabled, "
85
- // "encryption key is not allowed");
86
- // }
87
74
  #endif
88
75
 
89
76
  if (!location.empty()) {
@@ -96,585 +83,22 @@ void install(jsi::Runtime &rt,
96
83
  }
97
84
  }
98
85
 
86
+ std::shared_ptr<DBHostObject> db = std::make_shared<DBHostObject>(
87
+ rt, basePath, invoker, thread_pool, dbName, path, crsqlitePath,
88
+ encryptionKey);
89
+ return jsi::Object::createFromHostObject(rt, db);
90
+ });
91
+
92
+ auto is_sqlcipher = HOSTFN("isSQLCipher", 0) {
99
93
  #ifdef OP_SQLITE_USE_SQLCIPHER
100
- BridgeResult result =
101
- opsqlite_open(dbName, path, crsqlitePath, encryptionKey);
94
+ return true;
102
95
  #else
103
- BridgeResult result = opsqlite_open(dbName, path, crsqlitePath);
96
+ return false;
104
97
  #endif
105
-
106
- if (result.type == SQLiteError) {
107
- throw std::runtime_error(result.message);
108
- }
109
-
110
- return {};
111
98
  });
112
99
 
113
- auto attach = HOSTFN("attach", 4) {
114
- if (count < 3) {
115
- throw jsi::JSError(rt,
116
- "[op-sqlite][attach] Incorrect number of arguments");
117
- }
118
- if (!args[0].isString() || !args[1].isString() || !args[2].isString()) {
119
- throw jsi::JSError(
120
- rt, "dbName, databaseToAttach and alias must be a strings");
121
- return {};
122
- }
123
-
124
- std::string tempDocPath = std::string(basePath);
125
- if (count > 3 && !args[3].isUndefined() && !args[3].isNull()) {
126
- if (!args[3].isString()) {
127
- throw std::runtime_error(
128
- "[op-sqlite][attach] database location must be a string");
129
- }
130
-
131
- tempDocPath = tempDocPath + "/" + args[3].asString(rt).utf8(rt);
132
- }
133
-
134
- std::string dbName = args[0].asString(rt).utf8(rt);
135
- std::string databaseToAttach = args[1].asString(rt).utf8(rt);
136
- std::string alias = args[2].asString(rt).utf8(rt);
137
- BridgeResult result =
138
- opsqlite_attach(dbName, tempDocPath, databaseToAttach, alias);
139
-
140
- if (result.type == SQLiteError) {
141
- throw std::runtime_error(result.message);
142
- }
143
-
144
- return {};
145
- });
146
-
147
- auto detach = HOSTFN("detach", 2) {
148
- if (count < 2) {
149
- throw std::runtime_error(
150
- "[op-sqlite][detach] Incorrect number of arguments");
151
- }
152
- if (!args[0].isString() || !args[1].isString()) {
153
- throw std::runtime_error(
154
- "dbName, databaseToAttach and alias must be a strings");
155
- return {};
156
- }
157
-
158
- std::string dbName = args[0].asString(rt).utf8(rt);
159
- std::string alias = args[1].asString(rt).utf8(rt);
160
- BridgeResult result = opsqlite_detach(dbName, alias);
161
-
162
- if (result.type == SQLiteError) {
163
- throw jsi::JSError(rt, result.message.c_str());
164
- }
165
-
166
- return {};
167
- });
168
-
169
- auto close = HOSTFN("close", 1) {
170
- if (count == 0) {
171
- throw std::runtime_error("[op-sqlite][close] database name is required");
172
- }
173
-
174
- if (!args[0].isString()) {
175
- throw std::runtime_error(
176
- "[op-sqlite][close] database name must be a string");
177
- }
178
-
179
- std::string dbName = args[0].asString(rt).utf8(rt);
180
-
181
- BridgeResult result = opsqlite_close(dbName);
182
-
183
- if (result.type == SQLiteError) {
184
- throw jsi::JSError(rt, result.message.c_str());
185
- }
186
-
187
- return {};
188
- });
189
-
190
- auto remove = HOSTFN("delete", 2) {
191
- if (count == 0) {
192
- throw std::runtime_error("[op-sqlite][open] database name is required");
193
- }
194
-
195
- if (!args[0].isString()) {
196
- throw std::runtime_error(
197
- "[op-sqlite][open] database name must be a string");
198
- }
199
-
200
- std::string dbName = args[0].asString(rt).utf8(rt);
201
-
202
- std::string path = std::string(basePath);
203
-
204
- if (count > 1 && !args[1].isUndefined() && !args[1].isNull()) {
205
- if (!args[1].isString()) {
206
- throw std::runtime_error(
207
- "[op-sqlite][open] database location must be a string");
208
- }
209
-
210
- std::string location = args[1].asString(rt).utf8(rt);
211
-
212
- if (!location.empty()) {
213
- if (location == ":memory:") {
214
- path = ":memory:";
215
- } else if (location.rfind("/", 0) == 0) {
216
- path = location;
217
- } else {
218
- path = path + "/" + location;
219
- }
220
- }
221
- }
222
-
223
- BridgeResult result = opsqlite_remove(dbName, path);
224
-
225
- if (result.type == SQLiteError) {
226
- throw std::runtime_error(result.message);
227
- }
228
-
229
- return {};
230
- });
231
-
232
- auto execute = HOSTFN("execute", 3) {
233
- const std::string dbName = args[0].asString(rt).utf8(rt);
234
- const std::string query = args[1].asString(rt).utf8(rt);
235
- std::vector<JSVariant> params;
236
-
237
- if (count == 3) {
238
- const jsi::Value &originalParams = args[2];
239
- params = toVariantVec(rt, originalParams);
240
- }
241
-
242
- std::vector<DumbHostObject> results;
243
- std::shared_ptr<std::vector<SmartHostObject>> metadata =
244
- std::make_shared<std::vector<SmartHostObject>>();
245
-
246
- auto status = opsqlite_execute(dbName, query, &params, &results, metadata);
247
-
248
- if (status.type == SQLiteError) {
249
- throw std::runtime_error(status.message);
250
- }
251
-
252
- auto jsiResult = createResult(rt, status, &results, metadata);
253
- return jsiResult;
254
- });
255
-
256
- auto execute_raw_async = HOSTFN("executeRawAsync", 3) {
257
- if (count < 3) {
258
- throw std::runtime_error(
259
- "[op-sqlite][executeAsync] Incorrect arguments for executeAsync");
260
- }
261
-
262
- const std::string dbName = args[0].asString(rt).utf8(rt);
263
- const std::string query = args[1].asString(rt).utf8(rt);
264
- const jsi::Value &originalParams = args[2];
265
-
266
- std::vector<JSVariant> params = toVariantVec(rt, originalParams);
267
-
268
- auto promiseCtr = rt.global().getPropertyAsFunction(rt, "Promise");
269
-
270
- auto promise = promiseCtr.callAsConstructor(rt, HOSTFN("executor", 2) {
271
- auto resolve = std::make_shared<jsi::Value>(rt, args[0]);
272
- auto reject = std::make_shared<jsi::Value>(rt, args[1]);
273
-
274
- auto task = [&rt, dbName, query, params = std::move(params), resolve,
275
- reject]() {
276
- try {
277
- std::vector<std::vector<JSVariant>> results;
278
-
279
- auto status = opsqlite_execute_raw(dbName, query, &params, &results);
280
-
281
- if (invalidated) {
282
- return;
283
- }
284
-
285
- invoker->invokeAsync([&rt, results = std::move(results),
286
- status = std::move(status), resolve, reject] {
287
- if (status.type == SQLiteOk) {
288
- auto jsiResult = create_raw_result(rt, status, &results);
289
- resolve->asObject(rt).asFunction(rt).call(rt,
290
- std::move(jsiResult));
291
- } else {
292
- auto errorCtr = rt.global().getPropertyAsFunction(rt, "Error");
293
- auto error = errorCtr.callAsConstructor(
294
- rt, jsi::String::createFromUtf8(rt, status.message));
295
- reject->asObject(rt).asFunction(rt).call(rt, error);
296
- }
297
- });
298
-
299
- } catch (std::exception &exc) {
300
- invoker->invokeAsync([&rt, exc = std::move(exc), reject] {
301
- auto errorCtr = rt.global().getPropertyAsFunction(rt, "Error");
302
- auto error = errorCtr.callAsConstructor(
303
- rt, jsi::String::createFromAscii(rt, exc.what()));
304
- reject->asObject(rt).asFunction(rt).call(rt, error);
305
- });
306
- }
307
- };
308
-
309
- pool.queueWork(task);
310
-
311
- return {};
312
- }));
313
-
314
- return promise;
315
- });
316
-
317
- auto execute_async = HOSTFN("executeAsync", 3) {
318
- if (count < 3) {
319
- throw std::runtime_error(
320
- "[op-sqlite][executeAsync] Incorrect arguments for executeAsync");
321
- }
322
-
323
- const std::string dbName = args[0].asString(rt).utf8(rt);
324
- const std::string query = args[1].asString(rt).utf8(rt);
325
- const jsi::Value &originalParams = args[2];
326
-
327
- std::vector<JSVariant> params = toVariantVec(rt, originalParams);
328
-
329
- auto promiseCtr = rt.global().getPropertyAsFunction(rt, "Promise");
330
-
331
- auto promise = promiseCtr.callAsConstructor(rt, HOSTFN("executor", 2) {
332
- auto resolve = std::make_shared<jsi::Value>(rt, args[0]);
333
- auto reject = std::make_shared<jsi::Value>(rt, args[1]);
334
-
335
- auto task = [&rt, dbName, query, params = std::move(params), resolve,
336
- reject]() {
337
- try {
338
- std::vector<DumbHostObject> results;
339
- std::shared_ptr<std::vector<SmartHostObject>> metadata =
340
- std::make_shared<std::vector<SmartHostObject>>();
341
-
342
- auto status =
343
- opsqlite_execute(dbName, query, &params, &results, metadata);
344
-
345
- if (invalidated) {
346
- return;
347
- }
348
-
349
- invoker->invokeAsync(
350
- [&rt,
351
- results = std::make_shared<std::vector<DumbHostObject>>(results),
352
- metadata, status = std::move(status), resolve, reject] {
353
- if (status.type == SQLiteOk) {
354
- auto jsiResult =
355
- createResult(rt, status, results.get(), metadata);
356
- resolve->asObject(rt).asFunction(rt).call(
357
- rt, std::move(jsiResult));
358
- } else {
359
- auto errorCtr =
360
- rt.global().getPropertyAsFunction(rt, "Error");
361
- auto error = errorCtr.callAsConstructor(
362
- rt, jsi::String::createFromUtf8(rt, status.message));
363
- reject->asObject(rt).asFunction(rt).call(rt, error);
364
- }
365
- });
366
-
367
- } catch (std::exception &exc) {
368
- invoker->invokeAsync([&rt, exc = std::move(exc), reject] {
369
- auto errorCtr = rt.global().getPropertyAsFunction(rt, "Error");
370
- auto error = errorCtr.callAsConstructor(
371
- rt, jsi::String::createFromAscii(rt, exc.what()));
372
- reject->asObject(rt).asFunction(rt).call(rt, error);
373
- });
374
- }
375
- };
376
-
377
- pool.queueWork(task);
378
-
379
- return {};
380
- }));
381
-
382
- return promise;
383
- });
384
-
385
- auto execute_batch = HOSTFN("executeBatch", 2) {
386
- if (sizeof(args) < 2) {
387
- throw std::runtime_error(
388
- "[op-sqlite][executeBatch] - Incorrect parameter count");
389
- }
390
-
391
- const jsi::Value &params = args[1];
392
- if (params.isNull() || params.isUndefined()) {
393
- throw std::runtime_error("[op-sqlite][executeBatch] - An array of SQL "
394
- "commands or parameters is needed");
395
- }
396
- const std::string dbName = args[0].asString(rt).utf8(rt);
397
- const jsi::Array &batchParams = params.asObject(rt).asArray(rt);
398
- std::vector<BatchArguments> commands;
399
- toBatchArguments(rt, batchParams, &commands);
400
-
401
- auto batchResult = sqliteExecuteBatch(dbName, &commands);
402
- if (batchResult.type == SQLiteOk) {
403
- auto res = jsi::Object(rt);
404
- res.setProperty(rt, "rowsAffected", jsi::Value(batchResult.affectedRows));
405
- return std::move(res);
406
- } else {
407
- throw std::runtime_error(batchResult.message);
408
- }
409
- });
410
-
411
- auto execute_batch_async = HOSTFN("executeBatchAsync", 2) {
412
- if (sizeof(args) < 2) {
413
- throw std::runtime_error(
414
- "[op-sqlite][executeAsyncBatch] Incorrect parameter count");
415
- return {};
416
- }
417
-
418
- const jsi::Value &params = args[1];
419
-
420
- if (params.isNull() || params.isUndefined()) {
421
- throw std::runtime_error(
422
- "[op-sqlite][executeAsyncBatch] - An array of SQL "
423
- "commands or parameters is needed");
424
- return {};
425
- }
426
-
427
- const std::string dbName = args[0].asString(rt).utf8(rt);
428
- const jsi::Array &batchParams = params.asObject(rt).asArray(rt);
429
-
430
- std::vector<BatchArguments> commands;
431
- toBatchArguments(rt, batchParams, &commands);
432
-
433
- auto promiseCtr = rt.global().getPropertyAsFunction(rt, "Promise");
434
- auto promise = promiseCtr.callAsConstructor(rt, HOSTFN("executor", 2) {
435
- auto resolve = std::make_shared<jsi::Value>(rt, args[0]);
436
- auto reject = std::make_shared<jsi::Value>(rt, args[1]);
437
-
438
- auto task = [&rt, dbName,
439
- commands =
440
- std::make_shared<std::vector<BatchArguments>>(commands),
441
- resolve, reject]() {
442
- try {
443
- auto batchResult = sqliteExecuteBatch(dbName, commands.get());
444
- invoker->invokeAsync([&rt, batchResult = std::move(batchResult),
445
- resolve, reject] {
446
- if (batchResult.type == SQLiteOk) {
447
- auto res = jsi::Object(rt);
448
- res.setProperty(rt, "rowsAffected",
449
- jsi::Value(batchResult.affectedRows));
450
- resolve->asObject(rt).asFunction(rt).call(rt, std::move(res));
451
- } else {
452
- auto errorCtr = rt.global().getPropertyAsFunction(rt, "Error");
453
- auto error = errorCtr.callAsConstructor(
454
- rt, jsi::String::createFromUtf8(rt, batchResult.message));
455
- reject->asObject(rt).asFunction(rt).call(rt, error);
456
- }
457
- });
458
- } catch (std::exception &exc) {
459
- invoker->invokeAsync(
460
- [&rt, reject, &exc] { throw jsi::JSError(rt, exc.what()); });
461
- }
462
- };
463
- pool.queueWork(task);
464
-
465
- return {};
466
- }));
467
-
468
- return promise;
469
- });
470
-
471
- auto load_file = HOSTFN("loadFile", 2) {
472
- if (sizeof(args) < 2) {
473
- throw std::runtime_error(
474
- "[op-sqlite][loadFile] Incorrect parameter count");
475
- return {};
476
- }
477
-
478
- const std::string dbName = args[0].asString(rt).utf8(rt);
479
- const std::string sqlFileName = args[1].asString(rt).utf8(rt);
480
-
481
- auto promiseCtr = rt.global().getPropertyAsFunction(rt, "Promise");
482
- auto promise = promiseCtr.callAsConstructor(rt, HOSTFN("executor", 2) {
483
- auto resolve = std::make_shared<jsi::Value>(rt, args[0]);
484
- auto reject = std::make_shared<jsi::Value>(rt, args[1]);
485
-
486
- auto task = [&rt, dbName, sqlFileName, resolve, reject]() {
487
- try {
488
- const auto importResult = importSQLFile(dbName, sqlFileName);
489
-
490
- invoker->invokeAsync([&rt, result = std::move(importResult), resolve,
491
- reject] {
492
- if (result.type == SQLiteOk) {
493
- auto res = jsi::Object(rt);
494
- res.setProperty(rt, "rowsAffected",
495
- jsi::Value(result.affectedRows));
496
- res.setProperty(rt, "commands", jsi::Value(result.commands));
497
- resolve->asObject(rt).asFunction(rt).call(rt, std::move(res));
498
- } else {
499
- auto errorCtr = rt.global().getPropertyAsFunction(rt, "Error");
500
- auto error = errorCtr.callAsConstructor(
501
- rt, jsi::String::createFromUtf8(rt, result.message));
502
- reject->asObject(rt).asFunction(rt).call(rt, error);
503
- }
504
- });
505
- } catch (std::exception &exc) {
506
- invoker->invokeAsync(
507
- [&rt, err = exc.what(), reject] { throw jsi::JSError(rt, err); });
508
- }
509
- };
510
- pool.queueWork(task);
511
- return {};
512
- }));
513
-
514
- return promise;
515
- });
516
-
517
- auto update_hook = HOSTFN("updateHook", 2) {
518
- if (sizeof(args) < 2) {
519
- throw std::runtime_error("[op-sqlite][updateHook] Incorrect parameters: "
520
- "dbName and callback needed");
521
- return {};
522
- }
523
-
524
- auto dbName = args[0].asString(rt).utf8(rt);
525
- auto callback = std::make_shared<jsi::Value>(rt, args[1]);
526
-
527
- if (callback->isUndefined() || callback->isNull()) {
528
- opsqlite_deregister_update_hook(dbName);
529
- return {};
530
- }
531
-
532
- updateHooks[dbName] = callback;
533
-
534
- auto hook = [&rt, callback](std::string dbName, std::string tableName,
535
- std::string operation, int rowId) {
536
- std::vector<JSVariant> params;
537
- std::vector<DumbHostObject> results;
538
- std::shared_ptr<std::vector<SmartHostObject>> metadata =
539
- std::make_shared<std::vector<SmartHostObject>>();
540
-
541
- if (operation != "DELETE") {
542
- std::string query = "SELECT * FROM " + tableName +
543
- " where rowid = " + std::to_string(rowId) + ";";
544
- opsqlite_execute(dbName, query, &params, &results, metadata);
545
- }
546
-
547
- invoker->invokeAsync(
548
- [&rt,
549
- results = std::make_shared<std::vector<DumbHostObject>>(results),
550
- callback, tableName = std::move(tableName),
551
- operation = std::move(operation), &rowId] {
552
- auto res = jsi::Object(rt);
553
- res.setProperty(rt, "table",
554
- jsi::String::createFromUtf8(rt, tableName));
555
- res.setProperty(rt, "operation",
556
- jsi::String::createFromUtf8(rt, operation));
557
- res.setProperty(rt, "rowId", jsi::Value(rowId));
558
- if (results->size() != 0) {
559
- res.setProperty(
560
- rt, "row",
561
- jsi::Object::createFromHostObject(
562
- rt, std::make_shared<DumbHostObject>(results->at(0))));
563
- }
564
-
565
- callback->asObject(rt).asFunction(rt).call(rt, res);
566
- });
567
- };
568
-
569
- opsqlite_register_update_hook(dbName, std::move(hook));
570
-
571
- return {};
572
- });
573
-
574
- auto commit_hook = HOSTFN("commitHook", 2) {
575
- if (sizeof(args) < 2) {
576
- throw std::runtime_error("[op-sqlite][commitHook] Incorrect parameters: "
577
- "dbName and callback needed");
578
- return {};
579
- }
580
-
581
- auto dbName = args[0].asString(rt).utf8(rt);
582
- auto callback = std::make_shared<jsi::Value>(rt, args[1]);
583
- if (callback->isUndefined() || callback->isNull()) {
584
- opsqlite_deregister_commit_hook(dbName);
585
- return {};
586
- }
587
- commitHooks[dbName] = callback;
588
-
589
- auto hook = [&rt, callback](std::string dbName) {
590
- invoker->invokeAsync(
591
- [&rt, callback] { callback->asObject(rt).asFunction(rt).call(rt); });
592
- };
593
-
594
- opsqlite_register_commit_hook(dbName, std::move(hook));
595
-
596
- return {};
597
- });
598
-
599
- auto rollback_hook = HOSTFN("rollbackHook", 2) {
600
- if (sizeof(args) < 2) {
601
- throw std::runtime_error(
602
- "[op-sqlite][rollbackHook] Incorrect parameters: "
603
- "dbName and callback needed");
604
- return {};
605
- }
606
-
607
- auto dbName = args[0].asString(rt).utf8(rt);
608
- auto callback = std::make_shared<jsi::Value>(rt, args[1]);
609
-
610
- if (callback->isUndefined() || callback->isNull()) {
611
- opsqlite_deregister_rollback_hook(dbName);
612
- return {};
613
- }
614
- rollbackHooks[dbName] = callback;
615
-
616
- auto hook = [&rt, callback](std::string dbName) {
617
- invoker->invokeAsync(
618
- [&rt, callback] { callback->asObject(rt).asFunction(rt).call(rt); });
619
- };
620
-
621
- opsqlite_register_rollback_hook(dbName, std::move(hook));
622
- return {};
623
- });
624
-
625
- auto prepare_statement = HOSTFN("prepareStatement", 1) {
626
- auto dbName = args[0].asString(rt).utf8(rt);
627
- auto query = args[1].asString(rt).utf8(rt);
628
-
629
- sqlite3_stmt *statement = opsqlite_prepare_statement(dbName, query);
630
-
631
- auto preparedStatementHostObject =
632
- std::make_shared<PreparedStatementHostObject>(dbName, statement);
633
-
634
- return jsi::Object::createFromHostObject(rt, preparedStatementHostObject);
635
- });
636
-
637
- auto load_extension = HOSTFN("loadExtension", 2) {
638
- auto db_name = args[0].asString(rt).utf8(rt);
639
- auto path = args[1].asString(rt).utf8(rt);
640
- std::string entryPoint = "";
641
- if (count > 2 && args[2].isString()) {
642
- entryPoint = args[2].asString(rt).utf8(rt);
643
- }
644
-
645
- auto result = opsqlite_load_extension(db_name, path, entryPoint);
646
- if (result.type == SQLiteError) {
647
- throw std::runtime_error(result.message);
648
- }
649
- return {};
650
- });
651
-
652
- auto get_db_path = HOSTFN("getDbPath", 2) {
653
- std::string db_name = args[0].asString(rt).utf8(rt);
654
- std::string path = std::string(basePath);
655
- if (count > 1 && !args[1].isUndefined() && !args[1].isNull()) {
656
- if (!args[1].isString()) {
657
- throw std::runtime_error(
658
- "[op-sqlite][open] database location must be a string");
659
- }
660
-
661
- std::string lastPath = args[1].asString(rt).utf8(rt);
662
-
663
- if (lastPath == ":memory:") {
664
- path = ":memory:";
665
- } else if (lastPath.rfind("/", 0) == 0) {
666
- path = lastPath;
667
- } else {
668
- path = path + "/" + lastPath;
669
- }
670
- }
671
-
672
- auto result = opsqlite_get_db_path(db_name, path);
673
- return jsi::String::createFromUtf8(rt, result);
674
- });
675
-
676
- auto is_sqlcipher = HOSTFN("isSQLCipher", 0) {
677
- #ifdef OP_SQLITE_USE_SQLCIPHER
100
+ auto is_libsql = HOSTFN("isLibsql", 0) {
101
+ #ifdef OP_SQLITE_USE_LIBSQL
678
102
  return true;
679
103
  #else
680
104
  return false;
@@ -682,25 +106,9 @@ void install(jsi::Runtime &rt,
682
106
  });
683
107
 
684
108
  jsi::Object module = jsi::Object(rt);
685
-
686
109
  module.setProperty(rt, "open", std::move(open));
687
- module.setProperty(rt, "close", std::move(close));
688
- module.setProperty(rt, "attach", std::move(attach));
689
- module.setProperty(rt, "detach", std::move(detach));
690
- module.setProperty(rt, "delete", std::move(remove));
691
- module.setProperty(rt, "execute", std::move(execute));
692
- module.setProperty(rt, "executeAsync", std::move(execute_async));
693
- module.setProperty(rt, "executeBatch", std::move(execute_batch));
694
- module.setProperty(rt, "executeBatchAsync", std::move(execute_batch_async));
695
- module.setProperty(rt, "loadFile", std::move(load_file));
696
- module.setProperty(rt, "updateHook", std::move(update_hook));
697
- module.setProperty(rt, "commitHook", std::move(commit_hook));
698
- module.setProperty(rt, "rollbackHook", std::move(rollback_hook));
699
- module.setProperty(rt, "prepareStatement", std::move(prepare_statement));
700
- module.setProperty(rt, "loadExtension", std::move(load_extension));
701
- module.setProperty(rt, "executeRawAsync", std::move(execute_raw_async));
702
- module.setProperty(rt, "getDbPath", std::move(get_db_path));
703
110
  module.setProperty(rt, "isSQLCipher", std::move(is_sqlcipher));
111
+ module.setProperty(rt, "isLibsql", std::move(is_libsql));
704
112
 
705
113
  rt.global().setProperty(rt, "__OPSQLiteProxy", std::move(module));
706
114
  }