diff --git a/.claude/settings.local.json b/.claude/settings.local.json new file mode 100644 index 0000000..633cb5b --- /dev/null +++ b/.claude/settings.local.json @@ -0,0 +1,8 @@ +{ + "permissions": { + "allow": [ + "Bash(find:*)", + "Bash(grep:*)" + ] + } +} diff --git a/package/cpp/NitroSQLiteException.hpp b/package/cpp/NitroSQLiteException.hpp index 4a8469b..e63f5d7 100644 --- a/package/cpp/NitroSQLiteException.hpp +++ b/package/cpp/NitroSQLiteException.hpp @@ -2,12 +2,11 @@ #include #include -#include #include +#include const std::string NITRO_SQLITE_EXCEPTION_PREFIX = "[NativeNitroSQLiteException]"; - enum NitroSQLiteExceptionType { UnknownError, DatabaseCannotBeOpened, diff --git a/package/cpp/operations.cpp b/package/cpp/operations.cpp index bc339ca..af361dd 100644 --- a/package/cpp/operations.cpp +++ b/package/cpp/operations.cpp @@ -1,6 +1,7 @@ #include "operations.hpp" #include "NitroSQLiteException.hpp" #include "logs.hpp" +#include "specs/HybridNitroSQLiteQueryResult.hpp" #include "utils.hpp" #include #include @@ -121,8 +122,8 @@ void bindStatement(sqlite3_stmt* statement, const SQLiteQueryParams& values) { } } -SQLiteExecuteQueryResult sqliteExecute(const std::string& dbName, const std::string& query, - const std::optional& params) { +std::shared_ptr sqliteExecute(const std::string& dbName, const std::string& query, + const std::optional& params) { if (dbMap.count(dbName) == 0) { throw NitroSQLiteException::DatabaseNotOpen(dbName); } @@ -229,10 +230,7 @@ SQLiteExecuteQueryResult sqliteExecute(const std::string& dbName, const std::str int rowsAffected = sqlite3_changes(db); long long latestInsertRowId = sqlite3_last_insert_rowid(db); - return {.rowsAffected = rowsAffected, - .insertId = static_cast(latestInsertRowId), - .results = std::move(results), - .metadata = std::move(metadata)}; + return std::make_shared(results, static_cast(latestInsertRowId), rowsAffected, metadata); } SQLiteOperationResult sqliteExecuteLiteral(const std::string& dbName, const std::string& query) { diff --git a/package/cpp/operations.hpp b/package/cpp/operations.hpp index dd08693..36addea 100644 --- a/package/cpp/operations.hpp +++ b/package/cpp/operations.hpp @@ -1,5 +1,6 @@ #pragma once +#include "specs/HybridNitroSQLiteQueryResult.hpp" #include "types.hpp" namespace margelo::rnnitrosqlite { @@ -15,7 +16,8 @@ void sqliteAttachDb(const std::string& mainDBName, const std::string& docPath, c void sqliteDetachDb(const std::string& mainDBName, const std::string& alias); -SQLiteExecuteQueryResult sqliteExecute(const std::string& dbName, const std::string& query, const std::optional& params); +std::shared_ptr sqliteExecute(const std::string& dbName, const std::string& query, + const std::optional& params); SQLiteOperationResult sqliteExecuteLiteral(const std::string& dbName, const std::string& query); diff --git a/package/cpp/specs/HybridNitroSQLite.cpp b/package/cpp/specs/HybridNitroSQLite.cpp index b54b3f0..ceb0e55 100644 --- a/package/cpp/specs/HybridNitroSQLite.cpp +++ b/package/cpp/specs/HybridNitroSQLite.cpp @@ -50,12 +50,9 @@ void HybridNitroSQLite::detach(const std::string& mainDbName, const std::string& sqliteDetachDb(mainDbName, alias); }; -using ExecuteQueryResult = std::shared_ptr; - -ExecuteQueryResult HybridNitroSQLite::execute(const std::string& dbName, const std::string& query, - const std::optional& params) { - SQLiteExecuteQueryResult result = sqliteExecute(dbName, query, params); - return std::make_shared(std::move(result)); +std::shared_ptr HybridNitroSQLite::execute(const std::string& dbName, const std::string& query, + const std::optional& params) { + return sqliteExecute(dbName, query, params); }; std::shared_ptr>> diff --git a/package/cpp/specs/HybridNitroSQLiteQueryResult.cpp b/package/cpp/specs/HybridNitroSQLiteQueryResult.cpp index 5ccf734..762ca9b 100644 --- a/package/cpp/specs/HybridNitroSQLiteQueryResult.cpp +++ b/package/cpp/specs/HybridNitroSQLiteQueryResult.cpp @@ -9,41 +9,23 @@ namespace margelo::nitro::rnnitrosqlite { std::optional HybridNitroSQLiteQueryResult::getInsertId() { - return _result.insertId; + return _insertId; } double HybridNitroSQLiteQueryResult::getRowsAffected() { - return _result.rowsAffected; + return _rowsAffected; } SQLiteQueryResults HybridNitroSQLiteQueryResult::getResults() { - return _result.results; + return _results; }; std::optional HybridNitroSQLiteQueryResult::getRows() { - if (_result.results.empty()) { - return std::nullopt; - } - - auto rows = _result.results; - - // Create the item function that returns a Promise - auto itemFunction = [rows](double idx) -> std::shared_ptr>> { - return Promise>::async([rows, idx]() -> std::optional { - const auto index = static_cast(idx); - if (index >= rows.size()) { - return std::nullopt; - } - return rows[index]; - }); - }; - - const auto length = static_cast(rows.size()); - return NitroSQLiteQueryResultRows(std::move(rows), length, itemFunction); + return _rows; } std::optional HybridNitroSQLiteQueryResult::getMetadata() { - return _result.metadata; + return _metadata; } } // namespace margelo::nitro::rnnitrosqlite diff --git a/package/cpp/specs/HybridNitroSQLiteQueryResult.hpp b/package/cpp/specs/HybridNitroSQLiteQueryResult.hpp index bad545d..a06a99d 100644 --- a/package/cpp/specs/HybridNitroSQLiteQueryResult.hpp +++ b/package/cpp/specs/HybridNitroSQLiteQueryResult.hpp @@ -11,10 +11,39 @@ namespace margelo::nitro::rnnitrosqlite { class HybridNitroSQLiteQueryResult : public HybridNitroSQLiteQueryResultSpec { public: HybridNitroSQLiteQueryResult() : HybridObject(TAG) {} - HybridNitroSQLiteQueryResult(SQLiteExecuteQueryResult&& result) : HybridObject(TAG), _result(std::move(result)) {} + HybridNitroSQLiteQueryResult(SQLiteQueryResults results, std::optional insertId, double rowsAffected, + std::optional metadata) + : HybridObject(TAG), _insertId(insertId), _rowsAffected(rowsAffected), _results(std::move(results)), _metadata(metadata) { + if (_results.empty()) { + // Empty rows: empty vector, length 0, item callback always returns null + auto emptyItem = [](double /* idx */) -> std::shared_ptr>> { + return Promise>::async([]() -> std::optional { return std::nullopt; }); + }; + _rows = NitroSQLiteQueryResultRows(SQLiteQueryResults{}, 0.0, std::move(emptyItem)); + return; + } + + auto rows = _results; + auto itemFunction = [rows](double idx) -> std::shared_ptr>> { + return Promise>::async([rows, idx]() -> std::optional { + const auto index = static_cast(idx); + if (index >= rows.size()) { + return std::nullopt; + } + return rows[index]; + }); + }; + + const auto length = static_cast(rows.size()); + _rows = NitroSQLiteQueryResultRows(std::move(rows), length, std::move(itemFunction)); + } private: - SQLiteExecuteQueryResult _result; + std::optional _insertId; + double _rowsAffected; + SQLiteQueryResults _results; + std::optional _rows; + std::optional _metadata; public: // Properties diff --git a/package/cpp/sqliteExecuteBatch.cpp b/package/cpp/sqliteExecuteBatch.cpp index 7e06770..4aca8b5 100644 --- a/package/cpp/sqliteExecuteBatch.cpp +++ b/package/cpp/sqliteExecuteBatch.cpp @@ -49,7 +49,7 @@ SQLiteOperationResult sqliteExecuteBatch(const std::string& dbName, const std::v auto metadata = std::optional(std::nullopt); try { auto result = sqliteExecute(dbName, command.sql, command.params); - rowsAffected += result.rowsAffected; + rowsAffected += result->getRowsAffected(); } catch (NitroSQLiteException& e) { sqliteExecuteLiteral(dbName, "ROLLBACK"); throw e; diff --git a/package/cpp/types.hpp b/package/cpp/types.hpp index 48d1e5f..eefa83a 100644 --- a/package/cpp/types.hpp +++ b/package/cpp/types.hpp @@ -18,16 +18,7 @@ using SQLiteQueryTableMetadata = std::unordered_map metadata; + int commands = 0; }; // constexpr function that maps SQLiteColumnType to string literals diff --git a/package/src/operations/execute.ts b/package/src/operations/execute.ts index c0ef34b..071bdd3 100644 --- a/package/src/operations/execute.ts +++ b/package/src/operations/execute.ts @@ -1,5 +1,4 @@ import { HybridNitroSQLite } from '../nitro' -import type { NitroSQLiteQueryResult } from '../specs/NitroSQLiteQueryResult.nitro' import type { QueryResult, QueryResultRow, SQLiteQueryParams } from '../types' import NitroSQLiteError from '../NitroSQLiteError' @@ -10,7 +9,7 @@ export function execute( ): QueryResult { try { const result = HybridNitroSQLite.execute(dbName, query, params) - return buildJsQueryResult(result) + return result as QueryResult } catch (error) { throw NitroSQLiteError.fromError(error) } @@ -23,25 +22,8 @@ export async function executeAsync( ): Promise> { try { const result = await HybridNitroSQLite.executeAsync(dbName, query, params) - return buildJsQueryResult(result) + return result as QueryResult } catch (error) { throw NitroSQLiteError.fromError(error) } } - -function buildJsQueryResult( - result: NitroSQLiteQueryResult, -): QueryResult { - const data = result.results as Row[] - - return { - ...result, - insertId: result.insertId, - rowsAffected: result.rowsAffected, - rows: { - _array: data, - length: data.length, - item: (idx: number) => data[idx], - }, - } as QueryResult -} diff --git a/package/src/types.ts b/package/src/types.ts index 09e652e..3ceba31 100644 --- a/package/src/types.ts +++ b/package/src/types.ts @@ -1,5 +1,4 @@ import type { - NitroSQLiteQueryColumnMetadata, NitroSQLiteQueryResult, NitroSQLiteQueryResultRows, } from './specs/NitroSQLiteQueryResult.nitro' @@ -42,17 +41,8 @@ export type QueryResultRow = Record export type QueryResult = NitroSQLiteQueryResult & { - readonly rowsAffected: number - readonly insertId?: number - - /** Query results */ - readonly results: Row[] - /** Query results in a row format for TypeORM compatibility */ - readonly rows?: NitroSQLiteQueryResultRows - - /** Table metadata */ - readonly metadata?: Record + rows?: NitroSQLiteQueryResultRows } export type ExecuteQuery = (