@op-engineering/op-sqlite 2.0.7 → 2.0.8
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 +40 -1
- package/cpp/DumbHostObject.cpp +28 -0
- package/cpp/DumbHostObject.h +5 -0
- package/cpp/utils.cpp +43 -0
- package/cpp/utils.h +2 -0
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -119,10 +119,49 @@ const db = open({
|
|
|
119
119
|
db.execute('PRAGMA mmap_size=268435456');
|
|
120
120
|
```
|
|
121
121
|
|
|
122
|
-
|
|
122
|
+
You can also set journaling to memory (or even OFF if you are kinda crazy) to gain even more speed. Journaling is what allows SQLite to ROLLBACK statements and it is dangerous, so do it at your own risk
|
|
123
|
+
|
|
124
|
+
```ts
|
|
125
|
+
db.execute('PRAGMA journal_mode = MEMORY;'); // or OFF
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
If you use [prepared statements](#prepared-statements) plus memory mapping and set journaling to memory, you can get to inches of MMKV for the most performance critical queries, here is a simple example writing/reading a single value.
|
|
123
129
|
|
|
124
130
|

|
|
125
131
|
|
|
132
|
+
# SQLite Gotchas
|
|
133
|
+
|
|
134
|
+
## Strictness
|
|
135
|
+
|
|
136
|
+
It's important to notice SQLite unlike other databases by default does not strictly check for types, if you want true type safety when you declare your tables you need to use the `STRICT` keyword.
|
|
137
|
+
|
|
138
|
+
```ts
|
|
139
|
+
db.execute('CREATE TABLE Test (
|
|
140
|
+
id INT PRIMARY KEY,
|
|
141
|
+
name TEXT
|
|
142
|
+
) STRICT;');
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
If you don't set it, SQLite will happily write whatever you insert in your table, independtly of the declared type.
|
|
146
|
+
|
|
147
|
+
## Foreign constraints
|
|
148
|
+
|
|
149
|
+
When SQLite evaluates your query and you have forgein key constraints, it keeps track of the satisfied relations via a counter. Once your statement finishes executing and the counter is not 0, it throws a foreign key constraint failed error. Unfortunately, this simple design means it is impossible to catch which foreign constraint is failed and you will receive a generic error. Nothing op-sqlite can do about it, it's a design flaw in SQLite.
|
|
150
|
+
|
|
151
|
+
In order to catch foreign key errors, you also need to execute the pragma when you open your connection:
|
|
152
|
+
|
|
153
|
+
```
|
|
154
|
+
PRAGMA foreign_keys = true
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Error codes
|
|
158
|
+
|
|
159
|
+
Sometimes you might be using valid SQL syntax for other engines or you might be doing something else wrong. The errors returned by op-sqlite contain the raw error code returned by SQLite and you should check [the reference](https://www.sqlite.org/rescode.html) for more detailed information.
|
|
160
|
+
|
|
161
|
+
## Quirks
|
|
162
|
+
|
|
163
|
+
See the [full list of SQLite quirks](https://www.sqlite.org/quirks.html).
|
|
164
|
+
|
|
126
165
|
# API
|
|
127
166
|
|
|
128
167
|
```typescript
|
package/cpp/DumbHostObject.cpp
CHANGED
|
@@ -36,7 +36,35 @@ jsi::Value DumbHostObject::get(jsi::Runtime &rt,
|
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
for (auto pairField : ownValues) {
|
|
40
|
+
if (name == pairField.first) {
|
|
41
|
+
return toJSI(rt, pairField.second);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
39
45
|
return {};
|
|
40
46
|
}
|
|
41
47
|
|
|
48
|
+
void DumbHostObject::set(jsi::Runtime &rt, const jsi::PropNameID &name,
|
|
49
|
+
const jsi::Value &value) {
|
|
50
|
+
auto key = name.utf8(rt);
|
|
51
|
+
auto fields = metadata.get();
|
|
52
|
+
for (int i = 0; i < fields->size(); i++) {
|
|
53
|
+
auto fieldName = std::get<std::string>(fields->at(i).fields[0].second);
|
|
54
|
+
if (fieldName == key) {
|
|
55
|
+
values[i] = toVariant(rt, value);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
for (auto pairField : ownValues) {
|
|
61
|
+
if (key == pairField.first) {
|
|
62
|
+
pairField.second = toVariant(rt, value);
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
ownValues.push_back(std::make_pair(key, toVariant(rt, value)));
|
|
68
|
+
}
|
|
69
|
+
|
|
42
70
|
} // namespace opsqlite
|
package/cpp/DumbHostObject.h
CHANGED
|
@@ -23,9 +23,14 @@ public:
|
|
|
23
23
|
|
|
24
24
|
jsi::Value get(jsi::Runtime &rt, const jsi::PropNameID &propNameID);
|
|
25
25
|
|
|
26
|
+
void set(jsi::Runtime &rt, const jsi::PropNameID &name,
|
|
27
|
+
const jsi::Value &value);
|
|
28
|
+
|
|
26
29
|
std::vector<JSVariant> values;
|
|
27
30
|
|
|
28
31
|
std::shared_ptr<std::vector<SmartHostObject>> metadata;
|
|
32
|
+
|
|
33
|
+
std::vector<std::pair<std::string, JSVariant>> ownValues;
|
|
29
34
|
};
|
|
30
35
|
|
|
31
36
|
} // namespace opsqlite
|
package/cpp/utils.cpp
CHANGED
|
@@ -38,6 +38,49 @@ jsi::Value toJSI(jsi::Runtime &rt, JSVariant value) {
|
|
|
38
38
|
return jsi::Value::null();
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
JSVariant toVariant(jsi::Runtime &rt, const jsi::Value &value) {
|
|
42
|
+
if (value.isNull() || value.isUndefined()) {
|
|
43
|
+
return JSVariant(nullptr);
|
|
44
|
+
} else if (value.isBool()) {
|
|
45
|
+
return JSVariant(value.getBool());
|
|
46
|
+
} else if (value.isNumber()) {
|
|
47
|
+
double doubleVal = value.asNumber();
|
|
48
|
+
int intVal = (int)doubleVal;
|
|
49
|
+
long long longVal = (long)doubleVal;
|
|
50
|
+
if (intVal == doubleVal) {
|
|
51
|
+
return JSVariant(intVal);
|
|
52
|
+
} else if (longVal == doubleVal) {
|
|
53
|
+
return JSVariant(longVal);
|
|
54
|
+
} else {
|
|
55
|
+
return JSVariant(doubleVal);
|
|
56
|
+
}
|
|
57
|
+
} else if (value.isString()) {
|
|
58
|
+
std::string strVal = value.asString(rt).utf8(rt);
|
|
59
|
+
return JSVariant(strVal);
|
|
60
|
+
} else if (value.isObject()) {
|
|
61
|
+
auto obj = value.asObject(rt);
|
|
62
|
+
if (obj.isArrayBuffer(rt)) {
|
|
63
|
+
auto buffer = obj.getArrayBuffer(rt);
|
|
64
|
+
|
|
65
|
+
uint8_t *data = new uint8_t[buffer.size(rt)];
|
|
66
|
+
// You cannot share raw memory between native and JS
|
|
67
|
+
// always copy the data
|
|
68
|
+
// see https://github.com/facebook/hermes/pull/419 and
|
|
69
|
+
// https://github.com/facebook/hermes/issues/564.
|
|
70
|
+
memcpy(data, buffer.data(rt), buffer.size(rt));
|
|
71
|
+
|
|
72
|
+
return JSVariant(ArrayBuffer{.data = std::shared_ptr<uint8_t>{data},
|
|
73
|
+
.size = buffer.size(rt)});
|
|
74
|
+
} else {
|
|
75
|
+
throw std::invalid_argument(
|
|
76
|
+
"Unknown JSI ArrayBuffer to variant value conversion, received "
|
|
77
|
+
"object instead of ArrayBuffer");
|
|
78
|
+
}
|
|
79
|
+
} else {
|
|
80
|
+
throw std::invalid_argument("Unknown JSI to variant value conversion");
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
41
84
|
std::vector<JSVariant> toVariantVec(jsi::Runtime &rt,
|
|
42
85
|
jsi::Value const ¶ms) {
|
|
43
86
|
std::vector<JSVariant> res;
|
package/cpp/utils.h
CHANGED
|
@@ -33,6 +33,8 @@ struct BatchResult {
|
|
|
33
33
|
|
|
34
34
|
jsi::Value toJSI(jsi::Runtime &rt, JSVariant value);
|
|
35
35
|
|
|
36
|
+
JSVariant toVariant(jsi::Runtime &rt, jsi::Value const &value);
|
|
37
|
+
|
|
36
38
|
std::vector<JSVariant> toVariantVec(jsi::Runtime &rt, jsi::Value const &args);
|
|
37
39
|
|
|
38
40
|
jsi::Value createResult(jsi::Runtime &rt, BridgeResult status,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@op-engineering/op-sqlite",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.8",
|
|
4
4
|
"description": "Next generation SQLite for React Native",
|
|
5
5
|
"main": "lib/commonjs/index",
|
|
6
6
|
"module": "lib/module/index",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"typescript": "tsc --noEmit",
|
|
27
27
|
"prepare": "bob build",
|
|
28
28
|
"example": "yarn --cwd example",
|
|
29
|
-
"pods": "cd example &&
|
|
29
|
+
"pods": "cd example && yarn pods",
|
|
30
30
|
"bootstrap": "yarn example && yarn && yarn pods",
|
|
31
31
|
"bump": "./bump-version.sh"
|
|
32
32
|
},
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"lefthook": "^1.5.5",
|
|
50
50
|
"react": "18.2.0",
|
|
51
|
-
"react-native": "0.73.
|
|
51
|
+
"react-native": "0.73.1",
|
|
52
52
|
"react-native-builder-bob": "^0.23.2",
|
|
53
53
|
"typescript": "5.0.4"
|
|
54
54
|
},
|