From c5cf4a2672b3cdf588597d44fb2434c86840990e Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Thu, 26 May 2022 00:34:17 +0200 Subject: [PATCH] add Transaction class as a wrapper for transactions --- src/Makefile.dep | 2 + src/Makefile.o.dep | 2 +- src/morm.h | 3 +- src/transaction.cpp | 249 ++++++++++++++++++++++++++++++++++++++++++++ src/transaction.h | 81 ++++++++++++++ 5 files changed, 335 insertions(+), 2 deletions(-) create mode 100644 src/transaction.cpp create mode 100644 src/transaction.h diff --git a/src/Makefile.dep b/src/Makefile.dep index 8ea5025..79b39a0 100644 --- a/src/Makefile.dep +++ b/src/Makefile.dep @@ -61,3 +61,5 @@ postgresqlexpression.o: fieldvaluehelper.h wrapper.h spacewrapper.h postgresqlexpression.o: baseobjectwrapper.h modelcontainerwrapper.h ft.h postgresqlqueryresult.o: postgresqlqueryresult.h queryresult.h queryresult.o: queryresult.h +transaction.o: transaction.h modelconnector.h clearer.h ft.h dbconnector.h +transaction.o: queryresult.h flatconnector.h diff --git a/src/Makefile.o.dep b/src/Makefile.o.dep index 9a1dd42..036238d 100644 --- a/src/Makefile.o.dep +++ b/src/Makefile.o.dep @@ -1 +1 @@ -o = baseexpression.o clearer.o dbconnector.o dbexpression.o flatconnector.o flatexpression.o jsonconnector.o jsonexpression.o model.o modelconnector.o postgresqlconnector.o postgresqlexpression.o postgresqlqueryresult.o queryresult.o \ No newline at end of file +o = baseexpression.o clearer.o dbconnector.o dbexpression.o flatconnector.o flatexpression.o jsonconnector.o jsonexpression.o model.o modelconnector.o postgresqlconnector.o postgresqlexpression.o postgresqlqueryresult.o queryresult.o transaction.o \ No newline at end of file diff --git a/src/morm.h b/src/morm.h index 347f3d6..fed3870 100644 --- a/src/morm.h +++ b/src/morm.h @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2018-2019, Tomasz Sowa + * Copyright (c) 2018-2022, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -49,6 +49,7 @@ #include "modelconnector.h" #include "clearer.h" +#include "transaction.h" namespace morm diff --git a/src/transaction.cpp b/src/transaction.cpp new file mode 100644 index 0000000..e9aeea5 --- /dev/null +++ b/src/transaction.cpp @@ -0,0 +1,249 @@ +/* + * This file is a part of morm + * and is distributed under the 2-Clause BSD licence. + * Author: Tomasz Sowa + */ + +/* + * Copyright (c) 2022, Tomasz Sowa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "transaction.h" +#include "dbconnector.h" + + +namespace morm +{ + +Transaction::Transaction(ModelConnector * model_connector) +{ + this->model_connector = model_connector; + is_transaction_started = false; + is_transaction_successful = true; + begin(); +} + + +Transaction::Transaction(ModelConnector * model_connector, bool auto_begin_transaction) +{ + this->model_connector = model_connector; + is_transaction_started = false; + is_transaction_successful = true; + + if( auto_begin_transaction ) + { + begin(); + } +} + + +Transaction::~Transaction() +{ + if( is_transaction_started ) + { + rollback(); + } +} + + + +bool Transaction::is_started() +{ + return is_transaction_started; +} + + +bool Transaction::is_successful() +{ + return is_transaction_successful; +} + + +void Transaction::set_successful(bool is_successful) +{ + is_transaction_successful = is_successful; +} + + + + + +bool Transaction::begin() +{ + pt::Log * log = get_logger(); + + if( is_transaction_started ) + { + if( log ) + { + (*log) << pt::Log::log2 << "Morm: a transaction is already started - rollbacking existing transaction before creating a new one" << pt::Log::logend; + } + + rollback(); // what if there is an error here? skip it at the moment + } + + bool status = do_query("BEGIN"); + + if( status ) + { + is_transaction_started = true; + is_transaction_successful = true; + } + else + { + is_transaction_started = false; + is_transaction_successful = false; + + if( log ) + { + (*log) << pt::Log::log1 << "Morm: I cannot start a transaction" << pt::Log::logend; + } + } + + return status; +} + + +bool Transaction::begin_if_needed() +{ + bool status = true; + + if( !is_transaction_started ) + { + status = begin(); + } + + return status; +} + + +bool Transaction::rollback() +{ + bool status = false; + + if( is_transaction_started ) + { + status = do_query("ROLLBACK"); + + if( status ) + { + is_transaction_started = false; + } + } + else + { + pt::Log * log = get_logger(); + + if( log ) + { + (*log) << pt::Log::log1 << "Morm: not doing rollback, a transaction was not started - skipping" << pt::Log::logend; + } + } + + return status; +} + + +bool Transaction::commit() +{ + bool status = false; + + if( is_transaction_started ) + { + status = do_query("COMMIT"); + + if( status ) + { + is_transaction_started = false; + } + } + else + { + pt::Log * log = get_logger(); + + if( log ) + { + (*log) << pt::Log::log1 << "Morm: not doing commit, a transaction was not started - skipping" << pt::Log::logend; + } + } + + return status; +} + + +bool Transaction::finish() +{ + bool status = false; + + if( is_transaction_successful ) + status = commit(); + else + status = rollback(); + + return status; +} + + + + +bool Transaction::do_query(const char * query) +{ + bool status = false; + + if( model_connector ) + { + DbConnector * db_connector = model_connector->get_db_connector(); + + if( db_connector ) + { + status = db_connector->query(query); + } + } + + return status; +} + + + +pt::Log * Transaction::get_logger() +{ + pt::Log * logger = nullptr; + + if( model_connector ) + { + logger = model_connector->get_logger(); + } + + return logger; +} + + + + +} // namespace + + diff --git a/src/transaction.h b/src/transaction.h new file mode 100644 index 0000000..3294619 --- /dev/null +++ b/src/transaction.h @@ -0,0 +1,81 @@ +/* + * This file is a part of morm + * and is distributed under the 2-Clause BSD licence. + * Author: Tomasz Sowa + */ + +/* + * Copyright (c) 2022, Tomasz Sowa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef headerfile_morm_transaction +#define headerfile_morm_transaction + +#include "log/log.h" +#include "modelconnector.h" + + +namespace morm +{ + + +class Transaction +{ +public: + + Transaction(ModelConnector * model_connector); + Transaction(ModelConnector * model_connector, bool auto_begin_transaction); + virtual ~Transaction(); + + virtual bool is_started(); + + virtual bool is_successful(); + virtual void set_successful(bool is_successful = true); + + virtual bool begin(); + virtual bool begin_if_needed(); + virtual bool rollback(); + virtual bool commit(); + virtual bool finish(); + + +protected: + + ModelConnector * model_connector; + bool is_transaction_started; + bool is_transaction_successful; + + bool do_query(const char * query); + pt::Log * get_logger(); + +}; + + + +} // namespace + +#endif