00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <cassert>
00022
00023 #include <sigc++/object.h>
00024
00025 #include <pqxx-object/transaction.h>
00026
00027 using namespace pqxxobject;
00028
00029 transaction::transaction(pqxx::connection& connection,
00030 pqxx::transaction<>*& transaction):
00031 m_connection(connection),
00032 m_transaction(transaction),
00033 m_autocommit(true),
00034 m_state(STATE_NONE)
00035 {
00036
00037
00038 if (m_transaction != NULL)
00039 m_autocommit = false;
00040 }
00041
00042 transaction::~transaction()
00043 {
00044 }
00045
00046 SigC::Signal0<void>&
00047 transaction::signal_commit()
00048 {
00049 return m_signal_commit;
00050 }
00051
00052 SigC::Signal0<void>&
00053 transaction::signal_abort()
00054 {
00055 return m_signal_abort;
00056 }
00057
00058 void
00059 transaction::begin(const std::string& name)
00060 {
00061 assert ((m_transaction == NULL && m_autocommit == true) ||
00062 (m_transaction != NULL && m_autocommit == false));
00063
00064 try
00065 {
00066 if (m_transaction == NULL)
00067 {
00068 assert (m_state != STATE_EXECUTING);
00069 m_transaction = new pqxx::transaction<> (m_connection, name);
00070 m_state = STATE_EXECUTING;
00071 }
00072 }
00073 catch (const std::exception& e)
00074 {
00075 end();
00076 throw DatabaseError(e.what());
00077 }
00078 catch (...)
00079 {
00080 end();
00081 throw DatabaseError("An unknown exception occured in transaction::begin().");
00082 }
00083 }
00084
00085 void
00086 transaction::end()
00087 {
00088 try
00089 {
00090 if (m_autocommit == true)
00091 {
00092 if (m_state == STATE_EXECUTING)
00093 abort();
00094 if (m_transaction)
00095 {
00096 delete m_transaction;
00097 m_transaction = NULL;
00098 }
00099 m_state = STATE_NONE;
00100 }
00101 }
00102 catch (const std::exception& e)
00103 {
00104 throw DatabaseError(e.what());
00105 }
00106 catch (...)
00107 {
00108 throw DatabaseError("An unknown exception occured in transaction::end().");
00109 }
00110 }
00111
00112 pqxx::result *
00113 transaction::exec(const std::string& query)
00114 {
00115 pqxx::result *R = NULL;
00116 try
00117 {
00118 R = new pqxx::result(m_transaction->exec(query));
00119 return R;
00120 }
00121 catch (const std::exception& e)
00122 {
00123 delete R;
00124 throw DatabaseError(e.what());
00125 }
00126 catch (...)
00127 {
00128 delete R;
00129 throw DatabaseError("An unknown exception occured in transaction::exec().");
00130 }
00131 }
00132
00133 pqxx::result::size_type
00134 transaction::exec_noresult(const std::string& query)
00135 {
00136 pqxx::result *R = NULL;
00137 try
00138 {
00139 R = exec(query);
00140 pqxx::result::size_type rows = R->affected_rows();
00141
00142 delete R;
00143
00144 return rows;
00145 }
00146 catch (const std::exception& e)
00147 {
00148 delete R;
00149 throw DatabaseError(e.what());
00150 }
00151 catch (...)
00152 {
00153 delete R;
00154 throw DatabaseError("An unknown exception occured in transaction::exec_noresult().");
00155 }
00156 }
00157
00158 pqxx::result::size_type
00159 transaction::perform(const std::string& query,
00160 pqxx::result::size_type min_rows,
00161 pqxx::result::size_type max_rows)
00162 {
00163 try
00164 {
00165 begin("transaction::perform()");
00166
00167 pqxx::result::size_type rows;
00168 rows = exec_noresult(query);
00169
00170
00171
00172 if ((rows >= min_rows || min_rows == 0) &&
00173 (rows <= max_rows || max_rows == 0))
00174 commit();
00175 else
00176 abort();
00177
00178 end();
00179
00180 return rows;
00181 }
00182 catch (const std::exception& e)
00183 {
00184 end();
00185 throw DatabaseError(e.what());
00186 }
00187 catch (...)
00188 {
00189 end();
00190 throw DatabaseError("An unknown exception occured in transaction::perform().");
00191 }
00192
00193
00194 return 0;
00195 }
00196
00197 void
00198 transaction::commit()
00199 {
00200 try
00201 {
00202 if (m_autocommit == true)
00203 {
00204 if (m_autocommit == true)
00205 m_transaction->commit();
00206 }
00207 m_state = STATE_COMMITTED;
00208 end();
00209 m_signal_commit.emit();
00210 }
00211 catch (const std::exception& e)
00212 {
00213 end();
00214 throw DatabaseError(e.what());
00215 }
00216 catch (...)
00217 {
00218 end();
00219 throw DatabaseError("An unknown exception occured in transaction::commit().");
00220 }
00221 }
00222
00223 void
00224 transaction::abort()
00225 {
00226 try
00227 {
00228 if (m_autocommit == true)
00229 {
00230 if (m_autocommit == true)
00231 m_transaction->abort();
00232 }
00233 m_state = STATE_ABORTED;
00234 end();
00235 m_signal_abort.emit();
00236 }
00237 catch (const std::exception& e)
00238 {
00239 end();
00240 throw DatabaseError(e.what());
00241 }
00242 catch (...)
00243 {
00244 end();
00245 throw DatabaseError("An unknown exception occured in transaction::abort().");
00246 }
00247 }