Skip to content

Commit c5f294d

Browse files
committed
rebase and fix code after all merges
1 parent f584037 commit c5f294d

32 files changed

+647
-728
lines changed

docs/usage.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,12 @@ struct Record { int a; int b; int c; };
4141
auto conn = SqlConnection {};
4242
auto stmt = SqlStatement { conn };
4343
stmt.Prepare("SELECT a, b, c FROM That WHERE a = ? OR b = ?");
44-
stmt.Execute(42, 43);
44+
auto cursor = stmt.Execute(42, 43);
4545

46-
SqlResultCursor cursor = stmt.GetResultCursor();
4746
auto record = Record {};
48-
cursor.BindOutputColumns<Record>(&record.a, &rcord.b, &record.c);
47+
cursor.BindOutputColumns(&record.a, &record.b, &record.c);
4948
while (cursor.FetchRow())
50-
std::println("{}|{}|{}", a, b, c);
49+
std::println("{}|{}|{}", record.a, record.b, record.c);
5150
```
5251
5352
## SQL Query Builder

src/Lightweight/DataMapper/DataMapper.hpp

Lines changed: 56 additions & 100 deletions
Large diffs are not rendered by default.

src/Lightweight/SqlBackup/Backup.cpp

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -283,9 +283,9 @@ void ProcessTableBackup(BackupContext& ctx, SqlConnection& conn, SqlSchema::Tabl
283283
// Build query with current offset for resumption
284284
auto const selectQuery = BuildSelectQueryWithOffset(
285285
formatter, conn.ServerType(), table.schema, tableName, table.columns, table.primaryKeys, processedRows);
286-
stmt.ExecuteDirect(selectQuery);
286+
auto cursor = stmt.ExecuteDirect(selectQuery);
287287

288-
while (stmt.FetchRow())
288+
while (cursor.FetchRow())
289289
{
290290
if constexpr (DebugBackupWorker)
291291
std::println(stderr, "DEBUG: FetchRow returned true for {}", tableName);
@@ -305,7 +305,7 @@ void ProcessTableBackup(BackupContext& ctx, SqlConnection& conn, SqlSchema::Tabl
305305
{
306306
try
307307
{
308-
auto valOpt = stmt.GetNullableColumn<SqlDynamicBinary<MaxBinaryLobBufferSize>>(i);
308+
auto valOpt = cursor.GetNullableColumn<SqlDynamicBinary<MaxBinaryLobBufferSize>>(i);
309309
if (valOpt)
310310
{
311311
row.emplace_back(std::vector<uint8_t>(valOpt->data(), valOpt->data() + valOpt->size()));
@@ -325,7 +325,7 @@ void ProcessTableBackup(BackupContext& ctx, SqlConnection& conn, SqlSchema::Tabl
325325
}
326326
else if (std::holds_alternative<Bool>(colDef.type))
327327
{
328-
auto valOpt = stmt.GetNullableColumn<bool>(i);
328+
auto valOpt = cursor.GetNullableColumn<bool>(i);
329329
if (valOpt)
330330
row.emplace_back(*valOpt);
331331
else
@@ -335,23 +335,23 @@ void ProcessTableBackup(BackupContext& ctx, SqlConnection& conn, SqlSchema::Tabl
335335
|| std::holds_alternative<Smallint>(colDef.type)
336336
|| std::holds_alternative<Tinyint>(colDef.type))
337337
{
338-
auto valOpt = stmt.GetNullableColumn<int64_t>(i);
338+
auto valOpt = cursor.GetNullableColumn<int64_t>(i);
339339
if (valOpt)
340340
row.emplace_back(*valOpt);
341341
else
342342
row.emplace_back(std::monostate {});
343343
}
344344
else if (std::holds_alternative<Real>(colDef.type))
345345
{
346-
auto valOpt = stmt.GetNullableColumn<double>(i);
346+
auto valOpt = cursor.GetNullableColumn<double>(i);
347347
if (valOpt)
348348
row.emplace_back(*valOpt);
349349
else
350350
row.emplace_back(std::monostate {});
351351
}
352352
else if (std::holds_alternative<NVarchar>(colDef.type) || std::holds_alternative<NChar>(colDef.type))
353353
{
354-
auto valOpt = stmt.GetNullableColumn<std::u16string>(i);
354+
auto valOpt = cursor.GetNullableColumn<std::u16string>(i);
355355
if (valOpt)
356356
{
357357
auto u8 = ToUtf8(*valOpt);
@@ -363,7 +363,7 @@ void ProcessTableBackup(BackupContext& ctx, SqlConnection& conn, SqlSchema::Tabl
363363
else if (std::holds_alternative<Guid>(colDef.type))
364364
{
365365
// Read GUID columns using SqlGuid for proper ODBC binding, then convert to string
366-
auto valOpt = stmt.GetNullableColumn<SqlGuid>(i);
366+
auto valOpt = cursor.GetNullableColumn<SqlGuid>(i);
367367
if (valOpt)
368368
row.emplace_back(to_string(*valOpt));
369369
else
@@ -374,7 +374,7 @@ void ProcessTableBackup(BackupContext& ctx, SqlConnection& conn, SqlSchema::Tabl
374374
// Read Decimal as string directly to preserve full precision.
375375
// Using double would lose precision for values exceeding ~15-17 significant digits,
376376
// which is problematic for DECIMAL(38,10) and similar high-precision types.
377-
auto valOpt = stmt.GetNullableColumn<std::string>(i);
377+
auto valOpt = cursor.GetNullableColumn<std::string>(i);
378378
if (valOpt)
379379
row.emplace_back(*valOpt);
380380
else
@@ -383,7 +383,7 @@ void ProcessTableBackup(BackupContext& ctx, SqlConnection& conn, SqlSchema::Tabl
383383
else if (std::holds_alternative<Date>(colDef.type))
384384
{
385385
// Read Date using native type to avoid ODBC driver conversion issues.
386-
auto valOpt = stmt.GetNullableColumn<SqlDate>(i);
386+
auto valOpt = cursor.GetNullableColumn<SqlDate>(i);
387387
if (valOpt)
388388
row.emplace_back(std::format("{}", *valOpt));
389389
else
@@ -398,7 +398,7 @@ void ProcessTableBackup(BackupContext& ctx, SqlConnection& conn, SqlSchema::Tabl
398398
if (conn.ServerType() == SqlServerType::POSTGRESQL
399399
|| conn.ServerType() == SqlServerType::MICROSOFT_SQL)
400400
{
401-
auto valOpt = stmt.GetNullableColumn<std::string>(i);
401+
auto valOpt = cursor.GetNullableColumn<std::string>(i);
402402
if (valOpt)
403403
row.emplace_back(*valOpt);
404404
else
@@ -407,7 +407,7 @@ void ProcessTableBackup(BackupContext& ctx, SqlConnection& conn, SqlSchema::Tabl
407407
else
408408
{
409409
// Read Time using native type for other databases (e.g., SQLite).
410-
auto valOpt = stmt.GetNullableColumn<SqlTime>(i);
410+
auto valOpt = cursor.GetNullableColumn<SqlTime>(i);
411411
if (valOpt)
412412
row.emplace_back(std::format("{}", *valOpt));
413413
else
@@ -419,7 +419,7 @@ void ProcessTableBackup(BackupContext& ctx, SqlConnection& conn, SqlSchema::Tabl
419419
{
420420
// Read DateTime/Timestamp using native type to avoid MS SQL Server ODBC driver
421421
// issues with SQL_TYPE_TIMESTAMP to SQL_C_CHAR conversion (error 22003).
422-
auto valOpt = stmt.GetNullableColumn<SqlDateTime>(i);
422+
auto valOpt = cursor.GetNullableColumn<SqlDateTime>(i);
423423
if (valOpt)
424424
row.emplace_back(std::format("{}", *valOpt));
425425
else
@@ -431,7 +431,7 @@ void ProcessTableBackup(BackupContext& ctx, SqlConnection& conn, SqlSchema::Tabl
431431
// Read text/string types as strings directly.
432432
// Note: We must not use SqlDynamicBinary for text types on PostgreSQL as its ODBC driver
433433
// does not support reading TEXT as SQL_C_BINARY.
434-
auto valOpt = stmt.GetNullableColumn<std::string>(i);
434+
auto valOpt = cursor.GetNullableColumn<std::string>(i);
435435
if (valOpt)
436436
row.emplace_back(*valOpt);
437437
else
@@ -440,7 +440,7 @@ void ProcessTableBackup(BackupContext& ctx, SqlConnection& conn, SqlSchema::Tabl
440440
else
441441
{
442442
// Fallback for any unhandled types - try reading as string
443-
auto valOpt = stmt.GetNullableColumn<std::string>(i);
443+
auto valOpt = cursor.GetNullableColumn<std::string>(i);
444444
if (valOpt)
445445
row.emplace_back(*valOpt);
446446
else

src/Lightweight/SqlBackup/Common.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ bool DropTableIfExists(SqlConnection& conn,
116116
// PostgreSQL which uses CASCADE syntax, and SQLite which ignores cascade.
117117
auto dropSqls = formatter.DropTable(schema, tableName, /*ifExists=*/true, /*cascade=*/true);
118118
for (auto const& sql: dropSqls)
119-
SqlStatement { conn }.ExecuteDirect(sql);
119+
(void) SqlStatement { conn }.ExecuteDirect(sql);
120120
return true;
121121
}
122122
catch (std::exception const& e)

src/Lightweight/SqlBackup/Restore.cpp

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ bool RestoreChunkData(RestoreContext& ctx, SqlConnection& workerConn, RestoreChu
152152
if (hasIdentity)
153153
{
154154
identityTable = FormatTableName(ctx.schema, tableName);
155-
SqlStatement { workerConn }.ExecuteDirect(std::format("SET IDENTITY_INSERT {} ON", identityTable));
155+
(void) SqlStatement { workerConn }.ExecuteDirect(std::format("SET IDENTITY_INSERT {} ON", identityTable));
156156
}
157157
}
158158

@@ -166,7 +166,7 @@ bool RestoreChunkData(RestoreContext& ctx, SqlConnection& workerConn, RestoreChu
166166
stmt.Prepare(formatter.Insert(ctx.schema, tableName, fields, placeholders));
167167

168168
::Lightweight::detail::BatchManager batchManager(
169-
[&](std::vector<SqlRawColumn> const& cols, size_t rows) { stmt.ExecuteBatch(cols, rows); },
169+
[&](std::vector<SqlRawColumn> const& cols, size_t rows) { (void) stmt.ExecuteBatch(cols, rows); },
170170
tableInfo.columns,
171171
batchCapacity,
172172
workerConn.ServerType());
@@ -221,14 +221,14 @@ bool RestoreChunkData(RestoreContext& ctx, SqlConnection& workerConn, RestoreChu
221221

222222
batchManager.Flush();
223223
transaction.Commit();
224-
stmt.CloseCursor();
224+
// Cursor cleanup is handled by RAII
225225
}
226226

227227
if (hasIdentity)
228228
{
229229
try
230230
{
231-
SqlStatement { workerConn }.ExecuteDirect(std::format("SET IDENTITY_INSERT {} OFF", identityTable));
231+
(void) SqlStatement { workerConn }.ExecuteDirect(std::format("SET IDENTITY_INSERT {} OFF", identityTable));
232232
}
233233
catch (...) // NOLINT(bugprone-empty-catch)
234234
{
@@ -277,12 +277,12 @@ bool RestoreChunkData(RestoreContext& ctx, SqlConnection& workerConn, RestoreChu
277277
// Re-apply SQLite optimizations after reconnect
278278
if (workerConn.ServerType() == SqlServerType::SQLITE)
279279
{
280-
SqlStatement { workerConn }.ExecuteDirect("PRAGMA synchronous = OFF");
281-
SqlStatement { workerConn }.ExecuteDirect("PRAGMA journal_mode = WAL");
282-
SqlStatement { workerConn }.ExecuteDirect("PRAGMA foreign_keys = OFF");
280+
(void) SqlStatement { workerConn }.ExecuteDirect("PRAGMA synchronous = OFF");
281+
(void) SqlStatement { workerConn }.ExecuteDirect("PRAGMA journal_mode = WAL");
282+
(void) SqlStatement { workerConn }.ExecuteDirect("PRAGMA foreign_keys = OFF");
283283
if (ctx.restoreSettings.cacheSizeKB > 0)
284284
{
285-
SqlStatement { workerConn }.ExecuteDirect(
285+
(void) SqlStatement { workerConn }.ExecuteDirect(
286286
std::format("PRAGMA cache_size = -{}", ctx.restoreSettings.cacheSizeKB));
287287
}
288288
}
@@ -311,12 +311,12 @@ void RestoreWorker(RestoreContext ctx, SqlConnection& workerConn)
311311
// SQLite optimization: Turn off synchronization for faster restore
312312
if (workerConn.ServerType() == SqlServerType::SQLITE)
313313
{
314-
SqlStatement { workerConn }.ExecuteDirect("PRAGMA synchronous = OFF");
315-
SqlStatement { workerConn }.ExecuteDirect("PRAGMA journal_mode = WAL");
316-
SqlStatement { workerConn }.ExecuteDirect("PRAGMA foreign_keys = OFF");
314+
(void) SqlStatement { workerConn }.ExecuteDirect("PRAGMA synchronous = OFF");
315+
(void) SqlStatement { workerConn }.ExecuteDirect("PRAGMA journal_mode = WAL");
316+
(void) SqlStatement { workerConn }.ExecuteDirect("PRAGMA foreign_keys = OFF");
317317
if (ctx.restoreSettings.cacheSizeKB > 0)
318318
{
319-
SqlStatement { workerConn }.ExecuteDirect(
319+
(void) SqlStatement { workerConn }.ExecuteDirect(
320320
std::format("PRAGMA cache_size = -{}", ctx.restoreSettings.cacheSizeKB));
321321
}
322322
}
@@ -414,7 +414,7 @@ void RestoreIndexes(SqlConnectionString const& connectionString,
414414
std::string const sql = std::format(
415415
R"(CREATE {}INDEX "{}" ON {} ({}))", uniqueKeyword, idx.name, formattedTableName, columnList);
416416

417-
SqlStatement { conn }.ExecuteDirect(sql);
417+
(void) SqlStatement { conn }.ExecuteDirect(sql);
418418

419419
progress.Update({ .state = Progress::State::InProgress,
420420
.tableName = tableName,
@@ -475,7 +475,7 @@ void ApplyDatabaseConstraints(SqlConnectionString const& connectionString,
475475
{
476476
auto sqls = formatter.AlterTable(schema, tableName, commands);
477477
for (auto const& sql: sqls)
478-
SqlStatement { conn }.ExecuteDirect(sql);
478+
(void) SqlStatement { conn }.ExecuteDirect(sql);
479479
}
480480
catch (std::exception const& e)
481481
{
@@ -597,7 +597,7 @@ std::set<std::string> CreateTablesInOrder(SqlConnection& conn,
597597
std::string const formattedTableName = FormatTableName(schema, tableName);
598598
try
599599
{
600-
SqlStatement { conn }.ExecuteDirect(
600+
(void) SqlStatement { conn }.ExecuteDirect(
601601
std::format("ALTER TABLE {} DROP CONSTRAINT IF EXISTS \"{}\"", formattedTableName, fkName));
602602
}
603603
catch (...) // NOLINT(bugprone-empty-catch)
@@ -638,7 +638,7 @@ std::set<std::string> CreateTablesInOrder(SqlConnection& conn,
638638
{
639639
try
640640
{
641-
SqlStatement { conn }.ExecuteDirect(sql);
641+
(void) SqlStatement { conn }.ExecuteDirect(sql);
642642
}
643643
catch (std::exception const& e)
644644
{
@@ -690,9 +690,9 @@ std::set<std::string> RecreateDatabaseSchema(SqlConnectionString const& connecti
690690
if (isSQLite)
691691
{
692692
SqlStatement stmt { conn };
693-
stmt.ExecuteDirect("PRAGMA synchronous = OFF");
694-
stmt.ExecuteDirect("PRAGMA journal_mode = WAL");
695-
stmt.ExecuteDirect("PRAGMA foreign_keys = OFF"); // Disable FKs during restore
693+
(void) stmt.ExecuteDirect("PRAGMA synchronous = OFF");
694+
(void) stmt.ExecuteDirect("PRAGMA journal_mode = WAL");
695+
(void) stmt.ExecuteDirect("PRAGMA foreign_keys = OFF"); // Disable FKs during restore
696696
}
697697

698698
auto const tableOrder = ComputeTableCreationOrder(tableMap, isSQLite);

src/Lightweight/SqlConnection.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ void SqlConnection::PostConnect()
270270
// Set a busy timeout to prevent "database is locked" errors during concurrent access.
271271
// 60 seconds should be sufficient for most operations.
272272
SqlStatement stmt(*this);
273-
stmt.ExecuteDirect("PRAGMA busy_timeout = 60000");
273+
[[maybe_unused]] auto cursor = stmt.ExecuteDirect("PRAGMA busy_timeout = 60000");
274274

275275
// We could also enable WAL mode here, but that changes the database file structure.
276276
// However, for high-concurrency restoration, it is highly recommended.

src/Lightweight/SqlMigration.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ void MigrationManager::ApplySingleMigration(MigrationBase const& migration)
145145
{
146146
try
147147
{
148-
stmt.ExecuteDirect(sqlScript);
148+
(void) stmt.ExecuteDirect(sqlScript);
149149
}
150150
catch (SqlException const& ex)
151151
{
@@ -197,7 +197,7 @@ void MigrationManager::RevertSingleMigration(MigrationBase const& migration)
197197
{
198198
try
199199
{
200-
stmt.ExecuteDirect(sqlScript);
200+
(void) stmt.ExecuteDirect(sqlScript);
201201
}
202202
catch (SqlException const& ex)
203203
{

0 commit comments

Comments
 (0)