@op-engineering/op-sqlite 2.0.2 → 2.0.4
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 +6 -2
- package/cpp/bindings.cpp +63 -61
- package/cpp/bridge.cpp +5 -2
- package/op-sqlite.podspec +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -22,7 +22,7 @@ You can find the [benchmarking code in the example app](https://github.com/OP-En
|
|
|
22
22
|
|
|
23
23
|
Memory consumption is also 1/4 compared to `react-native-quick-sqlite`. This query used to take 1.2 GB of peak memory usage, and now runs in 250mbs.
|
|
24
24
|
|
|
25
|
-
You can also turn on Memory Mapping to make your queries even faster by skipping the kernel during I/O, this comes with some disadvantages though. If you want even more speed and you can re-use your queries you can use prepared
|
|
25
|
+
You can also turn on [Memory Mapping](#speed) to make your queries even faster by skipping the kernel during I/O and potentially reduce RAM usage, this comes with some disadvantages though. If you want even more speed and you can re-use your queries you can use [Prepared Statements](#prepared-statements).
|
|
26
26
|
|
|
27
27
|
# Encryption
|
|
28
28
|
|
|
@@ -115,10 +115,14 @@ const db = open({
|
|
|
115
115
|
name: 'mydb.sqlite',
|
|
116
116
|
});
|
|
117
117
|
|
|
118
|
-
// 0 turns
|
|
118
|
+
// 0 turns off memory mapping, any other number enables it with the cache size
|
|
119
119
|
db.execute('PRAGMA mmap_size=268435456');
|
|
120
120
|
```
|
|
121
121
|
|
|
122
|
+
If you use prepared statements plus memory mapping, you can get to inches of MMKV for the most performance critical queries, here is a simple example writing/reading a single value.
|
|
123
|
+
|
|
124
|
+

|
|
125
|
+
|
|
122
126
|
# API
|
|
123
127
|
|
|
124
128
|
```typescript
|
package/cpp/bindings.cpp
CHANGED
|
@@ -53,12 +53,12 @@ void install(jsi::Runtime &rt,
|
|
|
53
53
|
|
|
54
54
|
auto open = HOSTFN("open", 3) {
|
|
55
55
|
if (count == 0) {
|
|
56
|
-
throw
|
|
56
|
+
throw std::runtime_error("[op-sqlite][open] database name is required");
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
if (!args[0].isString()) {
|
|
60
|
-
throw
|
|
61
|
-
|
|
60
|
+
throw std::runtime_error(
|
|
61
|
+
"[op-sqlite][open] database name must be a string");
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
std::string dbName = args[0].asString(rt).utf8(rt);
|
|
@@ -66,8 +66,8 @@ void install(jsi::Runtime &rt,
|
|
|
66
66
|
|
|
67
67
|
if (count > 1 && !args[1].isUndefined() && !args[1].isNull()) {
|
|
68
68
|
if (!args[1].isString()) {
|
|
69
|
-
throw
|
|
70
|
-
|
|
69
|
+
throw std::runtime_error(
|
|
70
|
+
"[op-sqlite][open] database location must be a string");
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
std::string lastPath = args[1].asString(rt).utf8(rt);
|
|
@@ -84,7 +84,7 @@ void install(jsi::Runtime &rt,
|
|
|
84
84
|
BridgeResult result = sqliteOpenDb(dbName, path);
|
|
85
85
|
|
|
86
86
|
if (result.type == SQLiteError) {
|
|
87
|
-
throw
|
|
87
|
+
throw std::runtime_error(result.message);
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
return {};
|
|
@@ -104,8 +104,8 @@ void install(jsi::Runtime &rt,
|
|
|
104
104
|
std::string tempDocPath = std::string(basePath);
|
|
105
105
|
if (count > 3 && !args[3].isUndefined() && !args[3].isNull()) {
|
|
106
106
|
if (!args[3].isString()) {
|
|
107
|
-
throw
|
|
108
|
-
|
|
107
|
+
throw std::runtime_error(
|
|
108
|
+
"[op-sqlite][attach] database location must be a string");
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
tempDocPath = tempDocPath + "/" + args[3].asString(rt).utf8(rt);
|
|
@@ -118,7 +118,7 @@ void install(jsi::Runtime &rt,
|
|
|
118
118
|
sqliteAttachDb(dbName, tempDocPath, databaseToAttach, alias);
|
|
119
119
|
|
|
120
120
|
if (result.type == SQLiteError) {
|
|
121
|
-
throw
|
|
121
|
+
throw std::runtime_error(result.message);
|
|
122
122
|
}
|
|
123
123
|
|
|
124
124
|
return {};
|
|
@@ -126,12 +126,12 @@ void install(jsi::Runtime &rt,
|
|
|
126
126
|
|
|
127
127
|
auto detach = HOSTFN("detach", 2) {
|
|
128
128
|
if (count < 2) {
|
|
129
|
-
throw
|
|
130
|
-
|
|
129
|
+
throw std::runtime_error(
|
|
130
|
+
"[op-sqlite][detach] Incorrect number of arguments");
|
|
131
131
|
}
|
|
132
132
|
if (!args[0].isString() || !args[1].isString()) {
|
|
133
|
-
throw
|
|
134
|
-
|
|
133
|
+
throw std::runtime_error(
|
|
134
|
+
"dbName, databaseToAttach and alias must be a strings");
|
|
135
135
|
return {};
|
|
136
136
|
}
|
|
137
137
|
|
|
@@ -148,12 +148,12 @@ void install(jsi::Runtime &rt,
|
|
|
148
148
|
|
|
149
149
|
auto close = HOSTFN("close", 1) {
|
|
150
150
|
if (count == 0) {
|
|
151
|
-
throw
|
|
151
|
+
throw std::runtime_error("[op-sqlite][close] database name is required");
|
|
152
152
|
}
|
|
153
153
|
|
|
154
154
|
if (!args[0].isString()) {
|
|
155
|
-
throw
|
|
156
|
-
|
|
155
|
+
throw std::runtime_error(
|
|
156
|
+
"[op-sqlite][close] database name must be a string");
|
|
157
157
|
}
|
|
158
158
|
|
|
159
159
|
std::string dbName = args[0].asString(rt).utf8(rt);
|
|
@@ -169,12 +169,12 @@ void install(jsi::Runtime &rt,
|
|
|
169
169
|
|
|
170
170
|
auto remove = HOSTFN("delete", 2) {
|
|
171
171
|
if (count == 0) {
|
|
172
|
-
throw
|
|
172
|
+
throw std::runtime_error("[op-sqlite][open] database name is required");
|
|
173
173
|
}
|
|
174
174
|
|
|
175
175
|
if (!args[0].isString()) {
|
|
176
|
-
throw
|
|
177
|
-
|
|
176
|
+
throw std::runtime_error(
|
|
177
|
+
"[op-sqlite][open] database name must be a string");
|
|
178
178
|
}
|
|
179
179
|
|
|
180
180
|
std::string dbName = args[0].asString(rt).utf8(rt);
|
|
@@ -183,8 +183,8 @@ void install(jsi::Runtime &rt,
|
|
|
183
183
|
|
|
184
184
|
if (count > 1 && !args[1].isUndefined() && !args[1].isNull()) {
|
|
185
185
|
if (!args[1].isString()) {
|
|
186
|
-
throw
|
|
187
|
-
|
|
186
|
+
throw std::runtime_error(
|
|
187
|
+
"[op-sqlite][open] database location must be a string");
|
|
188
188
|
}
|
|
189
189
|
|
|
190
190
|
tempDocPath = tempDocPath + "/" + args[1].asString(rt).utf8(rt);
|
|
@@ -193,7 +193,7 @@ void install(jsi::Runtime &rt,
|
|
|
193
193
|
BridgeResult result = sqliteRemoveDb(dbName, tempDocPath);
|
|
194
194
|
|
|
195
195
|
if (result.type == SQLiteError) {
|
|
196
|
-
throw
|
|
196
|
+
throw std::runtime_error(result.message);
|
|
197
197
|
}
|
|
198
198
|
|
|
199
199
|
return {};
|
|
@@ -203,33 +203,30 @@ void install(jsi::Runtime &rt,
|
|
|
203
203
|
const std::string dbName = args[0].asString(rt).utf8(rt);
|
|
204
204
|
const std::string query = args[1].asString(rt).utf8(rt);
|
|
205
205
|
std::vector<JSVariant> params;
|
|
206
|
-
try {
|
|
207
|
-
if (count == 3) {
|
|
208
|
-
const jsi::Value &originalParams = args[2];
|
|
209
|
-
params = toVariantVec(rt, originalParams);
|
|
210
|
-
}
|
|
211
206
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
207
|
+
if (count == 3) {
|
|
208
|
+
const jsi::Value &originalParams = args[2];
|
|
209
|
+
params = toVariantVec(rt, originalParams);
|
|
210
|
+
}
|
|
215
211
|
|
|
216
|
-
|
|
212
|
+
std::vector<DumbHostObject> results;
|
|
213
|
+
std::shared_ptr<std::vector<SmartHostObject>> metadata =
|
|
214
|
+
std::make_shared<std::vector<SmartHostObject>>();
|
|
217
215
|
|
|
218
|
-
|
|
219
|
-
throw jsi::JSError(rt, status.message);
|
|
220
|
-
}
|
|
216
|
+
auto status = sqliteExecute(dbName, query, ¶ms, &results, metadata);
|
|
221
217
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
} catch (const std::exception &e) {
|
|
225
|
-
throw jsi::JSError(rt, e.what());
|
|
218
|
+
if (status.type == SQLiteError) {
|
|
219
|
+
throw std::runtime_error(status.message);
|
|
226
220
|
}
|
|
221
|
+
|
|
222
|
+
auto jsiResult = createResult(rt, status, &results, metadata);
|
|
223
|
+
return jsiResult;
|
|
227
224
|
});
|
|
228
225
|
|
|
229
226
|
auto executeAsync = HOSTFN("executeAsync", 3) {
|
|
230
227
|
if (count < 3) {
|
|
231
|
-
throw
|
|
232
|
-
|
|
228
|
+
throw std::runtime_error(
|
|
229
|
+
"[op-sqlite][executeAsync] Incorrect arguments for executeAsync");
|
|
233
230
|
}
|
|
234
231
|
|
|
235
232
|
const std::string dbName = args[0].asString(rt).utf8(rt);
|
|
@@ -239,7 +236,8 @@ void install(jsi::Runtime &rt,
|
|
|
239
236
|
std::vector<JSVariant> params = toVariantVec(rt, originalParams);
|
|
240
237
|
|
|
241
238
|
auto promiseCtr = rt.global().getPropertyAsFunction(rt, "Promise");
|
|
242
|
-
|
|
239
|
+
|
|
240
|
+
auto promise = promiseCtr.callAsConstructor(rt, HOSTFN("executor", 2) {
|
|
243
241
|
auto resolve = std::make_shared<jsi::Value>(rt, args[0]);
|
|
244
242
|
auto reject = std::make_shared<jsi::Value>(rt, args[1]);
|
|
245
243
|
|
|
@@ -249,7 +247,6 @@ void install(jsi::Runtime &rt,
|
|
|
249
247
|
std::vector<DumbHostObject> results;
|
|
250
248
|
std::shared_ptr<std::vector<SmartHostObject>> metadata =
|
|
251
249
|
std::make_shared<std::vector<SmartHostObject>>();
|
|
252
|
-
;
|
|
253
250
|
|
|
254
251
|
auto status =
|
|
255
252
|
sqliteExecute(dbName, query, ¶ms, &results, metadata);
|
|
@@ -289,23 +286,23 @@ void install(jsi::Runtime &rt,
|
|
|
289
286
|
pool.queueWork(task);
|
|
290
287
|
|
|
291
288
|
return {};
|
|
292
|
-
|
|
289
|
+
}));
|
|
293
290
|
|
|
294
|
-
|
|
291
|
+
return promise;
|
|
295
292
|
});
|
|
296
293
|
|
|
297
294
|
// Execute a batch of SQL queries in a transaction
|
|
298
295
|
// Parameters can be: [[sql: string, arguments: any[] | arguments: any[][] ]]
|
|
299
296
|
auto executeBatch = HOSTFN("executeBatch", 2) {
|
|
300
297
|
if (sizeof(args) < 2) {
|
|
301
|
-
throw
|
|
302
|
-
|
|
298
|
+
throw std::runtime_error(
|
|
299
|
+
"[op-sqlite][executeBatch] - Incorrect parameter count");
|
|
303
300
|
}
|
|
304
301
|
|
|
305
302
|
const jsi::Value ¶ms = args[1];
|
|
306
303
|
if (params.isNull() || params.isUndefined()) {
|
|
307
|
-
throw
|
|
308
|
-
|
|
304
|
+
throw std::runtime_error("[op-sqlite][executeBatch] - An array of SQL "
|
|
305
|
+
"commands or parameters is needed");
|
|
309
306
|
}
|
|
310
307
|
const std::string dbName = args[0].asString(rt).utf8(rt);
|
|
311
308
|
const jsi::Array &batchParams = params.asObject(rt).asArray(rt);
|
|
@@ -318,22 +315,23 @@ void install(jsi::Runtime &rt,
|
|
|
318
315
|
res.setProperty(rt, "rowsAffected", jsi::Value(batchResult.affectedRows));
|
|
319
316
|
return std::move(res);
|
|
320
317
|
} else {
|
|
321
|
-
throw
|
|
318
|
+
throw std::runtime_error(batchResult.message);
|
|
322
319
|
}
|
|
323
320
|
});
|
|
324
321
|
|
|
325
322
|
auto executeBatchAsync = HOSTFN("executeBatchAsync", 2) {
|
|
326
323
|
if (sizeof(args) < 2) {
|
|
327
|
-
throw
|
|
328
|
-
|
|
324
|
+
throw std::runtime_error(
|
|
325
|
+
"[op-sqlite][executeAsyncBatch] Incorrect parameter count");
|
|
329
326
|
return {};
|
|
330
327
|
}
|
|
331
328
|
|
|
332
329
|
const jsi::Value ¶ms = args[1];
|
|
333
330
|
|
|
334
331
|
if (params.isNull() || params.isUndefined()) {
|
|
335
|
-
throw
|
|
336
|
-
|
|
332
|
+
throw std::runtime_error(
|
|
333
|
+
"[op-sqlite][executeAsyncBatch] - An array of SQL "
|
|
334
|
+
"commands or parameters is needed");
|
|
337
335
|
return {};
|
|
338
336
|
}
|
|
339
337
|
|
|
@@ -362,6 +360,7 @@ void install(jsi::Runtime &rt,
|
|
|
362
360
|
jsi::Value(batchResult.affectedRows));
|
|
363
361
|
resolve->asObject(rt).asFunction(rt).call(rt, std::move(res));
|
|
364
362
|
} else {
|
|
363
|
+
// TODO replace with reject
|
|
365
364
|
throw jsi::JSError(rt, batchResult.message);
|
|
366
365
|
}
|
|
367
366
|
});
|
|
@@ -380,8 +379,8 @@ void install(jsi::Runtime &rt,
|
|
|
380
379
|
|
|
381
380
|
auto loadFile = HOSTFN("loadFile", 2) {
|
|
382
381
|
if (sizeof(args) < 2) {
|
|
383
|
-
throw
|
|
384
|
-
|
|
382
|
+
throw std::runtime_error(
|
|
383
|
+
"[op-sqlite][loadFileAsync] Incorrect parameter count");
|
|
385
384
|
return {};
|
|
386
385
|
}
|
|
387
386
|
|
|
@@ -423,8 +422,9 @@ void install(jsi::Runtime &rt,
|
|
|
423
422
|
|
|
424
423
|
auto updateHook = HOSTFN("updateHook", 2) {
|
|
425
424
|
if (sizeof(args) < 2) {
|
|
426
|
-
throw
|
|
427
|
-
|
|
425
|
+
throw std::runtime_error(
|
|
426
|
+
"[op-sqlite][loadFileAsync] Incorrect parameters: "
|
|
427
|
+
"dbName and callback needed");
|
|
428
428
|
return {};
|
|
429
429
|
}
|
|
430
430
|
|
|
@@ -481,8 +481,9 @@ void install(jsi::Runtime &rt,
|
|
|
481
481
|
|
|
482
482
|
auto commitHook = HOSTFN("commitHook", 2) {
|
|
483
483
|
if (sizeof(args) < 2) {
|
|
484
|
-
throw
|
|
485
|
-
|
|
484
|
+
throw std::runtime_error(
|
|
485
|
+
"[op-sqlite][loadFileAsync] Incorrect parameters: "
|
|
486
|
+
"dbName and callback needed");
|
|
486
487
|
return {};
|
|
487
488
|
}
|
|
488
489
|
|
|
@@ -506,8 +507,9 @@ void install(jsi::Runtime &rt,
|
|
|
506
507
|
|
|
507
508
|
auto rollbackHook = HOSTFN("rollbackHook", 2) {
|
|
508
509
|
if (sizeof(args) < 2) {
|
|
509
|
-
throw
|
|
510
|
-
|
|
510
|
+
throw std::runtime_error(
|
|
511
|
+
"[op-sqlite][loadFileAsync] Incorrect parameters: "
|
|
512
|
+
"dbName and callback needed");
|
|
511
513
|
return {};
|
|
512
514
|
}
|
|
513
515
|
|
package/cpp/bridge.cpp
CHANGED
|
@@ -543,8 +543,11 @@ sqliteExecute(std::string const dbName, std::string const &query,
|
|
|
543
543
|
if (isFailed) {
|
|
544
544
|
|
|
545
545
|
return {.type = SQLiteError,
|
|
546
|
-
.message =
|
|
547
|
-
|
|
546
|
+
.message =
|
|
547
|
+
"[op-sqlite] SQLite error code: " + std::to_string(result) +
|
|
548
|
+
", description: " + std::string(errorMessage) +
|
|
549
|
+
".\nSee SQLite error codes reference: "
|
|
550
|
+
"https://www.sqlite.org/rescode.html"};
|
|
548
551
|
}
|
|
549
552
|
|
|
550
553
|
int changedRowCount = sqlite3_changes(db);
|
package/op-sqlite.podspec
CHANGED
|
@@ -11,7 +11,7 @@ Pod::Spec.new do |s|
|
|
|
11
11
|
s.license = package["license"]
|
|
12
12
|
s.authors = package["author"]
|
|
13
13
|
|
|
14
|
-
s.platforms = { :ios => "12.0", :osx => "10.
|
|
14
|
+
s.platforms = { :ios => "12.0", :osx => "10.13" }
|
|
15
15
|
s.source = { :git => "https://github.com/op-engineering/op-sqlite.git", :tag => "#{s.version}" }
|
|
16
16
|
|
|
17
17
|
s.pod_target_xcconfig = {
|