diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a8462ed0..9026cf82 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -69,12 +69,13 @@ jobs: ./scripts/test-android.sh test-ios: runs-on: macos-latest - env: - TURBO_CACHE_DIR: .turbo/ios steps: - name: Checkout uses: actions/checkout@v4 + - name: Xcode Select + run: sudo xcode-select -s /Applications/Xcode_16.4.app + - name: Turn off addons run: | node ./scripts/turnOffEverything.js @@ -110,12 +111,13 @@ jobs: test-ios-embedded: runs-on: macos-latest - env: - TURBO_CACHE_DIR: .turbo/ios steps: - name: Checkout uses: actions/checkout@v4 + - name: Xcode Select + run: sudo xcode-select -s /Applications/Xcode_16.4.app + - name: Turn on ios embedded run: | node ./scripts/turnOnIOSEmbedded.js @@ -151,12 +153,13 @@ jobs: test-ios-sqlcipher: runs-on: macos-latest - env: - TURBO_CACHE_DIR: .turbo/ios steps: - name: Checkout uses: actions/checkout@v4 + - name: Xcode Select + run: sudo xcode-select -s /Applications/Xcode_16.4.app + - name: Turn on SQLCipher run: | node ./scripts/turnOnSQLCipher.js @@ -192,12 +195,13 @@ jobs: test-ios-libsql: runs-on: macos-latest - env: - TURBO_CACHE_DIR: .turbo/ios steps: - name: Checkout uses: actions/checkout@v4 + - name: Xcode Select + run: sudo xcode-select -s /Applications/Xcode_16.4.app + - name: Turn on SQLCipher run: | node ./scripts/turnOnLibsql.js diff --git a/cpp/DBHostObject.cpp b/cpp/DBHostObject.cpp index 17f92343..aa546c5a 100644 --- a/cpp/DBHostObject.cpp +++ b/cpp/DBHostObject.cpp @@ -361,6 +361,23 @@ void DBHostObject::create_jsi_functions() { return create_js_rows(rt, status); }); + + function_map["executeRawSync"] = HOSTFN("executeRawSync") { + const std::string query = args[0].asString(rt).utf8(rt); + std::vector params = count == 2 && args[1].isObject() + ? to_variant_vec(rt, args[1]) + : std::vector(); + + std::vector> results; + +#ifdef OP_SQLITE_USE_LIBSQL + auto status = opsqlite_libsql_execute_raw(db, query, ¶ms, &results); +#else + auto status = opsqlite_execute_raw(db, query, ¶ms, &results); +#endif + + return create_raw_result(rt, status, &results); + }); function_map["execute"] = HOSTFN("execute") { const std::string query = args[0].asString(rt).utf8(rt); diff --git a/example/src/tests/queries.spec.ts b/example/src/tests/queries.spec.ts index 62e5f945..5488384c 100644 --- a/example/src/tests/queries.spec.ts +++ b/example/src/tests/queries.spec.ts @@ -721,6 +721,23 @@ export function queriesTests() { expect(res).to.eql([[id, name, age, networth]]); }); + it('Execute raw sync should return just an array of objects', async () => { + const id = chance.integer(); + const name = chance.name(); + const age = chance.integer(); + const networth = chance.floating(); + + await db.execute( + 'INSERT INTO User (id, name, age, networth) VALUES(?, ?, ?, ?)', + [id, name, age, networth], + ); + + const res = db.executeRawSync( + 'SELECT id, name, age, networth FROM User', + ); + expect(res).to.eql([[id, name, age, networth]]); + }); + it('Create fts5 virtual table', async () => { await db.execute( 'CREATE VIRTUAL TABLE fts5_table USING fts5(name, content);', diff --git a/src/index.ts b/src/index.ts index a840524f..29ff39bc 100644 --- a/src/index.ts +++ b/src/index.ts @@ -134,6 +134,7 @@ type InternalDB = { prepareStatement: (query: string) => PreparedStatement; loadExtension: (path: string, entryPoint?: string) => void; executeRaw: (query: string, params?: Scalar[]) => Promise; + executeRawSync: (query: string, params?: Scalar[]) => any[]; getDbPath: (location?: string) => string; reactiveExecute: (params: { query: string; @@ -262,6 +263,11 @@ export type DB = { * It will be faster since a lot of repeated work is skipped and only the values you care about are returned */ executeRaw: (query: string, params?: Scalar[]) => Promise; + /** + * Same as `executeRaw` but it will block the JS thread and therefore your UI and should be used with caution + * It will return an array of arrays with just the values and not the keys + */ + executeRawSync: (query: string, params?: Scalar[]) => any[]; /** * Get's the absolute path to the db file. Useful for debugging on local builds and for attaching the DB from users devices */ @@ -478,6 +484,10 @@ function enhanceDB(db: InternalDB, options: DBParams): DB { return db.executeRaw(query, sanitizedParams as Scalar[]); }, + executeRawSync: (query: string, params?: Scalar[]) => { + const sanitizedParams = sanitizeArrayBuffersInArray(params); + return db.executeRawSync(query, sanitizedParams as Scalar[]); + }, executeSync: (query: string, params?: Scalar[]): QueryResult => { const sanitizedParams = sanitizeArrayBuffersInArray(params);