@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.
- package/android/CMakeLists.txt +1 -1
- package/android/build.gradle +1 -1
- package/android/cpp-adapter.cpp +1 -1
- package/android/src/main/java/com/op/sqlite/OPSQLiteModule.kt +7 -9
- package/cpp/DBHostObject.cpp +469 -677
- 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 +2 -2
- package/cpp/libsql/{bridge.h → bridge.hpp} +4 -4
- 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/lib/module/functions.js +52 -44
- 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 +12 -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 +64 -54
- 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,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
|
-
|
|
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
|
-
|
|
77
|
+
for (const auto &query_ptr : reactive_queries) {
|
|
78
|
+
auto query = query_ptr.get();
|
|
86
79
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
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
|
-
|
|
95
|
-
|
|
96
|
-
}
|
|
86
|
+
if (query->discriminators.empty()) {
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
97
89
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
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
|
-
|
|
122
|
-
|
|
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
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
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
|
-
|
|
157
|
-
|
|
148
|
+
_thread_pool = std::make_shared<ThreadPool>();
|
|
149
|
+
db = opsqlite_libsql_open_remote(url, auth_token);
|
|
158
150
|
|
|
159
|
-
|
|
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
|
-
|
|
164
|
+
_thread_pool = std::make_shared<ThreadPool>();
|
|
173
165
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
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
|
-
|
|
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
|
-
|
|
183
|
+
_thread_pool = std::make_shared<ThreadPool>();
|
|
192
184
|
|
|
193
185
|
#ifdef OP_SQLITE_USE_SQLCIPHER
|
|
194
|
-
|
|
195
|
-
|
|
186
|
+
db = opsqlite_open(db_name, path, crsqlite_path, sqlite_vec_path,
|
|
187
|
+
encryption_key);
|
|
196
188
|
#elif OP_SQLITE_USE_LIBSQL
|
|
197
|
-
|
|
189
|
+
db = opsqlite_libsql_open(db_name, path, crsqlite_path);
|
|
198
190
|
#else
|
|
199
|
-
|
|
191
|
+
db = opsqlite_open(db_name, path, crsqlite_path, sqlite_vec_path);
|
|
200
192
|
#endif
|
|
201
|
-
|
|
193
|
+
create_jsi_functions();
|
|
202
194
|
};
|
|
203
195
|
|
|
204
196
|
void DBHostObject::create_jsi_functions() {
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
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
|
-
|
|
214
|
+
opsqlite_libsql_attach(db, secondary_db_path, secondary_db_name, alias);
|
|
225
215
|
#else
|
|
226
|
-
|
|
216
|
+
opsqlite_attach(db, secondary_db_path, secondary_db_name, alias);
|
|
227
217
|
#endif
|
|
228
218
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
function_map["detach"] = HOSTFN("detach") {
|
|
219
|
+
return {};
|
|
220
|
+
});
|
|
233
221
|
|
|
234
|
-
|
|
235
|
-
|
|
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
|
-
|
|
227
|
+
std::string alias = args[0].asString(rt).utf8(rt);
|
|
239
228
|
#ifdef OP_SQLITE_USE_LIBSQL
|
|
240
|
-
|
|
229
|
+
opsqlite_libsql_detach(db, alias);
|
|
241
230
|
#else
|
|
242
|
-
|
|
231
|
+
opsqlite_detach(db, alias);
|
|
243
232
|
#endif
|
|
244
233
|
|
|
245
|
-
|
|
246
|
-
|
|
234
|
+
return {};
|
|
235
|
+
});
|
|
247
236
|
|
|
248
|
-
|
|
249
|
-
|
|
237
|
+
function_map["close"] = HFN(this) {
|
|
238
|
+
invalidated = true;
|
|
250
239
|
|
|
251
240
|
#ifdef OP_SQLITE_USE_LIBSQL
|
|
252
|
-
|
|
241
|
+
opsqlite_libsql_close(db);
|
|
253
242
|
#else
|
|
254
|
-
|
|
243
|
+
opsqlite_close(db);
|
|
255
244
|
#endif
|
|
256
245
|
|
|
257
|
-
|
|
258
|
-
|
|
246
|
+
return {};
|
|
247
|
+
});
|
|
259
248
|
|
|
260
|
-
|
|
261
|
-
|
|
249
|
+
function_map["delete"] = HFN(this) {
|
|
250
|
+
invalidated = true;
|
|
262
251
|
|
|
263
|
-
|
|
252
|
+
std::string path = std::string(base_path);
|
|
264
253
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
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
|
-
|
|
260
|
+
std::string location = args[1].asString(rt).utf8(rt);
|
|
272
261
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
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
|
-
|
|
274
|
+
opsqlite_libsql_remove(db, db_name, path);
|
|
286
275
|
#else
|
|
287
|
-
|
|
276
|
+
opsqlite_remove(db, db_name, path);
|
|
288
277
|
#endif
|
|
289
278
|
|
|
290
|
-
|
|
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
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
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
|
-
|
|
310
|
-
|
|
293
|
+
auto status =
|
|
294
|
+
opsqlite_libsql_execute_raw(db, query, ¶ms, &results);
|
|
311
295
|
#else
|
|
312
|
-
|
|
313
|
-
opsqlite_execute_raw(db, query, ¶ms, &results);
|
|
296
|
+
auto status = opsqlite_execute_raw(db, query, ¶ms, &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
|
-
|
|
317
|
-
|
|
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
|
-
|
|
362
|
-
|
|
363
|
-
|
|
313
|
+
if (count == 2) {
|
|
314
|
+
params = to_variant_vec(rt, args[1]);
|
|
315
|
+
}
|
|
364
316
|
#ifdef OP_SQLITE_USE_LIBSQL
|
|
365
|
-
|
|
317
|
+
auto status = opsqlite_libsql_execute(db, query, ¶ms);
|
|
366
318
|
#else
|
|
367
|
-
|
|
319
|
+
auto status = opsqlite_execute(db, query, ¶ms);
|
|
368
320
|
#endif
|
|
369
321
|
|
|
370
|
-
|
|
371
|
-
|
|
322
|
+
return create_js_rows(rt, status);
|
|
323
|
+
});
|
|
372
324
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
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
|
-
|
|
331
|
+
std::vector<std::vector<JSVariant>> results;
|
|
380
332
|
|
|
381
333
|
#ifdef OP_SQLITE_USE_LIBSQL
|
|
382
|
-
|
|
334
|
+
auto status = opsqlite_libsql_execute_raw(db, query, ¶ms, &results);
|
|
383
335
|
#else
|
|
384
|
-
|
|
336
|
+
auto status = opsqlite_execute_raw(db, query, ¶ms, &results);
|
|
385
337
|
#endif
|
|
386
338
|
|
|
387
|
-
|
|
388
|
-
|
|
339
|
+
return create_raw_result(rt, status, &results);
|
|
340
|
+
});
|
|
389
341
|
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
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
|
-
|
|
352
|
+
auto status = opsqlite_libsql_execute(db, query, ¶ms);
|
|
405
353
|
#else
|
|
406
|
-
|
|
354
|
+
auto status = opsqlite_execute(db, query, ¶ms);
|
|
407
355
|
#endif
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
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
|
-
|
|
475
|
-
|
|
377
|
+
auto status = opsqlite_libsql_execute_with_host_objects(
|
|
378
|
+
db, query, ¶ms, &results, metadata);
|
|
476
379
|
#else
|
|
477
|
-
|
|
478
|
-
|
|
380
|
+
auto status = opsqlite_execute_host_objects(db, query, ¶ms,
|
|
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
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
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
|
-
|
|
402
|
+
const jsi::Value ¶ms = args[0];
|
|
534
403
|
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
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
|
-
|
|
544
|
-
to_batch_arguments(rt, batchParams, &commands);
|
|
410
|
+
const jsi::Array &batchParams = params.asObject(rt).asArray(rt);
|
|
545
411
|
|
|
546
|
-
|
|
547
|
-
|
|
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
|
-
|
|
552
|
-
|
|
415
|
+
return promisify(
|
|
416
|
+
rt,
|
|
417
|
+
[this, commands]() {
|
|
553
418
|
#ifdef OP_SQLITE_USE_LIBSQL
|
|
554
|
-
|
|
555
|
-
opsqlite_libsql_execute_batch(db, &commands);
|
|
419
|
+
auto batchResult = opsqlite_libsql_execute_batch(db, &commands);
|
|
556
420
|
#else
|
|
557
|
-
|
|
421
|
+
auto batchResult = opsqlite_execute_batch(db, &commands);
|
|
558
422
|
#endif
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
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
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
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
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
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
|
-
|
|
671
|
-
});
|
|
456
|
+
const std::string sqlFileName = args[0].asString(rt).utf8(rt);
|
|
672
457
|
|
|
673
|
-
|
|
674
|
-
|
|
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
|
-
|
|
677
|
-
|
|
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
|
-
|
|
683
|
-
|
|
684
|
-
}
|
|
472
|
+
if (callback->isUndefined() || callback->isNull()) {
|
|
473
|
+
update_hook_callback = nullptr;
|
|
474
|
+
} else {
|
|
475
|
+
update_hook_callback = callback;
|
|
476
|
+
}
|
|
685
477
|
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
}
|
|
478
|
+
auto_register_update_hook();
|
|
479
|
+
return {};
|
|
480
|
+
});
|
|
690
481
|
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
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
|
-
|
|
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
|
-
|
|
703
|
-
|
|
704
|
-
throw std::runtime_error(
|
|
705
|
-
"[op-sqlite][rollbackHook] callback needed");
|
|
706
|
-
}
|
|
495
|
+
return {};
|
|
496
|
+
});
|
|
707
497
|
|
|
708
|
-
|
|
498
|
+
function_map["rollbackHook"] = HOSTFN("rollbackHook") {
|
|
499
|
+
if (count < 1) {
|
|
500
|
+
throw std::runtime_error("[op-sqlite][rollbackHook] callback needed");
|
|
501
|
+
}
|
|
709
502
|
|
|
710
|
-
|
|
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
|
-
|
|
717
|
-
|
|
718
|
-
|
|
505
|
+
if (callback->isUndefined() || callback->isNull()) {
|
|
506
|
+
opsqlite_deregister_rollback_hook(db);
|
|
507
|
+
return {};
|
|
508
|
+
}
|
|
509
|
+
rollback_hook_callback = callback;
|
|
719
510
|
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
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
|
-
|
|
728
|
-
|
|
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
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
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
|
-
|
|
768
|
-
|
|
769
|
-
|
|
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
|
-
|
|
565
|
+
reactive_queries.push_back(reactiveQuery);
|
|
774
566
|
|
|
775
|
-
|
|
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
|
-
|
|
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
|
-
|
|
790
|
-
|
|
583
|
+
function_map["prepareStatement"] = HOSTFN("prepareStatement") {
|
|
584
|
+
auto query = args[0].asString(rt).utf8(rt);
|
|
791
585
|
#ifdef OP_SQLITE_USE_LIBSQL
|
|
792
|
-
|
|
586
|
+
libsql_stmt_t statement = opsqlite_libsql_prepare_statement(db, query);
|
|
793
587
|
#else
|
|
794
|
-
|
|
588
|
+
sqlite3_stmt *statement = opsqlite_prepare_statement(db, query);
|
|
795
589
|
#endif
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
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
|
-
|
|
825
|
-
|
|
826
|
-
|
|
616
|
+
auto result = opsqlite_get_db_path(db_name, path);
|
|
617
|
+
return jsi::String::createFromUtf8(rt, result);
|
|
618
|
+
});
|
|
827
619
|
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
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
|
-
|
|
624
|
+
auto resolve = std::make_shared<jsi::Value>(rt, args[0]);
|
|
833
625
|
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
626
|
+
auto task = [&rt, this, resolve]() {
|
|
627
|
+
flush_pending_reactive_queries(resolve);
|
|
628
|
+
};
|
|
837
629
|
|
|
838
|
-
|
|
630
|
+
_thread_pool->queueWork(task);
|
|
839
631
|
|
|
840
|
-
|
|
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
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
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
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
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
|
-
|
|
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
|
-
|
|
664
|
+
throw std::runtime_error("You cannot write to this object!");
|
|
873
665
|
}
|
|
874
666
|
|
|
875
667
|
void DBHostObject::invalidate() {
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
668
|
+
if (invalidated) {
|
|
669
|
+
return;
|
|
670
|
+
}
|
|
879
671
|
|
|
880
|
-
|
|
881
|
-
|
|
672
|
+
invalidated = true;
|
|
673
|
+
_thread_pool->restartPool();
|
|
882
674
|
#ifdef OP_SQLITE_USE_LIBSQL
|
|
883
|
-
|
|
675
|
+
opsqlite_libsql_close(db);
|
|
884
676
|
#else
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
677
|
+
if (db != nullptr) {
|
|
678
|
+
opsqlite_close(db);
|
|
679
|
+
db = nullptr;
|
|
680
|
+
}
|
|
889
681
|
#endif
|
|
890
682
|
}
|
|
891
683
|
|