@op-engineering/op-sqlite 15.0.7 → 15.1.1

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 (45) hide show
  1. package/android/CMakeLists.txt +1 -1
  2. package/android/build.gradle +1 -1
  3. package/android/cpp-adapter.cpp +1 -1
  4. package/android/src/main/java/com/op/sqlite/OPSQLiteModule.kt +7 -9
  5. package/cpp/DBHostObject.cpp +469 -677
  6. package/cpp/DBHostObject.h +56 -58
  7. package/cpp/DumbHostObject.cpp +1 -1
  8. package/cpp/DumbHostObject.h +12 -13
  9. package/cpp/OPSqlite.cpp +207 -0
  10. package/cpp/OPThreadPool.cpp +79 -79
  11. package/cpp/OPThreadPool.h +28 -28
  12. package/cpp/PreparedStatementHostObject.cpp +87 -136
  13. package/cpp/PreparedStatementHostObject.h +16 -28
  14. package/cpp/SmartHostObject.cpp +1 -1
  15. package/cpp/SmartHostObject.h +6 -7
  16. package/cpp/bridge.cpp +639 -633
  17. package/cpp/bridge.h +2 -2
  18. package/cpp/libsql/LICENSE.txt +9 -0
  19. package/cpp/libsql/bridge.cpp +2 -2
  20. package/cpp/libsql/{bridge.h → bridge.hpp} +4 -4
  21. package/cpp/macros.hpp +21 -0
  22. package/cpp/sqlcipher/LICENSE.txt +24 -0
  23. package/cpp/types.hpp +42 -0
  24. package/cpp/utils.cpp +320 -255
  25. package/cpp/{utils.h → utils.hpp} +9 -1
  26. package/ios/OPSQLite.mm +104 -106
  27. package/lib/module/functions.js +52 -44
  28. package/lib/module/functions.js.map +1 -1
  29. package/lib/module/index.js +1 -1
  30. package/lib/module/index.js.map +1 -1
  31. package/lib/typescript/src/functions.d.ts +5 -1
  32. package/lib/typescript/src/functions.d.ts.map +1 -1
  33. package/lib/typescript/src/index.d.ts +1 -1
  34. package/lib/typescript/src/index.d.ts.map +1 -1
  35. package/lib/typescript/src/types.d.ts +12 -1
  36. package/lib/typescript/src/types.d.ts.map +1 -1
  37. package/op-sqlite.podspec +1 -1
  38. package/package.json +10 -8
  39. package/src/functions.ts +64 -54
  40. package/src/index.ts +1 -12
  41. package/src/types.ts +9 -1
  42. package/cpp/bindings.cpp +0 -202
  43. package/cpp/macros.h +0 -15
  44. package/cpp/types.h +0 -33
  45. /package/cpp/{bindings.h → OPSqlite.hpp} +0 -0
@@ -1,13 +1,13 @@
1
1
  #include "DBHostObject.h"
2
2
  #include "PreparedStatementHostObject.h"
3
3
  #if OP_SQLITE_USE_LIBSQL
4
- #include "libsql/bridge.h"
4
+ #include "libsql/bridge.hpp"
5
5
  #else
6
6
  #include "bridge.h"
7
7
  #endif
8
8
  #include "logs.h"
9
- #include "macros.h"
10
- #include "utils.h"
9
+ #include "macros.hpp"
10
+ #include "utils.hpp"
11
11
  #include <iostream>
12
12
  #include <utility>
13
13
 
@@ -19,125 +19,117 @@ namespace react = facebook::react;
19
19
  #ifdef OP_SQLITE_USE_LIBSQL
20
20
  void DBHostObject::flush_pending_reactive_queries(
21
21
  const std::shared_ptr<jsi::Value> &resolve) {
22
- invoker->invokeAsync([this, resolve]() {
23
- resolve->asObject(rt).asFunction(rt).call(rt, {});
24
- });
22
+ invoker->invokeAsync(
23
+ [this, resolve]() { resolve->asObject(rt).asFunction(rt).call(rt, {}); });
25
24
  }
26
25
  #else
27
26
  void DBHostObject::flush_pending_reactive_queries(
28
27
  const std::shared_ptr<jsi::Value> &resolve) {
29
- for (const auto &query_ptr : pending_reactive_queries) {
30
- auto query = query_ptr.get();
31
-
32
- std::vector<DumbHostObject> results;
33
- std::shared_ptr<std::vector<SmartHostObject>> metadata =
34
- std::make_shared<std::vector<SmartHostObject>>();
35
-
36
- auto status = opsqlite_execute_prepared_statement(db, query->stmt,
37
- &results, metadata);
38
-
39
- invoker->invokeAsync(
40
- [this,
41
- results = std::make_shared<std::vector<DumbHostObject>>(results),
42
- callback = query->callback, metadata, status = std::move(status)] {
43
- auto jsiResult =
44
- create_result(rt, status, results.get(), metadata);
45
- callback->asObject(rt).asFunction(rt).call(rt, jsiResult);
46
- });
47
- }
28
+ for (const auto &query_ptr : pending_reactive_queries) {
29
+ auto query = query_ptr.get();
48
30
 
49
- pending_reactive_queries.clear();
31
+ std::vector<DumbHostObject> results;
32
+ std::shared_ptr<std::vector<SmartHostObject>> metadata =
33
+ std::make_shared<std::vector<SmartHostObject>>();
50
34
 
51
- invoker->invokeAsync([this, resolve]() {
52
- resolve->asObject(rt).asFunction(rt).call(rt, {});
53
- });
35
+ auto status = opsqlite_execute_prepared_statement(db, query->stmt, &results,
36
+ metadata);
37
+
38
+ invoker->invokeAsync(
39
+ [this, results = std::make_shared<std::vector<DumbHostObject>>(results),
40
+ callback = query->callback, metadata, status = std::move(status)] {
41
+ auto jsiResult = create_result(rt, status, results.get(), metadata);
42
+ callback->asObject(rt).asFunction(rt).call(rt, jsiResult);
43
+ });
44
+ }
45
+
46
+ pending_reactive_queries.clear();
47
+
48
+ invoker->invokeAsync(
49
+ [this, resolve]() { resolve->asObject(rt).asFunction(rt).call(rt, {}); });
54
50
  }
55
51
 
56
52
  void DBHostObject::on_commit() {
57
- invoker->invokeAsync(
58
- [this] { commit_hook_callback->asObject(rt).asFunction(rt).call(rt); });
53
+ invoker->invokeAsync(
54
+ [this] { commit_hook_callback->asObject(rt).asFunction(rt).call(rt); });
59
55
  }
60
56
 
61
57
  void DBHostObject::on_rollback() {
62
- invoker->invokeAsync([this] {
63
- rollback_hook_callback->asObject(rt).asFunction(rt).call(rt);
64
- });
58
+ invoker->invokeAsync(
59
+ [this] { rollback_hook_callback->asObject(rt).asFunction(rt).call(rt); });
65
60
  }
66
61
 
67
62
  void DBHostObject::on_update(const std::string &table,
68
63
  const std::string &operation, long long row_id) {
69
- if (update_hook_callback != nullptr) {
70
- invoker->invokeAsync(
71
- [this, callback = update_hook_callback, table, operation, row_id] {
72
- auto res = jsi::Object(rt);
73
- res.setProperty(rt, "table",
74
- jsi::String::createFromUtf8(rt, table));
75
- res.setProperty(rt, "operation",
76
- jsi::String::createFromUtf8(rt, operation));
77
- res.setProperty(rt, "rowId",
78
- jsi::Value(static_cast<double>(row_id)));
79
-
80
- callback->asObject(rt).asFunction(rt).call(rt, res);
81
- });
82
- }
64
+ if (update_hook_callback != nullptr) {
65
+ invoker->invokeAsync(
66
+ [this, callback = update_hook_callback, table, operation, row_id] {
67
+ auto res = jsi::Object(rt);
68
+ res.setProperty(rt, "table", jsi::String::createFromUtf8(rt, table));
69
+ res.setProperty(rt, "operation",
70
+ jsi::String::createFromUtf8(rt, operation));
71
+ res.setProperty(rt, "rowId", jsi::Value(static_cast<double>(row_id)));
72
+
73
+ callback->asObject(rt).asFunction(rt).call(rt, res);
74
+ });
75
+ }
83
76
 
84
- for (const auto &query_ptr : reactive_queries) {
85
- auto query = query_ptr.get();
77
+ for (const auto &query_ptr : reactive_queries) {
78
+ auto query = query_ptr.get();
86
79
 
87
- // The JS environment might have cleared the query while the update was queued
88
- // For now this seems to prevent a EXC_BAD_ACCESS
89
- if (query == nullptr) {
90
- continue;
91
- }
80
+ // The JS environment might have cleared the query while the update was
81
+ // queued For now this seems to prevent a EXC_BAD_ACCESS
82
+ if (query == nullptr) {
83
+ continue;
84
+ }
92
85
 
93
-
94
- if (query->discriminators.empty()) {
95
- continue;
96
- }
86
+ if (query->discriminators.empty()) {
87
+ continue;
88
+ }
97
89
 
98
- bool shouldFire = false;
99
-
100
- for (const auto &discriminator : query->discriminators) {
101
- // Tables don't match then skip
102
- if (discriminator.table != table) {
103
- continue;
104
- }
105
-
106
- // If no ids are specified, then we should fire
107
- if (discriminator.ids.empty()) {
108
- shouldFire = true;
109
- break;
110
- }
111
-
112
- // If ids are specified, then we should check if the rowId matches
113
- for (const auto &discrimator_id : discriminator.ids) {
114
- if (row_id == discrimator_id) {
115
- shouldFire = true;
116
- break;
117
- }
118
- }
90
+ bool shouldFire = false;
91
+
92
+ for (const auto &discriminator : query->discriminators) {
93
+ // Tables don't match then skip
94
+ if (discriminator.table != table) {
95
+ continue;
96
+ }
97
+
98
+ // If no ids are specified, then we should fire
99
+ if (discriminator.ids.empty()) {
100
+ shouldFire = true;
101
+ break;
102
+ }
103
+
104
+ // If ids are specified, then we should check if the rowId matches
105
+ for (const auto &discrimator_id : discriminator.ids) {
106
+ if (row_id == discrimator_id) {
107
+ shouldFire = true;
108
+ break;
119
109
  }
110
+ }
111
+ }
120
112
 
121
- if (shouldFire) {
122
- pending_reactive_queries.insert(query_ptr);
123
- }
113
+ if (shouldFire) {
114
+ pending_reactive_queries.insert(query_ptr);
124
115
  }
116
+ }
125
117
  }
126
118
 
127
119
  void DBHostObject::auto_register_update_hook() {
128
- if (update_hook_callback == nullptr && reactive_queries.empty() &&
129
- is_update_hook_registered) {
130
- opsqlite_deregister_update_hook(db);
131
- is_update_hook_registered = false;
132
- return;
133
- }
134
-
135
- if (is_update_hook_registered) {
136
- return;
137
- }
138
-
139
- opsqlite_register_update_hook(db, this);
140
- is_update_hook_registered = true;
120
+ if (update_hook_callback == nullptr && reactive_queries.empty() &&
121
+ is_update_hook_registered) {
122
+ opsqlite_deregister_update_hook(db);
123
+ is_update_hook_registered = false;
124
+ return;
125
+ }
126
+
127
+ if (is_update_hook_registered) {
128
+ return;
129
+ }
130
+
131
+ opsqlite_register_update_hook(db, this);
132
+ is_update_hook_registered = true;
141
133
  }
142
134
  #endif
143
135
 
@@ -153,10 +145,10 @@ DBHostObject::DBHostObject(jsi::Runtime &rt, std::string &url,
153
145
  std::string &auth_token,
154
146
  std::shared_ptr<react::CallInvoker> invoker)
155
147
  : db_name(url), invoker(std::move(invoker)), rt(rt) {
156
- _thread_pool = std::make_shared<ThreadPool>();
157
- db = opsqlite_libsql_open_remote(url, auth_token);
148
+ _thread_pool = std::make_shared<ThreadPool>();
149
+ db = opsqlite_libsql_open_remote(url, auth_token);
158
150
 
159
- create_jsi_functions();
151
+ create_jsi_functions();
160
152
  }
161
153
 
162
154
  // Sync connection constructor
@@ -169,13 +161,13 @@ DBHostObject::DBHostObject(jsi::Runtime &rt,
169
161
  std::string &remote_encryption_key)
170
162
  : db_name(db_name), invoker(std::move(invoker)), rt(rt) {
171
163
 
172
- _thread_pool = std::make_shared<ThreadPool>();
164
+ _thread_pool = std::make_shared<ThreadPool>();
173
165
 
174
- db = opsqlite_libsql_open_sync(db_name, path, url, auth_token,
175
- sync_interval, offline, encryption_key,
176
- remote_encryption_key);
166
+ db =
167
+ opsqlite_libsql_open_sync(db_name, path, url, auth_token, sync_interval,
168
+ offline, encryption_key, remote_encryption_key);
177
169
 
178
- create_jsi_functions();
170
+ create_jsi_functions();
179
171
  }
180
172
 
181
173
  #endif
@@ -188,704 +180,504 @@ DBHostObject::DBHostObject(jsi::Runtime &rt, std::string &base_path,
188
180
  std::string &encryption_key)
189
181
  : base_path(base_path), invoker(std::move(invoker)), db_name(db_name),
190
182
  rt(rt) {
191
- _thread_pool = std::make_shared<ThreadPool>();
183
+ _thread_pool = std::make_shared<ThreadPool>();
192
184
 
193
185
  #ifdef OP_SQLITE_USE_SQLCIPHER
194
- db = opsqlite_open(db_name, path, crsqlite_path, sqlite_vec_path,
195
- encryption_key);
186
+ db = opsqlite_open(db_name, path, crsqlite_path, sqlite_vec_path,
187
+ encryption_key);
196
188
  #elif OP_SQLITE_USE_LIBSQL
197
- db = opsqlite_libsql_open(db_name, path, crsqlite_path);
189
+ db = opsqlite_libsql_open(db_name, path, crsqlite_path);
198
190
  #else
199
- db = opsqlite_open(db_name, path, crsqlite_path, sqlite_vec_path);
191
+ db = opsqlite_open(db_name, path, crsqlite_path, sqlite_vec_path);
200
192
  #endif
201
- create_jsi_functions();
193
+ create_jsi_functions();
202
194
  };
203
195
 
204
196
  void DBHostObject::create_jsi_functions() {
205
- function_map["attach"] = HOSTFN("attach") {
206
- std::string secondary_db_path = std::string(base_path);
207
-
208
- auto obj_params = args[0].asObject(rt);
209
-
210
- std::string secondary_db_name =
211
- obj_params.getProperty(rt, "secondaryDbFileName")
212
- .asString(rt)
213
- .utf8(rt);
214
- std::string alias =
215
- obj_params.getProperty(rt, "alias").asString(rt).utf8(rt);
216
-
217
- if (obj_params.hasProperty(rt, "location")) {
218
- std::string location =
219
- obj_params.getProperty(rt, "location").asString(rt).utf8(rt);
220
- secondary_db_path = secondary_db_path + location;
221
- }
197
+ function_map["attach"] = HFN(this) {
198
+ std::string secondary_db_path = std::string(base_path);
199
+
200
+ auto obj_params = args[0].asObject(rt);
201
+
202
+ std::string secondary_db_name =
203
+ obj_params.getProperty(rt, "secondaryDbFileName").asString(rt).utf8(rt);
204
+ std::string alias =
205
+ obj_params.getProperty(rt, "alias").asString(rt).utf8(rt);
206
+
207
+ if (obj_params.hasProperty(rt, "location")) {
208
+ std::string location =
209
+ obj_params.getProperty(rt, "location").asString(rt).utf8(rt);
210
+ secondary_db_path = secondary_db_path + location;
211
+ }
222
212
 
223
213
  #ifdef OP_SQLITE_USE_LIBSQL
224
- opsqlite_libsql_attach(db, secondary_db_path, secondary_db_name, alias);
214
+ opsqlite_libsql_attach(db, secondary_db_path, secondary_db_name, alias);
225
215
  #else
226
- opsqlite_attach(db, secondary_db_path, secondary_db_name, alias);
216
+ opsqlite_attach(db, secondary_db_path, secondary_db_name, alias);
227
217
  #endif
228
218
 
229
- return {};
230
- });
231
-
232
- function_map["detach"] = HOSTFN("detach") {
219
+ return {};
220
+ });
233
221
 
234
- if (!args[0].isString()) {
235
- throw std::runtime_error("[op-sqlite] alias must be a strings");
236
- }
222
+ function_map["detach"] = HFN(this) {
223
+ if (!args[0].isString()) {
224
+ throw std::runtime_error("[op-sqlite] alias must be a strings");
225
+ }
237
226
 
238
- std::string alias = args[0].asString(rt).utf8(rt);
227
+ std::string alias = args[0].asString(rt).utf8(rt);
239
228
  #ifdef OP_SQLITE_USE_LIBSQL
240
- opsqlite_libsql_detach(db, alias);
229
+ opsqlite_libsql_detach(db, alias);
241
230
  #else
242
- opsqlite_detach(db, alias);
231
+ opsqlite_detach(db, alias);
243
232
  #endif
244
233
 
245
- return {};
246
- });
234
+ return {};
235
+ });
247
236
 
248
- function_map["close"] = HOSTFN("close") {
249
- invalidated = true;
237
+ function_map["close"] = HFN(this) {
238
+ invalidated = true;
250
239
 
251
240
  #ifdef OP_SQLITE_USE_LIBSQL
252
- opsqlite_libsql_close(db);
241
+ opsqlite_libsql_close(db);
253
242
  #else
254
- opsqlite_close(db);
243
+ opsqlite_close(db);
255
244
  #endif
256
245
 
257
- return {};
258
- });
246
+ return {};
247
+ });
259
248
 
260
- function_map["delete"] = HOSTFN("delete") {
261
- invalidated = true;
249
+ function_map["delete"] = HFN(this) {
250
+ invalidated = true;
262
251
 
263
- std::string path = std::string(base_path);
252
+ std::string path = std::string(base_path);
264
253
 
265
- if (count == 1) {
266
- if (!args[1].isString()) {
267
- throw std::runtime_error(
268
- "[op-sqlite][open] database location must be a string");
269
- }
254
+ if (count == 1) {
255
+ if (!args[1].isString()) {
256
+ throw std::runtime_error(
257
+ "[op-sqlite][open] database location must be a string");
258
+ }
270
259
 
271
- std::string location = args[1].asString(rt).utf8(rt);
260
+ std::string location = args[1].asString(rt).utf8(rt);
272
261
 
273
- if (!location.empty()) {
274
- if (location == ":memory:") {
275
- path = ":memory:";
276
- } else if (location.rfind('/', 0) == 0) {
277
- path = location;
278
- } else {
279
- path = path + "/" + location;
280
- }
281
- }
262
+ if (!location.empty()) {
263
+ if (location == ":memory:") {
264
+ path = ":memory:";
265
+ } else if (location.rfind('/', 0) == 0) {
266
+ path = location;
267
+ } else {
268
+ path = path + "/" + location;
282
269
  }
270
+ }
271
+ }
283
272
 
284
273
  #ifdef OP_SQLITE_USE_LIBSQL
285
- opsqlite_libsql_remove(db, db_name, path);
274
+ opsqlite_libsql_remove(db, db_name, path);
286
275
  #else
287
- opsqlite_remove(db, db_name, path);
276
+ opsqlite_remove(db, db_name, path);
288
277
  #endif
289
278
 
290
- return {};
291
- });
292
-
293
- function_map["executeRaw"] = HOSTFN("executeRaw") {
294
- const std::string query = args[0].asString(rt).utf8(rt);
295
- std::vector<JSVariant> params = count == 2 && args[1].isObject()
296
- ? to_variant_vec(rt, args[1])
297
- : std::vector<JSVariant>();
279
+ return {};
280
+ });
298
281
 
299
- auto promiseCtr = rt.global().getPropertyAsFunction(rt, "Promise");
300
- auto promise = promiseCtr.callAsConstructor(rt, HOSTFN("executor") {
301
- auto resolve = std::make_shared<jsi::Value>(rt, args[0]);
302
- auto reject = std::make_shared<jsi::Value>(rt, args[1]);
303
-
304
- auto task = [this, &rt, query, params, resolve, reject]() {
305
- try {
306
- std::vector<std::vector<JSVariant>> results;
282
+ function_map["executeRaw"] = HFN(this) {
283
+ const std::string query = args[0].asString(rt).utf8(rt);
284
+ const std::vector<JSVariant> params = count == 2 && args[1].isObject()
285
+ ? to_variant_vec(rt, args[1])
286
+ : std::vector<JSVariant>();
307
287
 
288
+ return promisify(
289
+ rt,
290
+ [this, query, params]() {
291
+ std::vector<std::vector<JSVariant>> results;
308
292
  #ifdef OP_SQLITE_USE_LIBSQL
309
- auto status = opsqlite_libsql_execute_raw(
310
- db, query, &params, &results);
293
+ auto status =
294
+ opsqlite_libsql_execute_raw(db, query, &params, &results);
311
295
  #else
312
- auto status =
313
- opsqlite_execute_raw(db, query, &params, &results);
296
+ auto status = opsqlite_execute_raw(db, query, &params, &results);
314
297
  #endif
298
+ return std::make_tuple(status, results);
299
+ },
300
+ [](jsi::Runtime &rt, std::any prev) {
301
+ auto tuple = std::any_cast<
302
+ std::tuple<BridgeResult, std::vector<std::vector<JSVariant>>>>(
303
+ prev);
304
+
305
+ return create_raw_result(rt, std::get<0>(tuple), &std::get<1>(tuple));
306
+ });
307
+ });
315
308
 
316
- if (invalidated) {
317
- return;
318
- }
319
-
320
- invoker->invokeAsync([&rt, results = std::move(results),
321
- status = std::move(status), resolve,
322
- reject] {
323
- auto jsiResult =
324
- create_raw_result(rt, status, &results);
325
- resolve->asObject(rt).asFunction(rt).call(
326
- rt, std::move(jsiResult));
327
- });
328
- } catch (std::runtime_error &e) {
329
- auto what = e.what();
330
- invoker->invokeAsync([&rt, what, reject] {
331
- auto errorCtr =
332
- rt.global().getPropertyAsFunction(rt, "Error");
333
- auto error = errorCtr.callAsConstructor(
334
- rt, jsi::String::createFromAscii(rt, what));
335
- reject->asObject(rt).asFunction(rt).call(rt, error);
336
- });
337
- } catch (std::exception &exc) {
338
- auto what = exc.what();
339
- invoker->invokeAsync([&rt, what, reject] {
340
- auto errorCtr =
341
- rt.global().getPropertyAsFunction(rt, "Error");
342
- auto error = errorCtr.callAsConstructor(
343
- rt, jsi::String::createFromAscii(rt, what));
344
- reject->asObject(rt).asFunction(rt).call(rt, error);
345
- });
346
- }
347
- };
348
-
349
- _thread_pool->queueWork(task);
350
-
351
- return {};
352
- }));
353
-
354
- return promise;
355
- });
356
-
357
- function_map["executeSync"] = HOSTFN("executeSync") {
358
- std::string query = args[0].asString(rt).utf8(rt);
359
- std::vector<JSVariant> params;
309
+ function_map["executeSync"] = HFN(this) {
310
+ std::string query = args[0].asString(rt).utf8(rt);
311
+ std::vector<JSVariant> params;
360
312
 
361
- if (count == 2) {
362
- params = to_variant_vec(rt, args[1]);
363
- }
313
+ if (count == 2) {
314
+ params = to_variant_vec(rt, args[1]);
315
+ }
364
316
  #ifdef OP_SQLITE_USE_LIBSQL
365
- auto status = opsqlite_libsql_execute(db, query, &params);
317
+ auto status = opsqlite_libsql_execute(db, query, &params);
366
318
  #else
367
- auto status = opsqlite_execute(db, query, &params);
319
+ auto status = opsqlite_execute(db, query, &params);
368
320
  #endif
369
321
 
370
- return create_js_rows(rt, status);
371
- });
322
+ return create_js_rows(rt, status);
323
+ });
372
324
 
373
- function_map["executeRawSync"] = HOSTFN("executeRawSync") {
374
- const std::string query = args[0].asString(rt).utf8(rt);
375
- std::vector<JSVariant> params = count == 2 && args[1].isObject()
376
- ? to_variant_vec(rt, args[1])
377
- : std::vector<JSVariant>();
325
+ function_map["executeRawSync"] = HFN(this) {
326
+ const std::string query = args[0].asString(rt).utf8(rt);
327
+ std::vector<JSVariant> params = count == 2 && args[1].isObject()
328
+ ? to_variant_vec(rt, args[1])
329
+ : std::vector<JSVariant>();
378
330
 
379
- std::vector<std::vector<JSVariant>> results;
331
+ std::vector<std::vector<JSVariant>> results;
380
332
 
381
333
  #ifdef OP_SQLITE_USE_LIBSQL
382
- auto status = opsqlite_libsql_execute_raw(db, query, &params, &results);
334
+ auto status = opsqlite_libsql_execute_raw(db, query, &params, &results);
383
335
  #else
384
- auto status = opsqlite_execute_raw(db, query, &params, &results);
336
+ auto status = opsqlite_execute_raw(db, query, &params, &results);
385
337
  #endif
386
338
 
387
- return create_raw_result(rt, status, &results);
388
- });
339
+ return create_raw_result(rt, status, &results);
340
+ });
389
341
 
390
- function_map["execute"] = HOSTFN("execute") {
391
- const std::string query = args[0].asString(rt).utf8(rt);
392
- std::vector<JSVariant> params = count == 2 && args[1].isObject()
393
- ? to_variant_vec(rt, args[1])
394
- : std::vector<JSVariant>();
395
-
396
- auto promiseCtr = rt.global().getPropertyAsFunction(rt, "Promise");
397
- auto promise = promiseCtr.callAsConstructor(rt,
398
- HOSTFN("executor") {
399
- auto task = [this, &rt, query, params,
400
- resolve = std::make_shared<jsi::Value>(rt, args[0]),
401
- reject = std::make_shared<jsi::Value>(rt, args[1])]() {
402
- try {
342
+ function_map["execute"] = HFN(this) {
343
+ const std::string query = args[0].asString(rt).utf8(rt);
344
+ std::vector<JSVariant> params = count == 2 && args[1].isObject()
345
+ ? to_variant_vec(rt, args[1])
346
+ : std::vector<JSVariant>();
347
+
348
+ return promisify(
349
+ rt,
350
+ [this, query, params]() {
403
351
  #ifdef OP_SQLITE_USE_LIBSQL
404
- auto status = opsqlite_libsql_execute(db, query, &params);
352
+ auto status = opsqlite_libsql_execute(db, query, &params);
405
353
  #else
406
- auto status = opsqlite_execute(db, query, &params);
354
+ auto status = opsqlite_execute(db, query, &params);
407
355
  #endif
408
-
409
- if (invalidated) {
410
- return;
411
- }
412
-
413
- invoker->invokeAsync(
414
- [&rt, status = std::move(status), resolve, reject] {
415
- auto jsiResult = create_js_rows(rt, status);
416
- resolve->asObject(rt).asFunction(rt).call(
417
- rt, std::move(jsiResult));
418
- });
419
- // On Android RN is broken and does not correctly match
420
- // runtime_error to the generic exception We have to
421
- // explicitly catch it
422
- // https://github.com/facebook/react-native/issues/48027
423
- } catch (std::runtime_error &e) {
424
- auto what = e.what();
425
- invoker->invokeAsync(
426
- [&rt, what = std::string(what), reject] {
427
- auto errorCtr =
428
- rt.global().getPropertyAsFunction(rt, "Error");
429
- auto error = errorCtr.callAsConstructor(
430
- rt, jsi::String::createFromAscii(rt, what));
431
- reject->asObject(rt).asFunction(rt).call(rt, error);
432
- });
433
- } catch (std::exception &exc) {
434
- auto what = exc.what();
435
- invoker->invokeAsync(
436
- [&rt, what = std::string(what), reject] {
437
- auto errorCtr =
438
- rt.global().getPropertyAsFunction(rt, "Error");
439
- auto error = errorCtr.callAsConstructor(
440
- rt, jsi::String::createFromAscii(rt, what));
441
- reject->asObject(rt).asFunction(rt).call(rt, error);
442
- });
443
- }
444
- };
445
-
446
- _thread_pool->queueWork(task);
447
-
448
- return {};
449
- }));
450
-
451
- return promise;
452
- });
453
-
454
- function_map["executeWithHostObjects"] = HOSTFN("executeWithHostObjects") {
455
- const std::string query = args[0].asString(rt).utf8(rt);
456
- std::vector<JSVariant> params;
457
-
458
- if (count == 2) {
459
- const jsi::Value &originalParams = args[1];
460
- params = to_variant_vec(rt, originalParams);
461
- }
462
-
463
- auto promiseCtr = rt.global().getPropertyAsFunction(rt, "Promise");
464
- auto promise = promiseCtr.callAsConstructor(rt, HOSTFN("executor") {
465
- auto resolve = std::make_shared<jsi::Value>(rt, args[0]);
466
- auto reject = std::make_shared<jsi::Value>(rt, args[1]);
467
-
468
- auto task = [&rt, this, query, params, resolve, reject]() {
469
- try {
470
- std::vector<DumbHostObject> results;
471
- std::shared_ptr<std::vector<SmartHostObject>> metadata =
472
- std::make_shared<std::vector<SmartHostObject>>();
356
+ return status;
357
+ },
358
+ [](jsi::Runtime &rt, std::any prev) {
359
+ auto status = std::any_cast<BridgeResult>(prev);
360
+ return create_js_rows(rt, status);
361
+ });
362
+ });
363
+
364
+ function_map["executeWithHostObjects"] = HFN(this) {
365
+ const std::string query = args[0].asString(rt).utf8(rt);
366
+ std::vector<JSVariant> params = count == 2 && args[1].isObject()
367
+ ? to_variant_vec(rt, args[1])
368
+ : std::vector<JSVariant>();
369
+
370
+ return promisify(
371
+ rt,
372
+ [this, query, params]() {
373
+ std::vector<DumbHostObject> results;
374
+ std::shared_ptr<std::vector<SmartHostObject>> metadata =
375
+ std::make_shared<std::vector<SmartHostObject>>();
473
376
  #ifdef OP_SQLITE_USE_LIBSQL
474
- auto status = opsqlite_libsql_execute_with_host_objects(
475
- db, query, &params, &results, metadata);
377
+ auto status = opsqlite_libsql_execute_with_host_objects(
378
+ db, query, &params, &results, metadata);
476
379
  #else
477
- auto status = opsqlite_execute_host_objects(
478
- db, query, &params, &results, metadata);
380
+ auto status = opsqlite_execute_host_objects(db, query, &params,
381
+ &results, metadata);
479
382
  #endif
383
+ return std::make_tuple(status, results, metadata);
384
+ },
385
+ [](jsi::Runtime &rt, std::any prev) {
386
+ auto tuple = std::any_cast<
387
+ std::tuple<BridgeResult, std::vector<DumbHostObject>,
388
+ std::shared_ptr<std::vector<SmartHostObject>>>>(prev);
389
+ auto results =
390
+ std::make_shared<std::vector<DumbHostObject>>(std::get<1>(tuple));
391
+ return create_result(rt, std::get<0>(tuple), results.get(),
392
+ std::get<2>(tuple));
393
+ });
394
+ });
480
395
 
481
- if (invalidated) {
482
- return;
483
- }
484
-
485
- invoker->invokeAsync(
486
- [&rt,
487
- results =
488
- std::make_shared<std::vector<DumbHostObject>>(
489
- results),
490
- metadata, status = std::move(status), resolve,
491
- reject] {
492
- auto jsiResult = create_result(
493
- rt, status, results.get(), metadata);
494
- resolve->asObject(rt).asFunction(rt).call(
495
- rt, std::move(jsiResult));
496
- });
497
- } catch (std::runtime_error &e) {
498
- auto what = e.what();
499
- invoker->invokeAsync(
500
- [&rt, what = std::string(what), reject] {
501
- auto errorCtr =
502
- rt.global().getPropertyAsFunction(rt, "Error");
503
- auto error = errorCtr.callAsConstructor(
504
- rt, jsi::String::createFromAscii(rt, what));
505
- reject->asObject(rt).asFunction(rt).call(rt, error);
506
- });
507
- } catch (std::exception &exc) {
508
- auto what = exc.what();
509
- invoker->invokeAsync([&rt, what, reject] {
510
- auto errorCtr =
511
- rt.global().getPropertyAsFunction(rt, "Error");
512
- auto error = errorCtr.callAsConstructor(
513
- rt, jsi::String::createFromAscii(rt, what));
514
- reject->asObject(rt).asFunction(rt).call(rt, error);
515
- });
516
- }
517
- };
518
-
519
- _thread_pool->queueWork(task);
520
-
521
- return {};
522
- }));
523
-
524
- return promise;
525
- });
526
-
527
- function_map["executeBatch"] = HOSTFN("executeBatch") {
528
- if (count < 1) {
529
- throw std::runtime_error(
530
- "[op-sqlite][executeAsyncBatch] Incorrect parameter count");
531
- }
396
+ function_map["executeBatch"] = HFN(this) {
397
+ if (count < 1) {
398
+ throw std::runtime_error(
399
+ "[op-sqlite][executeAsyncBatch] Incorrect parameter count");
400
+ }
532
401
 
533
- const jsi::Value &params = args[0];
402
+ const jsi::Value &params = args[0];
534
403
 
535
- if (params.isNull() || params.isUndefined()) {
536
- throw std::runtime_error(
537
- "[op-sqlite][executeAsyncBatch] - An array of SQL "
538
- "commands or parameters is needed");
539
- }
540
-
541
- const jsi::Array &batchParams = params.asObject(rt).asArray(rt);
404
+ if (params.isNull() || params.isUndefined()) {
405
+ throw std::runtime_error(
406
+ "[op-sqlite][executeAsyncBatch] - An array of SQL "
407
+ "commands or parameters is needed");
408
+ }
542
409
 
543
- std::vector<BatchArguments> commands;
544
- to_batch_arguments(rt, batchParams, &commands);
410
+ const jsi::Array &batchParams = params.asObject(rt).asArray(rt);
545
411
 
546
- auto promiseCtr = rt.global().getPropertyAsFunction(rt, "Promise");
547
- auto promise = promiseCtr.callAsConstructor(rt, HOSTFN("executor") {
548
- auto resolve = std::make_shared<jsi::Value>(rt, args[0]);
549
- auto reject = std::make_shared<jsi::Value>(rt, args[1]);
412
+ std::vector<BatchArguments> commands;
413
+ to_batch_arguments(rt, batchParams, &commands);
550
414
 
551
- auto task = [this, &rt, commands, resolve, reject]() {
552
- try {
415
+ return promisify(
416
+ rt,
417
+ [this, commands]() {
553
418
  #ifdef OP_SQLITE_USE_LIBSQL
554
- auto batchResult =
555
- opsqlite_libsql_execute_batch(db, &commands);
419
+ auto batchResult = opsqlite_libsql_execute_batch(db, &commands);
556
420
  #else
557
- auto batchResult = opsqlite_execute_batch(db, &commands);
421
+ auto batchResult = opsqlite_execute_batch(db, &commands);
558
422
  #endif
559
-
560
- if (invalidated) {
561
- return;
562
- }
563
-
564
- invoker->invokeAsync([&rt,
565
- batchResult = std::move(batchResult),
566
- resolve] {
567
- auto res = jsi::Object(rt);
568
- res.setProperty(rt, "rowsAffected",
569
- jsi::Value(batchResult.affectedRows));
570
- resolve->asObject(rt).asFunction(rt).call(
571
- rt, std::move(res));
572
- });
573
- } catch (std::runtime_error &e) {
574
- auto what = e.what();
575
- invoker->invokeAsync([&rt, what, reject] {
576
- auto errorCtr =
577
- rt.global().getPropertyAsFunction(rt, "Error");
578
- auto error = errorCtr.callAsConstructor(
579
- rt, jsi::String::createFromAscii(rt, what));
580
- reject->asObject(rt).asFunction(rt).call(rt, error);
581
- });
582
- } catch (std::exception &exc) {
583
- auto what = exc.what();
584
- invoker->invokeAsync([&rt, what, reject] {
585
- auto errorCtr =
586
- rt.global().getPropertyAsFunction(rt, "Error");
587
- auto error = errorCtr.callAsConstructor(
588
- rt, jsi::String::createFromAscii(rt, what));
589
- reject->asObject(rt).asFunction(rt).call(rt, error);
590
- });
591
- }
592
- };
593
- _thread_pool->queueWork(task);
594
-
595
- return {};
596
- }));
597
-
598
- return promise;
599
- });
423
+ return batchResult;
424
+ },
425
+ [](jsi::Runtime &rt, std::any prev) {
426
+ auto batchResult = std::any_cast<BatchResult>(prev);
427
+ auto res = jsi::Object(rt);
428
+ res.setProperty(rt, "rowsAffected",
429
+ jsi::Value(batchResult.affectedRows));
430
+ return res;
431
+ });
432
+ });
600
433
 
601
434
  #ifdef OP_SQLITE_USE_LIBSQL
602
- function_map["sync"] = HOSTFN("sync") {
603
- opsqlite_libsql_sync(db);
604
- return {};
605
- });
606
-
607
- function_map["setReservedBytes"] = HOSTFN("setReservedBytes") {
608
- int32_t reserved_bytes = static_cast<int32_t>(args[0].asNumber());
609
- opsqlite_libsql_set_reserved_bytes(db, reserved_bytes);
610
- return {};
611
- });
612
-
613
- function_map["getReservedBytes"] = HOSTFN("getReservedBytes") {
614
- return jsi::Value(opsqlite_libsql_get_reserved_bytes(db));
615
- });
435
+ function_map["sync"] = HOSTFN("sync") {
436
+ opsqlite_libsql_sync(db);
437
+ return {};
438
+ });
439
+
440
+ function_map["setReservedBytes"] = HOSTFN("setReservedBytes") {
441
+ int32_t reserved_bytes = static_cast<int32_t>(args[0].asNumber());
442
+ opsqlite_libsql_set_reserved_bytes(db, reserved_bytes);
443
+ return {};
444
+ });
445
+
446
+ function_map["getReservedBytes"] = HOSTFN("getReservedBytes") {
447
+ return jsi::Value(opsqlite_libsql_get_reserved_bytes(db));
448
+ });
616
449
  #else
617
- function_map["loadFile"] = HOSTFN("loadFile") {
618
- if (count < 1) {
619
- throw std::runtime_error(
620
- "[op-sqlite][loadFile] Incorrect parameter count");
621
- return {};
622
- }
623
-
624
- const std::string sqlFileName = args[0].asString(rt).utf8(rt);
625
-
626
- auto promiseCtr = rt.global().getPropertyAsFunction(rt, "Promise");
627
- auto promise = promiseCtr.callAsConstructor(rt, HOSTFN("executor") {
628
- auto resolve = std::make_shared<jsi::Value>(rt, args[0]);
629
- auto reject = std::make_shared<jsi::Value>(rt, args[1]);
630
-
631
- auto task = [&rt, this, sqlFileName, resolve, reject]() {
632
- try {
633
- const auto result = import_sql_file(db, sqlFileName);
634
-
635
- invoker->invokeAsync([&rt, result, resolve] {
636
- auto res = jsi::Object(rt);
637
- res.setProperty(rt, "rowsAffected",
638
- jsi::Value(result.affectedRows));
639
- res.setProperty(rt, "commands",
640
- jsi::Value(result.commands));
641
- resolve->asObject(rt).asFunction(rt).call(
642
- rt, std::move(res));
643
- });
644
- } catch (std::runtime_error &e) {
645
- auto what = e.what();
646
- invoker->invokeAsync(
647
- [&rt, what = std::string(what), reject] {
648
- auto errorCtr =
649
- rt.global().getPropertyAsFunction(rt, "Error");
650
- auto error = errorCtr.callAsConstructor(
651
- rt, jsi::String::createFromAscii(rt, what));
652
- reject->asObject(rt).asFunction(rt).call(rt, error);
653
- });
654
- } catch (std::exception &exc) {
655
- auto what = exc.what();
656
- invoker->invokeAsync(
657
- [&rt, what = std::string(what), reject] {
658
- auto errorCtr =
659
- rt.global().getPropertyAsFunction(rt, "Error");
660
- auto error = errorCtr.callAsConstructor(
661
- rt, jsi::String::createFromAscii(rt, what));
662
- reject->asObject(rt).asFunction(rt).call(rt, error);
663
- });
664
- }
665
- };
666
- _thread_pool->queueWork(task);
667
- return {};
668
- }));
450
+ function_map["loadFile"] = HFN(this) {
451
+ if (count < 1) {
452
+ throw std::runtime_error(
453
+ "[op-sqlite][loadFile] Incorrect parameter count");
454
+ }
669
455
 
670
- return promise;
671
- });
456
+ const std::string sqlFileName = args[0].asString(rt).utf8(rt);
672
457
 
673
- function_map["updateHook"] = HOSTFN("updateHook") {
674
- auto callback = std::make_shared<jsi::Value>(rt, args[0]);
458
+ return promisify(
459
+ rt, [this, sqlFileName]() { return import_sql_file(db, sqlFileName); },
460
+ [](jsi::Runtime &rt, std::any prev) {
461
+ auto result = std::any_cast<BatchResult>(prev);
462
+ auto res = jsi::Object(rt);
463
+ res.setProperty(rt, "rowsAffected", jsi::Value(result.affectedRows));
464
+ res.setProperty(rt, "commands", jsi::Value(result.commands));
465
+ return res;
466
+ });
467
+ });
675
468
 
676
- if (callback->isUndefined() || callback->isNull()) {
677
- update_hook_callback = nullptr;
678
- } else {
679
- update_hook_callback = callback;
680
- }
469
+ function_map["updateHook"] = HOSTFN("updateHook") {
470
+ auto callback = std::make_shared<jsi::Value>(rt, args[0]);
681
471
 
682
- auto_register_update_hook();
683
- return {};
684
- });
472
+ if (callback->isUndefined() || callback->isNull()) {
473
+ update_hook_callback = nullptr;
474
+ } else {
475
+ update_hook_callback = callback;
476
+ }
685
477
 
686
- function_map["commitHook"] = HOSTFN("commitHook") {
687
- if (count < 1) {
688
- throw std::runtime_error("[op-sqlite][commitHook] callback needed");
689
- }
478
+ auto_register_update_hook();
479
+ return {};
480
+ });
690
481
 
691
- auto callback = std::make_shared<jsi::Value>(rt, args[0]);
692
- if (callback->isUndefined() || callback->isNull()) {
693
- opsqlite_deregister_commit_hook(db);
694
- return {};
695
- }
696
- commit_hook_callback = callback;
697
- opsqlite_register_commit_hook(db, this);
482
+ function_map["commitHook"] = HOSTFN("commitHook") {
483
+ if (count < 1) {
484
+ throw std::runtime_error("[op-sqlite][commitHook] callback needed");
485
+ }
698
486
 
699
- return {};
700
- });
487
+ auto callback = std::make_shared<jsi::Value>(rt, args[0]);
488
+ if (callback->isUndefined() || callback->isNull()) {
489
+ opsqlite_deregister_commit_hook(db);
490
+ return {};
491
+ }
492
+ commit_hook_callback = callback;
493
+ opsqlite_register_commit_hook(db, this);
701
494
 
702
- function_map["rollbackHook"] = HOSTFN("rollbackHook") {
703
- if (count < 1) {
704
- throw std::runtime_error(
705
- "[op-sqlite][rollbackHook] callback needed");
706
- }
495
+ return {};
496
+ });
707
497
 
708
- auto callback = std::make_shared<jsi::Value>(rt, args[0]);
498
+ function_map["rollbackHook"] = HOSTFN("rollbackHook") {
499
+ if (count < 1) {
500
+ throw std::runtime_error("[op-sqlite][rollbackHook] callback needed");
501
+ }
709
502
 
710
- if (callback->isUndefined() || callback->isNull()) {
711
- opsqlite_deregister_rollback_hook(db);
712
- return {};
713
- }
714
- rollback_hook_callback = callback;
503
+ auto callback = std::make_shared<jsi::Value>(rt, args[0]);
715
504
 
716
- opsqlite_register_rollback_hook(db, this);
717
- return {};
718
- });
505
+ if (callback->isUndefined() || callback->isNull()) {
506
+ opsqlite_deregister_rollback_hook(db);
507
+ return {};
508
+ }
509
+ rollback_hook_callback = callback;
719
510
 
720
- function_map["loadExtension"] = HOSTFN("loadExtension") {
721
- auto path = args[0].asString(rt).utf8(rt);
722
- std::string entry_point;
723
- if (count > 1 && args[1].isString()) {
724
- entry_point = args[1].asString(rt).utf8(rt);
725
- }
511
+ opsqlite_register_rollback_hook(db, this);
512
+ return {};
513
+ });
726
514
 
727
- opsqlite_load_extension(db, path, entry_point);
728
- return {};
729
- });
515
+ function_map["loadExtension"] = HOSTFN("loadExtension") {
516
+ auto path = args[0].asString(rt).utf8(rt);
517
+ std::string entry_point;
518
+ if (count > 1 && args[1].isString()) {
519
+ entry_point = args[1].asString(rt).utf8(rt);
520
+ }
730
521
 
731
- function_map["reactiveExecute"] = HOSTFN("reactiveExecute") {
732
- auto query = args[0].asObject(rt);
733
-
734
- const std::string query_str =
735
- query.getProperty(rt, "query").asString(rt).utf8(rt);
736
- auto js_args = query.getProperty(rt, "arguments");
737
- auto js_discriminators =
738
- query.getProperty(rt, "fireOn").asObject(rt).asArray(rt);
739
- auto variant_args = to_variant_vec(rt, js_args);
740
-
741
- sqlite3_stmt *stmt = opsqlite_prepare_statement(db, query_str);
742
- opsqlite_bind_statement(stmt, &variant_args);
743
-
744
- auto callback =
745
- std::make_shared<jsi::Value>(query.getProperty(rt, "callback"));
746
-
747
- std::vector<TableRowDiscriminator> discriminators;
748
-
749
- for (size_t i = 0; i < js_discriminators.length(rt); i++) {
750
- auto js_discriminator =
751
- js_discriminators.getValueAtIndex(rt, i).asObject(rt);
752
- std::string table =
753
- js_discriminator.getProperty(rt, "table").asString(rt).utf8(rt);
754
- std::vector<int> ids;
755
- if (js_discriminator.hasProperty(rt, "ids")) {
756
- auto js_ids = js_discriminator.getProperty(rt, "ids")
757
- .asObject(rt)
758
- .asArray(rt);
759
- for (size_t j = 0; j < js_ids.length(rt); j++) {
760
- ids.push_back(static_cast<int>(
761
- js_ids.getValueAtIndex(rt, j).asNumber()));
762
- }
763
- }
764
- discriminators.push_back({table, ids});
522
+ opsqlite_load_extension(db, path, entry_point);
523
+ return {};
524
+ });
525
+
526
+ function_map["reactiveExecute"] = HOSTFN("reactiveExecute") {
527
+ auto query = args[0].asObject(rt);
528
+
529
+ const std::string query_str =
530
+ query.getProperty(rt, "query").asString(rt).utf8(rt);
531
+ auto js_args = query.getProperty(rt, "arguments");
532
+ auto js_discriminators =
533
+ query.getProperty(rt, "fireOn").asObject(rt).asArray(rt);
534
+ auto variant_args = to_variant_vec(rt, js_args);
535
+
536
+ sqlite3_stmt *stmt = opsqlite_prepare_statement(db, query_str);
537
+ opsqlite_bind_statement(stmt, &variant_args);
538
+
539
+ auto callback =
540
+ std::make_shared<jsi::Value>(query.getProperty(rt, "callback"));
541
+
542
+ std::vector<TableRowDiscriminator> discriminators;
543
+
544
+ for (size_t i = 0; i < js_discriminators.length(rt); i++) {
545
+ auto js_discriminator =
546
+ js_discriminators.getValueAtIndex(rt, i).asObject(rt);
547
+ std::string table =
548
+ js_discriminator.getProperty(rt, "table").asString(rt).utf8(rt);
549
+ std::vector<int> ids;
550
+ if (js_discriminator.hasProperty(rt, "ids")) {
551
+ auto js_ids =
552
+ js_discriminator.getProperty(rt, "ids").asObject(rt).asArray(rt);
553
+ for (size_t j = 0; j < js_ids.length(rt); j++) {
554
+ ids.push_back(
555
+ static_cast<int>(js_ids.getValueAtIndex(rt, j).asNumber()));
765
556
  }
557
+ }
558
+ discriminators.push_back({table, ids});
559
+ }
766
560
 
767
- std::shared_ptr<ReactiveQuery> reactiveQuery =
768
- std::make_shared<ReactiveQuery>(
769
- ReactiveQuery{stmt, discriminators, callback});
770
-
771
- reactive_queries.push_back(reactiveQuery);
561
+ std::shared_ptr<ReactiveQuery> reactiveQuery =
562
+ std::make_shared<ReactiveQuery>(
563
+ ReactiveQuery{stmt, discriminators, callback});
772
564
 
773
- auto_register_update_hook();
565
+ reactive_queries.push_back(reactiveQuery);
774
566
 
775
- auto unsubscribe = HOSTFN("unsubscribe") {
776
- auto it = std::find(reactive_queries.begin(),
777
- reactive_queries.end(), reactiveQuery);
778
- if (it != reactive_queries.end()) {
779
- reactive_queries.erase(it);
780
- }
781
- auto_register_update_hook();
782
- return {};
783
- });
567
+ auto_register_update_hook();
784
568
 
785
- return unsubscribe;
569
+ auto unsubscribe = HOSTFN("unsubscribe") {
570
+ auto it = std::find(reactive_queries.begin(), reactive_queries.end(),
571
+ reactiveQuery);
572
+ if (it != reactive_queries.end()) {
573
+ reactive_queries.erase(it);
574
+ }
575
+ auto_register_update_hook();
576
+ return {};
786
577
  });
578
+
579
+ return unsubscribe;
580
+ });
787
581
  #endif
788
582
 
789
- function_map["prepareStatement"] = HOSTFN("prepareStatement") {
790
- auto query = args[0].asString(rt).utf8(rt);
583
+ function_map["prepareStatement"] = HOSTFN("prepareStatement") {
584
+ auto query = args[0].asString(rt).utf8(rt);
791
585
  #ifdef OP_SQLITE_USE_LIBSQL
792
- libsql_stmt_t statement = opsqlite_libsql_prepare_statement(db, query);
586
+ libsql_stmt_t statement = opsqlite_libsql_prepare_statement(db, query);
793
587
  #else
794
- sqlite3_stmt *statement = opsqlite_prepare_statement(db, query);
588
+ sqlite3_stmt *statement = opsqlite_prepare_statement(db, query);
795
589
  #endif
796
- auto preparedStatementHostObject =
797
- std::make_shared<PreparedStatementHostObject>(
798
- db, db_name, statement, invoker, _thread_pool);
799
-
800
- return jsi::Object::createFromHostObject(rt,
801
- preparedStatementHostObject);
802
- });
803
-
804
- function_map["getDbPath"] = HOSTFN("getDbPath") {
805
- std::string path = std::string(base_path);
806
-
807
- if (count == 1) {
808
- if (!args[0].isString()) {
809
- throw std::runtime_error(
810
- "[op-sqlite][open] database location must be a string");
811
- }
812
-
813
- std::string last_path = args[0].asString(rt).utf8(rt);
814
-
815
- if (last_path == ":memory:") {
816
- path = ":memory:";
817
- } else if (last_path.rfind('/', 0) == 0) {
818
- path = last_path;
819
- } else {
820
- path = path + "/" + last_path;
821
- }
822
- }
590
+ auto preparedStatementHostObject =
591
+ std::make_shared<PreparedStatementHostObject>(db, statement);
592
+
593
+ return jsi::Object::createFromHostObject(rt, preparedStatementHostObject);
594
+ });
595
+
596
+ function_map["getDbPath"] = HOSTFN("getDbPath") {
597
+ std::string path = std::string(base_path);
598
+
599
+ if (count == 1) {
600
+ if (!args[0].isString()) {
601
+ throw std::runtime_error(
602
+ "[op-sqlite][open] database location must be a string");
603
+ }
604
+
605
+ std::string last_path = args[0].asString(rt).utf8(rt);
606
+
607
+ if (last_path == ":memory:") {
608
+ path = ":memory:";
609
+ } else if (last_path.rfind('/', 0) == 0) {
610
+ path = last_path;
611
+ } else {
612
+ path = path + "/" + last_path;
613
+ }
614
+ }
823
615
 
824
- auto result = opsqlite_get_db_path(db_name, path);
825
- return jsi::String::createFromUtf8(rt, result);
826
- });
616
+ auto result = opsqlite_get_db_path(db_name, path);
617
+ return jsi::String::createFromUtf8(rt, result);
618
+ });
827
619
 
828
- function_map["flushPendingReactiveQueries"] =
829
- HOSTFN("flushPendingReactiveQueries") {
830
- auto promiseCtr = rt.global().getPropertyAsFunction(rt, "Promise");
620
+ function_map["flushPendingReactiveQueries"] =
621
+ HOSTFN("flushPendingReactiveQueries") {
622
+ auto promiseCtr = rt.global().getPropertyAsFunction(rt, "Promise");
831
623
  auto promise = promiseCtr.callAsConstructor(rt, HOSTFN("executor") {
832
- auto resolve = std::make_shared<jsi::Value>(rt, args[0]);
624
+ auto resolve = std::make_shared<jsi::Value>(rt, args[0]);
833
625
 
834
- auto task = [&rt, this, resolve]() {
835
- flush_pending_reactive_queries(resolve);
836
- };
626
+ auto task = [&rt, this, resolve]() {
627
+ flush_pending_reactive_queries(resolve);
628
+ };
837
629
 
838
- _thread_pool->queueWork(task);
630
+ _thread_pool->queueWork(task);
839
631
 
840
- return {};
632
+ return {};
841
633
  }));
842
634
 
843
635
  return promise;
844
- });
636
+ });
845
637
  }
846
638
 
847
639
  std::vector<jsi::PropNameID> DBHostObject::getPropertyNames(jsi::Runtime &_rt) {
848
- std::vector<jsi::PropNameID> keys;
849
- keys.reserve(function_map.size());
850
- for (const auto &pair : function_map) {
851
- keys.emplace_back(jsi::PropNameID::forUtf8(_rt, pair.first));
852
- }
853
- return keys;
640
+ std::vector<jsi::PropNameID> keys;
641
+ keys.reserve(function_map.size());
642
+ for (const auto &pair : function_map) {
643
+ keys.emplace_back(jsi::PropNameID::forUtf8(_rt, pair.first));
644
+ }
645
+ return keys;
854
646
  }
855
647
 
856
648
  jsi::Value DBHostObject::get(jsi::Runtime &_rt,
857
649
  const jsi::PropNameID &propNameID) {
858
- auto name = propNameID.utf8(rt);
859
- if (function_map.count(name) != 1) {
860
- return HOST_STATIC_FN(name.c_str()) {
861
- throw std::runtime_error(
862
- "[op-sqlite] Function " + name +
863
- " not implemented for current backend (libsql or sqlcipher)");
864
- });
865
- }
650
+ auto name = propNameID.utf8(rt);
651
+ if (function_map.count(name) != 1) {
652
+ return HOST_STATIC_FN(name.c_str()) {
653
+ throw std::runtime_error(
654
+ "[op-sqlite] Function " + name +
655
+ " not implemented for current backend (libsql or sqlcipher)");
656
+ });
657
+ }
866
658
 
867
- return {rt, function_map[name]};
659
+ return {rt, function_map[name]};
868
660
  }
869
661
 
870
662
  void DBHostObject::set(jsi::Runtime &_rt, const jsi::PropNameID &name,
871
663
  const jsi::Value &value) {
872
- throw std::runtime_error("You cannot write to this object!");
664
+ throw std::runtime_error("You cannot write to this object!");
873
665
  }
874
666
 
875
667
  void DBHostObject::invalidate() {
876
- if (invalidated) {
877
- return;
878
- }
668
+ if (invalidated) {
669
+ return;
670
+ }
879
671
 
880
- invalidated = true;
881
- _thread_pool->restartPool();
672
+ invalidated = true;
673
+ _thread_pool->restartPool();
882
674
  #ifdef OP_SQLITE_USE_LIBSQL
883
- opsqlite_libsql_close(db);
675
+ opsqlite_libsql_close(db);
884
676
  #else
885
- if (db != nullptr) {
886
- opsqlite_close(db);
887
- db = nullptr;
888
- }
677
+ if (db != nullptr) {
678
+ opsqlite_close(db);
679
+ db = nullptr;
680
+ }
889
681
  #endif
890
682
  }
891
683