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