@op-engineering/op-sqlite 7.4.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.
- package/README.md +11 -3
- package/android/build.gradle +8 -0
- package/cpp/DBHostObject.cpp +101 -106
- package/cpp/PreparedStatementHostObject.cpp +39 -14
- package/cpp/PreparedStatementHostObject.h +17 -4
- package/cpp/bindings.cpp +5 -5
- package/cpp/bridge.cpp +206 -85
- package/cpp/bridge.h +9 -7
- package/cpp/libsql/bridge.cpp +212 -92
- package/cpp/libsql/bridge.h +7 -3
- package/cpp/macros.h +2 -2
- package/cpp/types.h +11 -8
- package/cpp/utils.cpp +43 -7
- package/cpp/utils.h +2 -0
- package/lib/commonjs/index.js +53 -30
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/package.json +1 -0
- package/lib/module/NativeOPSQLite.js +2 -0
- package/lib/module/NativeOPSQLite.js.map +1 -1
- package/lib/module/index.js +55 -29
- package/lib/module/index.js.map +1 -1
- package/lib/module/package.json +1 -0
- package/lib/typescript/commonjs/package.json +1 -0
- package/lib/typescript/commonjs/src/NativeOPSQLite.d.ts.map +1 -0
- package/lib/typescript/{src → commonjs/src}/index.d.ts +11 -11
- package/lib/typescript/commonjs/src/index.d.ts.map +1 -0
- package/lib/typescript/module/package.json +1 -0
- package/lib/typescript/module/src/NativeOPSQLite.d.ts +15 -0
- package/lib/typescript/module/src/NativeOPSQLite.d.ts.map +1 -0
- package/lib/typescript/module/src/index.d.ts +163 -0
- package/lib/typescript/module/src/index.d.ts.map +1 -0
- package/package.json +44 -14
- package/src/index.ts +80 -46
- package/android/.project +0 -17
- package/android/.settings/org.eclipse.buildship.core.prefs +0 -13
- package/lib/typescript/src/NativeOPSQLite.d.ts.map +0 -1
- package/lib/typescript/src/index.d.ts.map +0 -1
- /package/lib/typescript/{src → commonjs/src}/NativeOPSQLite.d.ts +0 -0
package/cpp/libsql/bridge.cpp
CHANGED
|
@@ -49,21 +49,19 @@ BridgeResult opsqlite_libsql_open_sync(std::string const &name,
|
|
|
49
49
|
int sync_interval) {
|
|
50
50
|
std::string path = opsqlite_get_db_path(name, base_path);
|
|
51
51
|
|
|
52
|
-
int status
|
|
52
|
+
int status;
|
|
53
53
|
libsql_database_t db;
|
|
54
54
|
libsql_connection_t c;
|
|
55
|
-
const char *err =
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
};
|
|
66
|
-
status = libsql_open_sync_with_config(config, &db, &err);
|
|
55
|
+
const char *err = nullptr;
|
|
56
|
+
|
|
57
|
+
libsql_config config = {.db_path = path.c_str(),
|
|
58
|
+
.primary_url = url.c_str(),
|
|
59
|
+
.auth_token = auth_token.c_str(),
|
|
60
|
+
.read_your_writes = '1',
|
|
61
|
+
.encryption_key = nullptr,
|
|
62
|
+
.sync_interval = sync_interval,
|
|
63
|
+
.with_webpki = '1'};
|
|
64
|
+
status = libsql_open_sync_with_config(config, &db, &err);
|
|
67
65
|
if (status != 0) {
|
|
68
66
|
return {.type = SQLiteError, .message = err};
|
|
69
67
|
}
|
|
@@ -84,10 +82,10 @@ BridgeResult opsqlite_libsql_open(std::string const &name,
|
|
|
84
82
|
std::string const &crsqlitePath) {
|
|
85
83
|
std::string path = opsqlite_get_db_path(name, last_path);
|
|
86
84
|
|
|
87
|
-
int status
|
|
85
|
+
int status;
|
|
88
86
|
libsql_database_t db;
|
|
89
87
|
libsql_connection_t c;
|
|
90
|
-
const char *err =
|
|
88
|
+
const char *err = nullptr;
|
|
91
89
|
|
|
92
90
|
status = libsql_open_file(path.c_str(), &db, &err);
|
|
93
91
|
|
|
@@ -105,7 +103,8 @@ BridgeResult opsqlite_libsql_open(std::string const &name,
|
|
|
105
103
|
const char *errMsg;
|
|
106
104
|
const char *crsqliteEntryPoint = "sqlite3_crsqlite_init";
|
|
107
105
|
|
|
108
|
-
status = libsql_load_extension(c, crsqlitePath.c_str(), crsqliteEntryPoint,
|
|
106
|
+
status = libsql_load_extension(c, crsqlitePath.c_str(), crsqliteEntryPoint,
|
|
107
|
+
&errMsg);
|
|
109
108
|
|
|
110
109
|
if (status != 0) {
|
|
111
110
|
return {.type = SQLiteError, .message = errMsg};
|
|
@@ -121,10 +120,10 @@ BridgeResult opsqlite_libsql_open(std::string const &name,
|
|
|
121
120
|
|
|
122
121
|
BridgeResult opsqlite_libsql_open_remote(std::string const &url,
|
|
123
122
|
std::string const &auth_token) {
|
|
124
|
-
int status
|
|
123
|
+
int status;
|
|
125
124
|
libsql_database_t db;
|
|
126
125
|
libsql_connection_t c;
|
|
127
|
-
const char *err =
|
|
126
|
+
const char *err = nullptr;
|
|
128
127
|
|
|
129
128
|
status = libsql_open_remote_with_webpki(url.c_str(), auth_token.c_str(), &db,
|
|
130
129
|
&err);
|
|
@@ -176,8 +175,7 @@ BridgeResult opsqlite_libsql_attach(std::string const &mainDBName,
|
|
|
176
175
|
std::string dbPath = opsqlite_get_db_path(databaseToAttach, docPath);
|
|
177
176
|
std::string statement = "ATTACH DATABASE '" + dbPath + "' AS " + alias;
|
|
178
177
|
|
|
179
|
-
BridgeResult result =
|
|
180
|
-
opsqlite_libsql_execute(mainDBName, statement, nullptr, nullptr, nullptr);
|
|
178
|
+
BridgeResult result = opsqlite_libsql_execute(mainDBName, statement, nullptr);
|
|
181
179
|
|
|
182
180
|
if (result.type == SQLiteError) {
|
|
183
181
|
return {
|
|
@@ -194,8 +192,7 @@ BridgeResult opsqlite_libsql_attach(std::string const &mainDBName,
|
|
|
194
192
|
BridgeResult opsqlite_libsql_detach(std::string const &mainDBName,
|
|
195
193
|
std::string const &alias) {
|
|
196
194
|
std::string statement = "DETACH DATABASE " + alias;
|
|
197
|
-
BridgeResult result =
|
|
198
|
-
opsqlite_libsql_execute(mainDBName, statement, nullptr, nullptr, nullptr);
|
|
195
|
+
BridgeResult result = opsqlite_libsql_execute(mainDBName, statement, nullptr);
|
|
199
196
|
if (result.type == SQLiteError) {
|
|
200
197
|
return BridgeResult{
|
|
201
198
|
.type = SQLiteError,
|
|
@@ -212,7 +209,7 @@ BridgeResult opsqlite_libsql_sync(std::string const &name) {
|
|
|
212
209
|
check_db_open(name);
|
|
213
210
|
|
|
214
211
|
auto db = db_map[name].db;
|
|
215
|
-
const char *err =
|
|
212
|
+
const char *err = nullptr;
|
|
216
213
|
|
|
217
214
|
int status = libsql_sync(db, &err);
|
|
218
215
|
|
|
@@ -254,23 +251,30 @@ void opsqlite_libsql_bind_statement(libsql_stmt_t statement,
|
|
|
254
251
|
for (int ii = 0; ii < size; ii++) {
|
|
255
252
|
int index = ii + 1;
|
|
256
253
|
JSVariant value = values->at(ii);
|
|
254
|
+
int status;
|
|
257
255
|
|
|
258
|
-
if (std::holds_alternative<bool>(value)
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
libsql_bind_int(statement, index, std::get<int>(value), &err);
|
|
256
|
+
if (std::holds_alternative<bool>(value) ||
|
|
257
|
+
std::holds_alternative<int>(value)) {
|
|
258
|
+
status = libsql_bind_int(statement, index, std::get<int>(value), &err);
|
|
262
259
|
} else if (std::holds_alternative<long long>(value)) {
|
|
263
|
-
|
|
260
|
+
status =
|
|
261
|
+
libsql_bind_int(statement, index, std::get<long long>(value), &err);
|
|
264
262
|
} else if (std::holds_alternative<double>(value)) {
|
|
265
|
-
|
|
263
|
+
status =
|
|
264
|
+
libsql_bind_float(statement, index, std::get<double>(value), &err);
|
|
266
265
|
} else if (std::holds_alternative<std::string>(value)) {
|
|
267
266
|
std::string str = std::get<std::string>(value);
|
|
268
|
-
libsql_bind_string(statement, index, str.c_str(), &err);
|
|
267
|
+
status = libsql_bind_string(statement, index, str.c_str(), &err);
|
|
269
268
|
} else if (std::holds_alternative<ArrayBuffer>(value)) {
|
|
270
269
|
ArrayBuffer buffer = std::get<ArrayBuffer>(value);
|
|
271
|
-
libsql_bind_blob(statement, index, buffer.data.get(),
|
|
270
|
+
status = libsql_bind_blob(statement, index, buffer.data.get(),
|
|
271
|
+
static_cast<int>(buffer.size), &err);
|
|
272
272
|
} else {
|
|
273
|
-
libsql_bind_null(statement, index, &err);
|
|
273
|
+
status = libsql_bind_null(statement, index, &err);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
if (status != 0) {
|
|
277
|
+
throw std::runtime_error(err);
|
|
274
278
|
}
|
|
275
279
|
}
|
|
276
280
|
}
|
|
@@ -278,7 +282,7 @@ void opsqlite_libsql_bind_statement(libsql_stmt_t statement,
|
|
|
278
282
|
BridgeResult opsqlite_libsql_execute_prepared_statement(
|
|
279
283
|
std::string const &name, libsql_stmt_t stmt,
|
|
280
284
|
std::vector<DumbHostObject> *results,
|
|
281
|
-
std::shared_ptr<std::vector<SmartHostObject>> metadatas) {
|
|
285
|
+
const std::shared_ptr<std::vector<SmartHostObject>> &metadatas) {
|
|
282
286
|
|
|
283
287
|
check_db_open(name);
|
|
284
288
|
|
|
@@ -286,12 +290,8 @@ BridgeResult opsqlite_libsql_execute_prepared_statement(
|
|
|
286
290
|
libsql_rows_t rows;
|
|
287
291
|
libsql_row_t row;
|
|
288
292
|
|
|
289
|
-
int status
|
|
290
|
-
const char *err =
|
|
291
|
-
|
|
292
|
-
if (status != 0) {
|
|
293
|
-
return {.type = SQLiteError, .message = err};
|
|
294
|
-
}
|
|
293
|
+
int status;
|
|
294
|
+
const char *err = nullptr;
|
|
295
295
|
|
|
296
296
|
status = libsql_query_stmt(stmt, &rows, &err);
|
|
297
297
|
|
|
@@ -319,39 +319,39 @@ BridgeResult opsqlite_libsql_execute_prepared_statement(
|
|
|
319
319
|
case LIBSQL_INT:
|
|
320
320
|
long long int_value;
|
|
321
321
|
status = libsql_get_int(row, col, &int_value, &err);
|
|
322
|
-
row_host_object.values.
|
|
322
|
+
row_host_object.values.emplace_back(int_value);
|
|
323
323
|
break;
|
|
324
324
|
|
|
325
325
|
case LIBSQL_FLOAT:
|
|
326
326
|
double float_value;
|
|
327
327
|
status = libsql_get_float(row, col, &float_value, &err);
|
|
328
|
-
row_host_object.values.
|
|
328
|
+
row_host_object.values.emplace_back(float_value);
|
|
329
329
|
break;
|
|
330
330
|
|
|
331
331
|
case LIBSQL_TEXT:
|
|
332
332
|
const char *text_value;
|
|
333
333
|
status = libsql_get_string(row, col, &text_value, &err);
|
|
334
|
-
row_host_object.values.
|
|
334
|
+
row_host_object.values.emplace_back(text_value);
|
|
335
335
|
break;
|
|
336
336
|
|
|
337
337
|
case LIBSQL_BLOB: {
|
|
338
338
|
blob value_blob;
|
|
339
339
|
libsql_get_blob(row, col, &value_blob, &err);
|
|
340
|
-
|
|
340
|
+
auto *data = new uint8_t[value_blob.len];
|
|
341
341
|
// You cannot share raw memory between native and JS
|
|
342
342
|
// always copy the data
|
|
343
343
|
memcpy(data, value_blob.ptr, value_blob.len);
|
|
344
344
|
libsql_free_blob(value_blob);
|
|
345
|
-
row_host_object.values.
|
|
345
|
+
row_host_object.values.emplace_back(
|
|
346
346
|
ArrayBuffer{.data = std::shared_ptr<uint8_t>{data},
|
|
347
|
-
.size = static_cast<size_t>(value_blob.len)})
|
|
347
|
+
.size = static_cast<size_t>(value_blob.len)});
|
|
348
348
|
break;
|
|
349
349
|
}
|
|
350
350
|
|
|
351
351
|
case LIBSQL_NULL:
|
|
352
352
|
// intentional fall-through
|
|
353
353
|
default:
|
|
354
|
-
row_host_object.values.
|
|
354
|
+
row_host_object.values.emplace_back(nullptr);
|
|
355
355
|
break;
|
|
356
356
|
}
|
|
357
357
|
|
|
@@ -366,9 +366,9 @@ BridgeResult opsqlite_libsql_execute_prepared_statement(
|
|
|
366
366
|
status = libsql_column_name(rows, col, &col_name, &err);
|
|
367
367
|
|
|
368
368
|
auto metadata = SmartHostObject();
|
|
369
|
-
metadata.fields.
|
|
370
|
-
metadata.fields.
|
|
371
|
-
metadata.fields.
|
|
369
|
+
metadata.fields.emplace_back("name", col_name);
|
|
370
|
+
metadata.fields.emplace_back("index", col);
|
|
371
|
+
metadata.fields.emplace_back("type", "UNKNOWN");
|
|
372
372
|
// metadata.fields.push_back(
|
|
373
373
|
// std::make_pair("type", type == -1 ? "UNKNOWN" :
|
|
374
374
|
// type));
|
|
@@ -382,7 +382,7 @@ BridgeResult opsqlite_libsql_execute_prepared_statement(
|
|
|
382
382
|
}
|
|
383
383
|
|
|
384
384
|
metadata_set = true;
|
|
385
|
-
err =
|
|
385
|
+
err = nullptr;
|
|
386
386
|
}
|
|
387
387
|
|
|
388
388
|
if (status != 0) {
|
|
@@ -391,13 +391,13 @@ BridgeResult opsqlite_libsql_execute_prepared_statement(
|
|
|
391
391
|
|
|
392
392
|
libsql_free_rows(rows);
|
|
393
393
|
|
|
394
|
-
|
|
394
|
+
unsigned long long changes = libsql_changes(c);
|
|
395
395
|
long long insert_row_id = libsql_last_insert_rowid(c);
|
|
396
396
|
|
|
397
397
|
libsql_reset_stmt(stmt, &err);
|
|
398
398
|
|
|
399
399
|
return {.type = SQLiteOk,
|
|
400
|
-
.affectedRows = changes,
|
|
400
|
+
.affectedRows = static_cast<int>(changes),
|
|
401
401
|
.insertId = static_cast<double>(insert_row_id)};
|
|
402
402
|
}
|
|
403
403
|
|
|
@@ -420,11 +420,132 @@ libsql_stmt_t opsqlite_libsql_prepare_statement(std::string const &name,
|
|
|
420
420
|
return stmt;
|
|
421
421
|
}
|
|
422
422
|
|
|
423
|
-
|
|
424
|
-
|
|
423
|
+
BridgeResult opsqlite_libsql_execute(std::string const &name,
|
|
424
|
+
std::string const &query,
|
|
425
|
+
const std::vector<JSVariant> *params) {
|
|
426
|
+
|
|
427
|
+
check_db_open(name);
|
|
428
|
+
|
|
429
|
+
std::vector<std::string> column_names;
|
|
430
|
+
std::vector<std::vector<JSVariant>> out_rows;
|
|
431
|
+
std::vector<JSVariant> out_row;
|
|
432
|
+
libsql_connection_t c = db_map[name].c;
|
|
433
|
+
libsql_rows_t rows;
|
|
434
|
+
libsql_row_t row;
|
|
435
|
+
libsql_stmt_t stmt;
|
|
436
|
+
int status;
|
|
437
|
+
const char *err = nullptr;
|
|
438
|
+
|
|
439
|
+
status = libsql_prepare(c, query.c_str(), &stmt, &err);
|
|
440
|
+
|
|
441
|
+
if (status != 0) {
|
|
442
|
+
return {.type = SQLiteError, .message = err};
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
if (params != nullptr && !params->empty()) {
|
|
446
|
+
opsqlite_libsql_bind_statement(stmt, params);
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
status = libsql_query_stmt(stmt, &rows, &err);
|
|
450
|
+
|
|
451
|
+
if (status != 0) {
|
|
452
|
+
return {.type = SQLiteError, .message = err};
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
// Get the column names on the first pass
|
|
456
|
+
int column_count = libsql_column_count(rows);
|
|
457
|
+
const char *col_name;
|
|
458
|
+
|
|
459
|
+
for (int i = 0; i < column_count; i++) {
|
|
460
|
+
status = libsql_column_name(rows, i, &col_name, &err);
|
|
461
|
+
if (status != 0) {
|
|
462
|
+
throw std::runtime_error(err);
|
|
463
|
+
}
|
|
464
|
+
column_names.emplace_back(col_name);
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
long long int_value;
|
|
468
|
+
double float_value;
|
|
469
|
+
const char *text_value;
|
|
470
|
+
blob blob_value;
|
|
471
|
+
|
|
472
|
+
status = libsql_next_row(rows, &row, &err);
|
|
473
|
+
while (status == 0) {
|
|
474
|
+
out_row = std::vector<JSVariant>();
|
|
475
|
+
|
|
476
|
+
if (!err && !row) {
|
|
477
|
+
break;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
for (int col = 0; col < column_count; col++) {
|
|
481
|
+
int type;
|
|
482
|
+
|
|
483
|
+
libsql_column_type(rows, row, col, &type, &err);
|
|
484
|
+
|
|
485
|
+
switch (type) {
|
|
486
|
+
case LIBSQL_INT:
|
|
487
|
+
status = libsql_get_int(row, col, &int_value, &err);
|
|
488
|
+
out_row.emplace_back(int_value);
|
|
489
|
+
break;
|
|
490
|
+
|
|
491
|
+
case LIBSQL_FLOAT:
|
|
492
|
+
status = libsql_get_float(row, col, &float_value, &err);
|
|
493
|
+
out_row.emplace_back(float_value);
|
|
494
|
+
break;
|
|
495
|
+
|
|
496
|
+
case LIBSQL_TEXT:
|
|
497
|
+
|
|
498
|
+
status = libsql_get_string(row, col, &text_value, &err);
|
|
499
|
+
out_row.emplace_back(text_value);
|
|
500
|
+
break;
|
|
501
|
+
|
|
502
|
+
case LIBSQL_BLOB: {
|
|
503
|
+
libsql_get_blob(row, col, &blob_value, &err);
|
|
504
|
+
auto data = new uint8_t[blob_value.len];
|
|
505
|
+
// You cannot share raw memory between native and JS
|
|
506
|
+
// always copy the data
|
|
507
|
+
memcpy(data, blob_value.ptr, blob_value.len);
|
|
508
|
+
libsql_free_blob(blob_value);
|
|
509
|
+
out_row.emplace_back(
|
|
510
|
+
ArrayBuffer{.data = std::shared_ptr<uint8_t>{data},
|
|
511
|
+
.size = static_cast<size_t>(blob_value.len)});
|
|
512
|
+
break;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
case LIBSQL_NULL:
|
|
516
|
+
// intentional fall-through
|
|
517
|
+
default:
|
|
518
|
+
out_row.emplace_back(nullptr);
|
|
519
|
+
break;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
if (status != 0) {
|
|
523
|
+
throw std::runtime_error(err);
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
out_rows.emplace_back(out_row);
|
|
528
|
+
err = nullptr;
|
|
529
|
+
status = libsql_next_row(rows, &row, &err);
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
libsql_free_rows(rows);
|
|
533
|
+
libsql_free_stmt(stmt);
|
|
534
|
+
|
|
535
|
+
unsigned long long changes = libsql_changes(c);
|
|
536
|
+
long long insert_row_id = libsql_last_insert_rowid(c);
|
|
537
|
+
|
|
538
|
+
return {.type = SQLiteOk,
|
|
539
|
+
.affectedRows = static_cast<int>(changes),
|
|
540
|
+
.insertId = static_cast<double>(insert_row_id),
|
|
541
|
+
.rows = std::move(out_rows),
|
|
542
|
+
.column_names = std::move(column_names)};
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
BridgeResult opsqlite_libsql_execute_with_host_objects(
|
|
425
546
|
std::string const &name, std::string const &query,
|
|
426
547
|
const std::vector<JSVariant> *params, std::vector<DumbHostObject> *results,
|
|
427
|
-
std::shared_ptr<std::vector<SmartHostObject>> metadatas) {
|
|
548
|
+
const std::shared_ptr<std::vector<SmartHostObject>> &metadatas) {
|
|
428
549
|
|
|
429
550
|
check_db_open(name);
|
|
430
551
|
|
|
@@ -432,8 +553,8 @@ BridgeResult opsqlite_libsql_execute(
|
|
|
432
553
|
libsql_rows_t rows;
|
|
433
554
|
libsql_row_t row;
|
|
434
555
|
libsql_stmt_t stmt;
|
|
435
|
-
int status
|
|
436
|
-
const char *err =
|
|
556
|
+
int status;
|
|
557
|
+
const char *err = nullptr;
|
|
437
558
|
|
|
438
559
|
status = libsql_prepare(c, query.c_str(), &stmt, &err);
|
|
439
560
|
|
|
@@ -441,7 +562,7 @@ BridgeResult opsqlite_libsql_execute(
|
|
|
441
562
|
return {.type = SQLiteError, .message = err};
|
|
442
563
|
}
|
|
443
564
|
|
|
444
|
-
if (params != nullptr && params->
|
|
565
|
+
if (params != nullptr && !params->empty()) {
|
|
445
566
|
opsqlite_libsql_bind_statement(stmt, params);
|
|
446
567
|
}
|
|
447
568
|
|
|
@@ -471,45 +592,45 @@ BridgeResult opsqlite_libsql_execute(
|
|
|
471
592
|
case LIBSQL_INT:
|
|
472
593
|
long long int_value;
|
|
473
594
|
status = libsql_get_int(row, col, &int_value, &err);
|
|
474
|
-
row_host_object.values.
|
|
595
|
+
row_host_object.values.emplace_back(int_value);
|
|
475
596
|
break;
|
|
476
597
|
|
|
477
598
|
case LIBSQL_FLOAT:
|
|
478
599
|
double float_value;
|
|
479
600
|
status = libsql_get_float(row, col, &float_value, &err);
|
|
480
|
-
row_host_object.values.
|
|
601
|
+
row_host_object.values.emplace_back(float_value);
|
|
481
602
|
break;
|
|
482
603
|
|
|
483
604
|
case LIBSQL_TEXT:
|
|
484
605
|
const char *text_value;
|
|
485
606
|
status = libsql_get_string(row, col, &text_value, &err);
|
|
486
|
-
row_host_object.values.
|
|
607
|
+
row_host_object.values.emplace_back(text_value);
|
|
487
608
|
break;
|
|
488
609
|
|
|
489
610
|
case LIBSQL_BLOB: {
|
|
490
611
|
blob value_blob;
|
|
491
612
|
libsql_get_blob(row, col, &value_blob, &err);
|
|
492
|
-
|
|
613
|
+
auto *data = new uint8_t[value_blob.len];
|
|
493
614
|
// You cannot share raw memory between native and JS
|
|
494
615
|
// always copy the data
|
|
495
616
|
memcpy(data, value_blob.ptr, value_blob.len);
|
|
496
617
|
libsql_free_blob(value_blob);
|
|
497
|
-
row_host_object.values.
|
|
618
|
+
row_host_object.values.emplace_back(
|
|
498
619
|
ArrayBuffer{.data = std::shared_ptr<uint8_t>{data},
|
|
499
|
-
.size = static_cast<size_t>(value_blob.len)})
|
|
620
|
+
.size = static_cast<size_t>(value_blob.len)});
|
|
500
621
|
break;
|
|
501
622
|
}
|
|
502
623
|
|
|
503
624
|
case LIBSQL_NULL:
|
|
504
625
|
// intentional fall-through
|
|
505
626
|
default:
|
|
506
|
-
row_host_object.values.
|
|
627
|
+
row_host_object.values.emplace_back(nullptr);
|
|
507
628
|
break;
|
|
508
629
|
}
|
|
509
630
|
|
|
510
631
|
if (status != 0) {
|
|
511
632
|
fprintf(stderr, "%s\n", err);
|
|
512
|
-
throw std::runtime_error(
|
|
633
|
+
throw std::runtime_error(err);
|
|
513
634
|
}
|
|
514
635
|
|
|
515
636
|
// On the first interation through the columns, set the metadata
|
|
@@ -518,9 +639,9 @@ BridgeResult opsqlite_libsql_execute(
|
|
|
518
639
|
status = libsql_column_name(rows, col, &col_name, &err);
|
|
519
640
|
|
|
520
641
|
auto metadata = SmartHostObject();
|
|
521
|
-
metadata.fields.
|
|
522
|
-
metadata.fields.
|
|
523
|
-
metadata.fields.
|
|
642
|
+
metadata.fields.emplace_back("name", col_name);
|
|
643
|
+
metadata.fields.emplace_back("index", col);
|
|
644
|
+
metadata.fields.emplace_back("type", "UNKNOWN");
|
|
524
645
|
// metadata.fields.push_back(
|
|
525
646
|
// std::make_pair("type", type == -1 ? "UNKNOWN" :
|
|
526
647
|
// type));
|
|
@@ -534,7 +655,7 @@ BridgeResult opsqlite_libsql_execute(
|
|
|
534
655
|
}
|
|
535
656
|
|
|
536
657
|
metadata_set = true;
|
|
537
|
-
err =
|
|
658
|
+
err = nullptr;
|
|
538
659
|
}
|
|
539
660
|
|
|
540
661
|
if (status != 0) {
|
|
@@ -544,11 +665,11 @@ BridgeResult opsqlite_libsql_execute(
|
|
|
544
665
|
libsql_free_rows(rows);
|
|
545
666
|
libsql_free_stmt(stmt);
|
|
546
667
|
|
|
547
|
-
|
|
668
|
+
unsigned long long changes = libsql_changes(c);
|
|
548
669
|
long long insert_row_id = libsql_last_insert_rowid(c);
|
|
549
670
|
|
|
550
671
|
return {.type = SQLiteOk,
|
|
551
|
-
.affectedRows = changes,
|
|
672
|
+
.affectedRows = static_cast<int>(changes),
|
|
552
673
|
.insertId = static_cast<double>(insert_row_id)};
|
|
553
674
|
}
|
|
554
675
|
|
|
@@ -565,8 +686,8 @@ opsqlite_libsql_execute_raw(std::string const &name, std::string const &query,
|
|
|
565
686
|
libsql_rows_t rows;
|
|
566
687
|
libsql_row_t row;
|
|
567
688
|
libsql_stmt_t stmt;
|
|
568
|
-
int status
|
|
569
|
-
const char *err =
|
|
689
|
+
int status;
|
|
690
|
+
const char *err = nullptr;
|
|
570
691
|
|
|
571
692
|
status = libsql_prepare(c, query.c_str(), &stmt, &err);
|
|
572
693
|
|
|
@@ -574,7 +695,7 @@ opsqlite_libsql_execute_raw(std::string const &name, std::string const &query,
|
|
|
574
695
|
return {.type = SQLiteError, .message = err};
|
|
575
696
|
}
|
|
576
697
|
|
|
577
|
-
if (params != nullptr && params->
|
|
698
|
+
if (params != nullptr && !params->empty()) {
|
|
578
699
|
opsqlite_libsql_bind_statement(stmt, params);
|
|
579
700
|
}
|
|
580
701
|
|
|
@@ -602,39 +723,39 @@ opsqlite_libsql_execute_raw(std::string const &name, std::string const &query,
|
|
|
602
723
|
case LIBSQL_INT:
|
|
603
724
|
long long int_value;
|
|
604
725
|
status = libsql_get_int(row, col, &int_value, &err);
|
|
605
|
-
row_vector.
|
|
726
|
+
row_vector.emplace_back(int_value);
|
|
606
727
|
break;
|
|
607
728
|
|
|
608
729
|
case LIBSQL_FLOAT:
|
|
609
730
|
double float_value;
|
|
610
731
|
status = libsql_get_float(row, col, &float_value, &err);
|
|
611
|
-
row_vector.
|
|
732
|
+
row_vector.emplace_back(float_value);
|
|
612
733
|
break;
|
|
613
734
|
|
|
614
735
|
case LIBSQL_TEXT:
|
|
615
736
|
const char *text_value;
|
|
616
737
|
status = libsql_get_string(row, col, &text_value, &err);
|
|
617
|
-
row_vector.
|
|
738
|
+
row_vector.emplace_back(text_value);
|
|
618
739
|
break;
|
|
619
740
|
|
|
620
741
|
case LIBSQL_BLOB: {
|
|
621
742
|
blob value_blob;
|
|
622
743
|
libsql_get_blob(row, col, &value_blob, &err);
|
|
623
|
-
|
|
744
|
+
auto *data = new uint8_t[value_blob.len];
|
|
624
745
|
// You cannot share raw memory between native and JS
|
|
625
746
|
// always copy the data
|
|
626
747
|
memcpy(data, value_blob.ptr, value_blob.len);
|
|
627
748
|
libsql_free_blob(value_blob);
|
|
628
|
-
row_vector.
|
|
749
|
+
row_vector.emplace_back(
|
|
629
750
|
ArrayBuffer{.data = std::shared_ptr<uint8_t>{data},
|
|
630
|
-
.size = static_cast<size_t>(value_blob.len)})
|
|
751
|
+
.size = static_cast<size_t>(value_blob.len)});
|
|
631
752
|
break;
|
|
632
753
|
}
|
|
633
754
|
|
|
634
755
|
case LIBSQL_NULL:
|
|
635
756
|
// intentional fall-through
|
|
636
757
|
default:
|
|
637
|
-
row_vector.
|
|
758
|
+
row_vector.emplace_back(nullptr);
|
|
638
759
|
break;
|
|
639
760
|
}
|
|
640
761
|
|
|
@@ -648,7 +769,7 @@ opsqlite_libsql_execute_raw(std::string const &name, std::string const &query,
|
|
|
648
769
|
results->push_back(row_vector);
|
|
649
770
|
}
|
|
650
771
|
|
|
651
|
-
err =
|
|
772
|
+
err = nullptr;
|
|
652
773
|
}
|
|
653
774
|
|
|
654
775
|
if (status != 0) {
|
|
@@ -658,11 +779,11 @@ opsqlite_libsql_execute_raw(std::string const &name, std::string const &query,
|
|
|
658
779
|
libsql_free_rows(rows);
|
|
659
780
|
libsql_free_stmt(stmt);
|
|
660
781
|
|
|
661
|
-
|
|
782
|
+
unsigned long long changes = libsql_changes(c);
|
|
662
783
|
long long insert_row_id = libsql_last_insert_rowid(c);
|
|
663
784
|
|
|
664
785
|
return {.type = SQLiteOk,
|
|
665
|
-
.affectedRows = changes,
|
|
786
|
+
.affectedRows = static_cast<int>(changes),
|
|
666
787
|
.insertId = static_cast<double>(insert_row_id)};
|
|
667
788
|
}
|
|
668
789
|
|
|
@@ -679,16 +800,15 @@ opsqlite_libsql_execute_batch(std::string const &name,
|
|
|
679
800
|
|
|
680
801
|
try {
|
|
681
802
|
int affectedRows = 0;
|
|
682
|
-
opsqlite_libsql_execute(name, "BEGIN EXCLUSIVE TRANSACTION", nullptr
|
|
683
|
-
nullptr, nullptr);
|
|
803
|
+
opsqlite_libsql_execute(name, "BEGIN EXCLUSIVE TRANSACTION", nullptr);
|
|
684
804
|
for (int i = 0; i < commandCount; i++) {
|
|
685
805
|
auto command = commands->at(i);
|
|
686
806
|
// We do not provide a datastructure to receive query data because we
|
|
687
807
|
// don't need/want to handle this results in a batch execution
|
|
688
|
-
auto result =
|
|
689
|
-
name, command.sql, command.params.get()
|
|
808
|
+
auto result =
|
|
809
|
+
opsqlite_libsql_execute(name, command.sql, command.params.get());
|
|
690
810
|
if (result.type == SQLiteError) {
|
|
691
|
-
opsqlite_libsql_execute(name, "ROLLBACK", nullptr
|
|
811
|
+
opsqlite_libsql_execute(name, "ROLLBACK", nullptr);
|
|
692
812
|
return BatchResult{
|
|
693
813
|
.type = SQLiteError,
|
|
694
814
|
.message = result.message,
|
|
@@ -697,14 +817,14 @@ opsqlite_libsql_execute_batch(std::string const &name,
|
|
|
697
817
|
affectedRows += result.affectedRows;
|
|
698
818
|
}
|
|
699
819
|
}
|
|
700
|
-
opsqlite_libsql_execute(name, "COMMIT", nullptr
|
|
820
|
+
opsqlite_libsql_execute(name, "COMMIT", nullptr);
|
|
701
821
|
return BatchResult{
|
|
702
822
|
.type = SQLiteOk,
|
|
703
823
|
.affectedRows = affectedRows,
|
|
704
824
|
.commands = static_cast<int>(commandCount),
|
|
705
825
|
};
|
|
706
826
|
} catch (std::exception &exc) {
|
|
707
|
-
opsqlite_libsql_execute(name, "ROLLBACK", nullptr
|
|
827
|
+
opsqlite_libsql_execute(name, "ROLLBACK", nullptr);
|
|
708
828
|
return BatchResult{
|
|
709
829
|
.type = SQLiteError,
|
|
710
830
|
.message = exc.what(),
|
package/cpp/libsql/bridge.h
CHANGED
|
@@ -57,8 +57,12 @@ BridgeResult opsqlite_libsql_sync(std::string const &name);
|
|
|
57
57
|
|
|
58
58
|
BridgeResult opsqlite_libsql_execute(
|
|
59
59
|
std::string const &name, std::string const &query,
|
|
60
|
-
const std::vector<JSVariant> *params
|
|
61
|
-
|
|
60
|
+
const std::vector<JSVariant> *params);
|
|
61
|
+
|
|
62
|
+
BridgeResult opsqlite_libsql_execute_with_host_objects(
|
|
63
|
+
std::string const &name, std::string const &query,
|
|
64
|
+
const std::vector<JSVariant> *params, std::vector<DumbHostObject> *results,
|
|
65
|
+
const std::shared_ptr<std::vector<SmartHostObject>>& metadatas);
|
|
62
66
|
|
|
63
67
|
BridgeResult
|
|
64
68
|
opsqlite_libsql_execute_raw(std::string const &dbName, std::string const &query,
|
|
@@ -80,6 +84,6 @@ void opsqlite_libsql_bind_statement(libsql_stmt_t stmt,
|
|
|
80
84
|
BridgeResult opsqlite_libsql_execute_prepared_statement(
|
|
81
85
|
std::string const &name, libsql_stmt_t stmt,
|
|
82
86
|
std::vector<DumbHostObject> *results,
|
|
83
|
-
std::shared_ptr<std::vector<SmartHostObject
|
|
87
|
+
const std::shared_ptr<std::vector<SmartHostObject>>& metadatas);
|
|
84
88
|
|
|
85
89
|
} // namespace opsqlite
|
package/cpp/macros.h
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#ifndef macros_h
|
|
2
2
|
#define macros_h
|
|
3
3
|
|
|
4
|
-
#define HOSTFN(name
|
|
4
|
+
#define HOSTFN(name) \
|
|
5
5
|
jsi::Function::createFromHostFunction( \
|
|
6
6
|
rt, \
|
|
7
7
|
jsi::PropNameID::forAscii(rt, name), \
|
|
8
|
-
|
|
8
|
+
0, \
|
|
9
9
|
[=](jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count) -> jsi::Value
|
|
10
10
|
|
|
11
11
|
#endif /* macros_h */
|
package/cpp/types.h
CHANGED
|
@@ -4,6 +4,15 @@
|
|
|
4
4
|
#include <memory>
|
|
5
5
|
#include <string>
|
|
6
6
|
#include <variant>
|
|
7
|
+
#include <vector>
|
|
8
|
+
|
|
9
|
+
struct ArrayBuffer {
|
|
10
|
+
std::shared_ptr<uint8_t> data;
|
|
11
|
+
size_t size;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
using JSVariant = std::variant<nullptr_t, bool, int, double, long, long long,
|
|
15
|
+
std::string, ArrayBuffer>;
|
|
7
16
|
|
|
8
17
|
enum ResultType { SQLiteOk, SQLiteError };
|
|
9
18
|
|
|
@@ -12,6 +21,8 @@ struct BridgeResult {
|
|
|
12
21
|
std::string message;
|
|
13
22
|
int affectedRows;
|
|
14
23
|
double insertId;
|
|
24
|
+
std::vector<std::vector<JSVariant>> rows;
|
|
25
|
+
std::vector<std::string> column_names;
|
|
15
26
|
};
|
|
16
27
|
|
|
17
28
|
struct BatchResult {
|
|
@@ -21,14 +32,6 @@ struct BatchResult {
|
|
|
21
32
|
int commands;
|
|
22
33
|
};
|
|
23
34
|
|
|
24
|
-
struct ArrayBuffer {
|
|
25
|
-
std::shared_ptr<uint8_t> data;
|
|
26
|
-
size_t size;
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
using JSVariant = std::variant<nullptr_t, bool, int, double, long, long long,
|
|
30
|
-
std::string, ArrayBuffer>;
|
|
31
|
-
|
|
32
35
|
struct BatchArguments {
|
|
33
36
|
std::string sql;
|
|
34
37
|
std::shared_ptr<std::vector<JSVariant>> params;
|