@op-engineering/op-sqlite 2.0.0 → 2.0.2
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/README.md +82 -24
- package/android/CMakeLists.txt +4 -2
- package/cpp/DumbHostObject.cpp +32 -27
- package/cpp/DumbHostObject.h +16 -16
- package/cpp/PreparedStatementHostObject.cpp +88 -0
- package/cpp/PreparedStatementHostObject.h +36 -0
- package/cpp/SmartHostObject.cpp +33 -0
- package/cpp/SmartHostObject.h +26 -0
- package/cpp/ThreadPool.cpp +103 -116
- package/cpp/ThreadPool.h +27 -27
- package/cpp/bindings.cpp +525 -530
- package/cpp/bindings.h +6 -5
- package/cpp/bridge.cpp +713 -651
- package/cpp/bridge.h +41 -19
- package/cpp/logs.h +17 -17
- package/cpp/macros.h +1 -1
- package/cpp/sqlbatchexecutor.cpp +75 -77
- package/cpp/sqlbatchexecutor.h +9 -8
- package/cpp/sqlite3.h +1295 -1389
- package/cpp/types.h +5 -4
- package/cpp/utils.cpp +159 -191
- package/cpp/utils.h +28 -35
- package/ios/OPSQLite.mm +13 -5
- package/lib/commonjs/index.js +2 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/module/index.js +2 -1
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/index.d.ts +6 -0
- package/package.json +2 -1
- package/src/index.ts +8 -0
- package/cpp/DynamicHostObject.cpp +0 -32
- package/cpp/DynamicHostObject.h +0 -26
package/cpp/bindings.cpp
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
#include "bindings.h"
|
|
2
|
+
#include "DumbHostObject.h"
|
|
3
|
+
#include "PreparedStatementHostObject.h"
|
|
4
|
+
#include "ThreadPool.h"
|
|
2
5
|
#include "bridge.h"
|
|
3
6
|
#include "logs.h"
|
|
4
|
-
#include "utils.h"
|
|
5
|
-
#include "ThreadPool.h"
|
|
6
|
-
#include "sqlbatchexecutor.h"
|
|
7
|
-
#include <vector>
|
|
8
|
-
#include <string>
|
|
9
7
|
#include "macros.h"
|
|
8
|
+
#include "sqlbatchexecutor.h"
|
|
9
|
+
#include "utils.h"
|
|
10
10
|
#include <iostream>
|
|
11
|
-
#include
|
|
11
|
+
#include <sqlite3.h>
|
|
12
|
+
#include <string>
|
|
12
13
|
#include <unordered_map>
|
|
14
|
+
#include <vector>
|
|
13
15
|
|
|
14
16
|
namespace opsqlite {
|
|
15
17
|
|
|
@@ -18,552 +20,545 @@ namespace jsi = facebook::jsi;
|
|
|
18
20
|
std::string basePath;
|
|
19
21
|
std::shared_ptr<react::CallInvoker> invoker;
|
|
20
22
|
ThreadPool pool;
|
|
21
|
-
std::unordered_map<std::string, std::shared_ptr<jsi::Value>> updateHooks =
|
|
22
|
-
std::unordered_map<std::string, std::shared_ptr<jsi::Value>>
|
|
23
|
-
std::unordered_map<std::string, std::shared_ptr<jsi::Value>>
|
|
24
|
-
|
|
23
|
+
std::unordered_map<std::string, std::shared_ptr<jsi::Value>> updateHooks =
|
|
24
|
+
std::unordered_map<std::string, std::shared_ptr<jsi::Value>>();
|
|
25
|
+
std::unordered_map<std::string, std::shared_ptr<jsi::Value>> commitHooks =
|
|
26
|
+
std::unordered_map<std::string, std::shared_ptr<jsi::Value>>();
|
|
27
|
+
std::unordered_map<std::string, std::shared_ptr<jsi::Value>> rollbackHooks =
|
|
28
|
+
std::unordered_map<std::string, std::shared_ptr<jsi::Value>>();
|
|
25
29
|
|
|
26
|
-
// React native will try to clean the module on JS context invalidation
|
|
27
|
-
// The clearState function is called and we use this flag
|
|
28
|
-
// operations from continuing work and can return early
|
|
30
|
+
// React native will try to clean the module on JS context invalidation
|
|
31
|
+
// (CodePush/Hot Reload) The clearState function is called and we use this flag
|
|
32
|
+
// to prevent any ongoing operations from continuing work and can return early
|
|
29
33
|
bool invalidated = false;
|
|
30
34
|
|
|
31
35
|
void clearState() {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
36
|
+
invalidated = true;
|
|
37
|
+
// Will terminate all operations and database connections
|
|
38
|
+
sqliteCloseAll();
|
|
39
|
+
// We then join all the threads before the context gets invalidated
|
|
40
|
+
pool.restartPool();
|
|
41
|
+
|
|
42
|
+
updateHooks.clear();
|
|
43
|
+
commitHooks.clear();
|
|
44
|
+
rollbackHooks.clear();
|
|
37
45
|
}
|
|
38
46
|
|
|
39
|
-
void install(jsi::Runtime &rt,
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
auto open = HOSTFN("open", 3) {
|
|
46
|
-
if (count == 0)
|
|
47
|
-
{
|
|
48
|
-
throw jsi::JSError(rt, "[op-sqlite][open] database name is required");
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
if (!args[0].isString())
|
|
52
|
-
{
|
|
53
|
-
throw jsi::JSError(rt, "[op-sqlite][open] database name must be a string");
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
std::string dbName = args[0].asString(rt).utf8(rt);
|
|
57
|
-
std::string path = std::string(basePath);
|
|
58
|
-
|
|
59
|
-
if (count > 1 && !args[1].isUndefined() && !args[1].isNull())
|
|
60
|
-
{
|
|
61
|
-
if (!args[1].isString())
|
|
62
|
-
{
|
|
63
|
-
throw jsi::JSError(rt, "[op-sqlite][open] database location must be a string");
|
|
64
|
-
}
|
|
47
|
+
void install(jsi::Runtime &rt,
|
|
48
|
+
std::shared_ptr<react::CallInvoker> jsCallInvoker,
|
|
49
|
+
const char *docPath) {
|
|
50
|
+
invalidated = false;
|
|
51
|
+
basePath = std::string(docPath);
|
|
52
|
+
invoker = jsCallInvoker;
|
|
65
53
|
|
|
66
|
-
|
|
54
|
+
auto open = HOSTFN("open", 3) {
|
|
55
|
+
if (count == 0) {
|
|
56
|
+
throw jsi::JSError(rt, "[op-sqlite][open] database name is required");
|
|
57
|
+
}
|
|
67
58
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
auto status = sqliteExecute(dbName, query, ¶ms, &results, metadata);
|
|
219
|
-
|
|
220
|
-
if(status.type == SQLiteError) {
|
|
221
|
-
throw jsi::JSError(rt, status.message);
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
auto jsiResult = createResult(rt, status, &results, metadata);
|
|
225
|
-
return jsiResult;
|
|
226
|
-
} catch (const std::exception &e) {
|
|
227
|
-
throw jsi::JSError(rt, e.what());
|
|
228
|
-
}
|
|
229
|
-
});
|
|
230
|
-
|
|
231
|
-
auto executeAsync = HOSTFN("executeAsync", 3)
|
|
232
|
-
{
|
|
233
|
-
if (count < 3)
|
|
234
|
-
{
|
|
235
|
-
throw jsi::JSError(rt, "[op-sqlite][executeAsync] Incorrect arguments for executeAsync");
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
const std::string dbName = args[0].asString(rt).utf8(rt);
|
|
239
|
-
const std::string query = args[1].asString(rt).utf8(rt);
|
|
59
|
+
if (!args[0].isString()) {
|
|
60
|
+
throw jsi::JSError(rt,
|
|
61
|
+
"[op-sqlite][open] database name must be a string");
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
std::string dbName = args[0].asString(rt).utf8(rt);
|
|
65
|
+
std::string path = std::string(basePath);
|
|
66
|
+
|
|
67
|
+
if (count > 1 && !args[1].isUndefined() && !args[1].isNull()) {
|
|
68
|
+
if (!args[1].isString()) {
|
|
69
|
+
throw jsi::JSError(
|
|
70
|
+
rt, "[op-sqlite][open] database location must be a string");
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
std::string lastPath = args[1].asString(rt).utf8(rt);
|
|
74
|
+
|
|
75
|
+
if (lastPath == ":memory:") {
|
|
76
|
+
path = ":memory:";
|
|
77
|
+
} else if (lastPath.rfind("/", 0) == 0) {
|
|
78
|
+
path = lastPath;
|
|
79
|
+
} else {
|
|
80
|
+
path = path + "/" + lastPath;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
BridgeResult result = sqliteOpenDb(dbName, path);
|
|
85
|
+
|
|
86
|
+
if (result.type == SQLiteError) {
|
|
87
|
+
throw jsi::JSError(rt, result.message.c_str());
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return {};
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
auto attach = HOSTFN("attach", 4) {
|
|
94
|
+
if (count < 3) {
|
|
95
|
+
throw jsi::JSError(rt,
|
|
96
|
+
"[op-sqlite][attach] Incorrect number of arguments");
|
|
97
|
+
}
|
|
98
|
+
if (!args[0].isString() || !args[1].isString() || !args[2].isString()) {
|
|
99
|
+
throw jsi::JSError(
|
|
100
|
+
rt, "dbName, databaseToAttach and alias must be a strings");
|
|
101
|
+
return {};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
std::string tempDocPath = std::string(basePath);
|
|
105
|
+
if (count > 3 && !args[3].isUndefined() && !args[3].isNull()) {
|
|
106
|
+
if (!args[3].isString()) {
|
|
107
|
+
throw jsi::JSError(
|
|
108
|
+
rt, "[op-sqlite][attach] database location must be a string");
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
tempDocPath = tempDocPath + "/" + args[3].asString(rt).utf8(rt);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
std::string dbName = args[0].asString(rt).utf8(rt);
|
|
115
|
+
std::string databaseToAttach = args[1].asString(rt).utf8(rt);
|
|
116
|
+
std::string alias = args[2].asString(rt).utf8(rt);
|
|
117
|
+
BridgeResult result =
|
|
118
|
+
sqliteAttachDb(dbName, tempDocPath, databaseToAttach, alias);
|
|
119
|
+
|
|
120
|
+
if (result.type == SQLiteError) {
|
|
121
|
+
throw jsi::JSError(rt, result.message.c_str());
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return {};
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
auto detach = HOSTFN("detach", 2) {
|
|
128
|
+
if (count < 2) {
|
|
129
|
+
throw jsi::JSError(rt,
|
|
130
|
+
"[op-sqlite][detach] Incorrect number of arguments");
|
|
131
|
+
}
|
|
132
|
+
if (!args[0].isString() || !args[1].isString()) {
|
|
133
|
+
throw jsi::JSError(
|
|
134
|
+
rt, "dbName, databaseToAttach and alias must be a strings");
|
|
135
|
+
return {};
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
std::string dbName = args[0].asString(rt).utf8(rt);
|
|
139
|
+
std::string alias = args[1].asString(rt).utf8(rt);
|
|
140
|
+
BridgeResult result = sqliteDetachDb(dbName, alias);
|
|
141
|
+
|
|
142
|
+
if (result.type == SQLiteError) {
|
|
143
|
+
throw jsi::JSError(rt, result.message.c_str());
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return {};
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
auto close = HOSTFN("close", 1) {
|
|
150
|
+
if (count == 0) {
|
|
151
|
+
throw jsi::JSError(rt, "[op-sqlite][close] database name is required");
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (!args[0].isString()) {
|
|
155
|
+
throw jsi::JSError(rt,
|
|
156
|
+
"[op-sqlite][close] database name must be a string");
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
std::string dbName = args[0].asString(rt).utf8(rt);
|
|
160
|
+
|
|
161
|
+
BridgeResult result = sqliteCloseDb(dbName);
|
|
162
|
+
|
|
163
|
+
if (result.type == SQLiteError) {
|
|
164
|
+
throw jsi::JSError(rt, result.message.c_str());
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return {};
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
auto remove = HOSTFN("delete", 2) {
|
|
171
|
+
if (count == 0) {
|
|
172
|
+
throw jsi::JSError(rt, "[op-sqlite][open] database name is required");
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if (!args[0].isString()) {
|
|
176
|
+
throw jsi::JSError(rt,
|
|
177
|
+
"[op-sqlite][open] database name must be a string");
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
std::string dbName = args[0].asString(rt).utf8(rt);
|
|
181
|
+
|
|
182
|
+
std::string tempDocPath = std::string(basePath);
|
|
183
|
+
|
|
184
|
+
if (count > 1 && !args[1].isUndefined() && !args[1].isNull()) {
|
|
185
|
+
if (!args[1].isString()) {
|
|
186
|
+
throw jsi::JSError(
|
|
187
|
+
rt, "[op-sqlite][open] database location must be a string");
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
tempDocPath = tempDocPath + "/" + args[1].asString(rt).utf8(rt);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
BridgeResult result = sqliteRemoveDb(dbName, tempDocPath);
|
|
194
|
+
|
|
195
|
+
if (result.type == SQLiteError) {
|
|
196
|
+
throw jsi::JSError(rt, result.message.c_str());
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
return {};
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
auto execute = HOSTFN("execute", 3) {
|
|
203
|
+
const std::string dbName = args[0].asString(rt).utf8(rt);
|
|
204
|
+
const std::string query = args[1].asString(rt).utf8(rt);
|
|
205
|
+
std::vector<JSVariant> params;
|
|
206
|
+
try {
|
|
207
|
+
if (count == 3) {
|
|
240
208
|
const jsi::Value &originalParams = args[2];
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
209
|
+
params = toVariantVec(rt, originalParams);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
std::vector<DumbHostObject> results;
|
|
213
|
+
std::shared_ptr<std::vector<SmartHostObject>> metadata =
|
|
214
|
+
std::make_shared<std::vector<SmartHostObject>>();
|
|
215
|
+
|
|
216
|
+
auto status = sqliteExecute(dbName, query, ¶ms, &results, metadata);
|
|
217
|
+
|
|
218
|
+
if (status.type == SQLiteError) {
|
|
219
|
+
throw jsi::JSError(rt, status.message);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
auto jsiResult = createResult(rt, status, &results, metadata);
|
|
223
|
+
return jsiResult;
|
|
224
|
+
} catch (const std::exception &e) {
|
|
225
|
+
throw jsi::JSError(rt, e.what());
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
auto executeAsync = HOSTFN("executeAsync", 3) {
|
|
230
|
+
if (count < 3) {
|
|
231
|
+
throw jsi::JSError(
|
|
232
|
+
rt, "[op-sqlite][executeAsync] Incorrect arguments for executeAsync");
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
const std::string dbName = args[0].asString(rt).utf8(rt);
|
|
236
|
+
const std::string query = args[1].asString(rt).utf8(rt);
|
|
237
|
+
const jsi::Value &originalParams = args[2];
|
|
238
|
+
|
|
239
|
+
std::vector<JSVariant> params = toVariantVec(rt, originalParams);
|
|
240
|
+
|
|
241
|
+
auto promiseCtr = rt.global().getPropertyAsFunction(rt, "Promise");
|
|
245
242
|
auto promise = promiseCtr.callAsConstructor(rt, HOSTFN("executor", 2) {
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
}
|
|
280
|
-
catch (std::exception &exc)
|
|
281
|
-
{
|
|
282
|
-
invoker->invokeAsync([&rt, exc = std::move(exc), reject] {
|
|
283
|
-
auto errorCtr = rt.global().getPropertyAsFunction(rt, "Error");
|
|
284
|
-
auto error = errorCtr.callAsConstructor(rt, jsi::String::createFromAscii(rt, exc.what()));
|
|
285
|
-
reject->asObject(rt).asFunction(rt).call(rt, error);
|
|
286
|
-
});
|
|
243
|
+
auto resolve = std::make_shared<jsi::Value>(rt, args[0]);
|
|
244
|
+
auto reject = std::make_shared<jsi::Value>(rt, args[1]);
|
|
245
|
+
|
|
246
|
+
auto task = [&rt, dbName, query, params = std::move(params), resolve,
|
|
247
|
+
reject]() {
|
|
248
|
+
try {
|
|
249
|
+
std::vector<DumbHostObject> results;
|
|
250
|
+
std::shared_ptr<std::vector<SmartHostObject>> metadata =
|
|
251
|
+
std::make_shared<std::vector<SmartHostObject>>();
|
|
252
|
+
;
|
|
253
|
+
|
|
254
|
+
auto status =
|
|
255
|
+
sqliteExecute(dbName, query, ¶ms, &results, metadata);
|
|
256
|
+
|
|
257
|
+
if (invalidated) {
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
invoker->invokeAsync(
|
|
262
|
+
[&rt,
|
|
263
|
+
results = std::make_shared<std::vector<DumbHostObject>>(results),
|
|
264
|
+
metadata, status = std::move(status), resolve, reject] {
|
|
265
|
+
if (status.type == SQLiteOk) {
|
|
266
|
+
auto jsiResult =
|
|
267
|
+
createResult(rt, status, results.get(), metadata);
|
|
268
|
+
resolve->asObject(rt).asFunction(rt).call(
|
|
269
|
+
rt, std::move(jsiResult));
|
|
270
|
+
} else {
|
|
271
|
+
auto errorCtr =
|
|
272
|
+
rt.global().getPropertyAsFunction(rt, "Error");
|
|
273
|
+
auto error = errorCtr.callAsConstructor(
|
|
274
|
+
rt, jsi::String::createFromUtf8(rt, status.message));
|
|
275
|
+
reject->asObject(rt).asFunction(rt).call(rt, error);
|
|
287
276
|
}
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
} catch (std::exception &exc) {
|
|
280
|
+
invoker->invokeAsync([&rt, exc = std::move(exc), reject] {
|
|
281
|
+
auto errorCtr = rt.global().getPropertyAsFunction(rt, "Error");
|
|
282
|
+
auto error = errorCtr.callAsConstructor(
|
|
283
|
+
rt, jsi::String::createFromAscii(rt, exc.what()));
|
|
284
|
+
reject->asObject(rt).asFunction(rt).call(rt, error);
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
pool.queueWork(task);
|
|
290
|
+
|
|
291
|
+
return {};
|
|
293
292
|
}));
|
|
294
|
-
|
|
293
|
+
|
|
295
294
|
return promise;
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
{
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
std::vector<BatchArguments> commands;
|
|
350
|
-
toBatchArguments(rt, batchParams, &commands);
|
|
351
|
-
|
|
352
|
-
auto promiseCtr = rt.global().getPropertyAsFunction(rt, "Promise");
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
// Execute a batch of SQL queries in a transaction
|
|
298
|
+
// Parameters can be: [[sql: string, arguments: any[] | arguments: any[][] ]]
|
|
299
|
+
auto executeBatch = HOSTFN("executeBatch", 2) {
|
|
300
|
+
if (sizeof(args) < 2) {
|
|
301
|
+
throw jsi::JSError(
|
|
302
|
+
rt, "[op-sqlite][executeBatch] - Incorrect parameter count");
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
const jsi::Value ¶ms = args[1];
|
|
306
|
+
if (params.isNull() || params.isUndefined()) {
|
|
307
|
+
throw jsi::JSError(rt, "[op-sqlite][executeBatch] - An array of SQL "
|
|
308
|
+
"commands or parameters is needed");
|
|
309
|
+
}
|
|
310
|
+
const std::string dbName = args[0].asString(rt).utf8(rt);
|
|
311
|
+
const jsi::Array &batchParams = params.asObject(rt).asArray(rt);
|
|
312
|
+
std::vector<BatchArguments> commands;
|
|
313
|
+
toBatchArguments(rt, batchParams, &commands);
|
|
314
|
+
|
|
315
|
+
auto batchResult = sqliteExecuteBatch(dbName, &commands);
|
|
316
|
+
if (batchResult.type == SQLiteOk) {
|
|
317
|
+
auto res = jsi::Object(rt);
|
|
318
|
+
res.setProperty(rt, "rowsAffected", jsi::Value(batchResult.affectedRows));
|
|
319
|
+
return std::move(res);
|
|
320
|
+
} else {
|
|
321
|
+
throw jsi::JSError(rt, batchResult.message);
|
|
322
|
+
}
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
auto executeBatchAsync = HOSTFN("executeBatchAsync", 2) {
|
|
326
|
+
if (sizeof(args) < 2) {
|
|
327
|
+
throw jsi::JSError(
|
|
328
|
+
rt, "[op-sqlite][executeAsyncBatch] Incorrect parameter count");
|
|
329
|
+
return {};
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
const jsi::Value ¶ms = args[1];
|
|
333
|
+
|
|
334
|
+
if (params.isNull() || params.isUndefined()) {
|
|
335
|
+
throw jsi::JSError(rt, "[op-sqlite][executeAsyncBatch] - An array of SQL "
|
|
336
|
+
"commands or parameters is needed");
|
|
337
|
+
return {};
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
const std::string dbName = args[0].asString(rt).utf8(rt);
|
|
341
|
+
const jsi::Array &batchParams = params.asObject(rt).asArray(rt);
|
|
342
|
+
|
|
343
|
+
std::vector<BatchArguments> commands;
|
|
344
|
+
toBatchArguments(rt, batchParams, &commands);
|
|
345
|
+
|
|
346
|
+
auto promiseCtr = rt.global().getPropertyAsFunction(rt, "Promise");
|
|
353
347
|
auto promise = promiseCtr.callAsConstructor(rt, HOSTFN("executor", 2) {
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
throw jsi::JSError(rt, batchResult.message);
|
|
373
|
-
} });
|
|
374
|
-
}
|
|
375
|
-
catch (std::exception &exc)
|
|
376
|
-
{
|
|
377
|
-
invoker->invokeAsync([&rt, reject, &exc]
|
|
378
|
-
{
|
|
379
|
-
throw jsi::JSError(rt, exc.what());
|
|
380
|
-
});
|
|
348
|
+
auto resolve = std::make_shared<jsi::Value>(rt, args[0]);
|
|
349
|
+
auto reject = std::make_shared<jsi::Value>(rt, args[1]);
|
|
350
|
+
|
|
351
|
+
auto task = [&rt, dbName,
|
|
352
|
+
commands =
|
|
353
|
+
std::make_shared<std::vector<BatchArguments>>(commands),
|
|
354
|
+
resolve, reject]() {
|
|
355
|
+
try {
|
|
356
|
+
auto batchResult = sqliteExecuteBatch(dbName, commands.get());
|
|
357
|
+
invoker->invokeAsync(
|
|
358
|
+
[&rt, batchResult = std::move(batchResult), resolve, reject] {
|
|
359
|
+
if (batchResult.type == SQLiteOk) {
|
|
360
|
+
auto res = jsi::Object(rt);
|
|
361
|
+
res.setProperty(rt, "rowsAffected",
|
|
362
|
+
jsi::Value(batchResult.affectedRows));
|
|
363
|
+
resolve->asObject(rt).asFunction(rt).call(rt, std::move(res));
|
|
364
|
+
} else {
|
|
365
|
+
throw jsi::JSError(rt, batchResult.message);
|
|
381
366
|
}
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
367
|
+
});
|
|
368
|
+
} catch (std::exception &exc) {
|
|
369
|
+
invoker->invokeAsync(
|
|
370
|
+
[&rt, reject, &exc] { throw jsi::JSError(rt, exc.what()); });
|
|
371
|
+
}
|
|
372
|
+
};
|
|
373
|
+
pool.queueWork(task);
|
|
374
|
+
|
|
375
|
+
return {};
|
|
386
376
|
}));
|
|
387
|
-
|
|
377
|
+
|
|
388
378
|
return promise;
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
{
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
auto promiseCtr = rt.global().getPropertyAsFunction(rt, "Promise");
|
|
379
|
+
});
|
|
380
|
+
|
|
381
|
+
auto loadFile = HOSTFN("loadFile", 2) {
|
|
382
|
+
if (sizeof(args) < 2) {
|
|
383
|
+
throw jsi::JSError(
|
|
384
|
+
rt, "[op-sqlite][loadFileAsync] Incorrect parameter count");
|
|
385
|
+
return {};
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
const std::string dbName = args[0].asString(rt).utf8(rt);
|
|
389
|
+
const std::string sqlFileName = args[1].asString(rt).utf8(rt);
|
|
390
|
+
|
|
391
|
+
auto promiseCtr = rt.global().getPropertyAsFunction(rt, "Promise");
|
|
403
392
|
auto promise = promiseCtr.callAsConstructor(rt, HOSTFN("executor", 2) {
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
resolve->asObject(rt).asFunction(rt).call(rt, std::move(res));
|
|
422
|
-
} else {
|
|
423
|
-
throw jsi::JSError(rt, result.message);
|
|
424
|
-
} });
|
|
425
|
-
}
|
|
426
|
-
catch (std::exception &exc)
|
|
427
|
-
{
|
|
428
|
-
invoker->invokeAsync([&rt, err = exc.what(), reject]
|
|
429
|
-
{
|
|
430
|
-
throw jsi::JSError(rt, err);
|
|
431
|
-
});
|
|
393
|
+
auto resolve = std::make_shared<jsi::Value>(rt, args[0]);
|
|
394
|
+
auto reject = std::make_shared<jsi::Value>(rt, args[1]);
|
|
395
|
+
|
|
396
|
+
auto task = [&rt, dbName, sqlFileName, resolve, reject]() {
|
|
397
|
+
try {
|
|
398
|
+
const auto importResult = importSQLFile(dbName, sqlFileName);
|
|
399
|
+
|
|
400
|
+
invoker->invokeAsync(
|
|
401
|
+
[&rt, result = std::move(importResult), resolve, reject] {
|
|
402
|
+
if (result.type == SQLiteOk) {
|
|
403
|
+
auto res = jsi::Object(rt);
|
|
404
|
+
res.setProperty(rt, "rowsAffected",
|
|
405
|
+
jsi::Value(result.affectedRows));
|
|
406
|
+
res.setProperty(rt, "commands", jsi::Value(result.commands));
|
|
407
|
+
resolve->asObject(rt).asFunction(rt).call(rt, std::move(res));
|
|
408
|
+
} else {
|
|
409
|
+
throw jsi::JSError(rt, result.message);
|
|
432
410
|
}
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
411
|
+
});
|
|
412
|
+
} catch (std::exception &exc) {
|
|
413
|
+
invoker->invokeAsync(
|
|
414
|
+
[&rt, err = exc.what(), reject] { throw jsi::JSError(rt, err); });
|
|
415
|
+
}
|
|
416
|
+
};
|
|
417
|
+
pool.queueWork(task);
|
|
418
|
+
return {};
|
|
436
419
|
}));
|
|
437
|
-
|
|
420
|
+
|
|
438
421
|
return promise;
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
{
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
auto updateHook = HOSTFN("updateHook", 2) {
|
|
425
|
+
if (sizeof(args) < 2) {
|
|
426
|
+
throw jsi::JSError(rt, "[op-sqlite][loadFileAsync] Incorrect parameters: "
|
|
427
|
+
"dbName and callback needed");
|
|
428
|
+
return {};
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
auto dbName = args[0].asString(rt).utf8(rt);
|
|
432
|
+
auto callback = std::make_shared<jsi::Value>(rt, args[1]);
|
|
433
|
+
|
|
434
|
+
if (callback->isUndefined() || callback->isNull()) {
|
|
435
|
+
unregisterUpdateHook(dbName);
|
|
436
|
+
return {};
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
updateHooks[dbName] = callback;
|
|
457
440
|
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
441
|
+
auto hook = [&rt, callback](std::string dbName, std::string tableName,
|
|
442
|
+
std::string operation, int rowId) {
|
|
443
|
+
std::vector<JSVariant> params;
|
|
444
|
+
std::vector<DumbHostObject> results;
|
|
445
|
+
std::shared_ptr<std::vector<SmartHostObject>> metadata =
|
|
446
|
+
std::make_shared<std::vector<SmartHostObject>>();
|
|
447
|
+
;
|
|
448
|
+
|
|
449
|
+
if (operation != "DELETE") {
|
|
450
|
+
std::string query = "SELECT * FROM " + tableName +
|
|
451
|
+
" where rowid = " + std::to_string(rowId) + ";";
|
|
452
|
+
sqliteExecute(dbName, query, ¶ms, &results, metadata);
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
invoker->invokeAsync(
|
|
456
|
+
[&rt,
|
|
457
|
+
results = std::make_shared<std::vector<DumbHostObject>>(results),
|
|
458
|
+
callback, tableName = std::move(tableName),
|
|
459
|
+
operation = std::move(operation), &rowId] {
|
|
460
|
+
auto res = jsi::Object(rt);
|
|
461
|
+
res.setProperty(rt, "table",
|
|
462
|
+
jsi::String::createFromUtf8(rt, tableName));
|
|
463
|
+
res.setProperty(rt, "operation",
|
|
464
|
+
jsi::String::createFromUtf8(rt, operation));
|
|
465
|
+
res.setProperty(rt, "rowId", jsi::Value(rowId));
|
|
466
|
+
if (results->size() != 0) {
|
|
467
|
+
res.setProperty(
|
|
468
|
+
rt, "row",
|
|
469
|
+
jsi::Object::createFromHostObject(
|
|
470
|
+
rt, std::make_shared<DumbHostObject>(results->at(0))));
|
|
468
471
|
}
|
|
469
|
-
|
|
470
|
-
invoker->invokeAsync([&rt, results = std::make_shared<std::vector<DumbHostObject>>(results), callback, tableName = std::move(tableName), operation = std::move(operation), &rowId]
|
|
471
|
-
{
|
|
472
|
-
auto res = jsi::Object(rt);
|
|
473
|
-
res.setProperty(rt, "table", jsi::String::createFromUtf8(rt, tableName));
|
|
474
|
-
res.setProperty(rt, "operation", jsi::String::createFromUtf8(rt, operation));
|
|
475
|
-
res.setProperty(rt, "rowId", jsi::Value(rowId));
|
|
476
|
-
if(results->size() != 0) {
|
|
477
|
-
res.setProperty(rt, "row", jsi::Object::createFromHostObject(rt, std::make_shared<DumbHostObject>(results->at(0))));
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
callback->asObject(rt).asFunction(rt).call(rt, res);
|
|
481
|
-
|
|
482
|
-
});
|
|
483
|
-
};
|
|
484
|
-
|
|
485
|
-
registerUpdateHook(dbName, std::move(hook));
|
|
486
|
-
|
|
487
|
-
return {};
|
|
488
|
-
});
|
|
489
|
-
|
|
490
|
-
auto commitHook = HOSTFN("commitHook", 2)
|
|
491
|
-
{
|
|
492
|
-
if (sizeof(args) < 2)
|
|
493
|
-
{
|
|
494
|
-
throw jsi::JSError(rt, "[op-sqlite][loadFileAsync] Incorrect parameters: dbName and callback needed");
|
|
495
|
-
return {};
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
auto dbName = args[0].asString(rt).utf8(rt);
|
|
499
|
-
auto callback = std::make_shared<jsi::Value>(rt, args[1]);
|
|
500
|
-
if (callback->isUndefined() || callback->isNull())
|
|
501
|
-
{
|
|
502
|
-
unregisterCommitHook(dbName);
|
|
503
|
-
return {};
|
|
504
|
-
}
|
|
505
|
-
commitHooks[dbName] = callback;
|
|
506
|
-
|
|
507
|
-
auto hook = [&rt, callback](std::string dbName) {
|
|
508
|
-
invoker->invokeAsync([&rt, callback]
|
|
509
|
-
{
|
|
510
|
-
callback->asObject(rt).asFunction(rt).call(rt);
|
|
511
|
-
});
|
|
512
|
-
};
|
|
513
|
-
|
|
514
|
-
registerCommitHook(dbName, std::move(hook));
|
|
515
|
-
|
|
516
|
-
return {};
|
|
517
|
-
});
|
|
518
|
-
|
|
519
|
-
auto rollbackHook = HOSTFN("rollbackHook", 2)
|
|
520
|
-
{
|
|
521
|
-
if (sizeof(args) < 2)
|
|
522
|
-
{
|
|
523
|
-
throw jsi::JSError(rt, "[op-sqlite][loadFileAsync] Incorrect parameters: dbName and callback needed");
|
|
524
|
-
return {};
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
auto dbName = args[0].asString(rt).utf8(rt);
|
|
528
|
-
auto callback = std::make_shared<jsi::Value>(rt, args[1]);
|
|
529
|
-
|
|
530
|
-
if (callback->isUndefined() || callback->isNull())
|
|
531
|
-
{
|
|
532
|
-
unregisterRollbackHook(dbName);
|
|
533
|
-
return {};
|
|
534
|
-
}
|
|
535
|
-
rollbackHooks[dbName] = callback;
|
|
536
|
-
|
|
537
|
-
auto hook = [&rt, callback](std::string dbName) {
|
|
538
|
-
|
|
539
|
-
invoker->invokeAsync([&rt, callback] {
|
|
540
|
-
callback->asObject(rt).asFunction(rt).call(rt);
|
|
541
|
-
|
|
542
|
-
});
|
|
543
|
-
};
|
|
544
|
-
|
|
545
|
-
registerRollbackHook(dbName, std::move(hook));
|
|
546
|
-
|
|
547
|
-
return {};
|
|
548
|
-
});
|
|
549
|
-
|
|
550
|
-
jsi::Object module = jsi::Object(rt);
|
|
551
|
-
|
|
552
|
-
module.setProperty(rt, "open", std::move(open));
|
|
553
|
-
module.setProperty(rt, "close", std::move(close));
|
|
554
|
-
module.setProperty(rt, "attach", std::move(attach));
|
|
555
|
-
module.setProperty(rt, "detach", std::move(detach));
|
|
556
|
-
module.setProperty(rt, "delete", std::move(remove));
|
|
557
|
-
module.setProperty(rt, "execute", std::move(execute));
|
|
558
|
-
module.setProperty(rt, "executeAsync", std::move(executeAsync));
|
|
559
|
-
module.setProperty(rt, "executeBatch", std::move(executeBatch));
|
|
560
|
-
module.setProperty(rt, "executeBatchAsync", std::move(executeBatchAsync));
|
|
561
|
-
module.setProperty(rt, "loadFile", std::move(loadFile));
|
|
562
|
-
module.setProperty(rt, "updateHook", std::move(updateHook));
|
|
563
|
-
module.setProperty(rt, "commitHook", std::move(commitHook));
|
|
564
|
-
module.setProperty(rt, "rollbackHook", std::move(rollbackHook));
|
|
565
|
-
|
|
566
|
-
rt.global().setProperty(rt, "__OPSQLiteProxy", std::move(module));
|
|
567
|
-
}
|
|
568
472
|
|
|
473
|
+
callback->asObject(rt).asFunction(rt).call(rt, res);
|
|
474
|
+
});
|
|
475
|
+
};
|
|
476
|
+
|
|
477
|
+
registerUpdateHook(dbName, std::move(hook));
|
|
478
|
+
|
|
479
|
+
return {};
|
|
480
|
+
});
|
|
481
|
+
|
|
482
|
+
auto commitHook = HOSTFN("commitHook", 2) {
|
|
483
|
+
if (sizeof(args) < 2) {
|
|
484
|
+
throw jsi::JSError(rt, "[op-sqlite][loadFileAsync] Incorrect parameters: "
|
|
485
|
+
"dbName and callback needed");
|
|
486
|
+
return {};
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
auto dbName = args[0].asString(rt).utf8(rt);
|
|
490
|
+
auto callback = std::make_shared<jsi::Value>(rt, args[1]);
|
|
491
|
+
if (callback->isUndefined() || callback->isNull()) {
|
|
492
|
+
unregisterCommitHook(dbName);
|
|
493
|
+
return {};
|
|
494
|
+
}
|
|
495
|
+
commitHooks[dbName] = callback;
|
|
496
|
+
|
|
497
|
+
auto hook = [&rt, callback](std::string dbName) {
|
|
498
|
+
invoker->invokeAsync(
|
|
499
|
+
[&rt, callback] { callback->asObject(rt).asFunction(rt).call(rt); });
|
|
500
|
+
};
|
|
501
|
+
|
|
502
|
+
registerCommitHook(dbName, std::move(hook));
|
|
503
|
+
|
|
504
|
+
return {};
|
|
505
|
+
});
|
|
506
|
+
|
|
507
|
+
auto rollbackHook = HOSTFN("rollbackHook", 2) {
|
|
508
|
+
if (sizeof(args) < 2) {
|
|
509
|
+
throw jsi::JSError(rt, "[op-sqlite][loadFileAsync] Incorrect parameters: "
|
|
510
|
+
"dbName and callback needed");
|
|
511
|
+
return {};
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
auto dbName = args[0].asString(rt).utf8(rt);
|
|
515
|
+
auto callback = std::make_shared<jsi::Value>(rt, args[1]);
|
|
516
|
+
|
|
517
|
+
if (callback->isUndefined() || callback->isNull()) {
|
|
518
|
+
unregisterRollbackHook(dbName);
|
|
519
|
+
return {};
|
|
520
|
+
}
|
|
521
|
+
rollbackHooks[dbName] = callback;
|
|
522
|
+
|
|
523
|
+
auto hook = [&rt, callback](std::string dbName) {
|
|
524
|
+
invoker->invokeAsync(
|
|
525
|
+
[&rt, callback] { callback->asObject(rt).asFunction(rt).call(rt); });
|
|
526
|
+
};
|
|
527
|
+
|
|
528
|
+
registerRollbackHook(dbName, std::move(hook));
|
|
529
|
+
return {};
|
|
530
|
+
});
|
|
531
|
+
|
|
532
|
+
auto prepareStatement = HOSTFN("prepareStatement", 1) {
|
|
533
|
+
auto dbName = args[0].asString(rt).utf8(rt);
|
|
534
|
+
auto query = args[1].asString(rt).utf8(rt);
|
|
535
|
+
|
|
536
|
+
sqlite3_stmt *statement = sqlite_prepare_statement(dbName, query);
|
|
537
|
+
|
|
538
|
+
auto preparedStatementHostObject =
|
|
539
|
+
std::make_shared<PreparedStatementHostObject>(dbName, statement);
|
|
540
|
+
|
|
541
|
+
return jsi::Object::createFromHostObject(rt, preparedStatementHostObject);
|
|
542
|
+
});
|
|
543
|
+
|
|
544
|
+
jsi::Object module = jsi::Object(rt);
|
|
545
|
+
|
|
546
|
+
module.setProperty(rt, "open", std::move(open));
|
|
547
|
+
module.setProperty(rt, "close", std::move(close));
|
|
548
|
+
module.setProperty(rt, "attach", std::move(attach));
|
|
549
|
+
module.setProperty(rt, "detach", std::move(detach));
|
|
550
|
+
module.setProperty(rt, "delete", std::move(remove));
|
|
551
|
+
module.setProperty(rt, "execute", std::move(execute));
|
|
552
|
+
module.setProperty(rt, "executeAsync", std::move(executeAsync));
|
|
553
|
+
module.setProperty(rt, "executeBatch", std::move(executeBatch));
|
|
554
|
+
module.setProperty(rt, "executeBatchAsync", std::move(executeBatchAsync));
|
|
555
|
+
module.setProperty(rt, "loadFile", std::move(loadFile));
|
|
556
|
+
module.setProperty(rt, "updateHook", std::move(updateHook));
|
|
557
|
+
module.setProperty(rt, "commitHook", std::move(commitHook));
|
|
558
|
+
module.setProperty(rt, "rollbackHook", std::move(rollbackHook));
|
|
559
|
+
module.setProperty(rt, "prepareStatement", std::move(prepareStatement));
|
|
560
|
+
|
|
561
|
+
rt.global().setProperty(rt, "__OPSQLiteProxy", std::move(module));
|
|
569
562
|
}
|
|
563
|
+
|
|
564
|
+
} // namespace opsqlite
|