@op-engineering/op-sqlite 1.0.2 → 1.0.3

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 CHANGED
@@ -37,9 +37,9 @@ You can find the [benchmarking code in the example app](https://github.com/OP-En
37
37
  | ------------ | ------------- | ---------- |
38
38
  | quick-sqlite | 2719 | 8851 |
39
39
  | expo-sqlite | 2293 | 10626 |
40
- | op-sqlite | 488 | 981 |
40
+ | op-sqlite | 507 | 1125 |
41
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.
42
+ Memory consumption is also is also 1/4 compared to `react-native-quick-sqlite`. This query used to take 1.2gb of peak memory usage, now runs in 250mbs.
43
43
 
44
44
  # DB Paths
45
45
 
@@ -31,6 +31,8 @@ add_library(
31
31
  ../cpp/sqlbatchexecutor.cpp
32
32
  ../cpp/DynamicHostObject.cpp
33
33
  ../cpp/DynamicHostObject.h
34
+ ../cpp/DumbHostObject.cpp
35
+ ../cpp/DumbHostObject.h
34
36
  ../cpp/macros.h
35
37
  ../cpp/types.h
36
38
  cpp-adapter.cpp
@@ -0,0 +1,37 @@
1
+ #include "DumbHostObject.h"
2
+ #include "utils.h"
3
+ #include <iostream>
4
+
5
+ namespace osp {
6
+
7
+ namespace jsi = facebook::jsi;
8
+
9
+ DumbHostObject::DumbHostObject(std::shared_ptr<std::vector<DynamicHostObject>> metadata) {
10
+ this->metadata = metadata;
11
+ };
12
+
13
+ std::vector<jsi::PropNameID> DumbHostObject::getPropertyNames(jsi::Runtime &rt) {
14
+ std::vector<jsi::PropNameID> keys;
15
+
16
+ for (auto field : *metadata) {
17
+ // TODO improve this by generating the propName once on metadata creation
18
+ keys.push_back(jsi::PropNameID::forAscii(rt, std::get<std::string>(field.fields[0].second)));
19
+ }
20
+
21
+ return keys;
22
+ }
23
+
24
+ jsi::Value DumbHostObject::get(jsi::Runtime &rt, const jsi::PropNameID &propNameID) {
25
+ auto name = propNameID.utf8(rt);
26
+ auto fields = metadata.get();
27
+ for(int i = 0; i < fields->size(); i++) {
28
+ auto fieldName = std::get<std::string>(fields->at(i).fields[0].second);
29
+ if(fieldName == name) {
30
+ return toJSI(rt, values.at(i));
31
+ }
32
+ }
33
+
34
+ return {};
35
+ }
36
+
37
+ }
@@ -0,0 +1,33 @@
1
+ #ifndef DumbHostObject_h
2
+ #define DumbHostObject_h
3
+
4
+ #include <stdio.h>
5
+
6
+ #include <jsi/jsi.h>
7
+ #include <any>
8
+ #include <vector>
9
+ #include "types.h"
10
+ #include "DynamicHostObject.h"
11
+
12
+ namespace osp {
13
+
14
+ namespace jsi = facebook::jsi;
15
+
16
+ class JSI_EXPORT DumbHostObject: public jsi::HostObject {
17
+ public:
18
+ DumbHostObject() {};
19
+
20
+ DumbHostObject(std::shared_ptr<std::vector<DynamicHostObject>> metadata);
21
+
22
+ std::vector<jsi::PropNameID> getPropertyNames(jsi::Runtime &rt);
23
+
24
+ jsi::Value get(jsi::Runtime &rt, const jsi::PropNameID &propNameID);
25
+
26
+ std::vector<jsVal> values;
27
+
28
+ std::shared_ptr<std::vector<DynamicHostObject>> metadata;
29
+ };
30
+
31
+ }
32
+
33
+ #endif /* DumbHostObject_h */
@@ -14,13 +14,10 @@ namespace osp {
14
14
  public:
15
15
  DynamicHostObject() {};
16
16
 
17
- virtual ~DynamicHostObject() {};
18
-
19
17
  std::vector<jsi::PropNameID> getPropertyNames(jsi::Runtime &rt);
20
18
 
21
19
  jsi::Value get(jsi::Runtime &rt, const jsi::PropNameID &propNameID);
22
20
 
23
-
24
21
  std::vector<std::pair<std::string, jsVal>> fields;
25
22
  };
26
23
 
package/cpp/bindings.cpp CHANGED
@@ -8,6 +8,7 @@
8
8
  #include <string>
9
9
  #include "macros.h"
10
10
  #include <iostream>
11
+ #include "DumbHostObject.h"
11
12
 
12
13
  namespace osp {
13
14
 
@@ -188,17 +189,17 @@ void install(jsi::Runtime &rt, std::shared_ptr<react::CallInvoker> jsCallInvoker
188
189
  params = toAnyVec(rt, originalParams);
189
190
  }
190
191
 
191
- std::vector<std::shared_ptr<DynamicHostObject>> results;
192
- std::vector<std::shared_ptr<DynamicHostObject>> metadata;
192
+ std::vector<DumbHostObject> results;
193
+ std::shared_ptr<std::vector<DynamicHostObject>> metadata = std::make_shared<std::vector<DynamicHostObject>>();
193
194
 
194
195
  try {
195
- auto status = sqliteExecute(dbName, query, &params, &results, &metadata);
196
+ auto status = sqliteExecute(dbName, query, &params, &results, metadata);
196
197
 
197
198
  if(status.type == SQLiteError) {
198
199
  throw jsi::JSError(rt, status.message);
199
200
  }
200
201
 
201
- auto jsiResult = createResult(rt, status, &results, &metadata);
202
+ auto jsiResult = createResult(rt, status, &results, metadata);
202
203
  return jsiResult;
203
204
  } catch(std::exception &e) {
204
205
  throw jsi::JSError(rt, e.what());
@@ -228,19 +229,19 @@ void install(jsi::Runtime &rt, std::shared_ptr<react::CallInvoker> jsCallInvoker
228
229
  {
229
230
  try
230
231
  {
231
- std::vector<std::shared_ptr<DynamicHostObject>> results;
232
- std::vector<std::shared_ptr<DynamicHostObject>> metadata;
233
-
234
- auto status = sqliteExecute(dbName, query, params.get(), &results, &metadata);
232
+ std::vector<DumbHostObject> results;
233
+ std::shared_ptr<std::vector<DynamicHostObject>> metadata = std::make_shared<std::vector<DynamicHostObject>>();;
235
234
 
235
+ auto status = sqliteExecute(dbName, query, params.get(), &results, metadata);
236
+
236
237
  invoker->invokeAsync([&rt,
237
- results = std::make_shared<std::vector<std::shared_ptr<DynamicHostObject>>>(results),
238
- metadata = std::make_shared<std::vector<std::shared_ptr<DynamicHostObject>>>(metadata),
238
+ results = std::make_shared<std::vector<DumbHostObject>>(results),
239
+ metadata,
239
240
  status = std::move(status),
240
241
  resolve,
241
242
  reject] {
242
243
  if(status.type == SQLiteOk) {
243
- auto jsiResult = createResult(rt, status, results.get(), metadata.get());
244
+ auto jsiResult = createResult(rt, status, results.get(), metadata);
244
245
  resolve->asObject(rt).asFunction(rt).call(rt, std::move(jsiResult));
245
246
  } else {
246
247
  auto errorCtr = rt.global().getPropertyAsFunction(rt, "Error");
package/cpp/bridge.cpp CHANGED
@@ -8,6 +8,7 @@
8
8
  #include <unordered_map>
9
9
  #include "logs.h"
10
10
  #include "DynamicHostObject.h"
11
+ #include "DumbHostObject.h"
11
12
  #include <variant>
12
13
 
13
14
  namespace osp {
@@ -208,7 +209,7 @@ inline void bindStatement(sqlite3_stmt *statement, std::vector<jsVal> *values)
208
209
  {
209
210
  int sqIndex = ii + 1;
210
211
  jsVal value = values->at(ii);
211
-
212
+
212
213
  if (std::holds_alternative<bool>(value))
213
214
  {
214
215
  sqlite3_bind_int(statement, sqIndex, std::get<bool>(value));
@@ -237,22 +238,22 @@ inline void bindStatement(sqlite3_stmt *statement, std::vector<jsVal> *values)
237
238
  } else {
238
239
  sqlite3_bind_null(statement, sqIndex);
239
240
  }
240
- // else if (value.type() == typeid(const char*))
241
- // {
242
- // sqlite3_bind_text(statement, sqIndex, str.c_str(), str.length(), SQLITE_TRANSIENT);
243
- // return jsi::String::createFromAscii(rt, std::any_cast<const char*>(value));
244
- // }
241
+ // else if (value.type() == typeid(const char*))
242
+ // {
243
+ // sqlite3_bind_text(statement, sqIndex, str.c_str(), str.length(), SQLITE_TRANSIENT);
244
+ // return jsi::String::createFromAscii(rt, std::any_cast<const char*>(value));
245
+ // }
245
246
  }
246
247
  }
247
248
 
248
249
  BridgeResult sqliteExecute(std::string const dbName,
249
- std::string const &query,
250
- std::vector<jsVal> *params,
251
- std::vector<std::shared_ptr<DynamicHostObject>> *results,
252
- std::vector<std::shared_ptr<DynamicHostObject>> *metadatas)
250
+ std::string const &query,
251
+ std::vector<jsVal> *params,
252
+ std::vector<DumbHostObject> *results,
253
+ std::shared_ptr<std::vector<DynamicHostObject>> metadatas)
253
254
  {
254
255
 
255
- if (dbMap.count(dbName) == 0)
256
+ if (dbMap.find(dbName) == dbMap.end())
256
257
  {
257
258
  return {
258
259
  .type = SQLiteError,
@@ -283,7 +284,6 @@ BridgeResult sqliteExecute(std::string const dbName,
283
284
 
284
285
  int result, i, count, column_type;
285
286
  std::string column_name, column_declared_type;
286
- std::shared_ptr<DynamicHostObject> row;
287
287
 
288
288
  while (isConsuming)
289
289
  {
@@ -291,24 +291,23 @@ BridgeResult sqliteExecute(std::string const dbName,
291
291
 
292
292
  switch (result)
293
293
  {
294
- case SQLITE_ROW:
294
+ case SQLITE_ROW: {
295
295
  if(results == NULL)
296
296
  {
297
297
  break;
298
298
  }
299
299
 
300
300
  i = 0;
301
- row = std::make_shared<DynamicHostObject>();
301
+ DumbHostObject row = DumbHostObject(metadatas);
302
+
302
303
  count = sqlite3_column_count(statement);
303
304
 
304
305
  while (i < count)
305
306
  {
306
307
  column_type = sqlite3_column_type(statement, i);
307
- column_name = sqlite3_column_name(statement, i);
308
308
 
309
309
  switch (column_type)
310
310
  {
311
-
312
311
  case SQLITE_INTEGER:
313
312
  {
314
313
  /**
@@ -316,14 +315,14 @@ BridgeResult sqliteExecute(std::string const dbName,
316
315
  * only represent Integers up to 53 bits
317
316
  */
318
317
  double column_value = sqlite3_column_double(statement, i);
319
- row->fields.push_back(std::make_pair(column_name, jsVal(column_value)));
318
+ row.values.push_back(jsVal(column_value));
320
319
  break;
321
320
  }
322
321
 
323
322
  case SQLITE_FLOAT:
324
323
  {
325
324
  double column_value = sqlite3_column_double(statement, i);
326
- row->fields.push_back(std::make_pair(column_name, jsVal(column_value)));
325
+ row.values.push_back(jsVal(column_value));
327
326
  break;
328
327
  }
329
328
 
@@ -332,7 +331,7 @@ BridgeResult sqliteExecute(std::string const dbName,
332
331
  const char *column_value = reinterpret_cast<const char *>(sqlite3_column_text(statement, i));
333
332
  int byteLen = sqlite3_column_bytes(statement, i);
334
333
  // Specify length too; in case string contains NULL in the middle (which SQLite supports!)
335
- row->fields.push_back(std::make_pair(column_name, jsVal(std::string(column_value, byteLen))));
334
+ row.values.push_back(jsVal(std::string(column_value, byteLen)));
336
335
  break;
337
336
  }
338
337
 
@@ -342,42 +341,43 @@ BridgeResult sqliteExecute(std::string const dbName,
342
341
  const void *blob = sqlite3_column_blob(statement, i);
343
342
  uint8_t *data = new uint8_t[blob_size];
344
343
  memcpy(data, blob, blob_size);
345
- row->fields.push_back(std::make_pair(column_name, jsVal(JSBuffer {
344
+ row.values.push_back(jsVal(JSBuffer {
346
345
  .data = std::shared_ptr<uint8_t>{data},
347
346
  .size = static_cast<size_t>(blob_size)
348
- })));
347
+ }));
349
348
  break;
350
349
  }
351
350
 
352
351
  case SQLITE_NULL:
353
352
  // Intentionally left blank
354
-
353
+
355
354
  default:
356
- row->fields.push_back(std::make_pair(column_name, jsVal(NULL)));
355
+ row.values.push_back(jsVal(NULL));
357
356
  break;
358
357
  }
359
358
  i++;
360
359
  }
361
360
  results->push_back(row);
362
361
  break;
363
-
362
+ }
363
+
364
364
  case SQLITE_DONE:
365
- if(metadatas != nullptr)
365
+ i = 0;
366
+ count = sqlite3_column_count(statement);
367
+
368
+ while (i < count)
366
369
  {
367
- i = 0;
368
- count = sqlite3_column_count(statement);
369
- while (i < count)
370
- {
371
- column_name = sqlite3_column_name(statement, i);
372
- const char *type = sqlite3_column_decltype(statement, i);
373
- auto metadata = std::make_shared<DynamicHostObject>();
374
- metadata->fields.push_back(std::make_pair("name", column_name));
375
- metadata->fields.push_back(std::make_pair("index", i));
376
- metadata->fields.push_back(std::make_pair("type", type));
377
-
378
- i++;
379
- }
370
+ column_name = sqlite3_column_name(statement, i);
371
+ const char *type = sqlite3_column_decltype(statement, i);
372
+ auto metadata = DynamicHostObject();
373
+ metadata.fields.push_back(std::make_pair("name", column_name));
374
+ metadata.fields.push_back(std::make_pair("index", i));
375
+ metadata.fields.push_back(std::make_pair("type", type));
376
+
377
+ metadatas->push_back(metadata);
378
+ i++;
380
379
  }
380
+
381
381
  isConsuming = false;
382
382
  break;
383
383
 
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 "DumbHostObject.h"
7
8
  #include "types.h"
8
9
 
9
10
  namespace osp {
@@ -23,8 +24,8 @@ BridgeResult sqliteDetachDb(std::string const mainDBName, std::string const alia
23
24
  BridgeResult sqliteExecute(std::string const dbName,
24
25
  std::string const &query,
25
26
  std::vector<jsVal> *values,
26
- std::vector<std::shared_ptr<DynamicHostObject>> *result,
27
- std::vector<std::shared_ptr<DynamicHostObject>> *metadata);
27
+ std::vector<DumbHostObject> *results,
28
+ std::shared_ptr<std::vector<DynamicHostObject>> metadatas);
28
29
 
29
30
  BridgeResult sqliteExecuteLiteral(std::string const dbName, std::string const &query);
30
31
 
package/cpp/utils.cpp CHANGED
@@ -118,8 +118,8 @@ std::vector<jsVal> toAnyVec(jsi::Runtime &rt, jsi::Value const &params)
118
118
 
119
119
  jsi::Value createResult(jsi::Runtime &rt,
120
120
  BridgeResult status,
121
- std::vector<std::shared_ptr<DynamicHostObject>> *results,
122
- std::vector<std::shared_ptr<DynamicHostObject>> *metadata)
121
+ std::vector<DumbHostObject> *results,
122
+ std::shared_ptr<std::vector<DynamicHostObject>> metadata)
123
123
  {
124
124
  if(status.type == SQLiteError) {
125
125
  throw std::invalid_argument(status.message);
@@ -142,7 +142,8 @@ jsi::Value createResult(jsi::Runtime &rt,
142
142
  auto array = jsi::Array(rt, rowCount);
143
143
  for (int i = 0; i < rowCount; i++)
144
144
  {
145
- array.setValueAtIndex(rt, i, jsi::Object::createFromHostObject(rt, results->at(i)));
145
+ auto obj = results->at(i);
146
+ array.setValueAtIndex(rt, i, jsi::Object::createFromHostObject(rt, std::make_shared<DumbHostObject>(obj)));
146
147
  }
147
148
  rows.setProperty(rt, "_array", std::move(array));
148
149
  res.setProperty(rt, "rows", std::move(rows));
@@ -154,7 +155,7 @@ jsi::Value createResult(jsi::Runtime &rt,
154
155
  auto column_array = jsi::Array(rt, column_count);
155
156
  for (int i = 0; i < column_count; i++) {
156
157
  auto column = metadata->at(i);
157
- column_array.setValueAtIndex(rt, i, jsi::Object::createFromHostObject(rt, column));
158
+ column_array.setValueAtIndex(rt, i, jsi::Object::createFromHostObject(rt, std::make_shared<DynamicHostObject>(column)));
158
159
  }
159
160
  res.setProperty(rt, "metadata", std::move(column_array));
160
161
  }
package/cpp/utils.h CHANGED
@@ -9,6 +9,7 @@
9
9
  #include <any>
10
10
  #include "types.h"
11
11
  #include "DynamicHostObject.h"
12
+ #include "DumbHostObject.h"
12
13
 
13
14
  namespace osp {
14
15
 
@@ -46,8 +47,8 @@ std::vector<jsVal> toAnyVec(jsi::Runtime &rt, jsi::Value const &args);
46
47
 
47
48
  jsi::Value createResult(jsi::Runtime &rt,
48
49
  BridgeResult status,
49
- std::vector<std::shared_ptr<DynamicHostObject>> *results,
50
- std::vector<std::shared_ptr<DynamicHostObject>> *metadata);
50
+ std::vector<DumbHostObject> *results,
51
+ std::shared_ptr<std::vector<DynamicHostObject>> metadata);
51
52
 
52
53
  BatchResult importSQLFile(std::string dbName, std::string fileLocation);
53
54
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@op-engineering/op-sqlite",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "Next generation SQLite for React Native",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",