Added support for SQLite transaction types using Session property (#3018)

This commit is contained in:
Maksim Kita 2022-05-30 05:06:48 +02:00 committed by GitHub
parent 2b7b9531f1
commit 5c29df0860
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 81 additions and 7 deletions

View File

@ -58,5 +58,22 @@
#endif
#endif
//
// SQLite Transaction type
//
namespace Poco {
namespace Data {
namespace SQLite {
extern const std::string TRANSACTION_TYPE_PROPERTY_KEY;
enum class TransactionType {
deferred,
exclusive,
immediate
};
} } } // namespace Poco::Data::SQLite
#endif // SQLite_SQLite_INCLUDED

View File

@ -117,6 +117,11 @@ public:
bool isAutoCommit(const std::string& name="") const;
/// Returns autocommit property value.
void setTransactionType(TransactionType transactionType);
/// Sets begin transaction type for the session.
TransactionType getTransactionType() const;
/// Returns begin transaction type.
const std::string& connectorName() const;
/// Returns the name of the connector.
@ -124,16 +129,20 @@ protected:
void setConnectionTimeout(const std::string& prop, const Poco::Any& value);
Poco::Any getConnectionTimeout(const std::string& prop) const;
void setTransactionType(const std::string &prop, const Poco::Any& value);
Poco::Any getTransactionType(const std::string& prop) const;
private:
std::string _connector;
sqlite3* _pDB;
bool _connected;
bool _isTransaction;
TransactionType _transactionType;
int _timeout;
mutable
Poco::Mutex _mutex;
static const std::string DEFERRED_BEGIN_TRANSACTION;
static const std::string EXCLUSIVE_BEGIN_TRANSACTION;
static const std::string IMMEDIATE_BEGIN_TRANSACTION;
static const std::string COMMIT_TRANSACTION;
static const std::string ABORT_TRANSACTION;
};
@ -148,7 +157,7 @@ inline bool SessionImpl::canTransact() const
}
inline bool SessionImpl::isTransaction() const
inline bool SessionImpl::isTransaction() const
{
return _isTransaction;
}
@ -165,6 +174,10 @@ inline std::size_t SessionImpl::getConnectionTimeout() const
return static_cast<std::size_t>(_timeout/1000);
}
inline TransactionType SessionImpl::getTransactionType() const
{
return _transactionType;
}
} } } // namespace Poco::Data::SQLite

View File

@ -38,8 +38,10 @@ namespace Poco {
namespace Data {
namespace SQLite {
const std::string TRANSACTION_TYPE_PROPERTY_KEY = "transactionType";
const std::string SessionImpl::DEFERRED_BEGIN_TRANSACTION("BEGIN DEFERRED");
const std::string SessionImpl::EXCLUSIVE_BEGIN_TRANSACTION("BEGIN EXCLUSIVE");
const std::string SessionImpl::IMMEDIATE_BEGIN_TRANSACTION("BEGIN IMMEDIATE");
const std::string SessionImpl::COMMIT_TRANSACTION("COMMIT");
const std::string SessionImpl::ABORT_TRANSACTION("ROLLBACK");
@ -49,7 +51,8 @@ SessionImpl::SessionImpl(const std::string& fileName, std::size_t loginTimeout):
_connector(Connector::KEY),
_pDB(0),
_connected(false),
_isTransaction(false)
_isTransaction(false),
_transactionType(TransactionType::deferred)
{
open();
setConnectionTimeout(loginTimeout);
@ -58,6 +61,7 @@ SessionImpl::SessionImpl(const std::string& fileName, std::size_t loginTimeout):
&SessionImpl::autoCommit,
&SessionImpl::isAutoCommit);
addProperty("connectionTimeout", &SessionImpl::setConnectionTimeout, &SessionImpl::getConnectionTimeout);
addProperty(TRANSACTION_TYPE_PROPERTY_KEY, &SessionImpl::setTransactionType, &SessionImpl::getTransactionType);
}
@ -85,7 +89,18 @@ void SessionImpl::begin()
{
Poco::Mutex::ScopedLock l(_mutex);
SQLiteStatementImpl tmp(*this, _pDB);
tmp.add(DEFERRED_BEGIN_TRANSACTION);
switch (_transactionType)
{
case TransactionType::deferred:
tmp.add(DEFERRED_BEGIN_TRANSACTION);
break;
case TransactionType::exclusive:
tmp.add(EXCLUSIVE_BEGIN_TRANSACTION);
break;
case TransactionType::immediate:
tmp.add(IMMEDIATE_BEGIN_TRANSACTION);
break;
}
tmp.execute();
_isTransaction = true;
}
@ -223,6 +238,20 @@ Poco::Any SessionImpl::getConnectionTimeout(const std::string& prop) const
return Poco::Any(_timeout/1000);
}
void SessionImpl::setTransactionType(TransactionType transactionType)
{
_transactionType = transactionType;
}
void SessionImpl::setTransactionType(const std::string &prop, const Poco::Any& value)
{
setTransactionType(Poco::RefAnyCast<TransactionType>(value));
}
Poco::Any SessionImpl::getTransactionType(const std::string& prop) const
{
return Poco::Any(_transactionType);
}
void SessionImpl::autoCommit(const std::string&, bool)
{

View File

@ -3205,7 +3205,7 @@ void SQLiteTest::testTransaction()
std::string result;
session.setTransactionIsolation(Session::TRANSACTION_READ_COMMITTED);
session.setProperty(Poco::Data::SQLite::TRANSACTION_TYPE_PROPERTY_KEY, Poco::Data::SQLite::TransactionType::exclusive);
{
Transaction trans(session);
assertTrue (trans.isActive());
@ -3227,7 +3227,7 @@ void SQLiteTest::testTransaction()
session << "SELECT count(*) FROM Person", into(count), now;
assertTrue (0 == count);
assertTrue (!session.isTransaction());
session.setProperty(Poco::Data::SQLite::TRANSACTION_TYPE_PROPERTY_KEY, Poco::Data::SQLite::TransactionType::immediate);
{
Transaction trans(session);
session << "INSERT INTO Person VALUES (?,?,?,?)", use(lastNames), use(firstNames), use(addresses), use(ages), now;
@ -3436,6 +3436,19 @@ void SQLiteTest::testIllegalFilePath()
}
}
void SQLiteTest::testTransactionTypeProperty()
{
try {
using namespace Poco::Data::SQLite;
Session tmp(Connector::KEY, "dummy.db");
tmp.setProperty(TRANSACTION_TYPE_PROPERTY_KEY, TransactionType::exclusive);
Poco::Any property = tmp.getProperty(TRANSACTION_TYPE_PROPERTY_KEY);
TransactionType value = Poco::RefAnyCast<TransactionType>(property);
assertTrue(value == TransactionType::exclusive);
} catch (Poco::Exception&) {}
}
void SQLiteTest::setUp()
{
@ -3540,6 +3553,7 @@ CppUnit::Test* SQLiteTest::suite()
CppUnit_addTest(pSuite, SQLiteTest, testTransactor);
CppUnit_addTest(pSuite, SQLiteTest, testFTS3);
CppUnit_addTest(pSuite, SQLiteTest, testIllegalFilePath);
CppUnit_addTest(pSuite, SQLiteTest, testTransactionTypeProperty);
return pSuite;
}

View File

@ -137,6 +137,7 @@ public:
void testFTS3();
void testIllegalFilePath();
void testTransactionTypeProperty();
void setUp();
void tearDown();