00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00038
00039 #ifndef PQXXOBJECT_ROW_H
00040 #define PQXXOBJECT_ROW_H
00041
00042 #include <cassert>
00043 #include <iostream>
00044 #include <memory>
00045
00046 #include <pqxxobject/row_base.h>
00047
00048 namespace pqxxobject
00049 {
00081 template<typename Row>
00082 class row : public row_base
00083 {
00084 private:
00086 Row *m_checkpoint;
00087
00088 public:
00090 typedef std::auto_ptr<Row> row_ptr;
00091
00093 row():
00094 row_base(),
00095 m_checkpoint(0)
00096 {}
00097
00103 explicit row(row_state status,
00104 bool modified=false):
00105 row_base(status, modified),
00106 m_checkpoint(0)
00107 {}
00108
00113 row(const row& rhs):
00114 row_base(rhs),
00115 m_checkpoint(0)
00116 {
00117 }
00118
00120 virtual ~row()
00121 {
00122 if (m_checkpoint)
00123 {
00124 #ifdef PQXXOBJECT_DEBUG
00125 std::cerr << "~row: deleting checkpoint object at 0x" << m_checkpoint
00126 << " (for row " << this << ")" << std::endl;
00127 #endif
00128 delete m_checkpoint;
00129 }
00130 }
00131
00136 row& operator = (const row& rhs)
00137 {
00138 if (&rhs != this)
00139 {
00140 row_base::operator=(rhs);
00141 m_checkpoint = 0;
00142 }
00143 return *this;
00144 }
00145
00152 static row_ptr create(pqxx::result::const_iterator row,
00153 pqxxobject::transaction& tran)
00154 {
00155 row_ptr p(new Row);
00156 p->convert_impl(row, tran);
00157 p->row_base::m_state = STATE_INITIALISED;
00158 return p;
00159 }
00160
00161 private:
00162 bool get_checkpoint() const
00163 {
00164 return m_checkpoint != 0;
00165 }
00166
00167 void begin_impl(pqxxobject::transaction& tran)
00168 {
00169 assert (m_checkpoint == 0);
00170
00171 if (tran.get_checkpoint() == false)
00172 {
00173 #ifdef PQXXOBJECT_DEBUG
00174 std::cerr << "begin_impl: ";
00175 #endif
00176
00177 Row *current = dynamic_cast<Row *>(this);
00178 assert(current != 0);
00179
00180 Row *saved = new Row(*current);
00181 m_checkpoint = saved;
00182 #ifdef PQXXOBJECT_DEBUG
00183 std::cerr << "checkpoint object at 0x" << m_checkpoint
00184 << " (for row " << this << ")" << std::endl;
00185 #endif
00186 }
00187 }
00188
00189 void abort_impl(pqxxobject::transaction& tran)
00190 {
00191 if (m_checkpoint)
00192 {
00193 #ifdef PQXXOBJECT_DEBUG
00194 std::cerr << "abort_impl: rolling back to checkpoint 0x" << m_checkpoint
00195 << " (for row " << this << ")" << std::endl;
00196 #endif
00197
00198 Row *current = dynamic_cast<Row *>(this);
00199 assert(current != 0);
00200
00201 Row *saved = m_checkpoint;
00202
00203 *current = *saved;
00204 #ifdef PQXXOBJECT_DEBUG
00205 std::cerr << "abort_impl: deleting checkpoint object at 0x" << saved
00206 << " (for row " << this << ")" << std::endl;
00207 #endif
00208 delete saved;
00209 saved = 0;
00210 #ifdef PQXXOBJECT_DEBUG
00211 std::cerr << "In rolled back object, m_checkpoint is " << m_checkpoint << std::endl;
00212 #endif
00213 }
00214 #ifdef PQXXOBJECT_DEBUG
00215 else
00216 std::cerr << "abort_impl: can't roll back" << std::endl;
00217 #endif
00218 }
00219
00220 void commit_impl(pqxxobject::transaction& tran)
00221 {
00222 #ifdef PQXXOBJECT_DEBUG
00223 std::cerr << "commit_impl" << std::endl;
00224 #endif
00225 if (m_checkpoint)
00226 {
00227 #ifdef PQXXOBJECT_DEBUG
00228 std::cerr << "commit_impl: deleting checkpoint object at 0x" << m_checkpoint
00229 << " (for row " << this << ")" << std::endl;
00230 #endif
00231 delete m_checkpoint;
00232 m_checkpoint = 0;
00233 }
00234 }
00235
00236 };
00237
00238 };
00239
00240 #endif // PQXXOBJECT_ROW_H