add support for nested transactions
while here: - don't allow to copy/move DbConnector
This commit is contained in:
@@ -51,16 +51,9 @@ DbConnector::DbConnector()
|
||||
expression_allocated = false;
|
||||
log = nullptr;
|
||||
log_queries = false;
|
||||
transaction_index = 0;
|
||||
}
|
||||
|
||||
DbConnector::DbConnector(const DbConnector &)
|
||||
{
|
||||
db_expression = nullptr;
|
||||
expression_allocated = false;
|
||||
log = nullptr;
|
||||
}
|
||||
|
||||
|
||||
DbConnector::~DbConnector()
|
||||
{
|
||||
deallocate_expression();
|
||||
@@ -173,6 +166,206 @@ bool DbConnector::query_remove(const pt::TextStream & stream, QueryResult & quer
|
||||
}
|
||||
|
||||
|
||||
bool DbConnector::begin()
|
||||
{
|
||||
bool status = false;
|
||||
|
||||
if( transaction_index > 0 )
|
||||
{
|
||||
pt::TextStream str;
|
||||
str << "SAVEPOINT savepoint_" << transaction_index;
|
||||
status = DbConnector::query(str);
|
||||
}
|
||||
else
|
||||
{
|
||||
status = DbConnector::query("BEGIN");
|
||||
}
|
||||
|
||||
if( status )
|
||||
{
|
||||
transaction_index += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( log )
|
||||
{
|
||||
(*log) << pt::Log::log1 << "Morm: I cannot start a transaction" << pt::Log::logend;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
bool DbConnector::begin_if_needed()
|
||||
{
|
||||
bool status = true;
|
||||
|
||||
if( transaction_index == 0 )
|
||||
{
|
||||
status = begin();
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
bool DbConnector::rollback()
|
||||
{
|
||||
return rollback(transaction_index);
|
||||
}
|
||||
|
||||
|
||||
bool DbConnector::commit()
|
||||
{
|
||||
return commit(transaction_index);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool DbConnector::rollback_one_transaction(size_t index)
|
||||
{
|
||||
bool status = false;
|
||||
|
||||
if( index > 1 )
|
||||
{
|
||||
pt::TextStream str;
|
||||
str << "ROLLBACK TO SAVEPOINT savepoint_" << (index - 1);
|
||||
status = DbConnector::query(str);
|
||||
transaction_index = index - 1; // decrement it even if rollback failed
|
||||
}
|
||||
else
|
||||
if( index == 1 )
|
||||
{
|
||||
status = DbConnector::query("ROLLBACK");
|
||||
transaction_index = 0;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool DbConnector::rollback(size_t index)
|
||||
{
|
||||
bool status = false;
|
||||
|
||||
if( index == 0 )
|
||||
{
|
||||
if( log )
|
||||
{
|
||||
(*log) << pt::Log::log1 << "Morm: there is no a transaction with zero index - skipping rollback";
|
||||
}
|
||||
}
|
||||
else
|
||||
if( index > transaction_index )
|
||||
{
|
||||
if( log )
|
||||
{
|
||||
(*log) << pt::Log::log1 << "Morm: transaction";
|
||||
|
||||
if( index > 1 )
|
||||
(*log) << " for savepoint_" << (index-1);
|
||||
|
||||
(*log) << " does not exist - skipping rollback" << pt::Log::logend;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = true;
|
||||
|
||||
for(size_t i = transaction_index ; i >= index ; --i)
|
||||
{
|
||||
if( !rollback_one_transaction(i) )
|
||||
{
|
||||
/*
|
||||
* return false if at least one rollback failed
|
||||
*/
|
||||
status = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
bool DbConnector::commit_one_transaction(size_t index)
|
||||
{
|
||||
bool status = false;
|
||||
|
||||
if( index > 1 )
|
||||
{
|
||||
pt::TextStream str;
|
||||
str << "RELEASE SAVEPOINT savepoint_" << (index - 1);
|
||||
status = DbConnector::query(str);
|
||||
transaction_index = index - 1;
|
||||
}
|
||||
else
|
||||
if( index == 1 )
|
||||
{
|
||||
status = DbConnector::query("COMMIT");
|
||||
transaction_index = 0;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
bool DbConnector::commit(size_t index)
|
||||
{
|
||||
bool status = false;
|
||||
|
||||
if( index == 0 )
|
||||
{
|
||||
if( log )
|
||||
{
|
||||
(*log) << pt::Log::log1 << "Morm: there is no a transaction with zero index - skipping commit";
|
||||
}
|
||||
}
|
||||
else
|
||||
if( index > transaction_index )
|
||||
{
|
||||
if( log )
|
||||
{
|
||||
(*log) << pt::Log::log1 << "Morm: transaction";
|
||||
|
||||
if( index > 1 )
|
||||
(*log) << " for savepoint_" << (index-1);
|
||||
|
||||
(*log) << " does not exist - skipping commit" << pt::Log::logend;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = true;
|
||||
|
||||
for(size_t i = transaction_index ; i >= index ; --i)
|
||||
{
|
||||
if( !commit_one_transaction(i) )
|
||||
{
|
||||
/*
|
||||
* return false if at least one commit failed
|
||||
*/
|
||||
status = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
size_t DbConnector::get_transaction_index()
|
||||
{
|
||||
return transaction_index;
|
||||
}
|
||||
|
||||
|
||||
|
||||
DbExpression * DbConnector::get_expression()
|
||||
{
|
||||
|
Reference in New Issue
Block a user