Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class Members

pqxx-object/transaction.cc

Go to the documentation of this file.
00001 // database transaction convenience wrapper                      -*- C++ -*-
00002 // $Id: transaction.cc,v 1.4 2004/01/07 14:29:39 roger Exp $
00003 //
00004 // Copyright (C) 2003  Roger Leigh <rleigh@debian.org>
00005 //
00006 //
00007 // This program is free software; you can redistribute it and/or modify
00008 // it under the terms of the GNU General Public License as published by
00009 // the Free Software Foundation; either version 2 of the License, or
00010 // (at your option) any later version.
00011 //
00012 // This program is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 //
00017 // You should have received a copy of the GNU General Public License
00018 // along with this program; if not, write to the Free Software
00019 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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   // Set up database.
00037   // Turn off auto-committing of changes if the creator gave us a transaction.
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); // can't be executing without a transaction
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) // abort a running transaction
00088             abort();
00089           if (m_transaction) // abort() might delete the 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       // Commit if the number of altered rows is greater or equal to
00143       // min_rows, or if min_rows is 0.
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       // This should never be reached.
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 }

Generated on Sat Jan 17 20:58:42 2004 for pqxx-object API Reference by doxygen 1.3.4