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 }
00079
00080 void
00081 transaction::end()
00082 {
00083 try
00084 {
00085 if (m_autocommit == true)
00086 {
00087 if (m_state == STATE_EXECUTING)
00088 abort();
00089 if (m_transaction)
00090 {
00091 delete m_transaction;
00092 m_transaction = NULL;
00093 }
00094 m_state = STATE_NONE;
00095 }
00096 }
00097 catch (const std::exception& e)
00098 {
00099 throw DatabaseError(e.what());
00100 }
00101 }
00102
00103 pqxx::result
00104 transaction::exec(const std::string& query)
00105 {
00106 try
00107 {
00108 return m_transaction->exec(query);
00109 }
00110 catch (const std::exception& e)
00111 {
00112 throw DatabaseError(e.what());
00113 }
00114 }
00115
00116 pqxx::result::size_type
00117 transaction::exec_noresult(const std::string& query)
00118 {
00119 try
00120 {
00121 pqxx::result R = exec(query);
00122 return R.affected_rows();
00123 }
00124 catch (const std::exception& e)
00125 {
00126 throw DatabaseError(e.what());
00127 }
00128 }
00129
00130 pqxx::result::size_type
00131 transaction::perform(const std::string& query,
00132 pqxx::result::size_type min_rows,
00133 pqxx::result::size_type max_rows)
00134 {
00135 try
00136 {
00137 begin("transaction::perform()");
00138
00139 pqxx::result::size_type rows;
00140 rows = exec_noresult(query);
00141
00142
00143
00144 if ((rows >= min_rows || min_rows == 0) &&
00145 (rows <= max_rows || max_rows == 0))
00146 commit();
00147 else
00148 abort();
00149
00150 end();
00151
00152 return rows;
00153 }
00154 catch (const std::exception& e)
00155 {
00156 end();
00157 throw DatabaseError(e.what());
00158 }
00159
00160
00161 return 0;
00162 }
00163
00164 void
00165 transaction::commit()
00166 {
00167 try
00168 {
00169 if (m_autocommit == true)
00170 {
00171 if (m_autocommit == true)
00172 m_transaction->commit();
00173 }
00174 m_state = STATE_COMMITTED;
00175 end();
00176 m_signal_commit.emit();
00177 }
00178 catch (const std::exception& e)
00179 {
00180 end();
00181 throw DatabaseError(e.what());
00182 }
00183 }
00184
00185 void
00186 transaction::abort()
00187 {
00188 try
00189 {
00190 if (m_autocommit == true)
00191 {
00192 if (m_autocommit == true)
00193 m_transaction->abort();
00194 }
00195 m_state = STATE_ABORTED;
00196 end();
00197 m_signal_abort.emit();
00198 }
00199 catch (const std::exception& e)
00200 {
00201 end();
00202 throw DatabaseError(e.what());
00203 }
00204 }