kexi
transaction.cpp
00001 /* This file is part of the KDE project 00002 Copyright (C) 2003 Jaroslaw Staniek <js@iidea.pl> 00003 00004 This program is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Library General Public 00006 License as published by the Free Software Foundation; either 00007 version 2 of the License, or (at your option) any later version. 00008 00009 This program is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 Library General Public License for more details. 00013 00014 You should have received a copy of the GNU Library General Public License 00015 along with this program; see the file COPYING. If not, write to 00016 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00017 * Boston, MA 02110-1301, USA. 00018 */ 00019 00020 #include <kexidb/transaction.h> 00021 #include <kexidb/connection.h> 00022 00023 #include <kdebug.h> 00024 00025 #include <assert.h> 00026 00027 //remove debug 00028 #undef KexiDBDbg 00029 #define KexiDBDbg if (0) kdDebug() 00030 00031 using namespace KexiDB; 00032 00033 //helper for debugging 00034 KEXI_DB_EXPORT int Transaction::globalcount = 0; 00035 KEXI_DB_EXPORT int Transaction::globalCount() { return Transaction::globalcount; } 00036 KEXI_DB_EXPORT int TransactionData::globalcount = 0; 00037 KEXI_DB_EXPORT int TransactionData::globalCount() { return TransactionData::globalcount; } 00038 00039 TransactionData::TransactionData(Connection *conn) 00040 : m_conn(conn) 00041 , m_active(true) 00042 , refcount(1) 00043 { 00044 assert(conn); 00045 Transaction::globalcount++; //because refcount(1) init. 00046 TransactionData::globalcount++; 00047 KexiDBDbg << "-- TransactionData::globalcount == " << TransactionData::globalcount << endl; 00048 } 00049 00050 TransactionData::~TransactionData() 00051 { 00052 TransactionData::globalcount--; 00053 KexiDBDbg << "-- TransactionData::globalcount == " << TransactionData::globalcount << endl; 00054 } 00055 00056 //--------------------------------------------------- 00057 00058 const Transaction Transaction::null; 00059 00060 Transaction::Transaction() 00061 : QObject(0,"kexidb_transaction") 00062 , m_data(0) 00063 { 00064 } 00065 00066 Transaction::Transaction( const Transaction& trans ) 00067 : QObject(0,"kexidb_transaction") 00068 , m_data(trans.m_data) 00069 { 00070 if (m_data) { 00071 m_data->refcount++; 00072 Transaction::globalcount++; 00073 } 00074 } 00075 00076 Transaction::~Transaction() 00077 { 00078 if (m_data) { 00079 m_data->refcount--; 00080 Transaction::globalcount--; 00081 KexiDBDbg << "~Transaction(): m_data->refcount==" << m_data->refcount << endl; 00082 if (m_data->refcount==0) 00083 delete m_data; 00084 } 00085 else { 00086 KexiDBDbg << "~Transaction(): null" << endl; 00087 } 00088 KexiDBDbg << "-- Transaction::globalcount == " << Transaction::globalcount << endl; 00089 } 00090 00091 Transaction& Transaction::operator=(const Transaction& trans) 00092 { 00093 if (m_data) { 00094 m_data->refcount--; 00095 Transaction::globalcount--; 00096 KexiDBDbg << "Transaction::operator=: m_data->refcount==" << m_data->refcount << endl; 00097 if (m_data->refcount==0) 00098 delete m_data; 00099 } 00100 m_data = trans.m_data; 00101 if (m_data) { 00102 m_data->refcount++; 00103 Transaction::globalcount++; 00104 } 00105 return *this; 00106 } 00107 00108 bool Transaction::operator==(const Transaction& trans) const 00109 { 00110 return m_data==trans.m_data; 00111 } 00112 00113 Connection* Transaction::connection() const 00114 { 00115 return m_data ? m_data->m_conn : 0; 00116 } 00117 00118 bool Transaction::active() const 00119 { 00120 return m_data && m_data->m_active; 00121 } 00122 00123 bool Transaction::isNull() const 00124 { 00125 return m_data==0; 00126 } 00127 00128 //--------------------------------------------------- 00129 00130 TransactionGuard::TransactionGuard( Connection& conn ) 00131 : m_trans( conn.beginTransaction() ) 00132 , m_doNothing(false) 00133 { 00134 } 00135 00136 TransactionGuard::TransactionGuard( const Transaction& trans ) 00137 : m_trans(trans) 00138 , m_doNothing(false) 00139 { 00140 } 00141 00142 TransactionGuard::TransactionGuard() 00143 : m_doNothing(false) 00144 { 00145 } 00146 00147 TransactionGuard::~TransactionGuard() 00148 { 00149 if (!m_doNothing && m_trans.active() && m_trans.connection()) 00150 m_trans.connection()->rollbackTransaction(m_trans); 00151 } 00152 00153 bool TransactionGuard::commit() 00154 { 00155 if (m_trans.active() && m_trans.connection()) { 00156 return m_trans.connection()->commitTransaction(m_trans); 00157 } 00158 return false; 00159 } 00160 00161 void TransactionGuard::doNothing() 00162 { 00163 m_doNothing = true; 00164 } 00165