@op-engineering/op-sqlite 7.3.0 → 8.0.0-beta0

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.
Files changed (53) hide show
  1. package/README.md +11 -3
  2. package/android/CMakeLists.txt +6 -0
  3. package/android/build.gradle +20 -1
  4. package/android/cpp-adapter.cpp +1 -1
  5. package/android/src/main/jniLibs/arm64-v8a/libsqlite_vec.so +0 -0
  6. package/android/src/main/jniLibs/armeabi-v7a/libsqlite_vec.so +0 -0
  7. package/android/src/main/jniLibs/x86/libsqlite_vec.so +0 -0
  8. package/android/src/main/jniLibs/x86_64/libsqlite_vec.so +0 -0
  9. package/cpp/DBHostObject.cpp +104 -107
  10. package/cpp/DBHostObject.h +1 -1
  11. package/cpp/PreparedStatementHostObject.cpp +39 -14
  12. package/cpp/PreparedStatementHostObject.h +17 -4
  13. package/cpp/bindings.cpp +12 -9
  14. package/cpp/bindings.h +2 -1
  15. package/cpp/bridge.cpp +229 -91
  16. package/cpp/bridge.h +13 -9
  17. package/cpp/libsql/bridge.cpp +212 -92
  18. package/cpp/libsql/bridge.h +7 -3
  19. package/cpp/macros.h +2 -2
  20. package/cpp/types.h +11 -8
  21. package/cpp/utils.cpp +43 -7
  22. package/cpp/utils.h +2 -0
  23. package/ios/OPSQLite.mm +15 -5
  24. package/ios/sqlitevec.xcframework/Info.plist +46 -0
  25. package/ios/sqlitevec.xcframework/ios-arm64/sqlitevec.framework/Info.plist +24 -0
  26. package/ios/sqlitevec.xcframework/ios-arm64/sqlitevec.framework/sqlitevec +0 -0
  27. package/ios/sqlitevec.xcframework/ios-arm64_x86_64-simulator/sqlitevec.framework/Info.plist +24 -0
  28. package/ios/sqlitevec.xcframework/ios-arm64_x86_64-simulator/sqlitevec.framework/sqlitevec +0 -0
  29. package/lib/commonjs/index.js +53 -30
  30. package/lib/commonjs/index.js.map +1 -1
  31. package/lib/commonjs/package.json +1 -0
  32. package/lib/module/NativeOPSQLite.js +2 -0
  33. package/lib/module/NativeOPSQLite.js.map +1 -1
  34. package/lib/module/index.js +55 -29
  35. package/lib/module/index.js.map +1 -1
  36. package/lib/module/package.json +1 -0
  37. package/lib/typescript/commonjs/package.json +1 -0
  38. package/lib/typescript/commonjs/src/NativeOPSQLite.d.ts.map +1 -0
  39. package/lib/typescript/{src → commonjs/src}/index.d.ts +11 -11
  40. package/lib/typescript/commonjs/src/index.d.ts.map +1 -0
  41. package/lib/typescript/module/package.json +1 -0
  42. package/lib/typescript/module/src/NativeOPSQLite.d.ts +15 -0
  43. package/lib/typescript/module/src/NativeOPSQLite.d.ts.map +1 -0
  44. package/lib/typescript/module/src/index.d.ts +163 -0
  45. package/lib/typescript/module/src/index.d.ts.map +1 -0
  46. package/op-sqlite.podspec +13 -4
  47. package/package.json +45 -15
  48. package/src/index.ts +80 -46
  49. package/android/.project +0 -17
  50. package/android/.settings/org.eclipse.buildship.core.prefs +0 -13
  51. package/lib/typescript/src/NativeOPSQLite.d.ts.map +0 -1
  52. package/lib/typescript/src/index.d.ts.map +0 -1
  53. /package/lib/typescript/{src → commonjs/src}/NativeOPSQLite.d.ts +0 -0
package/cpp/bridge.cpp CHANGED
@@ -51,12 +51,14 @@ std::string opsqlite_get_db_path(std::string const &db_name,
51
51
  #ifdef OP_SQLITE_USE_SQLCIPHER
52
52
  BridgeResult opsqlite_open(std::string const &dbName,
53
53
  std::string const &last_path,
54
- std::string const &crsqlitePath,
54
+ std::string const &crsqlite_path,
55
+ std::string const &sqlite_vec_path,
55
56
  std::string const &encryptionKey) {
56
57
  #else
57
58
  BridgeResult opsqlite_open(std::string const &dbName,
58
59
  std::string const &last_path,
59
- std::string const &crsqlitePath) {
60
+ std::string const &crsqlite_path,
61
+ std::string const &sqlite_vec_path) {
60
62
  #endif
61
63
  std::string dbPath = opsqlite_get_db_path(dbName, last_path);
62
64
 
@@ -74,17 +76,18 @@ BridgeResult opsqlite_open(std::string const &dbName,
74
76
  dbMap[dbName] = db;
75
77
 
76
78
  #ifdef OP_SQLITE_USE_SQLCIPHER
77
- opsqlite_execute(dbName, "PRAGMA key = '" + encryptionKey + "'", nullptr,
78
- nullptr, nullptr);
79
+ opsqlite_execute(dbName, "PRAGMA key = '" + encryptionKey + "'", nullptr);
79
80
  #endif
80
81
 
81
- #ifdef OP_SQLITE_USE_CRSQLITE
82
+ sqlite3_enable_load_extension(db, 1);
83
+
82
84
  char *errMsg;
83
- const char *crsqliteEntryPoint = "sqlite3_crsqlite_init";
84
85
 
85
- sqlite3_enable_load_extension(db, 1);
86
+ #ifdef OP_SQLITE_USE_CRSQLITE
87
+ const char *crsqliteEntryPoint = "sqlite3_crsqlite_init";
86
88
 
87
- sqlite3_load_extension(db, crsqlitePath.c_str(), crsqliteEntryPoint, &errMsg);
89
+ sqlite3_load_extension(db, crsqlite_path.c_str(), crsqliteEntryPoint,
90
+ &errMsg);
88
91
 
89
92
  if (errMsg != nullptr) {
90
93
  return {.type = SQLiteError, .message = errMsg};
@@ -93,6 +96,19 @@ BridgeResult opsqlite_open(std::string const &dbName,
93
96
  }
94
97
  #endif
95
98
 
99
+ #ifdef OP_SQLITE_USE_SQLITE_VEC
100
+ const char *vec_entry_point = "sqlite3_vec_init";
101
+
102
+ sqlite3_load_extension(db, sqlite_vec_path.c_str(), vec_entry_point, &errMsg);
103
+
104
+ if (errMsg != nullptr) {
105
+ return {.type = SQLiteError, .message = errMsg};
106
+ } else {
107
+ LOGI("Loaded sqlite-vec successfully");
108
+ }
109
+
110
+ #endif
111
+
96
112
  return {.type = SQLiteOk, .affectedRows = 0};
97
113
  }
98
114
 
@@ -103,8 +119,7 @@ BridgeResult opsqlite_close(std::string const &dbName) {
103
119
  sqlite3 *db = dbMap[dbName];
104
120
 
105
121
  #ifdef OP_SQLITE_USE_CRSQLITE
106
- opsqlite_execute(dbName, "select crsql_finalize();", nullptr, nullptr,
107
- nullptr);
122
+ opsqlite_execute(dbName, "select crsql_finalize();", nullptr);
108
123
  #endif
109
124
 
110
125
  sqlite3_close_v2(db);
@@ -123,8 +138,7 @@ BridgeResult opsqlite_attach(std::string const &mainDBName,
123
138
  std::string dbPath = opsqlite_get_db_path(databaseToAttach, docPath);
124
139
  std::string statement = "ATTACH DATABASE '" + dbPath + "' AS " + alias;
125
140
 
126
- BridgeResult result =
127
- opsqlite_execute(mainDBName, statement, nullptr, nullptr, nullptr);
141
+ BridgeResult result = opsqlite_execute(mainDBName, statement, nullptr);
128
142
 
129
143
  if (result.type == SQLiteError) {
130
144
  return {
@@ -141,8 +155,7 @@ BridgeResult opsqlite_attach(std::string const &mainDBName,
141
155
  BridgeResult opsqlite_detach(std::string const &mainDBName,
142
156
  std::string const &alias) {
143
157
  std::string statement = "DETACH DATABASE " + alias;
144
- BridgeResult result =
145
- opsqlite_execute(mainDBName, statement, nullptr, nullptr, nullptr);
158
+ BridgeResult result = opsqlite_execute(mainDBName, statement, nullptr);
146
159
  if (result.type == SQLiteError) {
147
160
  return BridgeResult{
148
161
  .type = SQLiteError,
@@ -189,22 +202,22 @@ inline void opsqlite_bind_statement(sqlite3_stmt *statement,
189
202
  int sqIndex = ii + 1;
190
203
  JSVariant value = values->at(ii);
191
204
 
192
- if (std::holds_alternative<bool>(value)) {
193
- sqlite3_bind_int(statement, sqIndex, std::get<bool>(value));
194
- } else if (std::holds_alternative<int>(value)) {
205
+ if (std::holds_alternative<bool>(value) ||
206
+ std::holds_alternative<int>(value)) {
195
207
  sqlite3_bind_int(statement, sqIndex, std::get<int>(value));
196
208
  } else if (std::holds_alternative<long long>(value)) {
197
- sqlite3_bind_double(statement, sqIndex, std::get<long long>(value));
209
+ sqlite3_bind_double(statement, sqIndex,
210
+ static_cast<double>(std::get<long long>(value)));
198
211
  } else if (std::holds_alternative<double>(value)) {
199
212
  sqlite3_bind_double(statement, sqIndex, std::get<double>(value));
200
213
  } else if (std::holds_alternative<std::string>(value)) {
201
214
  std::string str = std::get<std::string>(value);
202
- sqlite3_bind_text(statement, sqIndex, str.c_str(), str.length(),
203
- SQLITE_TRANSIENT);
215
+ sqlite3_bind_text(statement, sqIndex, str.c_str(),
216
+ static_cast<int>(str.length()), SQLITE_TRANSIENT);
204
217
  } else if (std::holds_alternative<ArrayBuffer>(value)) {
205
218
  ArrayBuffer buffer = std::get<ArrayBuffer>(value);
206
- sqlite3_bind_blob(statement, sqIndex, buffer.data.get(), buffer.size,
207
- SQLITE_TRANSIENT);
219
+ sqlite3_bind_blob(statement, sqIndex, buffer.data.get(),
220
+ static_cast<int>(buffer.size), SQLITE_TRANSIENT);
208
221
  } else {
209
222
  sqlite3_bind_null(statement, sqIndex);
210
223
  }
@@ -214,7 +227,7 @@ inline void opsqlite_bind_statement(sqlite3_stmt *statement,
214
227
  BridgeResult opsqlite_execute_prepared_statement(
215
228
  std::string const &dbName, sqlite3_stmt *statement,
216
229
  std::vector<DumbHostObject> *results,
217
- std::shared_ptr<std::vector<SmartHostObject>> metadatas) {
230
+ std::shared_ptr<std::vector<SmartHostObject>> &metadatas) {
218
231
 
219
232
  check_db_open(dbName);
220
233
 
@@ -227,8 +240,6 @@ BridgeResult opsqlite_execute_prepared_statement(
227
240
 
228
241
  int result = SQLITE_OK;
229
242
 
230
- isConsuming = true;
231
-
232
243
  int i, count, column_type;
233
244
  std::string column_name, column_declared_type;
234
245
 
@@ -237,7 +248,7 @@ BridgeResult opsqlite_execute_prepared_statement(
237
248
 
238
249
  switch (result) {
239
250
  case SQLITE_ROW: {
240
- if (results == NULL) {
251
+ if (results == nullptr) {
241
252
  break;
242
253
  }
243
254
 
@@ -256,13 +267,13 @@ BridgeResult opsqlite_execute_prepared_statement(
256
267
  * only represent Integers up to 53 bits
257
268
  */
258
269
  double column_value = sqlite3_column_double(statement, i);
259
- row.values.push_back(JSVariant(column_value));
270
+ row.values.emplace_back(column_value);
260
271
  break;
261
272
  }
262
273
 
263
274
  case SQLITE_FLOAT: {
264
275
  double column_value = sqlite3_column_double(statement, i);
265
- row.values.push_back(JSVariant(column_value));
276
+ row.values.emplace_back(column_value);
266
277
  break;
267
278
  }
268
279
 
@@ -271,20 +282,20 @@ BridgeResult opsqlite_execute_prepared_statement(
271
282
  reinterpret_cast<const char *>(sqlite3_column_text(statement, i));
272
283
  int byteLen = sqlite3_column_bytes(statement, i);
273
284
  // Specify length too; in case string contains NULL in the middle
274
- row.values.push_back(JSVariant(std::string(column_value, byteLen)));
285
+ row.values.emplace_back(std::string(column_value, byteLen));
275
286
  break;
276
287
  }
277
288
 
278
289
  case SQLITE_BLOB: {
279
290
  int blob_size = sqlite3_column_bytes(statement, i);
280
291
  const void *blob = sqlite3_column_blob(statement, i);
281
- uint8_t *data = new uint8_t[blob_size];
292
+ auto *data = new uint8_t[blob_size];
282
293
  // You cannot share raw memory between native and JS
283
294
  // always copy the data
284
295
  memcpy(data, blob, blob_size);
285
- row.values.push_back(
286
- JSVariant(ArrayBuffer{.data = std::shared_ptr<uint8_t>{data},
287
- .size = static_cast<size_t>(blob_size)}));
296
+ row.values.emplace_back(
297
+ ArrayBuffer{.data = std::shared_ptr<uint8_t>{data},
298
+ .size = static_cast<size_t>(blob_size)});
288
299
  break;
289
300
  }
290
301
 
@@ -292,14 +303,16 @@ BridgeResult opsqlite_execute_prepared_statement(
292
303
  // Intentionally left blank
293
304
 
294
305
  default:
295
- row.values.push_back(JSVariant(nullptr));
306
+ row.values.emplace_back(nullptr);
296
307
  break;
297
308
  }
298
309
  i++;
299
310
  }
311
+
300
312
  if (results != nullptr) {
301
313
  results->push_back(row);
302
314
  }
315
+
303
316
  break;
304
317
  }
305
318
 
@@ -312,10 +325,10 @@ BridgeResult opsqlite_execute_prepared_statement(
312
325
  column_name = sqlite3_column_name(statement, i);
313
326
  const char *type = sqlite3_column_decltype(statement, i);
314
327
  auto metadata = SmartHostObject();
315
- metadata.fields.push_back(std::make_pair("name", column_name));
316
- metadata.fields.push_back(std::make_pair("index", i));
317
- metadata.fields.push_back(
318
- std::make_pair("type", type == NULL ? "UNKNOWN" : type));
328
+ metadata.fields.emplace_back("name", column_name);
329
+ metadata.fields.emplace_back("index", i);
330
+ metadata.fields.emplace_back("type",
331
+ type == nullptr ? "UNKNOWN" : type);
319
332
 
320
333
  metadatas->push_back(metadata);
321
334
  i++;
@@ -357,7 +370,8 @@ sqlite3_stmt *opsqlite_prepare_statement(std::string const &dbName,
357
370
 
358
371
  const char *queryStr = query.c_str();
359
372
 
360
- int statementStatus = sqlite3_prepare_v2(db, queryStr, -1, &statement, NULL);
373
+ int statementStatus =
374
+ sqlite3_prepare_v2(db, queryStr, -1, &statement, nullptr);
361
375
 
362
376
  if (statementStatus == SQLITE_ERROR) {
363
377
  const char *message = sqlite3_errmsg(db);
@@ -368,12 +382,144 @@ sqlite3_stmt *opsqlite_prepare_statement(std::string const &dbName,
368
382
  return statement;
369
383
  }
370
384
 
385
+ BridgeResult opsqlite_execute(std::string const &name, std::string const &query,
386
+ const std::vector<JSVariant> *params) {
387
+ check_db_open(name);
388
+
389
+ sqlite3 *db = dbMap[name];
390
+
391
+ sqlite3_stmt *statement;
392
+ const char *errorMessage;
393
+ const char *remainingStatement = nullptr;
394
+
395
+ bool isFailed = false;
396
+ int step_result, current_column, column_count, column_type;
397
+ std::string column_name, column_declared_type;
398
+ std::vector<std::string> column_names;
399
+ std::vector<std::vector<JSVariant>> rows;
400
+ std::vector<JSVariant> row;
401
+
402
+ do {
403
+ const char *queryStr =
404
+ remainingStatement == nullptr ? query.c_str() : remainingStatement;
405
+
406
+ int statementStatus =
407
+ sqlite3_prepare_v2(db, queryStr, -1, &statement, &remainingStatement);
408
+
409
+ if (statementStatus != SQLITE_OK) {
410
+ errorMessage = sqlite3_errmsg(db);
411
+ return {.type = SQLiteError,
412
+ .message =
413
+ "[op-sqlite] SQL prepare error: " + std::string(errorMessage),
414
+ .affectedRows = 0};
415
+ }
416
+
417
+ if (params != nullptr && !params->empty()) {
418
+ opsqlite_bind_statement(statement, params);
419
+ }
420
+
421
+ column_count = sqlite3_column_count(statement);
422
+ bool is_consuming = true;
423
+ // Do a first pass to get the column names
424
+ for (int i = 0; i < column_count; i++) {
425
+ column_name = sqlite3_column_name(statement, i);
426
+ column_names.push_back(column_name);
427
+ }
428
+
429
+ double double_value;
430
+ const char *string_value;
431
+ while (is_consuming) {
432
+ step_result = sqlite3_step(statement);
433
+
434
+ switch (step_result) {
435
+ case SQLITE_ROW:
436
+ current_column = 0;
437
+ row = std::vector<JSVariant>();
438
+ column_count = sqlite3_column_count(statement);
439
+
440
+ while (current_column < column_count) {
441
+ column_type = sqlite3_column_type(statement, current_column);
442
+
443
+ switch (column_type) {
444
+
445
+ case SQLITE_INTEGER:
446
+ // intentional fallthrough
447
+ case SQLITE_FLOAT: {
448
+ double_value = sqlite3_column_double(statement, current_column);
449
+ row.emplace_back(double_value);
450
+ break;
451
+ }
452
+
453
+ case SQLITE_TEXT: {
454
+ string_value = reinterpret_cast<const char *>(
455
+ sqlite3_column_text(statement, current_column));
456
+ int byteLen = sqlite3_column_bytes(statement, current_column);
457
+ // Specify length too; in case string contains NULL in the middle
458
+ row.emplace_back(std::string(string_value, byteLen));
459
+ break;
460
+ }
461
+
462
+ case SQLITE_BLOB: {
463
+ int blob_size = sqlite3_column_bytes(statement, current_column);
464
+ const void *blob = sqlite3_column_blob(statement, current_column);
465
+ auto *data = new uint8_t[blob_size];
466
+ memcpy(data, blob, blob_size);
467
+ row.emplace_back(
468
+ ArrayBuffer{.data = std::shared_ptr<uint8_t>{data},
469
+ .size = static_cast<size_t>(blob_size)});
470
+ break;
471
+ }
472
+
473
+ case SQLITE_NULL:
474
+ // Intentionally left blank to switch to default case
475
+ default:
476
+ row.emplace_back(nullptr);
477
+ break;
478
+ }
479
+
480
+ current_column++;
481
+ }
482
+
483
+ rows.push_back(row);
484
+ break;
485
+
486
+ case SQLITE_DONE:
487
+ is_consuming = false;
488
+ break;
489
+
490
+ default:
491
+ isFailed = true;
492
+ is_consuming = false;
493
+ }
494
+ }
495
+
496
+ sqlite3_finalize(statement);
497
+ } while (remainingStatement != nullptr &&
498
+ strcmp(remainingStatement, "") != 0 && !isFailed);
499
+
500
+ if (isFailed) {
501
+ const char *message = sqlite3_errmsg(db);
502
+ return {.type = SQLiteError,
503
+ .message =
504
+ "[op-sqlite] SQL execution error: " + std::string(message),
505
+ .affectedRows = 0,
506
+ .insertId = 0};
507
+ }
508
+
509
+ int changedRowCount = sqlite3_changes(db);
510
+ long long latestInsertRowId = sqlite3_last_insert_rowid(db);
511
+ return {.type = SQLiteOk,
512
+ .affectedRows = changedRowCount,
513
+ .insertId = static_cast<double>(latestInsertRowId),
514
+ .rows = std::move(rows),
515
+ .column_names = std::move(column_names)};
516
+ }
517
+
371
518
  /// Base execution function, returns HostObjects to the JS environment
372
- BridgeResult
373
- opsqlite_execute(std::string const &dbName, std::string const &query,
374
- const std::vector<JSVariant> *params,
375
- std::vector<DumbHostObject> *results,
376
- std::shared_ptr<std::vector<SmartHostObject>> metadatas) {
519
+ BridgeResult opsqlite_execute_host_objects(
520
+ std::string const &dbName, std::string const &query,
521
+ const std::vector<JSVariant> *params, std::vector<DumbHostObject> *results,
522
+ std::shared_ptr<std::vector<SmartHostObject>> &metadatas) {
377
523
 
378
524
  check_db_open(dbName);
379
525
 
@@ -406,16 +552,14 @@ opsqlite_execute(std::string const &dbName, std::string const &query,
406
552
 
407
553
  // The statement did not fail to parse but there is nothing to do, just
408
554
  // skip to the end
409
- if (statement == NULL) {
555
+ if (statement == nullptr) {
410
556
  continue;
411
557
  }
412
558
 
413
- if (params != nullptr && params->size() > 0) {
559
+ if (params != nullptr && !params->empty()) {
414
560
  opsqlite_bind_statement(statement, params);
415
561
  }
416
562
 
417
- isConsuming = true;
418
-
419
563
  int i, count, column_type;
420
564
  std::string column_name, column_declared_type;
421
565
 
@@ -424,7 +568,7 @@ opsqlite_execute(std::string const &dbName, std::string const &query,
424
568
 
425
569
  switch (result) {
426
570
  case SQLITE_ROW: {
427
- if (results == NULL) {
571
+ if (results == nullptr) {
428
572
  break;
429
573
  }
430
574
 
@@ -443,13 +587,13 @@ opsqlite_execute(std::string const &dbName, std::string const &query,
443
587
  * only represent Integers up to 53 bits
444
588
  */
445
589
  double column_value = sqlite3_column_double(statement, i);
446
- row.values.push_back(JSVariant(column_value));
590
+ row.values.emplace_back(column_value);
447
591
  break;
448
592
  }
449
593
 
450
594
  case SQLITE_FLOAT: {
451
595
  double column_value = sqlite3_column_double(statement, i);
452
- row.values.push_back(JSVariant(column_value));
596
+ row.values.emplace_back(column_value);
453
597
  break;
454
598
  }
455
599
 
@@ -458,20 +602,20 @@ opsqlite_execute(std::string const &dbName, std::string const &query,
458
602
  sqlite3_column_text(statement, i));
459
603
  int byteLen = sqlite3_column_bytes(statement, i);
460
604
  // Specify length too; in case string contains NULL in the middle
461
- row.values.push_back(JSVariant(std::string(column_value, byteLen)));
605
+ row.values.emplace_back(std::string(column_value, byteLen));
462
606
  break;
463
607
  }
464
608
 
465
609
  case SQLITE_BLOB: {
466
610
  int blob_size = sqlite3_column_bytes(statement, i);
467
611
  const void *blob = sqlite3_column_blob(statement, i);
468
- uint8_t *data = new uint8_t[blob_size];
612
+ auto *data = new uint8_t[blob_size];
469
613
  // You cannot share raw memory between native and JS
470
614
  // always copy the data
471
615
  memcpy(data, blob, blob_size);
472
- row.values.push_back(
473
- JSVariant(ArrayBuffer{.data = std::shared_ptr<uint8_t>{data},
474
- .size = static_cast<size_t>(blob_size)}));
616
+ row.values.emplace_back(
617
+ ArrayBuffer{.data = std::shared_ptr<uint8_t>{data},
618
+ .size = static_cast<size_t>(blob_size)});
475
619
  break;
476
620
  }
477
621
 
@@ -479,7 +623,7 @@ opsqlite_execute(std::string const &dbName, std::string const &query,
479
623
  // Intentionally left blank
480
624
 
481
625
  default:
482
- row.values.push_back(JSVariant(nullptr));
626
+ row.values.emplace_back(nullptr);
483
627
  break;
484
628
  }
485
629
  i++;
@@ -499,10 +643,10 @@ opsqlite_execute(std::string const &dbName, std::string const &query,
499
643
  column_name = sqlite3_column_name(statement, i);
500
644
  const char *type = sqlite3_column_decltype(statement, i);
501
645
  auto metadata = SmartHostObject();
502
- metadata.fields.push_back(std::make_pair("name", column_name));
503
- metadata.fields.push_back(std::make_pair("index", i));
504
- metadata.fields.push_back(
505
- std::make_pair("type", type == NULL ? "UNKNOWN" : type));
646
+ metadata.fields.emplace_back("name", column_name);
647
+ metadata.fields.emplace_back("index", i);
648
+ metadata.fields.emplace_back("type",
649
+ type == nullptr ? "UNKNOWN" : type);
506
650
 
507
651
  metadatas->push_back(metadata);
508
652
  i++;
@@ -519,8 +663,8 @@ opsqlite_execute(std::string const &dbName, std::string const &query,
519
663
  }
520
664
 
521
665
  sqlite3_finalize(statement);
522
- } while (remainingStatement != NULL && strcmp(remainingStatement, "") != 0 &&
523
- !isFailed);
666
+ } while (remainingStatement != nullptr &&
667
+ strcmp(remainingStatement, "") != 0 && !isFailed);
524
668
 
525
669
  if (isFailed) {
526
670
 
@@ -577,16 +721,14 @@ opsqlite_execute_raw(std::string const &dbName, std::string const &query,
577
721
 
578
722
  // The statement did not fail to parse but there is nothing to do, just
579
723
  // skip to the end
580
- if (statement == NULL) {
724
+ if (statement == nullptr) {
581
725
  continue;
582
726
  }
583
727
 
584
- if (params != nullptr && params->size() > 0) {
728
+ if (params != nullptr && !params->empty()) {
585
729
  opsqlite_bind_statement(statement, params);
586
730
  }
587
731
 
588
- isConsuming = true;
589
-
590
732
  int i, count, column_type;
591
733
  std::string column_name, column_declared_type;
592
734
 
@@ -615,13 +757,13 @@ opsqlite_execute_raw(std::string const &dbName, std::string const &query,
615
757
  * only represent Integers up to 53 bits
616
758
  */
617
759
  double column_value = sqlite3_column_double(statement, i);
618
- row.push_back(JSVariant(column_value));
760
+ row.emplace_back(column_value);
619
761
  break;
620
762
  }
621
763
 
622
764
  case SQLITE_FLOAT: {
623
765
  double column_value = sqlite3_column_double(statement, i);
624
- row.push_back(JSVariant(column_value));
766
+ row.emplace_back(column_value);
625
767
  break;
626
768
  }
627
769
 
@@ -630,27 +772,25 @@ opsqlite_execute_raw(std::string const &dbName, std::string const &query,
630
772
  sqlite3_column_text(statement, i));
631
773
  int byteLen = sqlite3_column_bytes(statement, i);
632
774
  // Specify length too; in case string contains NULL in the middle
633
- row.push_back(JSVariant(std::string(column_value, byteLen)));
775
+ row.emplace_back(std::string(column_value, byteLen));
634
776
  break;
635
777
  }
636
778
 
637
779
  case SQLITE_BLOB: {
638
780
  int blob_size = sqlite3_column_bytes(statement, i);
639
781
  const void *blob = sqlite3_column_blob(statement, i);
640
- uint8_t *data = new uint8_t[blob_size];
782
+ auto *data = new uint8_t[blob_size];
641
783
  memcpy(data, blob, blob_size);
642
- row.push_back(
643
- JSVariant(ArrayBuffer{.data = std::shared_ptr<uint8_t>{data},
644
- .size = static_cast<size_t>(blob_size)}));
784
+ row.emplace_back(
785
+ ArrayBuffer{.data = std::shared_ptr<uint8_t>{data},
786
+ .size = static_cast<size_t>(blob_size)});
645
787
  break;
646
788
  }
647
789
 
648
790
  case SQLITE_NULL:
649
- row.push_back(JSVariant(nullptr));
650
- break;
651
-
791
+ // intentional fallthrough
652
792
  default:
653
- row.push_back(JSVariant(nullptr));
793
+ row.emplace_back(nullptr);
654
794
  break;
655
795
  }
656
796
  i++;
@@ -673,8 +813,8 @@ opsqlite_execute_raw(std::string const &dbName, std::string const &query,
673
813
  }
674
814
 
675
815
  sqlite3_finalize(statement);
676
- } while (remainingStatement != NULL && strcmp(remainingStatement, "") != 0 &&
677
- !isFailed);
816
+ } while (remainingStatement != nullptr &&
817
+ strcmp(remainingStatement, "") != 0 && !isFailed);
678
818
 
679
819
  if (isFailed) {
680
820
 
@@ -756,7 +896,7 @@ BridgeResult opsqlite_deregister_update_hook(std::string const &dbName) {
756
896
  sqlite3 *db = dbMap[dbName];
757
897
  updateCallbackMap.erase(dbName);
758
898
 
759
- sqlite3_update_hook(db, NULL, NULL);
899
+ sqlite3_update_hook(db, nullptr, nullptr);
760
900
 
761
901
  return {SQLiteOk};
762
902
  }
@@ -794,7 +934,7 @@ BridgeResult opsqlite_deregister_commit_hook(std::string const &dbName) {
794
934
 
795
935
  sqlite3 *db = dbMap[dbName];
796
936
  commitCallbackMap.erase(dbName);
797
- sqlite3_commit_hook(db, NULL, NULL);
937
+ sqlite3_commit_hook(db, nullptr, nullptr);
798
938
 
799
939
  return {SQLiteOk};
800
940
  }
@@ -831,7 +971,7 @@ BridgeResult opsqlite_deregister_rollback_hook(std::string const &dbName) {
831
971
  sqlite3 *db = dbMap[dbName];
832
972
  rollbackCallbackMap.erase(dbName);
833
973
 
834
- sqlite3_rollback_hook(db, NULL, NULL);
974
+ sqlite3_rollback_hook(db, nullptr, nullptr);
835
975
 
836
976
  return {SQLiteOk};
837
977
  }
@@ -867,7 +1007,7 @@ BridgeResult opsqlite_load_extension(std::string const &db_name,
867
1007
  #endif
868
1008
  }
869
1009
 
870
- BatchResult opsqlite_execute_batch(std::string dbName,
1010
+ BatchResult opsqlite_execute_batch(std::string &name,
871
1011
  std::vector<BatchArguments> *commands) {
872
1012
  size_t commandCount = commands->size();
873
1013
  if (commandCount <= 0) {
@@ -879,16 +1019,14 @@ BatchResult opsqlite_execute_batch(std::string dbName,
879
1019
 
880
1020
  try {
881
1021
  int affectedRows = 0;
882
- opsqlite_execute(dbName, "BEGIN EXCLUSIVE TRANSACTION", nullptr, nullptr,
883
- nullptr);
1022
+ opsqlite_execute(name, "BEGIN EXCLUSIVE TRANSACTION", nullptr);
884
1023
  for (int i = 0; i < commandCount; i++) {
885
1024
  auto command = commands->at(i);
886
1025
  // We do not provide a datastructure to receive query data because we
887
1026
  // don't need/want to handle this results in a batch execution
888
- auto result = opsqlite_execute(dbName, command.sql, command.params.get(),
889
- nullptr, nullptr);
1027
+ auto result = opsqlite_execute(name, command.sql, command.params.get());
890
1028
  if (result.type == SQLiteError) {
891
- opsqlite_execute(dbName, "ROLLBACK", nullptr, nullptr, nullptr);
1029
+ opsqlite_execute(name, "ROLLBACK", nullptr);
892
1030
  return BatchResult{
893
1031
  .type = SQLiteError,
894
1032
  .message = result.message,
@@ -897,14 +1035,14 @@ BatchResult opsqlite_execute_batch(std::string dbName,
897
1035
  affectedRows += result.affectedRows;
898
1036
  }
899
1037
  }
900
- opsqlite_execute(dbName, "COMMIT", nullptr, nullptr, nullptr);
1038
+ opsqlite_execute(name, "COMMIT", nullptr);
901
1039
  return BatchResult{
902
1040
  .type = SQLiteOk,
903
1041
  .affectedRows = affectedRows,
904
1042
  .commands = static_cast<int>(commandCount),
905
1043
  };
906
1044
  } catch (std::exception &exc) {
907
- opsqlite_execute(dbName, "ROLLBACK", nullptr, nullptr, nullptr);
1045
+ opsqlite_execute(name, "ROLLBACK", nullptr);
908
1046
  return BatchResult{
909
1047
  .type = SQLiteError,
910
1048
  .message = exc.what(),
package/cpp/bridge.h CHANGED
@@ -24,11 +24,13 @@ std::string opsqlite_get_db_path(std::string const &db_name,
24
24
 
25
25
  #ifdef OP_SQLITE_USE_SQLCIPHER
26
26
  BridgeResult opsqlite_open(std::string const &dbName, std::string const &dbPath,
27
- std::string const &crsqlitePath,
27
+ std::string const &crsqlite_path,
28
+ std::string const &sqlite_vec_path,
28
29
  std::string const &encryptionKey);
29
30
  #else
30
31
  BridgeResult opsqlite_open(std::string const &dbName, std::string const &dbPath,
31
- std::string const &crsqlitePath);
32
+ std::string const &crsqlite_path,
33
+ std::string const &sqlite_vec_path);
32
34
  #endif
33
35
 
34
36
  BridgeResult opsqlite_close(std::string const &dbName);
@@ -44,13 +46,15 @@ BridgeResult opsqlite_attach(std::string const &mainDBName,
44
46
  BridgeResult opsqlite_detach(std::string const &mainDBName,
45
47
  std::string const &alias);
46
48
 
47
- BridgeResult
48
- opsqlite_execute(std::string const &dbName, std::string const &query,
49
- const std::vector<JSVariant> *params,
50
- std::vector<DumbHostObject> *results,
51
- std::shared_ptr<std::vector<SmartHostObject>> metadatas);
49
+ BridgeResult opsqlite_execute(std::string const &name, std::string const &query,
50
+ const std::vector<JSVariant> *params);
52
51
 
53
- BatchResult opsqlite_execute_batch(std::string dbName,
52
+ BridgeResult opsqlite_execute_host_objects(
53
+ std::string const &dbName, std::string const &query,
54
+ const std::vector<JSVariant> *params, std::vector<DumbHostObject> *results,
55
+ std::shared_ptr<std::vector<SmartHostObject>> &metadatas);
56
+
57
+ BatchResult opsqlite_execute_batch(std::string &name,
54
58
  std::vector<BatchArguments> *commands);
55
59
 
56
60
  BridgeResult opsqlite_execute_raw(std::string const &dbName,
@@ -79,7 +83,7 @@ void opsqlite_bind_statement(sqlite3_stmt *statement,
79
83
  BridgeResult opsqlite_execute_prepared_statement(
80
84
  std::string const &dbName, sqlite3_stmt *statement,
81
85
  std::vector<DumbHostObject> *results,
82
- std::shared_ptr<std::vector<SmartHostObject>> metadatas);
86
+ std::shared_ptr<std::vector<SmartHostObject>> &metadatas);
83
87
 
84
88
  BridgeResult opsqlite_load_extension(std::string const &db_name,
85
89
  std::string &path,