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