@op-engineering/op-sqlite 1.0.0 → 1.0.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/README.md +26 -18
- package/android/CMakeLists.txt +1 -0
- package/cpp/DynamicHostObject.cpp +1 -1
- package/cpp/DynamicHostObject.h +2 -3
- package/cpp/bindings.cpp +7 -5
- package/cpp/bridge.cpp +33 -52
- package/cpp/bridge.h +2 -1
- package/cpp/sqlbatchexecutor.cpp +2 -2
- package/cpp/sqlbatchexecutor.h +2 -1
- package/cpp/types.h +14 -0
- package/cpp/utils.cpp +46 -52
- package/cpp/utils.h +6 -5
- package/package.json +2 -2
- package/android/gradle.properties +0 -4
- package/op-sqlite.podspec +0 -39
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-

|
|
2
2
|
|
|
3
3
|
<div align="center">
|
|
4
4
|
<pre align="center">
|
|
@@ -20,11 +20,26 @@ Created by [@ospfranco](https://twitter.com/ospfranco). Also created `react-nati
|
|
|
20
20
|
|
|
21
21
|
[ArrayBuffer support is commented out right now](https://github.com/OP-Engineering/op-sqlite/blob/main/cpp/bridge.cpp#L247). I will get to it in the next days or feel free to submit a PR.
|
|
22
22
|
|
|
23
|
+
## Coming up
|
|
24
|
+
|
|
25
|
+
I will gladly review bug fixes, but in order for me to continue support and add new features, I ask you to sponsor me. Some of the things that can still be done to make this package faster and more complete:
|
|
26
|
+
|
|
27
|
+
- Prepared statements
|
|
28
|
+
- Inlining functions
|
|
29
|
+
- Batching queries
|
|
30
|
+
- Update hook
|
|
31
|
+
|
|
23
32
|
## Benchmarks
|
|
24
33
|
|
|
25
|
-
You can find the [benchmarking code in the example app](https://github.com/OP-Engineering/op-sqlite/blob/main/example/src/Database.ts#L44). Loading a 300k record database
|
|
34
|
+
You can find the [benchmarking code in the example app](https://github.com/OP-Engineering/op-sqlite/blob/main/example/src/Database.ts#L44). Non JSI libraries are not even a contender anymore, you should expect anywhere between a 5x to a 8x improvement over sqlite-storage, sqlite2 and so on. Loading a 300k record database (in milliseconds).
|
|
26
35
|
|
|
27
|
-
|
|
36
|
+
| Library | iPhone 15 Pro | Galaxy S22 |
|
|
37
|
+
| ------------ | ------------- | ---------- |
|
|
38
|
+
| quick-sqlite | 2719 | 8851 |
|
|
39
|
+
| expo-sqlite | 2293 | 10626 |
|
|
40
|
+
| op-sqlite | 634 | 1548 |
|
|
41
|
+
|
|
42
|
+
Memory consumption is also 50% to 80% reduced compared to `react-native-quick-sqlite`. `expo-sqlite` OOMS itself even when trying to insert 300k elements in a row. Queries that before might have OOM now can run just fine.
|
|
28
43
|
|
|
29
44
|
# DB Paths
|
|
30
45
|
|
|
@@ -46,7 +61,7 @@ Note that on iOS the file system is sand-boxed, so you cannot access files/direc
|
|
|
46
61
|
```typescript
|
|
47
62
|
import {open} from '@op-engineering/op-sqlite'
|
|
48
63
|
|
|
49
|
-
const db = open('myDb.sqlite')
|
|
64
|
+
const db = open({name: 'myDb.sqlite'})
|
|
50
65
|
|
|
51
66
|
// The db object contains the following methods:
|
|
52
67
|
db = {
|
|
@@ -203,21 +218,14 @@ if (!detachResult.status) {
|
|
|
203
218
|
|
|
204
219
|
### Loading SQL Dump Files
|
|
205
220
|
|
|
206
|
-
If you have a
|
|
207
|
-
|
|
208
|
-
```typescript
|
|
209
|
-
const { rowsAffected, commands } = db.loadFile(
|
|
210
|
-
'myDatabase',
|
|
211
|
-
'/absolute/path/to/file.sql'
|
|
212
|
-
);
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
Or use the async version which will load the file in another native thread
|
|
221
|
+
If you have a SQL dump file, you can load it directly, with low memory consumption:
|
|
216
222
|
|
|
217
223
|
```typescript
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
224
|
+
const { rowsAffected, commands } = db
|
|
225
|
+
.loadFile('myDatabase', '/absolute/path/to/file.sql')
|
|
226
|
+
.then((res) => {
|
|
227
|
+
const { rowsAffected, commands } = res;
|
|
228
|
+
});
|
|
221
229
|
```
|
|
222
230
|
|
|
223
231
|
## Use built-in SQLite
|
|
@@ -258,7 +266,7 @@ For example, you could add `SQLITE_ENABLE_FTS5=1` to `GCC_PREPROCESSOR_DEFINITIO
|
|
|
258
266
|
You can specify flags via `<PROJECT_ROOT>/android/gradle.properties` like so:
|
|
259
267
|
|
|
260
268
|
```
|
|
261
|
-
|
|
269
|
+
quickSqliteFlags="-DSQLITE_ENABLE_FTS5=1"
|
|
262
270
|
```
|
|
263
271
|
|
|
264
272
|
## Additional configuration
|
package/android/CMakeLists.txt
CHANGED
package/cpp/DynamicHostObject.h
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
#include <any>
|
|
6
6
|
#include <vector>
|
|
7
7
|
#include <unordered_map>
|
|
8
|
+
#include "types.h"
|
|
8
9
|
|
|
9
10
|
namespace osp {
|
|
10
11
|
|
|
@@ -20,9 +21,7 @@ namespace osp {
|
|
|
20
21
|
|
|
21
22
|
jsi::Value get(jsi::Runtime &rt, const jsi::PropNameID &propNameID);
|
|
22
23
|
|
|
23
|
-
std::unordered_map<std::string,
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
std::unordered_map<std::string, jsVal> fields;
|
|
26
25
|
};
|
|
27
26
|
|
|
28
27
|
}
|
package/cpp/bindings.cpp
CHANGED
|
@@ -182,7 +182,7 @@ void install(jsi::Runtime &rt, std::shared_ptr<react::CallInvoker> jsCallInvoker
|
|
|
182
182
|
{
|
|
183
183
|
const std::string dbName = args[0].asString(rt).utf8(rt);
|
|
184
184
|
const std::string query = args[1].asString(rt).utf8(rt);
|
|
185
|
-
std::vector<
|
|
185
|
+
std::vector<jsVal> params;
|
|
186
186
|
if(count == 3) {
|
|
187
187
|
const jsi::Value &originalParams = args[2];
|
|
188
188
|
params = toAnyVec(rt, originalParams);
|
|
@@ -216,7 +216,7 @@ void install(jsi::Runtime &rt, std::shared_ptr<react::CallInvoker> jsCallInvoker
|
|
|
216
216
|
const std::string query = args[1].asString(rt).utf8(rt);
|
|
217
217
|
const jsi::Value &originalParams = args[2];
|
|
218
218
|
|
|
219
|
-
std::vector<
|
|
219
|
+
std::vector<jsVal> params = toAnyVec(rt, originalParams);
|
|
220
220
|
|
|
221
221
|
auto promiseCtr = rt.global().getPropertyAsFunction(rt, "Promise");
|
|
222
222
|
auto promise = promiseCtr.callAsConstructor(rt, HOSTFN("executor", 2) {
|
|
@@ -224,7 +224,7 @@ void install(jsi::Runtime &rt, std::shared_ptr<react::CallInvoker> jsCallInvoker
|
|
|
224
224
|
auto reject = std::make_shared<jsi::Value>(rt, args[1]);
|
|
225
225
|
|
|
226
226
|
auto task =
|
|
227
|
-
[&rt, dbName, query, params = std::make_shared<std::vector<
|
|
227
|
+
[&rt, dbName, query, params = std::make_shared<std::vector<jsVal>>(params), resolve, reject]()
|
|
228
228
|
{
|
|
229
229
|
try
|
|
230
230
|
{
|
|
@@ -252,8 +252,10 @@ void install(jsi::Runtime &rt, std::shared_ptr<react::CallInvoker> jsCallInvoker
|
|
|
252
252
|
}
|
|
253
253
|
catch (std::exception &exc)
|
|
254
254
|
{
|
|
255
|
-
invoker->invokeAsync([&rt,
|
|
256
|
-
|
|
255
|
+
invoker->invokeAsync([&rt, exc = std::move(exc), reject] {
|
|
256
|
+
auto errorCtr = rt.global().getPropertyAsFunction(rt, "Error");
|
|
257
|
+
auto error = errorCtr.callAsConstructor(rt, jsi::String::createFromAscii(rt, exc.what()));
|
|
258
|
+
reject->asObject(rt).asFunction(rt).call(rt, error);
|
|
257
259
|
});
|
|
258
260
|
}
|
|
259
261
|
};
|
package/cpp/bridge.cpp
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
#include <map>
|
|
9
9
|
#include "logs.h"
|
|
10
10
|
#include "DynamicHostObject.h"
|
|
11
|
+
#include <variant>
|
|
11
12
|
|
|
12
13
|
namespace osp {
|
|
13
14
|
|
|
@@ -199,75 +200,54 @@ BridgeResult sqliteRemoveDb(std::string const dbName, std::string const docPath)
|
|
|
199
200
|
};
|
|
200
201
|
}
|
|
201
202
|
|
|
202
|
-
void bindStatement(sqlite3_stmt *statement, std::vector<
|
|
203
|
+
inline void bindStatement(sqlite3_stmt *statement, std::vector<jsVal> *values)
|
|
203
204
|
{
|
|
204
205
|
size_t size = values->size();
|
|
205
|
-
if (size <= 0)
|
|
206
|
-
{
|
|
207
|
-
return;
|
|
208
|
-
}
|
|
209
206
|
|
|
210
207
|
for (int ii = 0; ii < size; ii++)
|
|
211
208
|
{
|
|
212
209
|
int sqIndex = ii + 1;
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
if (
|
|
210
|
+
jsVal value = values->at(ii);
|
|
211
|
+
|
|
212
|
+
if (std::holds_alternative<bool>(value))
|
|
216
213
|
{
|
|
217
|
-
|
|
214
|
+
sqlite3_bind_int(statement, sqIndex, std::get<bool>(value));
|
|
218
215
|
}
|
|
219
|
-
else if (value
|
|
216
|
+
else if (std::holds_alternative<int>(value))
|
|
220
217
|
{
|
|
221
|
-
sqlite3_bind_int(statement, sqIndex, std::
|
|
218
|
+
sqlite3_bind_int(statement, sqIndex, std::get<int>(value));
|
|
222
219
|
}
|
|
223
|
-
else if (
|
|
220
|
+
else if (std::holds_alternative<long long>(value))
|
|
224
221
|
{
|
|
225
|
-
|
|
222
|
+
sqlite3_bind_double(statement, sqIndex, std::get<long long>(value));
|
|
226
223
|
}
|
|
227
|
-
else if (value
|
|
224
|
+
else if (std::holds_alternative<double>(value))
|
|
228
225
|
{
|
|
229
|
-
sqlite3_bind_double(statement, sqIndex, std::
|
|
226
|
+
sqlite3_bind_double(statement, sqIndex, std::get<double>(value));
|
|
230
227
|
}
|
|
231
|
-
else if (value
|
|
228
|
+
else if (std::holds_alternative<std::string>(value))
|
|
232
229
|
{
|
|
233
|
-
|
|
230
|
+
std::string str = std::get<std::string>(value);
|
|
231
|
+
sqlite3_bind_text(statement, sqIndex, str.c_str(), str.length(), SQLITE_TRANSIENT);
|
|
234
232
|
}
|
|
235
|
-
else if
|
|
233
|
+
else if(std::holds_alternative<JSBuffer>(value))
|
|
236
234
|
{
|
|
237
|
-
|
|
238
|
-
|
|
235
|
+
JSBuffer buffer = std::get<JSBuffer>(value);
|
|
236
|
+
sqlite3_bind_blob(statement, sqIndex, buffer.data.get(), buffer.size, SQLITE_STATIC);
|
|
239
237
|
} else {
|
|
240
|
-
|
|
238
|
+
sqlite3_bind_null(statement, sqIndex);
|
|
241
239
|
}
|
|
242
240
|
// else if (value.type() == typeid(const char*))
|
|
243
241
|
// {
|
|
244
242
|
// sqlite3_bind_text(statement, sqIndex, str.c_str(), str.length(), SQLITE_TRANSIENT);
|
|
245
243
|
// return jsi::String::createFromAscii(rt, std::any_cast<const char*>(value));
|
|
246
244
|
// }
|
|
247
|
-
// TODO Add support for array buffers
|
|
248
|
-
// else if (value.isObject())
|
|
249
|
-
// {
|
|
250
|
-
// auto obj = value.asObject(rt);
|
|
251
|
-
// if(obj.isArrayBuffer(rt)) {
|
|
252
|
-
// auto buf = obj.getArrayBuffer(rt);
|
|
253
|
-
// sqlite3_bind_blob(statement, sqIndex, buf.data(rt), buf.size(rt), SQLITE_STATIC);
|
|
254
|
-
// }
|
|
255
|
-
//
|
|
256
|
-
// else if (dataType == ARRAY_BUFFER)
|
|
257
|
-
// {
|
|
258
|
-
//
|
|
259
|
-
// }
|
|
260
|
-
// sqlite3_bind_blob(statement, sqIndex, value.arrayBufferValue.get(), value.arrayBufferSize, SQLITE_STATIC);
|
|
261
|
-
// }
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
245
|
}
|
|
266
246
|
}
|
|
267
247
|
|
|
268
248
|
BridgeResult sqliteExecute(std::string const dbName,
|
|
269
249
|
std::string const &query,
|
|
270
|
-
std::vector<
|
|
250
|
+
std::vector<jsVal> *params,
|
|
271
251
|
std::vector<std::shared_ptr<DynamicHostObject>> *results,
|
|
272
252
|
std::vector<std::shared_ptr<DynamicHostObject>> *metadatas)
|
|
273
253
|
{
|
|
@@ -287,11 +267,7 @@ BridgeResult sqliteExecute(std::string const dbName,
|
|
|
287
267
|
|
|
288
268
|
int statementStatus = sqlite3_prepare_v2(db, query.c_str(), -1, &statement, NULL);
|
|
289
269
|
|
|
290
|
-
if (statementStatus ==
|
|
291
|
-
{
|
|
292
|
-
bindStatement(statement, params);
|
|
293
|
-
}
|
|
294
|
-
else
|
|
270
|
+
if (statementStatus == SQLITE_ERROR)
|
|
295
271
|
{
|
|
296
272
|
const char *message = sqlite3_errmsg(db);
|
|
297
273
|
return {
|
|
@@ -300,6 +276,8 @@ BridgeResult sqliteExecute(std::string const dbName,
|
|
|
300
276
|
.affectedRows = 0};
|
|
301
277
|
}
|
|
302
278
|
|
|
279
|
+
bindStatement(statement, params);
|
|
280
|
+
|
|
303
281
|
bool isConsuming = true;
|
|
304
282
|
bool isFailed = false;
|
|
305
283
|
|
|
@@ -338,14 +316,14 @@ BridgeResult sqliteExecute(std::string const dbName,
|
|
|
338
316
|
* only represent Integers up to 53 bits
|
|
339
317
|
*/
|
|
340
318
|
double column_value = sqlite3_column_double(statement, i);
|
|
341
|
-
row->fields[column_name] =
|
|
319
|
+
row->fields[column_name] = jsVal(column_value);
|
|
342
320
|
break;
|
|
343
321
|
}
|
|
344
322
|
|
|
345
323
|
case SQLITE_FLOAT:
|
|
346
324
|
{
|
|
347
325
|
double column_value = sqlite3_column_double(statement, i);
|
|
348
|
-
row->fields[column_name] =
|
|
326
|
+
row->fields[column_name] = jsVal(column_value);
|
|
349
327
|
break;
|
|
350
328
|
}
|
|
351
329
|
|
|
@@ -354,7 +332,7 @@ BridgeResult sqliteExecute(std::string const dbName,
|
|
|
354
332
|
const char *column_value = reinterpret_cast<const char *>(sqlite3_column_text(statement, i));
|
|
355
333
|
int byteLen = sqlite3_column_bytes(statement, i);
|
|
356
334
|
// Specify length too; in case string contains NULL in the middle (which SQLite supports!)
|
|
357
|
-
row->fields[column_name] =
|
|
335
|
+
row->fields[column_name] = jsVal(std::string(column_value, byteLen));
|
|
358
336
|
break;
|
|
359
337
|
}
|
|
360
338
|
|
|
@@ -364,8 +342,10 @@ BridgeResult sqliteExecute(std::string const dbName,
|
|
|
364
342
|
const void *blob = sqlite3_column_blob(statement, i);
|
|
365
343
|
uint8_t *data = new uint8_t[blob_size];
|
|
366
344
|
memcpy(data, blob, blob_size);
|
|
367
|
-
|
|
368
|
-
|
|
345
|
+
row->fields[column_name] = jsVal(JSBuffer {
|
|
346
|
+
.data = std::shared_ptr<uint8_t>{data},
|
|
347
|
+
.size = static_cast<size_t>(blob_size)
|
|
348
|
+
});
|
|
369
349
|
break;
|
|
370
350
|
}
|
|
371
351
|
|
|
@@ -373,7 +353,7 @@ BridgeResult sqliteExecute(std::string const dbName,
|
|
|
373
353
|
// Intentionally left blank
|
|
374
354
|
|
|
375
355
|
default:
|
|
376
|
-
row->fields[column_name] =
|
|
356
|
+
row->fields[column_name] = jsVal(NULL);
|
|
377
357
|
break;
|
|
378
358
|
}
|
|
379
359
|
i++;
|
|
@@ -426,7 +406,8 @@ BridgeResult sqliteExecute(std::string const dbName,
|
|
|
426
406
|
return {
|
|
427
407
|
.type = SQLiteOk,
|
|
428
408
|
.affectedRows = changedRowCount,
|
|
429
|
-
.insertId = static_cast<double>(latestInsertRowId)
|
|
409
|
+
.insertId = static_cast<double>(latestInsertRowId)
|
|
410
|
+
};
|
|
430
411
|
}
|
|
431
412
|
|
|
432
413
|
BridgeResult sqliteExecuteLiteral(std::string const dbName, std::string const &query)
|
package/cpp/bridge.h
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
#include "utils.h"
|
|
5
5
|
#include <vector>
|
|
6
6
|
#include "DynamicHostObject.h"
|
|
7
|
+
#include "types.h"
|
|
7
8
|
|
|
8
9
|
namespace osp {
|
|
9
10
|
|
|
@@ -21,7 +22,7 @@ BridgeResult sqliteDetachDb(std::string const mainDBName, std::string const alia
|
|
|
21
22
|
|
|
22
23
|
BridgeResult sqliteExecute(std::string const dbName,
|
|
23
24
|
std::string const &query,
|
|
24
|
-
std::vector<
|
|
25
|
+
std::vector<jsVal> *values,
|
|
25
26
|
std::vector<std::shared_ptr<DynamicHostObject>> *result,
|
|
26
27
|
std::vector<std::shared_ptr<DynamicHostObject>> *metadata);
|
|
27
28
|
|
package/cpp/sqlbatchexecutor.cpp
CHANGED
|
@@ -25,7 +25,7 @@ void toBatchArguments(jsi::Runtime &rt, jsi::Array const &batchParams, std::vect
|
|
|
25
25
|
for (int x = 0; x < batchUpdateParams.length(rt); x++)
|
|
26
26
|
{
|
|
27
27
|
const jsi::Value &p = batchUpdateParams.getValueAtIndex(rt, x);
|
|
28
|
-
auto params = std::make_shared<std::vector<
|
|
28
|
+
auto params = std::make_shared<std::vector<jsVal>>(toAnyVec(rt, p));
|
|
29
29
|
commands->push_back({
|
|
30
30
|
query,
|
|
31
31
|
params
|
|
@@ -34,7 +34,7 @@ void toBatchArguments(jsi::Runtime &rt, jsi::Array const &batchParams, std::vect
|
|
|
34
34
|
}
|
|
35
35
|
else
|
|
36
36
|
{
|
|
37
|
-
auto params = std::make_shared<std::vector<
|
|
37
|
+
auto params = std::make_shared<std::vector<jsVal>>(toAnyVec(rt, commandParams));
|
|
38
38
|
commands->push_back({
|
|
39
39
|
query,
|
|
40
40
|
params
|
package/cpp/sqlbatchexecutor.h
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
#include "utils.h"
|
|
5
5
|
#include "bridge.h"
|
|
6
|
+
#include "types.h"
|
|
6
7
|
|
|
7
8
|
namespace osp {
|
|
8
9
|
|
|
@@ -10,7 +11,7 @@ namespace jsi = facebook::jsi;
|
|
|
10
11
|
|
|
11
12
|
struct BatchArguments {
|
|
12
13
|
std::string sql;
|
|
13
|
-
std::shared_ptr<std::vector<
|
|
14
|
+
std::shared_ptr<std::vector<jsVal>> params;
|
|
14
15
|
};
|
|
15
16
|
|
|
16
17
|
/**
|
package/cpp/types.h
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#ifndef jsVal_h
|
|
2
|
+
#define jsVal_h
|
|
3
|
+
|
|
4
|
+
#include <variant>
|
|
5
|
+
|
|
6
|
+
struct JSBuffer {
|
|
7
|
+
std::shared_ptr<uint8_t> data;
|
|
8
|
+
size_t size;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
using jsVal = std::variant<nullptr_t, bool, int, double, long, long long, std::string, JSBuffer>;
|
|
13
|
+
|
|
14
|
+
#endif /* jsVal_h */
|
package/cpp/utils.cpp
CHANGED
|
@@ -8,14 +8,14 @@ namespace osp {
|
|
|
8
8
|
|
|
9
9
|
namespace jsi = facebook::jsi;
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
jsVal toAny(jsi::Runtime &rt, jsi::Value &value) {
|
|
12
12
|
if (value.isNull() || value.isUndefined())
|
|
13
13
|
{
|
|
14
|
-
return
|
|
14
|
+
return jsVal(nullptr);
|
|
15
15
|
}
|
|
16
16
|
else if (value.isBool())
|
|
17
17
|
{
|
|
18
|
-
return
|
|
18
|
+
return jsVal(value.getBool());
|
|
19
19
|
}
|
|
20
20
|
else if (value.isNumber())
|
|
21
21
|
{
|
|
@@ -24,87 +24,81 @@ std::any toAny(jsi::Runtime &rt, jsi::Value &value) {
|
|
|
24
24
|
long long longVal = (long)doubleVal;
|
|
25
25
|
if (intVal == doubleVal)
|
|
26
26
|
{
|
|
27
|
-
return
|
|
27
|
+
return jsVal(intVal);
|
|
28
28
|
}
|
|
29
29
|
else if (longVal == doubleVal)
|
|
30
30
|
{
|
|
31
|
-
return
|
|
31
|
+
return jsVal(longVal);
|
|
32
32
|
}
|
|
33
33
|
else
|
|
34
34
|
{
|
|
35
|
-
return
|
|
35
|
+
return jsVal(doubleVal);
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
else if (value.isString())
|
|
39
39
|
{
|
|
40
40
|
std::string strVal = value.asString(rt).utf8(rt);
|
|
41
|
-
return
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
// }
|
|
41
|
+
return jsVal(strVal);
|
|
42
|
+
}
|
|
43
|
+
else if (value.isObject())
|
|
44
|
+
{
|
|
45
|
+
auto object = value.asObject(rt);
|
|
46
|
+
if (object.isArrayBuffer(rt))
|
|
47
|
+
{
|
|
48
|
+
auto buffer = object.getArrayBuffer(rt);
|
|
49
|
+
return jsVal(JSBuffer {
|
|
50
|
+
.data = std::shared_ptr<uint8_t>{buffer.data(rt)},
|
|
51
|
+
.size = buffer.size(rt)
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
56
55
|
|
|
57
56
|
throw new std::invalid_argument("Unknown JSI to any value conversion");
|
|
58
57
|
}
|
|
59
58
|
|
|
60
|
-
jsi::Value toJSI(jsi::Runtime &rt,
|
|
61
|
-
const std::type_info &type(value.type());
|
|
59
|
+
jsi::Value toJSI(jsi::Runtime &rt, jsVal value) {
|
|
62
60
|
|
|
63
|
-
if (
|
|
64
|
-
{
|
|
65
|
-
return jsi::Value::null();
|
|
66
|
-
}
|
|
67
|
-
else if (type == typeid(bool))
|
|
61
|
+
if (std::holds_alternative<bool>(value))
|
|
68
62
|
{
|
|
69
|
-
return std::
|
|
63
|
+
return std::get<bool>(value);
|
|
70
64
|
}
|
|
71
|
-
else if (
|
|
65
|
+
else if (std::holds_alternative<int>(value))
|
|
72
66
|
{
|
|
73
|
-
return jsi::Value(std::
|
|
67
|
+
return jsi::Value(std::get<int>(value));
|
|
74
68
|
}
|
|
75
|
-
else if (
|
|
69
|
+
else if (std::holds_alternative<long long>(value))
|
|
76
70
|
{
|
|
77
|
-
return jsi::Value(static_cast<double>(std::
|
|
71
|
+
return jsi::Value(static_cast<double>(std::get<long long>(value)));
|
|
78
72
|
}
|
|
79
|
-
else if (
|
|
73
|
+
else if (std::holds_alternative<double>(value))
|
|
80
74
|
{
|
|
81
|
-
return jsi::Value(std::
|
|
75
|
+
return jsi::Value(std::get<double>(value));
|
|
82
76
|
}
|
|
83
|
-
else if (
|
|
77
|
+
else if (std::holds_alternative<std::string>(value))
|
|
84
78
|
{
|
|
85
|
-
return jsi::String::createFromUtf8(rt, std::
|
|
79
|
+
return jsi::String::createFromUtf8(rt, std::get<std::string>(value));
|
|
86
80
|
}
|
|
87
|
-
else if (
|
|
81
|
+
// else if (std::holds_alternative<const char*>(value))
|
|
82
|
+
// {
|
|
83
|
+
// return jsi::String::createFromAscii(rt, std::get<const char*>(value));
|
|
84
|
+
// }
|
|
85
|
+
else if (std::holds_alternative<JSBuffer>(value))
|
|
88
86
|
{
|
|
89
|
-
|
|
87
|
+
auto jsBuffer = std::get<JSBuffer>(value);
|
|
88
|
+
jsi::Function array_buffer_ctor = rt.global().getPropertyAsFunction(rt, "ArrayBuffer");
|
|
89
|
+
jsi::Object o = array_buffer_ctor.callAsConstructor(rt, (int)jsBuffer.size).getObject(rt);
|
|
90
|
+
jsi::ArrayBuffer buf = o.getArrayBuffer(rt);
|
|
91
|
+
// It's a shame we have to copy here: see https://github.com/facebook/hermes/pull/419 and https://github.com/facebook/hermes/issues/564.
|
|
92
|
+
memcpy(buf.data(rt), jsBuffer.data.get(), jsBuffer.size);
|
|
93
|
+
return buf;
|
|
90
94
|
}
|
|
91
|
-
// TODO Add support for array buffers
|
|
92
|
-
// else if (value.isObject())
|
|
93
|
-
// {
|
|
94
|
-
// auto obj = value.asObject(rt);
|
|
95
|
-
// if(obj.isArrayBuffer(rt)) {
|
|
96
|
-
// auto buf = obj.getArrayBuffer(rt);
|
|
97
|
-
// sqlite3_bind_blob(statement, sqIndex, buf.data(rt), buf.size(rt), SQLITE_STATIC);
|
|
98
|
-
// }
|
|
99
|
-
//
|
|
100
|
-
// }
|
|
101
95
|
|
|
102
|
-
|
|
96
|
+
return jsi::Value::null();
|
|
103
97
|
}
|
|
104
98
|
|
|
105
|
-
std::vector<
|
|
99
|
+
std::vector<jsVal> toAnyVec(jsi::Runtime &rt, jsi::Value const ¶ms)
|
|
106
100
|
{
|
|
107
|
-
std::vector<
|
|
101
|
+
std::vector<jsVal> res;
|
|
108
102
|
|
|
109
103
|
if (params.isNull() || params.isUndefined())
|
|
110
104
|
{
|
package/cpp/utils.h
CHANGED
|
@@ -7,12 +7,15 @@
|
|
|
7
7
|
#include <vector>
|
|
8
8
|
#include <map>
|
|
9
9
|
#include <any>
|
|
10
|
+
#include "types.h"
|
|
10
11
|
#include "DynamicHostObject.h"
|
|
11
12
|
|
|
12
13
|
namespace osp {
|
|
13
14
|
|
|
14
15
|
namespace jsi = facebook::jsi;
|
|
15
16
|
|
|
17
|
+
|
|
18
|
+
|
|
16
19
|
enum ResultType
|
|
17
20
|
{
|
|
18
21
|
SQLiteOk,
|
|
@@ -35,13 +38,11 @@ struct BatchResult
|
|
|
35
38
|
int commands;
|
|
36
39
|
};
|
|
37
40
|
|
|
38
|
-
|
|
41
|
+
jsVal toAny(jsi::Runtime &rt, jsi::Value &value);
|
|
39
42
|
|
|
40
|
-
|
|
41
|
-
// throws an undefined Symbol
|
|
42
|
-
jsi::Value toJSI(jsi::Runtime &rt, std::any value);
|
|
43
|
+
jsi::Value toJSI(jsi::Runtime &rt, jsVal value);
|
|
43
44
|
|
|
44
|
-
std::vector<
|
|
45
|
+
std::vector<jsVal> toAnyVec(jsi::Runtime &rt, jsi::Value const &args);
|
|
45
46
|
|
|
46
47
|
jsi::Value createResult(jsi::Runtime &rt,
|
|
47
48
|
BridgeResult status,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@op-engineering/op-sqlite",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Next generation SQLite for React Native",
|
|
5
5
|
"main": "lib/commonjs/index",
|
|
6
6
|
"module": "lib/module/index",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"android",
|
|
14
14
|
"ios",
|
|
15
15
|
"cpp",
|
|
16
|
-
"op-sqlite.podspec",
|
|
16
|
+
"@op-engineering/op-sqlite.podspec",
|
|
17
17
|
"!lib/typescript/example",
|
|
18
18
|
"!android/build",
|
|
19
19
|
"!android/.cxx",
|
package/op-sqlite.podspec
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
require "json"
|
|
2
|
-
|
|
3
|
-
package = JSON.parse(File.read(File.join(__dir__, "package.json")))
|
|
4
|
-
|
|
5
|
-
Pod::Spec.new do |s|
|
|
6
|
-
s.name = "op-sqlite"
|
|
7
|
-
s.version = package["version"]
|
|
8
|
-
s.summary = package["description"]
|
|
9
|
-
s.homepage = package["homepage"]
|
|
10
|
-
s.license = package["license"]
|
|
11
|
-
s.authors = package["author"]
|
|
12
|
-
|
|
13
|
-
s.platforms = { :ios => "12.0", :osx => "10.7" }
|
|
14
|
-
s.source = { :git => "https://github.com/ospfranco/op-sqlite.git", :tag => "#{s.version}" }
|
|
15
|
-
|
|
16
|
-
s.pod_target_xcconfig = {
|
|
17
|
-
:GCC_PREPROCESSOR_DEFINITIONS => "HAVE_FULLFSYNC=1",
|
|
18
|
-
:WARNING_CFLAGS => "-Wno-shorten-64-to-32 -Wno-comma -Wno-unreachable-code -Wno-conditional-uninitialized -Wno-deprecated-declarations",
|
|
19
|
-
:USE_HEADERMAP => "No"
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
s.header_mappings_dir = "cpp"
|
|
23
|
-
s.source_files = "ios/**/*.{h,hpp,m,mm}", "cpp/**/*.{h,hpp,cpp,c}"
|
|
24
|
-
|
|
25
|
-
s.dependency "React-callinvoker"
|
|
26
|
-
s.dependency "React"
|
|
27
|
-
s.dependency "React-Core"
|
|
28
|
-
|
|
29
|
-
s.xcconfig = {
|
|
30
|
-
'CLANG_CXX_LANGUAGE_STANDARD' => 'c++17',
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
if ENV['OP_SQLITE_USE_PHONE_VERSION'] == '1' then
|
|
35
|
-
s.exclude_files = "cpp/sqlite3.c", "cpp/sqlite3.h"
|
|
36
|
-
s.library = "sqlite3"
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
end
|