Skip to content

Commit 5e108c5

Browse files
authored
fix: Keep hybrid object data (#255)
* fix: c++ hybrid objects not constructed properly * fix: remove `buildJsQueryResult` and simplify types * chore: update Claude permissions * fix: properly construct `HybridNitroSQLiteQueryResult` * chore: lint cpp
1 parent 4851d5d commit 5e108c5

11 files changed

Lines changed: 60 additions & 82 deletions

.claude/settings.local.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"permissions": {
3+
"allow": [
4+
"Bash(find:*)",
5+
"Bash(grep:*)"
6+
]
7+
}
8+
}

package/cpp/NitroSQLiteException.hpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,11 @@
22

33
#include <exception>
44
#include <iostream>
5-
#include <string>
65
#include <optional>
6+
#include <string>
77

88
const std::string NITRO_SQLITE_EXCEPTION_PREFIX = "[NativeNitroSQLiteException]";
99

10-
1110
enum NitroSQLiteExceptionType {
1211
UnknownError,
1312
DatabaseCannotBeOpened,

package/cpp/operations.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "operations.hpp"
22
#include "NitroSQLiteException.hpp"
33
#include "logs.hpp"
4+
#include "specs/HybridNitroSQLiteQueryResult.hpp"
45
#include "utils.hpp"
56
#include <NitroModules/ArrayBuffer.hpp>
67
#include <cmath>
@@ -121,8 +122,8 @@ void bindStatement(sqlite3_stmt* statement, const SQLiteQueryParams& values) {
121122
}
122123
}
123124

124-
SQLiteExecuteQueryResult sqliteExecute(const std::string& dbName, const std::string& query,
125-
const std::optional<SQLiteQueryParams>& params) {
125+
std::shared_ptr<HybridNitroSQLiteQueryResult> sqliteExecute(const std::string& dbName, const std::string& query,
126+
const std::optional<SQLiteQueryParams>& params) {
126127
if (dbMap.count(dbName) == 0) {
127128
throw NitroSQLiteException::DatabaseNotOpen(dbName);
128129
}
@@ -229,10 +230,7 @@ SQLiteExecuteQueryResult sqliteExecute(const std::string& dbName, const std::str
229230

230231
int rowsAffected = sqlite3_changes(db);
231232
long long latestInsertRowId = sqlite3_last_insert_rowid(db);
232-
return {.rowsAffected = rowsAffected,
233-
.insertId = static_cast<double>(latestInsertRowId),
234-
.results = std::move(results),
235-
.metadata = std::move(metadata)};
233+
return std::make_shared<HybridNitroSQLiteQueryResult>(results, static_cast<double>(latestInsertRowId), rowsAffected, metadata);
236234
}
237235

238236
SQLiteOperationResult sqliteExecuteLiteral(const std::string& dbName, const std::string& query) {

package/cpp/operations.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#pragma once
22

3+
#include "specs/HybridNitroSQLiteQueryResult.hpp"
34
#include "types.hpp"
45

56
namespace margelo::rnnitrosqlite {
@@ -15,7 +16,8 @@ void sqliteAttachDb(const std::string& mainDBName, const std::string& docPath, c
1516

1617
void sqliteDetachDb(const std::string& mainDBName, const std::string& alias);
1718

18-
SQLiteExecuteQueryResult sqliteExecute(const std::string& dbName, const std::string& query, const std::optional<SQLiteQueryParams>& params);
19+
std::shared_ptr<HybridNitroSQLiteQueryResult> sqliteExecute(const std::string& dbName, const std::string& query,
20+
const std::optional<SQLiteQueryParams>& params);
1921

2022
SQLiteOperationResult sqliteExecuteLiteral(const std::string& dbName, const std::string& query);
2123

package/cpp/specs/HybridNitroSQLite.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,9 @@ void HybridNitroSQLite::detach(const std::string& mainDbName, const std::string&
5050
sqliteDetachDb(mainDbName, alias);
5151
};
5252

53-
using ExecuteQueryResult = std::shared_ptr<HybridNitroSQLiteQueryResultSpec>;
54-
55-
ExecuteQueryResult HybridNitroSQLite::execute(const std::string& dbName, const std::string& query,
56-
const std::optional<SQLiteQueryParams>& params) {
57-
SQLiteExecuteQueryResult result = sqliteExecute(dbName, query, params);
58-
return std::make_shared<HybridNitroSQLiteQueryResult>(std::move(result));
53+
std::shared_ptr<HybridNitroSQLiteQueryResultSpec> HybridNitroSQLite::execute(const std::string& dbName, const std::string& query,
54+
const std::optional<SQLiteQueryParams>& params) {
55+
return sqliteExecute(dbName, query, params);
5956
};
6057

6158
std::shared_ptr<Promise<std::shared_ptr<HybridNitroSQLiteQueryResultSpec>>>

package/cpp/specs/HybridNitroSQLiteQueryResult.cpp

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -9,41 +9,23 @@
99
namespace margelo::nitro::rnnitrosqlite {
1010

1111
std::optional<double> HybridNitroSQLiteQueryResult::getInsertId() {
12-
return _result.insertId;
12+
return _insertId;
1313
}
1414

1515
double HybridNitroSQLiteQueryResult::getRowsAffected() {
16-
return _result.rowsAffected;
16+
return _rowsAffected;
1717
}
1818

1919
SQLiteQueryResults HybridNitroSQLiteQueryResult::getResults() {
20-
return _result.results;
20+
return _results;
2121
};
2222

2323
std::optional<NitroSQLiteQueryResultRows> HybridNitroSQLiteQueryResult::getRows() {
24-
if (_result.results.empty()) {
25-
return std::nullopt;
26-
}
27-
28-
auto rows = _result.results;
29-
30-
// Create the item function that returns a Promise
31-
auto itemFunction = [rows](double idx) -> std::shared_ptr<Promise<std::optional<SQLiteQueryResultRow>>> {
32-
return Promise<std::optional<SQLiteQueryResultRow>>::async([rows, idx]() -> std::optional<SQLiteQueryResultRow> {
33-
const auto index = static_cast<size_t>(idx);
34-
if (index >= rows.size()) {
35-
return std::nullopt;
36-
}
37-
return rows[index];
38-
});
39-
};
40-
41-
const auto length = static_cast<double>(rows.size());
42-
return NitroSQLiteQueryResultRows(std::move(rows), length, itemFunction);
24+
return _rows;
4325
}
4426

4527
std::optional<SQLiteQueryTableMetadata> HybridNitroSQLiteQueryResult::getMetadata() {
46-
return _result.metadata;
28+
return _metadata;
4729
}
4830

4931
} // namespace margelo::nitro::rnnitrosqlite

package/cpp/specs/HybridNitroSQLiteQueryResult.hpp

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,39 @@ namespace margelo::nitro::rnnitrosqlite {
1111
class HybridNitroSQLiteQueryResult : public HybridNitroSQLiteQueryResultSpec {
1212
public:
1313
HybridNitroSQLiteQueryResult() : HybridObject(TAG) {}
14-
HybridNitroSQLiteQueryResult(SQLiteExecuteQueryResult&& result) : HybridObject(TAG), _result(std::move(result)) {}
14+
HybridNitroSQLiteQueryResult(SQLiteQueryResults results, std::optional<double> insertId, double rowsAffected,
15+
std::optional<SQLiteQueryTableMetadata> metadata)
16+
: HybridObject(TAG), _insertId(insertId), _rowsAffected(rowsAffected), _results(std::move(results)), _metadata(metadata) {
17+
if (_results.empty()) {
18+
// Empty rows: empty vector, length 0, item callback always returns null
19+
auto emptyItem = [](double /* idx */) -> std::shared_ptr<Promise<std::optional<SQLiteQueryResultRow>>> {
20+
return Promise<std::optional<SQLiteQueryResultRow>>::async([]() -> std::optional<SQLiteQueryResultRow> { return std::nullopt; });
21+
};
22+
_rows = NitroSQLiteQueryResultRows(SQLiteQueryResults{}, 0.0, std::move(emptyItem));
23+
return;
24+
}
25+
26+
auto rows = _results;
27+
auto itemFunction = [rows](double idx) -> std::shared_ptr<Promise<std::optional<SQLiteQueryResultRow>>> {
28+
return Promise<std::optional<SQLiteQueryResultRow>>::async([rows, idx]() -> std::optional<SQLiteQueryResultRow> {
29+
const auto index = static_cast<size_t>(idx);
30+
if (index >= rows.size()) {
31+
return std::nullopt;
32+
}
33+
return rows[index];
34+
});
35+
};
36+
37+
const auto length = static_cast<double>(rows.size());
38+
_rows = NitroSQLiteQueryResultRows(std::move(rows), length, std::move(itemFunction));
39+
}
1540

1641
private:
17-
SQLiteExecuteQueryResult _result;
42+
std::optional<double> _insertId;
43+
double _rowsAffected;
44+
SQLiteQueryResults _results;
45+
std::optional<NitroSQLiteQueryResultRows> _rows;
46+
std::optional<SQLiteQueryTableMetadata> _metadata;
1847

1948
public:
2049
// Properties

package/cpp/sqliteExecuteBatch.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ SQLiteOperationResult sqliteExecuteBatch(const std::string& dbName, const std::v
4949
auto metadata = std::optional<SQLiteQueryTableMetadata>(std::nullopt);
5050
try {
5151
auto result = sqliteExecute(dbName, command.sql, command.params);
52-
rowsAffected += result.rowsAffected;
52+
rowsAffected += result->getRowsAffected();
5353
} catch (NitroSQLiteException& e) {
5454
sqliteExecuteLiteral(dbName, "ROLLBACK");
5555
throw e;

package/cpp/types.hpp

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,7 @@ using SQLiteQueryTableMetadata = std::unordered_map<std::string, NitroSQLiteQuer
1818

1919
struct SQLiteOperationResult {
2020
int rowsAffected;
21-
double insertId;
22-
int commands;
23-
};
24-
25-
struct SQLiteExecuteQueryResult {
26-
int rowsAffected;
27-
double insertId;
28-
29-
SQLiteQueryResults results;
30-
std::optional<SQLiteQueryTableMetadata> metadata;
21+
int commands = 0;
3122
};
3223

3324
// constexpr function that maps SQLiteColumnType to string literals

package/src/operations/execute.ts

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { HybridNitroSQLite } from '../nitro'
2-
import type { NitroSQLiteQueryResult } from '../specs/NitroSQLiteQueryResult.nitro'
32
import type { QueryResult, QueryResultRow, SQLiteQueryParams } from '../types'
43
import NitroSQLiteError from '../NitroSQLiteError'
54

@@ -10,7 +9,7 @@ export function execute<Row extends QueryResultRow = never>(
109
): QueryResult<Row> {
1110
try {
1211
const result = HybridNitroSQLite.execute(dbName, query, params)
13-
return buildJsQueryResult<Row>(result)
12+
return result as QueryResult<Row>
1413
} catch (error) {
1514
throw NitroSQLiteError.fromError(error)
1615
}
@@ -23,25 +22,8 @@ export async function executeAsync<Row extends QueryResultRow = never>(
2322
): Promise<QueryResult<Row>> {
2423
try {
2524
const result = await HybridNitroSQLite.executeAsync(dbName, query, params)
26-
return buildJsQueryResult<Row>(result)
25+
return result as QueryResult<Row>
2726
} catch (error) {
2827
throw NitroSQLiteError.fromError(error)
2928
}
3029
}
31-
32-
function buildJsQueryResult<Row extends QueryResultRow = never>(
33-
result: NitroSQLiteQueryResult,
34-
): QueryResult<Row> {
35-
const data = result.results as Row[]
36-
37-
return {
38-
...result,
39-
insertId: result.insertId,
40-
rowsAffected: result.rowsAffected,
41-
rows: {
42-
_array: data,
43-
length: data.length,
44-
item: (idx: number) => data[idx],
45-
},
46-
} as QueryResult<Row>
47-
}

0 commit comments

Comments
 (0)