@op-engineering/op-sqlite 6.0.2-beta1 → 6.0.2-beta4

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 +234 -87
  9. package/cpp/DBHostObject.h +19 -10
  10. package/cpp/PreparedStatementHostObject.cpp +28 -14
  11. package/cpp/PreparedStatementHostObject.h +18 -14
  12. package/cpp/bindings.cpp +49 -32
  13. package/cpp/bindings.h +4 -3
  14. package/cpp/bridge.cpp +45 -0
  15. package/cpp/bridge.h +3 -0
  16. package/cpp/libsql/bridge.cpp +660 -0
  17. package/cpp/libsql/bridge.h +76 -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 +45 -3
  22. package/cpp/utils.h +2 -3
  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 +167 -2
  29. package/lib/commonjs/index.js.map +1 -1
  30. package/lib/module/index.js +164 -1
  31. package/lib/module/index.js.map +1 -1
  32. package/lib/typescript/src/index.d.ts +14 -2
  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 +209 -3
  37. package/cpp/sqlbatchexecutor.cpp +0 -93
  38. package/cpp/sqlbatchexecutor.h +0 -30
@@ -1,8 +1,11 @@
1
1
  #include "DBHostObject.h"
2
2
  #include "PreparedStatementHostObject.h"
3
+ #if OP_SQLITE_USE_LIBSQL
4
+ #include "libsql/bridge.h"
5
+ #else
3
6
  #include "bridge.h"
7
+ #endif
4
8
  #include "macros.h"
5
- #include "sqlbatchexecutor.h"
6
9
  #include "utils.h"
7
10
  #include <iostream>
8
11
 
@@ -11,6 +14,7 @@ namespace opsqlite {
11
14
  namespace jsi = facebook::jsi;
12
15
  namespace react = facebook::react;
13
16
 
17
+ #ifndef OP_SQLITE_USE_LIBSQL
14
18
  void DBHostObject::auto_register_update_hook() {
15
19
  if (update_hook_callback == nullptr && reactive_queries.size() == 0 &&
16
20
  has_update_hook_registered) {
@@ -61,18 +65,35 @@ void DBHostObject::auto_register_update_hook() {
61
65
  for (const auto &query_ptr : reactive_queries) {
62
66
 
63
67
  auto query = query_ptr.get();
64
- if (query->tables.size() == 0) {
68
+ if (query->discriminators.size() == 0) {
65
69
  continue;
66
70
  }
67
71
 
68
- if (std::find(query->tables.begin(), query->tables.end(), table_name) ==
69
- query->tables.end()) {
70
- continue;
72
+ bool shouldFire = false;
73
+
74
+ for (const auto &discriminator : query->discriminators) {
75
+ if (discriminator.table != table_name) {
76
+ continue;
77
+ }
78
+
79
+ // Table has matched
80
+
81
+ // If no ids are specified, then we should fire
82
+ if (discriminator.ids.size() == 0) {
83
+ shouldFire = true;
84
+ break;
85
+ } else { // If ids are specified, then we should check if the rowId
86
+ // matches
87
+ for (const auto &discrimator_id : discriminator.ids) {
88
+ if (rowId == discrimator_id) {
89
+ shouldFire = true;
90
+ break;
91
+ }
92
+ }
93
+ }
71
94
  }
72
95
 
73
- if (query->rowIds.size() > 0 &&
74
- std::find(query->rowIds.begin(), query->rowIds.end(), rowId) ==
75
- query->rowIds.end()) {
96
+ if (!shouldFire) {
76
97
  continue;
77
98
  }
78
99
 
@@ -80,8 +101,8 @@ void DBHostObject::auto_register_update_hook() {
80
101
  std::shared_ptr<std::vector<SmartHostObject>> metadata =
81
102
  std::make_shared<std::vector<SmartHostObject>>();
82
103
 
83
- auto status = opsqlite_execute(dbName, query->query, &query->args,
84
- &results, metadata);
104
+ auto status = opsqlite_execute_prepared_statement(db_name, query->stmt,
105
+ &results, metadata);
85
106
 
86
107
  if (status.type == SQLiteError) {
87
108
  jsCallInvoker->invokeAsync(
@@ -114,6 +135,24 @@ void DBHostObject::auto_register_update_hook() {
114
135
  opsqlite_register_update_hook(db_name, std::move(hook));
115
136
  has_update_hook_registered = true;
116
137
  }
138
+ #endif
139
+
140
+ #ifdef OP_SQLITE_USE_LIBSQL
141
+ DBHostObject::DBHostObject(jsi::Runtime &rt, std::string &url,
142
+ std::string &auth_token,
143
+ std::shared_ptr<react::CallInvoker> js_call_invoker,
144
+ std::shared_ptr<ThreadPool> thread_pool)
145
+ : db_name(url), jsCallInvoker(js_call_invoker), thread_pool(thread_pool),
146
+ rt(rt) {
147
+ BridgeResult result = opsqlite_libsql_open_remote(url, auth_token);
148
+
149
+ if (result.type == SQLiteError) {
150
+ throw std::runtime_error(result.message);
151
+ }
152
+
153
+ create_jsi_functions();
154
+ }
155
+ #endif
117
156
 
118
157
  DBHostObject::DBHostObject(jsi::Runtime &rt, std::string &base_path,
119
158
  std::shared_ptr<react::CallInvoker> jsCallInvoker,
@@ -127,6 +166,8 @@ DBHostObject::DBHostObject(jsi::Runtime &rt, std::string &base_path,
127
166
  #ifdef OP_SQLITE_USE_SQLCIPHER
128
167
  BridgeResult result =
129
168
  opsqlite_open(db_name, path, crsqlite_path, encryption_key);
169
+ #elif OP_SQLITE_USE_LIBSQL
170
+ BridgeResult result = opsqlite_libsql_open(db_name, path);
130
171
  #else
131
172
  BridgeResult result = opsqlite_open(db_name, path, crsqlite_path);
132
173
  #endif
@@ -135,6 +176,10 @@ DBHostObject::DBHostObject(jsi::Runtime &rt, std::string &base_path,
135
176
  throw std::runtime_error(result.message);
136
177
  }
137
178
 
179
+ create_jsi_functions();
180
+ };
181
+
182
+ void DBHostObject::create_jsi_functions() {
138
183
  auto attach = HOSTFN("attach", 4) {
139
184
  if (count < 3) {
140
185
  throw jsi::JSError(rt,
@@ -159,9 +204,13 @@ DBHostObject::DBHostObject(jsi::Runtime &rt, std::string &base_path,
159
204
  std::string dbName = args[0].asString(rt).utf8(rt);
160
205
  std::string databaseToAttach = args[1].asString(rt).utf8(rt);
161
206
  std::string alias = args[2].asString(rt).utf8(rt);
207
+ #ifdef OP_SQLITE_USE_LIBSQL
208
+ BridgeResult result =
209
+ opsqlite_libsql_attach(dbName, tempDocPath, databaseToAttach, alias);
210
+ #else
162
211
  BridgeResult result =
163
212
  opsqlite_attach(dbName, tempDocPath, databaseToAttach, alias);
164
-
213
+ #endif
165
214
  if (result.type == SQLiteError) {
166
215
  throw std::runtime_error(result.message);
167
216
  }
@@ -182,7 +231,11 @@ DBHostObject::DBHostObject(jsi::Runtime &rt, std::string &base_path,
182
231
 
183
232
  std::string dbName = args[0].asString(rt).utf8(rt);
184
233
  std::string alias = args[1].asString(rt).utf8(rt);
234
+ #ifdef OP_SQLITE_USE_LIBSQL
235
+ BridgeResult result = opsqlite_libsql_detach(dbName, alias);
236
+ #else
185
237
  BridgeResult result = opsqlite_detach(dbName, alias);
238
+ #endif
186
239
 
187
240
  if (result.type == SQLiteError) {
188
241
  throw jsi::JSError(rt, result.message.c_str());
@@ -192,7 +245,11 @@ DBHostObject::DBHostObject(jsi::Runtime &rt, std::string &base_path,
192
245
  });
193
246
 
194
247
  auto close = HOSTFN("close", 0) {
248
+ #ifdef OP_SQLITE_USE_LIBSQL
249
+ BridgeResult result = opsqlite_libsql_close(db_name);
250
+ #else
195
251
  BridgeResult result = opsqlite_close(db_name);
252
+ #endif
196
253
 
197
254
  if (result.type == SQLiteError) {
198
255
  throw jsi::JSError(rt, result.message.c_str());
@@ -224,7 +281,11 @@ DBHostObject::DBHostObject(jsi::Runtime &rt, std::string &base_path,
224
281
  }
225
282
  }
226
283
 
284
+ #ifdef OP_SQLITE_USE_LIBSQL
285
+ BridgeResult result = opsqlite_libsql_remove(db_name, path);
286
+ #else
227
287
  BridgeResult result = opsqlite_remove(db_name, path);
288
+ #endif
228
289
 
229
290
  if (result.type == SQLiteError) {
230
291
  throw std::runtime_error(result.message);
@@ -246,7 +307,12 @@ DBHostObject::DBHostObject(jsi::Runtime &rt, std::string &base_path,
246
307
  std::shared_ptr<std::vector<SmartHostObject>> metadata =
247
308
  std::make_shared<std::vector<SmartHostObject>>();
248
309
 
310
+ #ifdef OP_SQLITE_USE_LIBSQL
311
+ auto status =
312
+ opsqlite_libsql_execute(db_name, query, &params, &results, metadata);
313
+ #else
249
314
  auto status = opsqlite_execute(db_name, query, &params, &results, metadata);
315
+ #endif
250
316
 
251
317
  if (status.type == SQLiteError) {
252
318
  throw std::runtime_error(status.message);
@@ -270,12 +336,17 @@ DBHostObject::DBHostObject(jsi::Runtime &rt, std::string &base_path,
270
336
  auto resolve = std::make_shared<jsi::Value>(rt, args[0]);
271
337
  auto reject = std::make_shared<jsi::Value>(rt, args[1]);
272
338
 
273
- auto task = [&rt, db_name, query, params = std::move(params), resolve,
339
+ auto task = [&rt, this, query, params = std::move(params), resolve,
274
340
  reject, invoker = this->jsCallInvoker]() {
275
341
  try {
276
342
  std::vector<std::vector<JSVariant>> results;
277
343
 
344
+ #ifdef OP_SQLITE_USE_LIBSQL
345
+ auto status =
346
+ opsqlite_libsql_execute_raw(db_name, query, &params, &results);
347
+ #else
278
348
  auto status = opsqlite_execute_raw(db_name, query, &params, &results);
349
+ #endif
279
350
  //
280
351
  // if (invalidated) {
281
352
  // return;
@@ -308,13 +379,12 @@ DBHostObject::DBHostObject(jsi::Runtime &rt, std::string &base_path,
308
379
  thread_pool->queueWork(task);
309
380
 
310
381
  return {};
311
- }));
382
+ }));
312
383
 
313
384
  return promise;
314
385
  });
315
386
 
316
387
  auto execute_async = HOSTFN("executeAsync", 2) {
317
-
318
388
  const std::string query = args[0].asString(rt).utf8(rt);
319
389
  std::vector<JSVariant> params;
320
390
 
@@ -328,15 +398,19 @@ DBHostObject::DBHostObject(jsi::Runtime &rt, std::string &base_path,
328
398
  auto resolve = std::make_shared<jsi::Value>(rt, args[0]);
329
399
  auto reject = std::make_shared<jsi::Value>(rt, args[1]);
330
400
 
331
- auto task = [&rt, &db_name, query, params = std::move(params), resolve,
401
+ auto task = [&rt, this, query, params = std::move(params), resolve,
332
402
  reject, invoker = this->jsCallInvoker]() {
333
403
  try {
334
404
  std::vector<DumbHostObject> results;
335
405
  std::shared_ptr<std::vector<SmartHostObject>> metadata =
336
406
  std::make_shared<std::vector<SmartHostObject>>();
337
-
407
+ #ifdef OP_SQLITE_USE_LIBSQL
408
+ auto status = opsqlite_libsql_execute(db_name, query, &params,
409
+ &results, metadata);
410
+ #else
338
411
  auto status =
339
412
  opsqlite_execute(db_name, query, &params, &results, metadata);
413
+ #endif
340
414
 
341
415
  // if (invalidated) {
342
416
  // return;
@@ -391,9 +465,13 @@ DBHostObject::DBHostObject(jsi::Runtime &rt, std::string &base_path,
391
465
  }
392
466
  const jsi::Array &batchParams = params.asObject(rt).asArray(rt);
393
467
  std::vector<BatchArguments> commands;
394
- toBatchArguments(rt, batchParams, &commands);
468
+ to_batch_arguments(rt, batchParams, &commands);
395
469
 
396
- auto batchResult = sqliteExecuteBatch(db_name, &commands);
470
+ #ifdef OP_SQLITE_USE_LIBSQL
471
+ auto batchResult = opsqlite_libsql_execute_batch(db_name, &commands);
472
+ #else
473
+ auto batchResult = opsqlite_execute_batch(db_name, &commands);
474
+ #endif
397
475
  if (batchResult.type == SQLiteOk) {
398
476
  auto res = jsi::Object(rt);
399
477
  res.setProperty(rt, "rowsAffected", jsi::Value(batchResult.affectedRows));
@@ -422,19 +500,24 @@ DBHostObject::DBHostObject(jsi::Runtime &rt, std::string &base_path,
422
500
  const jsi::Array &batchParams = params.asObject(rt).asArray(rt);
423
501
 
424
502
  std::vector<BatchArguments> commands;
425
- toBatchArguments(rt, batchParams, &commands);
503
+ to_batch_arguments(rt, batchParams, &commands);
426
504
 
427
505
  auto promiseCtr = rt.global().getPropertyAsFunction(rt, "Promise");
428
- auto promise = promiseCtr.callAsConstructor(rt, HOSTFN("executor", 2) {
506
+ auto promise = promiseCtr.callAsConstructor(rt, HOSTFN("executor", 2) {
429
507
  auto resolve = std::make_shared<jsi::Value>(rt, args[0]);
430
508
  auto reject = std::make_shared<jsi::Value>(rt, args[1]);
431
509
 
432
- auto task = [&rt, &db_name, &jsCallInvoker,
510
+ auto task = [&rt, this,
433
511
  commands =
434
512
  std::make_shared<std::vector<BatchArguments>>(commands),
435
513
  resolve, reject]() {
436
514
  try {
437
- auto batchResult = sqliteExecuteBatch(db_name, commands.get());
515
+ #ifdef OP_SQLITE_USE_LIBSQL
516
+ auto batchResult =
517
+ opsqlite_libsql_execute_batch(db_name, commands.get());
518
+ #else
519
+ auto batchResult = opsqlite_execute_batch(db_name, commands.get());
520
+ #endif
438
521
  jsCallInvoker->invokeAsync([&rt, batchResult = std::move(batchResult),
439
522
  resolve, reject] {
440
523
  if (batchResult.type == SQLiteOk) {
@@ -457,11 +540,12 @@ DBHostObject::DBHostObject(jsi::Runtime &rt, std::string &base_path,
457
540
  thread_pool->queueWork(task);
458
541
 
459
542
  return {};
460
- }));
543
+ }));
461
544
 
462
- return promise;
545
+ return promise;
463
546
  });
464
547
 
548
+ #ifndef OP_SQLITE_USE_LIBSQL
465
549
  auto load_file = HOSTFN("loadFile", 1) {
466
550
  if (sizeof(args) < 1) {
467
551
  throw std::runtime_error(
@@ -472,12 +556,12 @@ DBHostObject::DBHostObject(jsi::Runtime &rt, std::string &base_path,
472
556
  const std::string sqlFileName = args[0].asString(rt).utf8(rt);
473
557
 
474
558
  auto promiseCtr = rt.global().getPropertyAsFunction(rt, "Promise");
475
- auto promise = promiseCtr.callAsConstructor(rt, HOSTFN("executor", 2) {
559
+ auto promise = promiseCtr.callAsConstructor(rt, HOSTFN("executor", 2)
560
+ {
476
561
  auto resolve = std::make_shared<jsi::Value>(rt, args[0]);
477
562
  auto reject = std::make_shared<jsi::Value>(rt, args[1]);
478
563
 
479
- auto task = [&rt, &db_name, &jsCallInvoker, sqlFileName, resolve,
480
- reject]() {
564
+ auto task = [&rt, this, sqlFileName, resolve, reject]() {
481
565
  try {
482
566
  const auto importResult = importSQLFile(db_name, sqlFileName);
483
567
 
@@ -503,9 +587,9 @@ DBHostObject::DBHostObject(jsi::Runtime &rt, std::string &base_path,
503
587
  };
504
588
  thread_pool->queueWork(task);
505
589
  return {};
506
- }));
590
+ }));
507
591
 
508
- return promise;
592
+ return promise;
509
593
  });
510
594
 
511
595
  auto update_hook = HOSTFN("updateHook", 1) {
@@ -533,7 +617,7 @@ DBHostObject::DBHostObject(jsi::Runtime &rt, std::string &base_path,
533
617
  }
534
618
  commit_hook_callback = callback;
535
619
 
536
- auto hook = [&rt, jsCallInvoker, callback](std::string dbName) {
620
+ auto hook = [&rt, this, callback](std::string dbName) {
537
621
  jsCallInvoker->invokeAsync(
538
622
  [&rt, callback] { callback->asObject(rt).asFunction(rt).call(rt); });
539
623
  };
@@ -557,7 +641,7 @@ DBHostObject::DBHostObject(jsi::Runtime &rt, std::string &base_path,
557
641
  }
558
642
  rollback_hook_callback = callback;
559
643
 
560
- auto hook = [&rt, jsCallInvoker, callback](std::string db_name) {
644
+ auto hook = [&rt, this, callback](std::string db_name) {
561
645
  jsCallInvoker->invokeAsync(
562
646
  [&rt, callback] { callback->asObject(rt).asFunction(rt).call(rt); });
563
647
  };
@@ -566,17 +650,6 @@ DBHostObject::DBHostObject(jsi::Runtime &rt, std::string &base_path,
566
650
  return {};
567
651
  });
568
652
 
569
- auto prepare_statement = HOSTFN("prepareStatement", 1) {
570
- auto query = args[0].asString(rt).utf8(rt);
571
-
572
- sqlite3_stmt *statement = opsqlite_prepare_statement(db_name, query);
573
-
574
- auto preparedStatementHostObject =
575
- std::make_shared<PreparedStatementHostObject>(db_name, statement);
576
-
577
- return jsi::Object::createFromHostObject(rt, preparedStatementHostObject);
578
- });
579
-
580
653
  auto load_extension = HOSTFN("loadExtension", 1) {
581
654
  auto path = args[0].asString(rt).utf8(rt);
582
655
  std::string entry_point = "";
@@ -591,29 +664,6 @@ DBHostObject::DBHostObject(jsi::Runtime &rt, std::string &base_path,
591
664
  return {};
592
665
  });
593
666
 
594
- auto get_db_path = HOSTFN("getDbPath", 1) {
595
- std::string path = std::string(base_path);
596
- if (count == 1 && !args[0].isUndefined() && !args[0].isNull()) {
597
- if (!args[0].isString()) {
598
- throw std::runtime_error(
599
- "[op-sqlite][open] database location must be a string");
600
- }
601
-
602
- std::string lastPath = args[0].asString(rt).utf8(rt);
603
-
604
- if (lastPath == ":memory:") {
605
- path = ":memory:";
606
- } else if (lastPath.rfind("/", 0) == 0) {
607
- path = lastPath;
608
- } else {
609
- path = path + "/" + lastPath;
610
- }
611
- }
612
-
613
- auto result = opsqlite_get_db_path(db_name, path);
614
- return jsi::String::createFromUtf8(rt, result);
615
- });
616
-
617
667
  auto reactive_execute = HOSTFN("reactiveExecute", 0) {
618
668
  auto query = args[0].asObject(rt);
619
669
  // if (!query.hasProperty(rt, "query") || !query.hasProperty(rt, "args")
@@ -628,23 +678,47 @@ DBHostObject::DBHostObject(jsi::Runtime &rt, std::string &base_path,
628
678
 
629
679
  const std::string query_str =
630
680
  query.getProperty(rt, "query").asString(rt).utf8(rt);
631
- auto argsArray = query.getProperty(rt, "args");
632
- auto tablesArray = query.getProperty(rt, "tables");
681
+ auto js_args = query.getProperty(rt, "args");
682
+ auto js_discriminators =
683
+ query.getProperty(rt, "fireOn").asObject(rt).asArray(rt);
684
+ auto variant_args = to_variant_vec(rt, js_args);
685
+
686
+ sqlite3_stmt *stmt = opsqlite_prepare_statement(db_name, query_str);
687
+ opsqlite_bind_statement(stmt, &variant_args);
633
688
 
634
689
  auto callback =
635
690
  std::make_shared<jsi::Value>(query.getProperty(rt, "callback"));
636
691
 
637
- std::vector<JSVariant> query_args = to_variant_vec(rt, argsArray);
638
- std::vector<std::string> tables = to_string_vec(rt, tablesArray);
639
- std::vector<int> rowIds;
640
- if (query.hasProperty(rt, "rowIds")) {
641
- auto rowIdsArray = query.getProperty(rt, "rowIds");
642
- rowIds = to_int_vec(rt, rowIdsArray);
692
+ // std::vector<JSVariant> query_args = to_variant_vec(rt, argsArray);
693
+ // std::vector<std::string> tables = to_string_vec(rt, tablesArray);
694
+ // std::vector<int> rowIds;
695
+ // if (query.hasProperty(rt, "rowIds")) {
696
+ // auto rowIdsArray = query.getProperty(rt, "rowIds");
697
+ // rowIds = to_int_vec(rt, rowIdsArray);
698
+ // }
699
+
700
+ std::vector<TableRowDiscriminator> discriminators;
701
+
702
+ for (size_t i = 0; i < js_discriminators.length(rt); i++) {
703
+ auto js_discriminator =
704
+ js_discriminators.getValueAtIndex(rt, i).asObject(rt);
705
+ std::string table =
706
+ js_discriminator.getProperty(rt, "table").asString(rt).utf8(rt);
707
+ std::vector<int> ids;
708
+ if (js_discriminator.hasProperty(rt, "ids")) {
709
+ auto js_ids =
710
+ js_discriminator.getProperty(rt, "ids").asObject(rt).asArray(rt);
711
+ for (size_t j = 0; j < js_ids.length(rt); j++) {
712
+ ids.push_back(
713
+ static_cast<int>(js_ids.getValueAtIndex(rt, j).asNumber()));
714
+ }
715
+ }
716
+ discriminators.push_back({table, ids});
643
717
  }
644
718
 
645
719
  std::shared_ptr<ReactiveQuery> reactiveQuery =
646
720
  std::make_shared<ReactiveQuery>(
647
- ReactiveQuery{query_str, query_args, tables, rowIds, callback});
721
+ ReactiveQuery{stmt, discriminators, callback});
648
722
 
649
723
  reactive_queries.push_back(reactiveQuery);
650
724
 
@@ -663,6 +737,44 @@ DBHostObject::DBHostObject(jsi::Runtime &rt, std::string &base_path,
663
737
  return unsubscribe;
664
738
  });
665
739
 
740
+ #endif
741
+
742
+ auto prepare_statement = HOSTFN("prepareStatement", 1) {
743
+ auto query = args[0].asString(rt).utf8(rt);
744
+ #ifdef OP_SQLITE_USE_LIBSQL
745
+ libsql_stmt_t statement = opsqlite_libsql_prepare_statement(db_name, query);
746
+ #else
747
+ sqlite3_stmt *statement = opsqlite_prepare_statement(db_name, query);
748
+ #endif
749
+ auto preparedStatementHostObject =
750
+ std::make_shared<PreparedStatementHostObject>(db_name, statement);
751
+
752
+ return jsi::Object::createFromHostObject(rt, preparedStatementHostObject);
753
+ });
754
+
755
+ auto get_db_path = HOSTFN("getDbPath", 1) {
756
+ std::string path = std::string(base_path);
757
+ if (count == 1 && !args[0].isUndefined() && !args[0].isNull()) {
758
+ if (!args[0].isString()) {
759
+ throw std::runtime_error(
760
+ "[op-sqlite][open] database location must be a string");
761
+ }
762
+
763
+ std::string lastPath = args[0].asString(rt).utf8(rt);
764
+
765
+ if (lastPath == ":memory:") {
766
+ path = ":memory:";
767
+ } else if (lastPath.rfind("/", 0) == 0) {
768
+ path = lastPath;
769
+ } else {
770
+ path = path + "/" + lastPath;
771
+ }
772
+ }
773
+
774
+ auto result = opsqlite_get_db_path(db_name, path);
775
+ return jsi::String::createFromUtf8(rt, result);
776
+ });
777
+
666
778
  function_map["attach"] = std::move(attach);
667
779
  function_map["detach"] = std::move(detach);
668
780
  function_map["close"] = std::move(close);
@@ -672,15 +784,17 @@ DBHostObject::DBHostObject(jsi::Runtime &rt, std::string &base_path,
672
784
  function_map["delete"] = std::move(remove);
673
785
  function_map["executeBatch"] = std::move(execute_batch);
674
786
  function_map["executeBatchAsync"] = std::move(execute_batch_async);
787
+ function_map["prepareStatement"] = std::move(prepare_statement);
788
+ function_map["getDbPath"] = std::move(get_db_path);
789
+ #ifndef OP_SQLITE_USE_LIBSQL
675
790
  function_map["loadFile"] = std::move(load_file);
676
791
  function_map["updateHook"] = std::move(update_hook);
677
792
  function_map["commitHook"] = std::move(commit_hook);
678
793
  function_map["rollbackHook"] = std::move(rollback_hook);
679
- function_map["prepareStatement"] = std::move(prepare_statement);
680
794
  function_map["loadExtension"] = std::move(load_extension);
681
- function_map["getDbPath"] = std::move(get_db_path);
682
795
  function_map["reactiveExecute"] = std::move(reactive_execute);
683
- };
796
+ #endif
797
+ }
684
798
 
685
799
  std::vector<jsi::PropNameID> DBHostObject::getPropertyNames(jsi::Runtime &rt) {
686
800
  std::vector<jsi::PropNameID> keys;
@@ -719,6 +833,44 @@ jsi::Value DBHostObject::get(jsi::Runtime &rt,
719
833
  if (name == "executeBatchAsync") {
720
834
  return jsi::Value(rt, function_map["executeBatchAsync"]);
721
835
  }
836
+ if (name == "prepareStatement") {
837
+ return jsi::Value(rt, function_map["prepareStatement"]);
838
+ }
839
+ if (name == "getDbPath") {
840
+ return jsi::Value(rt, function_map["getDbPath"]);
841
+ }
842
+ #ifdef OP_SQLITE_USE_LIBSQL
843
+ if (name == "loadFile") {
844
+ return HOSTFN("loadFile", 0) {
845
+ throw std::runtime_error("[op-sqlite] Load file not implemented");
846
+ });
847
+ }
848
+ if (name == "updateHook") {
849
+ return HOSTFN("updateHook", 0) {
850
+ throw std::runtime_error("[op-sqlite] Hooks not supported in libsql");
851
+ });
852
+ }
853
+ if (name == "commitHook") {
854
+ return HOSTFN("commitHook", 0) {
855
+ throw std::runtime_error("[op-sqlite] Hooks not supported in libsql");
856
+ });
857
+ }
858
+ if (name == "rollbackHook") {
859
+ return HOSTFN("rollbackHook", 0) {
860
+ throw std::runtime_error("[op-sqlite] Hooks not supported in libsql");
861
+ });
862
+ }
863
+ if (name == "loadExtension") {
864
+ return HOSTFN("loadExtension", 0) {
865
+ throw std::runtime_error("[op-sqlite] Hooks not supported in libsql");
866
+ });
867
+ }
868
+ if (name == "reactiveExecute") {
869
+ return HOSTFN("reactiveExecute", 0) {
870
+ throw std::runtime_error("[op-sqlite] Hooks not supported in libsql");
871
+ });
872
+ }
873
+ #else
722
874
  if (name == "loadFile") {
723
875
  return jsi::Value(rt, function_map["loadFile"]);
724
876
  }
@@ -731,25 +883,20 @@ jsi::Value DBHostObject::get(jsi::Runtime &rt,
731
883
  if (name == "rollbackHook") {
732
884
  return jsi::Value(rt, function_map["rollbackHook"]);
733
885
  }
734
- if (name == "prepareStatement") {
735
- return jsi::Value(rt, function_map["prepareStatement"]);
736
- }
737
886
  if (name == "loadExtension") {
738
887
  return jsi::Value(rt, function_map["loadExtension"]);
739
888
  }
740
- if (name == "getDbPath") {
741
- return jsi::Value(rt, function_map["getDbPath"]);
742
- }
743
889
  if (name == "reactiveExecute") {
744
890
  return jsi::Value(rt, function_map["reactiveExecute"]);
745
891
  }
892
+ #endif
746
893
 
747
894
  return {};
748
895
  }
749
896
 
750
- // void DBHostObject::set(jsi::Runtime &rt, const jsi::PropNameID &name,
751
- // const jsi::Value &value) {
752
- // throw std::runtime_error("You cannot write to this object!");
753
- // }
897
+ void DBHostObject::set(jsi::Runtime &rt, const jsi::PropNameID &name,
898
+ const jsi::Value &value) {
899
+ throw std::runtime_error("You cannot write to this object!");
900
+ }
754
901
 
755
902
  } // namespace opsqlite
@@ -1,7 +1,7 @@
1
- #ifndef DBHostObject_h
2
- #define DBHostObject_h
1
+ #pragma once
3
2
 
4
3
  #include "ThreadPool.h"
4
+ #include "sqlite3.h"
5
5
  #include "types.h"
6
6
  #include <ReactCommon/CallInvoker.h>
7
7
  #include <any>
@@ -14,11 +14,14 @@ namespace opsqlite {
14
14
  namespace jsi = facebook::jsi;
15
15
  namespace react = facebook::react;
16
16
 
17
+ struct TableRowDiscriminator {
18
+ std::string table;
19
+ std::vector<int> ids;
20
+ };
21
+
17
22
  struct ReactiveQuery {
18
- std::string query;
19
- std::vector<JSVariant> args;
20
- std::vector<std::string> tables;
21
- std::vector<int> rowIds;
23
+ sqlite3_stmt *stmt;
24
+ std::vector<TableRowDiscriminator> discriminators;
22
25
  std::shared_ptr<jsi::Value> callback;
23
26
  };
24
27
 
@@ -30,15 +33,23 @@ public:
30
33
  std::string &path, std::string &crsqlite_path,
31
34
  std::string &encryption_key);
32
35
 
33
- std::vector<jsi::PropNameID> getPropertyNames(jsi::Runtime &rt);
36
+ #ifdef OP_SQLITE_USE_LIBSQL
37
+ DBHostObject(jsi::Runtime &rt, std::string &url, std::string &auth_token,
38
+ std::shared_ptr<react::CallInvoker> js_call_invoker,
39
+ std::shared_ptr<ThreadPool> thread_pool);
40
+ #endif
34
41
 
42
+ std::vector<jsi::PropNameID> getPropertyNames(jsi::Runtime &rt);
35
43
  jsi::Value get(jsi::Runtime &rt, const jsi::PropNameID &propNameID);
44
+ void set(jsi::Runtime &rt, const jsi::PropNameID &name,
45
+ const jsi::Value &value);
36
46
 
47
+ private:
37
48
  void auto_register_update_hook();
49
+ void create_jsi_functions();
38
50
 
39
51
  std::unordered_map<std::string, jsi::Value> function_map;
40
52
  std::string base_path;
41
-
42
53
  std::shared_ptr<jsi::Value> update_hook;
43
54
  std::shared_ptr<react::CallInvoker> jsCallInvoker;
44
55
  std::shared_ptr<ThreadPool> thread_pool;
@@ -52,5 +63,3 @@ public:
52
63
  };
53
64
 
54
65
  } // namespace opsqlite
55
-
56
- #endif /* DBHostObject_h */