From b8423147eba6909fd4e1c87fa31557b21a744dca Mon Sep 17 00:00:00 2001 From: ospfranco Date: Sun, 14 Jul 2024 08:44:03 -0500 Subject: [PATCH 1/2] Stubs for exposing sync call for remote sync db --- cpp/DBHostObject.cpp | 10 ++++++++++ cpp/libsql/bridge.cpp | 15 +++++++++++++++ cpp/libsql/bridge.h | 2 ++ 3 files changed, 27 insertions(+) diff --git a/cpp/DBHostObject.cpp b/cpp/DBHostObject.cpp index cca07d04..1f51ab3a 100644 --- a/cpp/DBHostObject.cpp +++ b/cpp/DBHostObject.cpp @@ -556,6 +556,16 @@ void DBHostObject::create_jsi_functions() { return promise; }); +#ifdef OP_SQLITE_USE_LIBSQL + auto sync = HOSTFN("sync", 0) { + BridgeResult result = opsqlite_libsql_sync(db_name); + if (result.type == SQLiteError) { + throw std::runtime_error(result.message); + } + return {}; + }); +#endif + #ifndef OP_SQLITE_USE_LIBSQL auto load_file = HOSTFN("loadFile", 1) { if (sizeof(args) < 1) { diff --git a/cpp/libsql/bridge.cpp b/cpp/libsql/bridge.cpp index 5cd79841..15f0984b 100644 --- a/cpp/libsql/bridge.cpp +++ b/cpp/libsql/bridge.cpp @@ -186,6 +186,21 @@ BridgeResult opsqlite_libsql_detach(std::string const &mainDBName, }; } +BridgeResult opsqlite_libsql_sync(std::string const &name) { + check_db_open(name); + + libsql_connection_t c = db_map[name].c; + const char *err = NULL; + + int status = libsql_sync(c, &err); + + if (status != 0) { + return {.type = SQLiteError, .message = err}; + } + + return {.type = SQLiteOk}; +} + BridgeResult opsqlite_libsql_remove(std::string const &name, std::string const &path) { if (db_map.count(name) == 1) { diff --git a/cpp/libsql/bridge.h b/cpp/libsql/bridge.h index 2236562e..be354bb5 100644 --- a/cpp/libsql/bridge.h +++ b/cpp/libsql/bridge.h @@ -51,6 +51,8 @@ BridgeResult opsqlite_libsql_attach(std::string const &mainDBName, BridgeResult opsqlite_libsql_detach(std::string const &mainDBName, std::string const &alias); +BridgeResult opsqlite_libsql_sync(std::string const &name); + BridgeResult opsqlite_libsql_execute( std::string const &name, std::string const &query, const std::vector *params, std::vector *results, From bc4d69b4b8c54d54ff3d1cb235be58aa63464c10 Mon Sep 17 00:00:00 2001 From: ospfranco Date: Mon, 15 Jul 2024 06:38:08 -0500 Subject: [PATCH 2/2] Sync call working --- cpp/DBHostObject.cpp | 7 ++++++- cpp/libsql/bridge.cpp | 4 ++-- example/ios/Podfile.lock | 4 ++-- example/package.json | 5 +++-- example/src/tests/queries.spec.ts | 7 +++++-- src/index.ts | 15 +++++++++------ 6 files changed, 27 insertions(+), 15 deletions(-) diff --git a/cpp/DBHostObject.cpp b/cpp/DBHostObject.cpp index 1f51ab3a..13a0d9a2 100644 --- a/cpp/DBHostObject.cpp +++ b/cpp/DBHostObject.cpp @@ -807,7 +807,9 @@ void DBHostObject::create_jsi_functions() { function_map["executeBatchAsync"] = std::move(execute_batch_async); function_map["prepareStatement"] = std::move(prepare_statement); function_map["getDbPath"] = std::move(get_db_path); -#ifndef OP_SQLITE_USE_LIBSQL +#ifdef OP_SQLITE_USE_LIBSQL + function_map["sync"] = std::move(sync); +#else OP_SQLITE_USE_LIBSQL function_map["loadFile"] = std::move(load_file); function_map["updateHook"] = std::move(update_hook); function_map["commitHook"] = std::move(commit_hook); @@ -860,6 +862,9 @@ jsi::Value DBHostObject::get(jsi::Runtime &rt, if (name == "getDbPath") { return jsi::Value(rt, function_map["getDbPath"]); } + if (name == "sync") { + return jsi::Value(rt, function_map["sync"]); + } #ifdef OP_SQLITE_USE_LIBSQL if (name == "loadFile") { return HOSTFN("loadFile", 0) { diff --git a/cpp/libsql/bridge.cpp b/cpp/libsql/bridge.cpp index 15f0984b..89533ff3 100644 --- a/cpp/libsql/bridge.cpp +++ b/cpp/libsql/bridge.cpp @@ -189,10 +189,10 @@ BridgeResult opsqlite_libsql_detach(std::string const &mainDBName, BridgeResult opsqlite_libsql_sync(std::string const &name) { check_db_open(name); - libsql_connection_t c = db_map[name].c; + auto db = db_map[name].db; const char *err = NULL; - int status = libsql_sync(c, &err); + int status = libsql_sync(db, &err); if (status != 0) { return {.type = SQLiteError, .message = err}; diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 0e8d7180..dcb27311 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -7,7 +7,7 @@ PODS: - hermes-engine (0.74.0): - hermes-engine/Pre-built (= 0.74.0) - hermes-engine/Pre-built (0.74.0) - - op-sqlite (6.1.3): + - op-sqlite (6.1.4): - React - React-callinvoker - React-Core @@ -1358,7 +1358,7 @@ SPEC CHECKSUMS: fmt: 4c2741a687cc09f0634a2e2c72a838b99f1ff120 glog: c5d68082e772fa1c511173d6b30a9de2c05a69a2 hermes-engine: 6eae7edb2f563ee41d7c1f91f4f2e57c26d8a5c3 - op-sqlite: 3b399d7e847783963ba53b0fe979e667225b76de + op-sqlite: 6681bc41de4af899fd7014c936b039ac330c007e RCT-Folly: 045d6ecaa59d826c5736dfba0b2f4083ff8d79df RCTDeprecation: 3ca8b6c36bfb302e1895b72cfe7db0de0c92cd47 RCTRequired: 9fc183af555fd0c89a366c34c1ae70b7e03b1dc5 diff --git a/example/package.json b/example/package.json index fce10116..071dd911 100644 --- a/example/package.json +++ b/example/package.json @@ -6,7 +6,8 @@ "android": "react-native run-android", "ios": "react-native run-ios --scheme='debug' --simulator='iPhone 15 Pro'", "start": "react-native start", - "pods": "cd ios && rm -rf Pods && rm -rf Podfile.lock && bundle exec pod install", + "pods": "cd ios && bundle exec pod install", + "pods:nuke": "cd ios && rm -rf Pods && rm -rf Podfile.lock && bundle exec pod install", "build:android": "cd android && ./gradlew assembleDebug --no-daemon --console=plain -PreactNativeArchitectures=arm64-v8a", "build:ios": "cd ios && xcodebuild -workspace OPSQLiteExample.xcworkspace -scheme debug -configuration Debug -sdk iphonesimulator CC=clang CPLUSPLUS=clang++ LD=clang LDPLUSPLUS=clang++ GCC_OPTIMIZATION_LEVEL=0 GCC_PRECOMPILE_PREFIX_HEADER=YES ASSETCATALOG_COMPILER_OPTIMIZATION=time DEBUG_INFORMATION_FORMAT=dwarf COMPILER_INDEX_STORE_ENABLE=NO" }, @@ -60,7 +61,7 @@ "crsqlite": false, "performanceMode": "2", "iosSqlite": false, - "fts5": false, + "fts5": true, "libsql": false } } diff --git a/example/src/tests/queries.spec.ts b/example/src/tests/queries.spec.ts index d1ff4b7a..c10b225c 100644 --- a/example/src/tests/queries.spec.ts +++ b/example/src/tests/queries.spec.ts @@ -7,7 +7,7 @@ import { type DB, type SQLBatchTuple, } from '@op-engineering/op-sqlite'; -import {beforeEach, describe, it} from './MochaRNAdapter'; +import {beforeEach, describe, it, itOnly} from './MochaRNAdapter'; import chai from 'chai'; const expect = chai.expect; @@ -50,7 +50,7 @@ export function queriesTests() { expect(res.rowsAffected).to.equal(0); }); - it('Open a libsql database replicated to turso', async () => { + itOnly('Open a libsql database replicated to turso', async () => { const remoteDb = openSync({ url: 'libsql://foo-ospfranco.turso.io', authToken: @@ -59,6 +59,9 @@ export function queriesTests() { }); const res = remoteDb.execute('SELECT 1'); + + remoteDb.sync(); + expect(res.rowsAffected).to.equal(0); }); } diff --git a/src/index.ts b/src/index.ts index e8d9ff72..4eb39699 100644 --- a/src/index.ts +++ b/src/index.ts @@ -59,19 +59,20 @@ export const { export type QueryResult = { insertId?: number; rowsAffected: number; + res?: any[]; rows?: { /** Raw array with all dataset */ _array: any[]; - /** The lengh of the dataset */ + /** The length of the dataset */ length: number; - /** A convenience function to acess the index based the row object + /** A convenience function to access the index based the row object * @param idx the row index * @returns the row structure identified by column names */ item: (idx: number) => any; }; /** - * Query metadata, avaliable only for select query results + * Query metadata, available only for select query results */ metadata?: ColumnMetadata[]; }; @@ -81,12 +82,12 @@ export type QueryResult = { * Describes some information about columns fetched by the query */ export type ColumnMetadata = { - /** The name used for this column for this resultset */ + /** The name used for this column for this result set */ name: string; /** The declared column type for this column, when fetched directly from a table or a View resulting from a table column. "UNKNOWN" for dynamic values, like function returned ones. */ type: string; /** - * The index for this column for this resultset*/ + * The index for this column for this result set*/ index: number; }; @@ -186,6 +187,7 @@ export type DB = { }[]; callback: (response: any) => void; }) => () => void; + sync: () => void; }; type OPSQLiteProxy = { @@ -211,7 +213,6 @@ const locks: Record< > = {}; // Enhance some host functions - // Add 'item' function to result object to allow the sqlite-storage typeorm driver to work function enhanceQueryResult(result: QueryResult): void { // Add 'item' function to result object to allow the sqlite-storage typeorm driver to work @@ -222,6 +223,7 @@ function enhanceQueryResult(result: QueryResult): void { item: (idx: number) => result.rows?._array[idx], }; } else { + result.res = result.rows._array; result.rows.item = (idx: number) => result.rows?._array[idx]; } } @@ -268,6 +270,7 @@ function enhanceDB(db: DB, options: any): DB { executeRawAsync: db.executeRawAsync, getDbPath: db.getDbPath, reactiveExecute: db.reactiveExecute, + sync: db.sync, close: () => { db.close(); delete locks[options.url];