mirror of
https://github.com/pocoproject/poco.git
synced 2025-01-31 14:39:53 +01:00
Added support for SQLite transaction types using Session property (#3018)
This commit is contained in:
parent
2b7b9531f1
commit
5c29df0860
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -137,6 +137,7 @@ public:
|
||||
void testFTS3();
|
||||
|
||||
void testIllegalFilePath();
|
||||
void testTransactionTypeProperty();
|
||||
|
||||
void setUp();
|
||||
void tearDown();
|
||||
|
Loading…
x
Reference in New Issue
Block a user