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

pqxxobject/row_base.cc

Go to the documentation of this file.
00001 // database row base class                                       -*- C++ -*-
00002 // $Id: row_base.cc,v 1.8 2004/04/02 21:48:13 roger Exp $
00003 //
00004 // Copyright (C) 2003  Roger Leigh <rleigh@debian.org>
00005 //
00006 //
00007 //  All rights reserved.
00008 //
00009 //  Redistribution and use in source and binary forms, with or without
00010 //  modification, are permitted provided that the following conditions
00011 //  are met:
00012 //
00013 //  * Redistributions of source code must retain the above copyright
00014 //    notice, this list of conditions and the following disclaimer.
00015 //  * Redistributions in binary form must reproduce the above
00016 //    copyright notice, this list of conditions and the following
00017 //    disclaimer in the documentation and/or other materials provided
00018 //    with the distribution.
00019 //  * Neither the name of the author, nor the names of other
00020 //    contributors may be used to endorse or promote products derived
00021 //    from this software without specific prior written permission.
00022 //
00023 //  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
00024 //  CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
00025 //  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00026 //  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00027 //  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
00028 //  BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00029 //  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
00030 //  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00031 //  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
00032 //  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
00033 //  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
00034 //  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00035 //  SUCH DAMAGE.
00036 //
00038 
00039 #include <pqxxobject/row_base.h>
00040 
00041 using namespace pqxxobject;
00042 
00043 namespace
00044 {
00045   std::string describe_status(row_base::row_state current_state)
00046   {
00047     std::string status;
00048     switch (current_state)
00049       {
00050       case row_base::STATE_UNINITIALISED:
00051         status = "the row is not initialised";
00052         break;
00053       case row_base::STATE_INITIALISED:
00054         status = "the row is initialised";
00055         break;
00056       case row_base::STATE_INCONSISTENT:
00057         status = "the row is in an inconsistent state";
00058         break;
00059       default:
00060         status = "the row is in an unknown state";
00061       }
00062     return status;
00063   }
00064 }
00065 
00066 row_base::row_base():
00067   m_state(STATE_UNINITIALISED),
00068   m_modified(false)
00069 {
00070 }
00071 
00072 row_base::row_base(row_state status,
00073                    bool modified):
00074   m_state(status),
00075   m_modified(modified)
00076 {
00077 }
00078 
00079 row_base::row_base(const row_base& rhs):
00080   SigC::Object(),
00081   m_state(rhs.m_state),
00082   m_modified(rhs.m_modified)
00083 {
00084 }
00085 
00086 row_base::~row_base()
00087 {
00088 }
00089 
00090 row_base&
00091 row_base::operator = (const row_base& rhs)
00092 {
00093   if (&rhs != this)
00094     {
00095       m_state = rhs.m_state;
00096       m_modified = rhs.m_modified;
00097     }
00098   return *this;
00099 }
00100 
00101 row_base::row_state
00102 row_base::get_state() const
00103 {
00104   return m_state;
00105 }
00106 
00107 bool
00108 row_base::is_modified() const
00109 {
00110   return m_modified;
00111 }
00112 
00113 void
00114 row_base::refresh(pqxxobject::transaction& tran)
00115 {
00116   try
00117     {
00118       if (m_state != STATE_UNINITIALISED)
00119         {
00120           begin(tran);
00121           // Register for special handling on transaction commit/abort.
00122           connect_safe_signal_handlers(tran);
00123           refresh_impl(tran);
00124           unset_checkpoint(tran);
00125           m_signal_refreshed.emit();
00126         }
00127       else
00128         {
00129           abort(tran);
00130           throw DatabaseError("The row could not be refreshed: " + describe_status(m_state));
00131         }
00132     }
00133   catch (const DatabaseError& e)
00134     {
00135       abort(tran);
00136       throw e;
00137     }
00138 }
00139 
00140 void
00141 row_base::insert(pqxxobject::transaction& tran)
00142 {
00143   try
00144     {
00145       if (m_state == STATE_UNINITIALISED)
00146         {
00147           begin(tran);
00148           // Register for special handling on transaction commit/abort.
00149           connect_signal_handlers(tran);
00150           insert_impl(tran);
00151           unset_checkpoint(tran);
00152           m_modified = false;
00153           m_signal_inserted.emit();
00154         }
00155       else
00156         {
00157           throw DatabaseError("The row could not be inserted: " + describe_status(m_state));
00158         }
00159     }
00160   catch (const DatabaseError& e)
00161     {
00162       abort(tran);
00163       throw e;
00164     }
00165 }
00166 
00167 void
00168 row_base::update(pqxxobject::transaction& tran)
00169 {
00170   try
00171     {
00172       if (m_state == STATE_INITIALISED)
00173         {
00174           begin(tran);
00175           // Register for special handling on transaction commit/abort.
00176           connect_signal_handlers(tran);
00177           update_impl(tran);
00178           unset_checkpoint(tran);
00179           m_modified = false;
00180           m_signal_updated.emit();
00181         }
00182       else
00183         {
00184           throw DatabaseError("The row could not be updated: " + describe_status(m_state));
00185         }
00186     }
00187   catch (const DatabaseError& e)
00188     {
00189       abort(tran);
00190       throw e;
00191     }
00192 }
00193 
00194 void
00195 row_base::autoupdate(pqxxobject::transaction& tran)
00196 {
00197   if (m_state == STATE_UNINITIALISED)
00198     insert(tran);
00199   else
00200     update(tran);
00201 }
00202 
00203 
00204 void
00205 row_base::erase(pqxxobject::transaction& tran)
00206 {
00207   try
00208     {
00209       if (m_state == STATE_INITIALISED)
00210         {
00211           begin(tran);
00212           // Register for special handling on transaction commit/abort.
00213           connect_safe_signal_handlers(tran);
00214           unset_checkpoint(tran);
00215           erase_impl(tran);
00216           m_signal_erased.emit();
00217         }
00218       else
00219         {
00220           throw DatabaseError("The row could not be deleted: " + describe_status(m_state));
00221         }
00222     }
00223   catch (const DatabaseError& e)
00224     {
00225       abort(tran);
00226       throw e;
00227     }
00228 }
00229 
00230 void
00231 row_base::abort(pqxxobject::transaction& tran)
00232 {
00233   abort_impl(tran);
00234 }
00235 
00236 void
00237 row_base::commit(pqxxobject::transaction& tran)
00238 {
00239   commit_impl(tran);
00240 }
00241 
00242 SigC::Signal0<void>&
00243 row_base::signal_changed()
00244 {
00245   return m_signal_changed;
00246 }
00247 
00248 SigC::Signal0<void>&
00249 row_base::signal_refreshed()
00250 {
00251   return m_signal_refreshed;
00252 }
00253 
00254 SigC::Signal0<void>&
00255 row_base::signal_inserted()
00256 {
00257   return m_signal_inserted;
00258 }
00259 
00260 SigC::Signal0<void>&
00261 row_base::signal_updated()
00262 {
00263   return m_signal_updated;
00264 }
00265 
00266 SigC::Signal0<void>&
00267 row_base::signal_erased()
00268 {
00269   return m_signal_erased;
00270 }
00271 
00272 void
00273 row_base::raise_changed()
00274 {
00275   m_signal_changed.emit();
00276 }
00277 
00278 void
00279 row_base::raise_refreshed()
00280 {
00281   m_signal_refreshed.emit();
00282 }
00283 
00284 void
00285 row_base::raise_inserted()
00286 {
00287   m_signal_inserted.emit();
00288 }
00289 
00290 void
00291 row_base::raise_updated()
00292 {
00293   m_signal_updated.emit();
00294 }
00295 
00296 void
00297 row_base::raise_erased()
00298 {
00299   m_signal_erased.emit();
00300 }
00301 
00302 void
00303 row_base::begin(pqxxobject::transaction& tran)
00304 {
00305   begin_impl(tran);
00306   m_state = STATE_INCONSISTENT;
00307 }
00308 
00309 void
00310 row_base::refresh_impl(pqxxobject::transaction& tran)
00311 {
00312 }
00313 
00314 void
00315 row_base::insert_impl(pqxxobject::transaction& tran)
00316 {
00317 }
00318 
00319 void
00320 row_base::update_impl(pqxxobject::transaction& tran)
00321 {
00322 }
00323 
00324 void
00325 row_base::erase_impl(pqxxobject::transaction& tran)
00326 {
00327 }
00328 
00329 void
00330 row_base::unset_checkpoint(pqxxobject::transaction& tran)
00331 {
00332   if (tran.get_checkpoint() == true && get_checkpoint() == true)
00333     tran.set_checkpoint(false);
00334 }
00335 
00336 void
00337 row_base::connect_signal_handlers(pqxxobject::transaction& tran)
00338 {
00339   tran.signal_commit().connect
00340     ( SigC::slot(*this, &row_base::commit) );
00341   tran.signal_abort().connect
00342     ( SigC::slot(*this, &row_base::abort) );
00343   tran.signal_refresh().connect
00344     ( SigC::slot(*this, &row_base::refresh) );
00345 }
00346 
00347 void
00348 row_base::connect_safe_signal_handlers(pqxxobject::transaction& tran)
00349 {
00350   tran.signal_commit().connect
00351     ( SigC::slot(*this, &row_base::commit) );
00352   tran.signal_abort().connect
00353     ( SigC::slot(*this, &row_base::abort) );
00354   // No refresh signal, to prevent recursion.
00355 }

Generated on Sat May 22 18:33:58 2004 for pqxxobject API Reference by doxygen 1.3.6-20040222