Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ if (statement.execute(transaction))
transaction.commit();
```

Note that `execute()` already fetches a SELECT's first row — that is why the loop above is
`if (execute()) do ... while (fetchNext());` and not `execute(); while (fetchNext()) ...`,
which would silently skip the first row. `execute()` is marked `[[nodiscard]]` so the
compiler warns about the latter shape; cast to `void` to deliberately discard the result
(e.g. for DDL/DML, or when a row is known to exist).

## Using with vcpkg

This library is present in [firebird-vcpkg-registry](https://github.com/asfernandes/firebird-vcpkg-registry).
Expand Down
18 changes: 18 additions & 0 deletions src/fb-cpp/Statement.h
Original file line number Diff line number Diff line change
Expand Up @@ -309,9 +309,15 @@ namespace fbcpp

///
/// @brief Executes a prepared statement using the supplied transaction.
///
/// For a SELECT, this opens the cursor and already fetches the first row - a subsequent
/// `fetchNext()` positions on the second row. Cast to `void` to deliberately discard the
/// result (e.g. for DDL/DML, or when a row is known to exist).
///
/// @param transaction Transaction that will own the execution context.
/// @return `true` when execution yields a record.
///
[[nodiscard("execute() already fetches a SELECT's first row; looping on fetchNext() alone skips it")]]

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As you see, this is not needed for DDL and I do not want that (void) thing everywhere.

bool execute(Transaction& transaction);

///
Expand All @@ -320,32 +326,44 @@ namespace fbcpp

///
/// @brief Fetches the next row in the current result set.
/// @return `true` when a row was fetched.
///
[[nodiscard("without checking the result, the cursor may be past the end")]]
bool fetchNext();

///
/// @brief Fetches the previous row in the current result set.
/// @return `true` when a row was fetched.
///
[[nodiscard("without checking the result, the cursor may be before the start")]]
bool fetchPrior();

///
/// @brief Positions the cursor on the first row.
/// @return `true` when a row was fetched.
///
[[nodiscard("without checking the result, the cursor position is unknown")]]
bool fetchFirst();

///
/// @brief Positions the cursor on the last row.
/// @return `true` when a row was fetched.
///
[[nodiscard("without checking the result, the cursor position is unknown")]]
bool fetchLast();

///
/// @brief Positions the cursor on the given absolute row number.
/// @return `true` when a row was fetched.
///
[[nodiscard("without checking the result, the cursor position is unknown")]]
bool fetchAbsolute(unsigned position);

///
/// @brief Moves the cursor by the requested relative offset.
/// @return `true` when a row was fetched.
///
[[nodiscard("without checking the result, the cursor position is unknown")]]
bool fetchRelative(int offset);

///
Expand Down
14 changes: 7 additions & 7 deletions src/test/BackupManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,11 +169,11 @@ BOOST_DATA_TEST_CASE(backupAndRestoreRoundTrip, data::make(BACKUP_RESTORE_VERBOS

Statement create{
attachment, transaction, "create table test(id integer not null primary key, name varchar(20))"};
create.execute(transaction);
(void) create.execute(transaction);
transaction.commitRetaining();

Statement insert{attachment, transaction, "insert into test(id, name) values (1, 'backup')"};
insert.execute(transaction);
(void) insert.execute(transaction);
transaction.commit();
}

Expand Down Expand Up @@ -225,11 +225,11 @@ BOOST_AUTO_TEST_CASE(restoreReplace)
Transaction transaction{attachment};

Statement create{attachment, transaction, "create table test(id integer not null primary key)"};
create.execute(transaction);
(void) create.execute(transaction);
transaction.commitRetaining();

Statement insert{attachment, transaction, "insert into test(id) values (7)"};
insert.execute(transaction);
(void) insert.execute(transaction);
transaction.commit();
}

Expand Down Expand Up @@ -270,20 +270,20 @@ BOOST_AUTO_TEST_CASE(multiFileDatabaseAndBackupRoundTrip)

Statement create{
attachment, transaction, "create table test(id integer not null primary key, name varchar(50))"};
create.execute(transaction);
(void) create.execute(transaction);
transaction.commitRetaining();

Statement addFile{
attachment, transaction, "alter database add file '" + sourceSecondaryPath + "' starting at page 241"};
addFile.execute(transaction);
(void) addFile.execute(transaction);
transaction.commitRetaining();

for (int i = 1; i <= 200; ++i)
{
Statement insert{attachment, transaction, "insert into test(id, name) values (?, ?)"};
insert.setInt32(0, i);
insert.setString(1, "row-" + std::to_string(i) + std::string(40, 'x'));
insert.execute(transaction);
(void) insert.execute(transaction);
}
transaction.commitRetaining();

Expand Down
18 changes: 9 additions & 9 deletions src/test/Batch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ BOOST_AUTO_TEST_CASE(constructorFromStatementAndExecute)
{ // scope
Transaction transaction{attachment};
Statement ddl{attachment, transaction, "recreate table batch_test (id integer not null, name varchar(50))"};
ddl.execute(transaction);
(void) ddl.execute(transaction);
transaction.commit();
}

Expand Down Expand Up @@ -111,7 +111,7 @@ BOOST_AUTO_TEST_CASE(constructorFromAttachmentAndExecute)
{ // scope
Transaction transaction{attachment};
Statement ddl{attachment, transaction, "recreate table batch_test (id integer not null, val integer)"};
ddl.execute(transaction);
(void) ddl.execute(transaction);
transaction.commit();
}

Expand Down Expand Up @@ -184,7 +184,7 @@ BOOST_AUTO_TEST_CASE(moveConstructorTransfersOwnership)
{ // scope
Transaction transaction{attachment};
Statement ddl{attachment, transaction, "recreate table batch_test (id integer not null)"};
ddl.execute(transaction);
(void) ddl.execute(transaction);
transaction.commit();
}

Expand Down Expand Up @@ -220,7 +220,7 @@ BOOST_AUTO_TEST_CASE(executeReportsNoInfoWhenRecordCountsDisabled)
{ // scope
Transaction transaction{attachment};
Statement ddl{attachment, transaction, "recreate table batch_test (id integer not null)"};
ddl.execute(transaction);
(void) ddl.execute(transaction);
transaction.commit();
}

Expand Down Expand Up @@ -253,7 +253,7 @@ BOOST_AUTO_TEST_CASE(executeWithBadDataReportsExecuteFailed)
{ // scope
Transaction transaction{attachment};
Statement ddl{attachment, transaction, "recreate table batch_test (id integer not null primary key)"};
ddl.execute(transaction);
(void) ddl.execute(transaction);
transaction.commit();
}

Expand Down Expand Up @@ -312,7 +312,7 @@ BOOST_AUTO_TEST_CASE(cancelDiscardsMessages)
{ // scope
Transaction transaction{attachment};
Statement ddl{attachment, transaction, "recreate table batch_test (id integer not null)"};
ddl.execute(transaction);
(void) ddl.execute(transaction);
transaction.commit();
}

Expand Down Expand Up @@ -352,7 +352,7 @@ BOOST_AUTO_TEST_CASE(blobWithIdEngine)
{ // scope
Transaction transaction{attachment};
Statement ddl{attachment, transaction, "recreate table batch_test (id integer not null, data blob)"};
ddl.execute(transaction);
(void) ddl.execute(transaction);
transaction.commit();
}

Expand Down Expand Up @@ -410,7 +410,7 @@ BOOST_AUTO_TEST_CASE(registerExistingBlob)
{ // scope
Transaction transaction{attachment};
Statement ddl{attachment, transaction, "recreate table batch_test (id integer not null, data blob)"};
ddl.execute(transaction);
(void) ddl.execute(transaction);
transaction.commit();
}

Expand Down Expand Up @@ -473,7 +473,7 @@ BOOST_AUTO_TEST_CASE(closeReleasesHandle)
{ // scope
Transaction transaction{attachment};
Statement ddl{attachment, transaction, "recreate table batch_test (id integer not null)"};
ddl.execute(transaction);
(void) ddl.execute(transaction);
transaction.commit();
}

Expand Down
2 changes: 1 addition & 1 deletion src/test/DatabaseManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ BOOST_AUTO_TEST_CASE(restoreWithReplicaMode)
CLIENT, sourceDatabaseUri, AttachmentOptions().setCreateDatabase(true).setConnectionCharSet("UTF8")};
Transaction transaction{attachment};
Statement create{attachment, transaction, "create table test(id integer)"};
create.execute(transaction);
(void) create.execute(transaction);
transaction.commit();
}

Expand Down
24 changes: 12 additions & 12 deletions src/test/RowSet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,14 @@ BOOST_AUTO_TEST_CASE(fetchRowsIntoRowSet)
Transaction transaction{attachment};

Statement ddl{attachment, transaction, "create table t (col integer)"};
ddl.execute(transaction);
(void) ddl.execute(transaction);
transaction.commitRetaining();

Statement insert{attachment, transaction, "insert into t (col) values (?)"};
for (int i = 1; i <= 5; ++i)
{
insert.setInt32(0, i);
insert.execute(transaction);
(void) insert.execute(transaction);
}

Statement select{attachment, transaction, "select col from t order by col"};
Expand Down Expand Up @@ -79,14 +79,14 @@ BOOST_AUTO_TEST_CASE(fetchFewerRowsThanMaxRows)
Transaction transaction{attachment};

Statement ddl{attachment, transaction, "create table t (col integer)"};
ddl.execute(transaction);
(void) ddl.execute(transaction);
transaction.commitRetaining();

Statement insert{attachment, transaction, "insert into t (col) values (?)"};
for (int i = 1; i <= 3; ++i)
{
insert.setInt32(0, i);
insert.execute(transaction);
(void) insert.execute(transaction);
}

Statement select{attachment, transaction, "select col from t order by col"};
Expand All @@ -110,14 +110,14 @@ BOOST_AUTO_TEST_CASE(rowSetIsDisconnectedFromStatement)
Transaction transaction{attachment};

Statement ddl{attachment, transaction, "create table t (col integer)"};
ddl.execute(transaction);
(void) ddl.execute(transaction);
transaction.commitRetaining();

Statement insert{attachment, transaction, "insert into t (col) values (?)"};
for (int i = 1; i <= 3; ++i)
{
insert.setInt32(0, i);
insert.execute(transaction);
(void) insert.execute(transaction);
}

Statement select{attachment, transaction, "select col from t order by col"};
Expand Down Expand Up @@ -147,14 +147,14 @@ BOOST_AUTO_TEST_CASE(moveConstructor)
Transaction transaction{attachment};

Statement ddl{attachment, transaction, "create table t (col integer)"};
ddl.execute(transaction);
(void) ddl.execute(transaction);
transaction.commitRetaining();

Statement insert{attachment, transaction, "insert into t (col) values (?)"};
for (int i = 1; i <= 3; ++i)
{
insert.setInt32(0, i);
insert.execute(transaction);
(void) insert.execute(transaction);
}

Statement select{attachment, transaction, "select col from t order by col"};
Expand Down Expand Up @@ -182,14 +182,14 @@ BOOST_AUTO_TEST_CASE(moveAssignment)
Transaction transaction{attachment};

Statement ddl{attachment, transaction, "create table t (col integer)"};
ddl.execute(transaction);
(void) ddl.execute(transaction);
transaction.commitRetaining();

Statement insert{attachment, transaction, "insert into t (col) values (?)"};
for (int i = 1; i <= 5; ++i)
{
insert.setInt32(0, i);
insert.execute(transaction);
(void) insert.execute(transaction);
}

Statement select{attachment, transaction, "select col from t order by col"};
Expand Down Expand Up @@ -223,14 +223,14 @@ BOOST_AUTO_TEST_CASE(fetchMultipleBatchesFromSameStatement)
Transaction transaction{attachment};

Statement ddl{attachment, transaction, "create table t (col integer)"};
ddl.execute(transaction);
(void) ddl.execute(transaction);
transaction.commitRetaining();

Statement insert{attachment, transaction, "insert into t (col) values (?)"};
for (int i = 1; i <= 10; ++i)
{
insert.setInt32(0, i);
insert.execute(transaction);
(void) insert.execute(transaction);
}

Statement select{attachment, transaction, "select col from t order by col"};
Expand Down
4 changes: 2 additions & 2 deletions src/test/ScrollableCursor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,14 @@ BOOST_AUTO_TEST_CASE(scrollableCursorSupportsFetchMethods)
Transaction transaction{attachment};

Statement ddl{attachment, transaction, "create table t (col integer)"};
ddl.execute(transaction);
(void) ddl.execute(transaction);
transaction.commitRetaining();

Statement insert{attachment, transaction, "insert into t (col) values (?)"};
for (int i = 1; i <= 5; ++i)
{
insert.setInt32(0, i);
insert.execute(transaction);
(void) insert.execute(transaction);
}

Statement select{attachment, transaction, "select col from t order by col",
Expand Down
Loading
Loading