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

pqxx-object/row_base.cc

Go to the documentation of this file.
00001 // database row base class                                       -*- C++ -*-
00002 // $Id: row_base.cc,v 1.7 2004/02/20 22:49:15 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 <pqxx-object/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::erase(pqxxobject::transaction& tran)
00196 {
00197   try
00198     {
00199       if (m_state == STATE_INITIALISED)
00200         {
00201           begin(tran);
00202           // Register for special handling on transaction commit/abort.
00203           connect_safe_signal_handlers(tran);
00204           unset_checkpoint(tran);
00205           erase_impl(tran);
00206           m_signal_erased.emit();
00207         }
00208       else
00209         {
00210           throw DatabaseError("The row could not be deleted: " + describe_status(m_state));
00211         }
00212     }
00213   catch (const DatabaseError& e)
00214     {
00215       abort(tran);
00216       throw e;
00217     }
00218 }
00219 
00220 void
00221 row_base::abort(pqxxobject::transaction& tran)
00222 {
00223   abort_impl(tran);
00224 }
00225 
00226 void
00227 row_base::commit(pqxxobject::transaction& tran)
00228 {
00229   commit_impl(tran);
00230 }
00231 
00232 SigC::Signal0<void>&
00233 row_base::signal_changed()
00234 {
00235   return m_signal_changed;
00236 }
00237 
00238 SigC::Signal0<void>&
00239 row_base::signal_refreshed()
00240 {
00241   return m_signal_refreshed;
00242 }
00243 
00244 SigC::Signal0<void>&
00245 row_base::signal_inserted()
00246 {
00247   return m_signal_inserted;
00248 }
00249 
00250 SigC::Signal0<void>&
00251 row_base::signal_updated()
00252 {
00253   return m_signal_updated;
00254 }
00255 
00256 SigC::Signal0<void>&
00257 row_base::signal_erased()
00258 {
00259   return m_signal_erased;
00260 }
00261 
00262 void
00263 row_base::raise_changed()
00264 {
00265   m_signal_changed.emit();
00266 }
00267 
00268 void
00269 row_base::raise_refreshed()
00270 {
00271   m_signal_refreshed.emit();
00272 }
00273 
00274 void
00275 row_base::raise_inserted()
00276 {
00277   m_signal_inserted.emit();
00278 }
00279 
00280 void
00281 row_base::raise_updated()
00282 {
00283   m_signal_updated.emit();
00284 }
00285 
00286 void
00287 row_base::raise_erased()
00288 {
00289   m_signal_erased.emit();
00290 }
00291 
00292 void
00293 row_base::begin(pqxxobject::transaction& tran)
00294 {
00295   begin_impl(tran);
00296   m_state = STATE_INCONSISTENT;
00297 }
00298 
00299 void
00300 row_base::refresh_impl(pqxxobject::transaction& tran)
00301 {
00302 }
00303 
00304 void
00305 row_base::insert_impl(pqxxobject::transaction& tran)
00306 {
00307 }
00308 
00309 void
00310 row_base::update_impl(pqxxobject::transaction& tran)
00311 {
00312 }
00313 
00314 void
00315 row_base::erase_impl(pqxxobject::transaction& tran)
00316 {
00317 }
00318 
00319 void
00320 row_base::unset_checkpoint(pqxxobject::transaction& tran)
00321 {
00322   if (tran.get_checkpoint() == true && get_checkpoint() == true)
00323     tran.set_checkpoint(false);
00324 }
00325 
00326 void
00327 row_base::connect_signal_handlers(pqxxobject::transaction& tran)
00328 {
00329   tran.signal_commit().connect
00330     ( SigC::slot(*this, &row_base::commit) );
00331   tran.signal_abort().connect
00332     ( SigC::slot(*this, &row_base::abort) );
00333   tran.signal_refresh().connect
00334     ( SigC::slot(*this, &row_base::refresh) );
00335 }
00336 
00337 void
00338 row_base::connect_safe_signal_handlers(pqxxobject::transaction& tran)
00339 {
00340   tran.signal_commit().connect
00341     ( SigC::slot(*this, &row_base::commit) );
00342   tran.signal_abort().connect
00343     ( SigC::slot(*this, &row_base::abort) );
00344   // No refresh signal, to prevent recursion.
00345 }

Generated on Thu Apr 1 10:37:56 2004 for pqxx-object API Reference by doxygen 1.3.5