Skip to content

Commit

Permalink
Allow specifying transaction behaviors DEFERRED, IMMEDIATE, and EXCLU…
Browse files Browse the repository at this point in the history
…SIVE
  • Loading branch information
jjenkins278 committed Oct 4, 2021
1 parent c7909ee commit abd139c
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 2 deletions.
22 changes: 21 additions & 1 deletion include/SQLiteCpp/Transaction.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,16 @@ namespace SQLite
// Forward declaration
class Database;

/**
* @brief Transaction behaviors when opening an SQLite transaction.
* Names correspond directly to the behavior.
*/
enum class TransactionBehavior {
DEFERRED,
IMMEDIATE,
EXCLUSIVE,
};

/**
* @brief RAII encapsulation of a SQLite Transaction.
*
Expand All @@ -44,14 +54,24 @@ class Transaction
{
public:
/**
* @brief Begins the SQLite transaction
* @brief Begins the SQLite transaction using the default transaction behavior.
*
* @param[in] aDatabase the SQLite Database Connection
*
* Exception is thrown in case of error, then the Transaction is NOT initiated.
*/
explicit Transaction(Database& aDatabase);

/**
* @brief Begins the SQLite transaction with the specified behavior.
*
* @param[in] aDatabase the SQLite Database Connection
* @param[in] behavior the requested transaction behavior
*
* Exception is thrown in case of error, then the Transaction is NOT initiated.
*/
explicit Transaction(Database& aDatabase, TransactionBehavior behavior);

// Transaction is non-copyable
Transaction(const Transaction&) = delete;
Transaction& operator=(const Transaction&) = delete;
Expand Down
25 changes: 24 additions & 1 deletion src/Transaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,36 @@
#include <SQLiteCpp/Database.h>
#include <SQLiteCpp/Assertion.h>

#include <sqlite3.h>

namespace SQLite
{


// Begins the SQLite transaction
Transaction::Transaction(Database& aDatabase) :
Transaction::Transaction(Database& aDatabase, TransactionBehavior behavior) :
mDatabase(aDatabase),
mbCommited(false)
{
const char *stmt;
switch (behavior) {
case TransactionBehavior::DEFERRED:
stmt = "BEGIN DEFERRED";
break;
case TransactionBehavior::IMMEDIATE:
stmt = "BEGIN IMMEDIATE";
break;
case TransactionBehavior::EXCLUSIVE:
stmt = "BEGIN EXCLUSIVE";
break;
default:
throw SQLite::Exception("invalid/unknown transaction behavior", SQLITE_ERROR);
}
mDatabase.exec(stmt);
}

// Begins the SQLite transaction
Transaction::Transaction(Database &aDatabase) :
mDatabase(aDatabase),
mbCommited(false)
{
Expand Down
14 changes: 14 additions & 0 deletions tests/Transaction_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,20 @@ TEST(Transaction, commitRollback)
EXPECT_THROW(transaction.commit(), SQLite::Exception);
}

// ensure transactions with different types are well-formed
{
for (auto behavior : {
SQLite::TransactionBehavior::DEFERRED,
SQLite::TransactionBehavior::IMMEDIATE,
SQLite::TransactionBehavior::EXCLUSIVE })
{
SQLite::Transaction transaction(db, behavior);
transaction.commit();
}

EXPECT_THROW(SQLite::Transaction(db, static_cast<SQLite::TransactionBehavior>(-1)), SQLite::Exception);
}

// Auto rollback if no commit() before the end of scope
{
// Begin transaction
Expand Down

0 comments on commit abd139c

Please sign in to comment.