Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

rdbModel::Table Class Reference

#include <Table.h>

List of all members.

Public Member Functions

Visitor::VisitorState accept (Visitor *v)
Visitor::VisitorState accept (Visitor *v)
AssertiongetAssertionByName (const std::string &name) const
AssertiongetAssertionByName (const std::string &name) const
ColumngetColumnByName (const std::string &name) const
ColumngetColumnByName (const std::string &name) const
IndexgetIndexByName (const std::string &name) const
IndexgetIndexByName (const std::string &name) const
InsertNewgetInsertNew () const
InsertNewgetInsertNew () const
const std::string & getName () const
const std::string & getName () const
SupersedegetSupersede () const
SupersedegetSupersede () const
int insertLatest (Row &row, int *serial=0) const
int insertLatest (Row &row, int *serial=0) const
int insertRow (Row &row, int *serial=0) const
int insertRow (Row &row, int *serial=0) const
void setConnection (Connection *connect)
void setConnection (Connection *connect)
void sortColumns ()
void sortColumns ()
int supersedeRow (Row &row, int oldKey, int *newKey=0) const
int supersedeRow (Row &row, int oldKey, int *newKey=0) const
 Table ()
 Table ()
int updateRows (Row &row, Assertion *where) const
int updateRows (Row &row, Assertion *where) const
 ~Table ()
 ~Table ()

Private Member Functions

void addAssert (Assertion *a)
 For use by builders.
void addAssert (Assertion *a)
 For use by builders.
void addColumn (Column *c)
 For use by builders.
void addColumn (Column *c)
 For use by builders.
void addIndex (Index *i)
 For use by builders.
void addIndex (Index *i)
 For use by builders.
bool doInterUpdate (const std::vector< Set > &sets, Assertion *subsAssert, Row &toBe) const
 Service routine for insertLatest.
bool doInterUpdate (const std::vector< Set > &sets, Assertion *subsAssert, Row &toBe) const
 Service routine for insertLatest.
void fillDefaults (Row &row) const
 Service routine when doing insert.
void fillDefaults (Row &row) const
 Service routine when doing insert.
bool fillProgramCols (Row &row, bool newRow) const
bool fillProgramCols (Row &row, bool newRow) const
bool isSupersedable (std::string oldKeyStr) const
 Service routine for supersedeRow. Check supersedable condition.
bool isSupersedable (std::string oldKeyStr) const
 Service routine for supersedeRow. Check supersedable condition.
const std::string & setPrimaryKeyCol ()
 Service routine for supersedeRow. Need to know table's primary key.
const std::string & setPrimaryKeyCol ()
 Service routine for supersedeRow. Need to know table's primary key.
void setValidRow (Assertion *v)
void setValidRow (Assertion *v)

Private Attributes

std::vector< Assertion * > m_asserts
std::vector< Assertion * > m_asserts
std::vector< Column * > m_cols
std::vector< Column * > m_cols
std::string m_comment
Connectionm_connect
Connectionm_connect
std::ostreamm_err
std::ostreamm_err
std::vector< Index * > m_indices
std::vector< Index * > m_indices
InsertNewm_iNew
InsertNewm_iNew
std::vector< Column * > m_mayDefault
 Subset of columns with defaults (includes those defaulting to null).
std::vector< Column * > m_mayDefault
 Subset of columns with defaults (includes those defaulting to null).
std::string m_name
unsigned m_nEndUser
std::ostreamm_out
std::ostreamm_out
std::string m_primaryKeyCol
std::vector< Column * > m_programCols
 Subset of columns which are responsibility of Program (us) to fill.
std::vector< Column * > m_programCols
 Subset of columns which are responsibility of Program (us) to fill.
bool m_sorted
std::vector< Column * > m_sortedCols
std::vector< Column * > m_sortedCols
Supersedem_sup
Supersedem_sup
std::vector< Column * > m_userCols
 Subset of columns which user *must* supply.
std::vector< Column * > m_userCols
 Subset of columns which user *must* supply.
Assertionm_validRow
Assertionm_validRow
std::string m_version

Friends

class rdbModel::Rdb
class rdbModel::XercesBuilder


Detailed Description

rdbModel representation of a(n SQL-like) table description


Constructor & Destructor Documentation

rdbModel::Table::Table  ) 
 

00020                : m_primaryKeyCol(""), m_sorted(false), m_nEndUser(0), 
00021                    m_validRow(0), m_iNew(0), m_sup(0), m_connect(0)    {
00022     m_sortedCols.clear(); m_programCols.clear(); 
00023     m_userCols.clear(); m_mayDefault.clear();
00024     m_out = &std::cout;    m_err = &std::cerr;
00025   }

rdbModel::Table::~Table  ) 
 

00028                 {
00029     while (m_cols.size() ) {
00030       Column* c = m_cols.back();
00031       m_cols.pop_back();
00032       delete c;
00033     }
00034 
00035     while (m_asserts.size() ) {
00036       Assertion* a = m_asserts.back();
00037       m_asserts.pop_back();
00038       delete a;
00039     }
00040 
00041     while (m_indices.size() ) {
00042       Index* i = m_indices.back();
00043       m_indices.pop_back();
00044       delete i;
00045     }
00046   }

rdbModel::Table::Table  ) 
 

rdbModel::Table::~Table  ) 
 


Member Function Documentation

Visitor::VisitorState rdbModel::Table::accept Visitor v  ) 
 

Visitor::VisitorState rdbModel::Table::accept Visitor v  ) 
 

00102                                               {
00103     
00104     Visitor::VisitorState state = v->visitTable(this);
00105     if (state == Visitor::VBRANCHDONE) return Visitor::VCONTINUE;
00106     if (state != Visitor::VCONTINUE)       return state;
00107 
00108     unsigned n = m_cols.size();
00109 
00110     for (unsigned i = 0; i < n; i++) {
00111       state = m_cols[i]->accept(v);
00112       if (state != Visitor::VCONTINUE) return state;
00113     }
00114 
00115     n = m_indices.size();
00116     for (unsigned i = 0; i < n; i++) {
00117       state = m_indices[i]->accept(v);
00118       if (state != Visitor::VCONTINUE) return state;
00119     }
00120 
00121     n = m_asserts.size();
00122     for (unsigned i = 0; i < n; i++) {
00123       state = m_asserts[i]->accept(v);
00124       if (state != Visitor::VCONTINUE) return state;
00125     }
00126     return state;
00127   }

void rdbModel::Table::addAssert Assertion a  )  [inline, private]
 

For use by builders.

00134 {m_asserts.push_back(a);}

void rdbModel::Table::addAssert Assertion a  )  [inline, private]
 

For use by builders.

00134 {m_asserts.push_back(a);}

void rdbModel::Table::addColumn Column c  )  [private]
 

For use by builders.

void rdbModel::Table::addColumn Column c  )  [private]
 

For use by builders.

00142                                  {
00143     m_cols.push_back(c);
00144     if (c->getSourceType() == Column::FROMendUser) {
00145       m_nEndUser++;
00146       // if not nullable and no default, user must supply it
00147       if (!(c->nullAllowed()) && ((c->getDefault()).size() == 0)) {
00148         m_userCols.push_back(c);
00149       }
00150       else {
00151         m_mayDefault.push_back(c);
00152       }
00153     }
00154     else if (c->getSourceType() == Column::FROMdefault) {
00155       m_mayDefault.push_back(c);
00156     }
00157     else if (c->getSourceType() == Column::FROMprogram) {
00158       m_programCols.push_back(c);
00159     }
00160   }

void rdbModel::Table::addIndex Index i  )  [inline, private]
 

For use by builders.

00136 {m_indices.push_back(i); }

void rdbModel::Table::addIndex Index i  )  [inline, private]
 

For use by builders.

00136 {m_indices.push_back(i); }

bool rdbModel::Table::doInterUpdate const std::vector< Set > &  sets,
Assertion subsAssert,
Row toBe
const [private]
 

Service routine for insertLatest.

bool rdbModel::Table::doInterUpdate const std::vector< Set > &  sets,
Assertion subsAssert,
Row toBe
const [private]
 

Service routine for insertLatest.

00539                                                                          {
00540     unsigned nSets = sets.size();
00541     std::vector<FieldVal> fields;
00542     fields.reserve(nSets);
00543 
00544     for (unsigned iSet = 0; iSet < sets.size(); iSet++) {
00545       std::string col = sets[iSet].getDestColName();
00546       std::string src;
00547       //      updateCols.push_back(sets[iSet].getDestColName());
00548       FIELDTYPE srcType = sets[iSet].getSrcType();
00549       if ((srcType == FIELDTYPElit) || (srcType == FIELDTYPElitDef)) {
00550         src = sets[iSet].getSrcValue();
00551         // May require special handling
00552         if (sets[iSet].hasInterp()) {
00553           Column* c = getColumnByName(col);
00554           c->interpret(sets[iSet].getInterp(), src);
00555           /*  should know how to substitute, e.g. val="NOW" should
00556            be transformed into a timestamp           */
00557         }
00558       }
00559       else {   // must be toBe
00560         std::string toBeCol = sets[iSet].getSrcValue();
00561         FieldVal* f = toBe.find(toBeCol);
00562         if (f == 0) {
00563           delete subsAssert;
00564           (*m_out) << "Table::InsertNew Row argument missing needed field"
00565                    << toBeCol << std::endl;
00566           m_out->flush();
00567           return false;
00568           //          throw RdbException
00569           //            ("Table::InsertNew Row argument missing needed field");
00570         }
00571         src = f->m_val;
00572         //        updateVals.push_back(f->m_val);
00573       }
00574       FieldVal g(col, src);
00575       fields.push_back(g);
00576     }
00577     Row row(fields);
00578 
00579     fillProgramCols(row, false);
00580 
00581     std::vector<std::string> updateCols;
00582     std::vector<std::string> updateVals;
00583     std::vector<std::string> nullCols;
00584 
00585     row.regroup(updateCols, updateVals, nullCols);
00586 
00587     // Make specified changes (update)
00588     m_connect->update(m_name, updateCols, updateVals, subsAssert);
00589     
00590     delete subsAssert;
00591     return true;
00592   }

void rdbModel::Table::fillDefaults Row row  )  const [private]
 

Service routine when doing insert.

void rdbModel::Table::fillDefaults Row row  )  const [private]
 

Service routine when doing insert.

00516                                          {
00517     for (unsigned i = 0; i < m_mayDefault.size(); i++) {
00518       Column* hasDef = m_mayDefault[i];
00519       FieldVal* f = row.find(hasDef->getName());
00520       if (f) continue;  
00521       // otherwise add it it
00522       if ((hasDef->getDefault()).size() > 0) {
00523         FieldVal g(hasDef->getName(), hasDef->getDefault());
00524         row.addField(g);
00525       }
00526       else {   // null
00527         FieldVal g(hasDef->getName(), "", true);
00528         row.addField(g);
00529       }
00530       row.rowSort();
00531     }
00532   }

bool rdbModel::Table::fillProgramCols Row row,
bool  newRow
const [private]
 

Service routine when doing insert or update. Augment Row with values for those columns which are responsibility of Program (not end-user).

  • newRow should be true for insert, false for update.

bool rdbModel::Table::fillProgramCols Row row,
bool  newRow
const [private]
 

Service routine when doing insert or update. Augment Row with values for those columns which are responsibility of Program (not end-user).

  • newRow should be true for insert, false for update.
00468                                                          {
00469     std::string val;
00470 
00471     for (unsigned i = 0; i < m_programCols.size(); i++) {
00472       Column* col = m_programCols[i];
00473       switch (col->getContentsType() ) {
00474       case Column::CONTENTSserviceName: 
00475         val="rdbModel";
00476         break;
00477       case Column::CONTENTSusername: {
00478 #ifdef    __GNUG__ 
00479         val = std::string("$(USER)");
00480 #else
00481         val = std::string("$(USERNAME)");
00482 #endif
00483 
00484         int nsub = facilities::Util::expandEnvVar(&val);
00485         if (nsub != 1) {
00486           val="no username";
00487         }
00488         break;
00489       }
00490 
00491       case Column::CONTENTSinsertTime:
00492         if (!newRow) continue;   // otherwise, same as updateTime case
00493       case Column::CONTENTSupdateTime: {
00494         facilities::Timestamp curTime;
00495         val = curTime.getString();
00496         break;
00497       }
00498       default:
00499         return false;    // unrecognized type
00500       }
00501       // look for this field in Row input. If there, overwrite value
00502       FieldVal* f = row.find(col->getName());
00503       if (f) {
00504         f->m_val = val;
00505         f->m_null = false;
00506       } 
00507       else {
00508         FieldVal g(col->getName(), val, false);
00509         row.addField(g);
00510         row.rowSort();
00511       }
00512     }
00513     return true;
00514   }

Assertion* rdbModel::Table::getAssertionByName const std::string &  name  )  const
 

Assertion * rdbModel::Table::getAssertionByName const std::string &  name  )  const
 

00091                                                                   {
00092     unsigned nAssert = m_asserts.size();
00093     for (unsigned i = 0; i < nAssert; i++) {
00094       Assertion* a = m_asserts[i];
00095       if (a->getName() == name) return a;
00096     }
00097     return 0;
00098 
00099   }

Column* rdbModel::Table::getColumnByName const std::string &  name  )  const
 

Column * rdbModel::Table::getColumnByName const std::string &  name  )  const
 

00056                                                             {
00057     unsigned nCol = m_sortedCols.size();
00058     unsigned minI = 0;
00059     unsigned maxI = nCol;
00060 
00061     unsigned guess = maxI/2;
00062     unsigned oldGuess = nCol;
00063 
00064     int cmp = name.compare(m_sortedCols[guess]->getName());
00065 
00066     while (cmp != 0)  {
00067       if (guess == oldGuess) return 0;        // not found
00068 
00069       if (cmp < 0 ) {    // thing we tried is > colName, so decrease maxI
00070         maxI = guess;
00071       }  else {   // thing we tried is > colName, so increase minI
00072         minI =  guess;
00073       }
00074       oldGuess = guess;
00075       guess = (minI + maxI)/2;
00076       cmp = name.compare(m_sortedCols[guess]->getName());
00077     }
00078     return m_sortedCols[guess];
00079 
00080   }

Index* rdbModel::Table::getIndexByName const std::string &  name  )  const
 

Index * rdbModel::Table::getIndexByName const std::string &  name  )  const
 

00082                                                           {
00083     unsigned nIx = m_indices.size();
00084     for (unsigned iIx = 0; iIx < nIx; iIx++) {
00085       Index* index = m_indices[iIx];
00086       if (index->getName() == name) return index;
00087     }
00088     return 0;
00089   }

InsertNew* rdbModel::Table::getInsertNew  )  const [inline]
 

00087 {return m_iNew;}

InsertNew* rdbModel::Table::getInsertNew  )  const [inline]
 

00087 {return m_iNew;}

const std::string& rdbModel::Table::getName  )  const [inline]
 

00040 { return m_name;}

const std::string& rdbModel::Table::getName  )  const [inline]
 

00040 { return m_name;}

Supersede* rdbModel::Table::getSupersede  )  const [inline]
 

00088 {return m_sup;}

Supersede* rdbModel::Table::getSupersede  )  const [inline]
 

00088 {return m_sup;}

int rdbModel::Table::insertLatest Row row,
int *  serial = 0
const
 

insertLatest is smart in the following respects: o Makes some checks to see if row is self-consistent o Fills in all fields which are to be supplied by "service" o If row satisfies conditions for being "official"

  • queries table to see if any pre-existing rows need adjustment; if so, they are adjusted o Finally inserts the row

If test is true, just output description of what would be done without actually doing it. Note row may be modified by the function. If a non-zero pointer is supplied for serial it will contain the primary key value (if there is one) of the new row on exit.

int rdbModel::Table::insertLatest Row row,
int *  serial = 0
const
 

insertLatest is smart in the following respects: o Makes some checks to see if row is self-consistent o Fills in all fields which are to be supplied by "service" o If row satisfies conditions for being "official"

  • queries table to see if any pre-existing rows need adjustment; if so, they are adjusted o Finally inserts the row

If test is true, just output description of what would be done without actually doing it. Note row may be modified by the function. If a non-zero pointer is supplied for serial it will contain the primary key value (if there is one) of the new row on exit.

00162                                                      {
00163 
00164     if (!m_connect) {
00165       throw RdbException("Table::insertLatest Need matching connection");
00166     }
00167     row.rowSort();
00168 
00169     // Fill in columns in m_programCols list
00170     fillProgramCols(row, true);
00171 
00172     // Check that all required columns are there and not null
00173     for (unsigned i = 0; i < m_userCols.size(); i++) {
00174       FieldVal* f = row.find(m_userCols[i]->getName());
00175       if ((!f) || (f->m_null)) {
00176         std::string 
00177           msg("Table::insertLatest Row to be inserted missing req'd field ");
00178         msg = msg + m_userCols[i]->getName();
00179         throw RdbException(msg);
00180       }
00181     }
00182     // Fill in defaults
00183     fillDefaults(row);
00184 
00185     // Check against consistency conditions specified by <insertNew>
00186     const Assertion* cond = m_iNew->getInternal();
00187     bool satisfied;
00188 
00189     try {
00190       satisfied = cond->verify(row, row);
00191     }
00192     catch (RdbException ex) {
00193       (*m_out) << ex.getMsg() << std::endl;
00194       return -1;
00195     }
00196 
00197     if (!satisfied) return -1;   // or maybe throw exception here?
00198 
00199     // Check against official conditions specified by <insertNew>
00200     const Assertion* condO = m_iNew->getOfficial();
00201     Row empty;
00202     std::vector<std::string> colNames;
00203     std::vector<std::string> colValues;
00204     std::vector<std::string> nullCols;
00205 
00206     row.regroup(colNames, colValues, nullCols);
00207 
00208     satisfied = condO->verify(empty, row);
00209 
00210     // If not official, do insert and exit
00211     if (!satisfied) {
00212       bool ok = m_connect->insertRow(m_name, colNames, colValues,
00213                                      serial, &nullCols);
00214       return (ok) ?  0 : -1;
00215     }
00216 
00217     const std::vector<InterRow* >& inter = m_iNew->getInterRow();
00218 
00219     unsigned nInter = inter.size();
00220     Assertion* subsAssert;
00221     for (unsigned iInter = 0; iInter < nInter; iInter++) {
00222       const Query* q = inter[iInter]->getQuery();
00223       const std::vector<std::string>& toSelect = q->getToSelect();
00224 
00225       // Need to make a new Assertion which substitues our proposed row
00226       // values for all "toBe" entries
00227       subsAssert = new Assertion(q->getAssertion(), &row);
00228 
00229       std::vector<std::string> orderCols;
00230       orderCols.clear();
00231       ResultHandle* r = m_connect->select(m_name, toSelect, orderCols, 
00232                                           subsAssert);
00233 
00234       if (r->getNRows() == 0) {    // no conflicts found
00235         delete subsAssert;
00236         continue;   // go on to next InterRow, if any.  
00237       }
00238 
00239       // otherwise
00240       //    if quit  go ahead and quit
00241       if (inter[iInter]->getQuit()) {
00242         delete subsAssert;
00243         (*m_out) << "insert latest not done because of irreconcilable " 
00244                  << std::endl << "conflict with existing rows" << std::endl;
00245         return -1;
00246       }
00247       //    else modify conflicting rows as specified in <interRow>.
00248       //    (i.e., do an update with where clause = subsAssert
00249 
00250       std::vector<Set> sets = inter[iInter]->getSets();
00251 
00252       bool iu = doInterUpdate(sets, subsAssert, row);
00253       if (!iu) return -1;
00254     }
00255     // Insert and exit
00256     bool ok = m_connect->insertRow(m_name, colNames, colValues,
00257                                    serial, &nullCols);
00258     return (ok) ?  0 : -1;
00259   }

int rdbModel::Table::insertRow Row row,
int *  serial = 0
const
 

The less smart insertRow function fills in all fields which are to be supplied by "service" and inserts the row, without any further checks. Good return value is 0

int rdbModel::Table::insertRow Row row,
int *  serial = 0
const
 

The less smart insertRow function fills in all fields which are to be supplied by "service" and inserts the row, without any further checks. Good return value is 0

00261                                                   {
00262 
00263     if (!m_connect) {
00264       throw RdbException("Table::insertRow Need matching connection");
00265     }
00266     row.rowSort();
00267 
00268     // Fill in columns in m_programCols list
00269     fillProgramCols(row, true);
00270 
00271 
00272     // Check that all required columns are there and not null
00273     for (unsigned i = 0; i < m_userCols.size(); i++) {
00274       FieldVal* f = row.find(m_userCols[i]->getName());
00275       if ((!f) || (f->m_null)) {
00276         std::string 
00277           msg("Table::insertRow Row to be inserted missing req'd field ");
00278         msg = msg + m_userCols[i]->getName();
00279         throw RdbException(msg);
00280       }
00281     }
00282 
00283     // Fill in defaults
00284     fillDefaults(row);
00285 
00286     // Check standard valid row condition if there is one
00287     if (m_validRow) {
00288       bool satisfied;
00289       try {
00290         satisfied = m_validRow->verify(row, row);
00291       }
00292       catch (RdbException ex) {
00293         (*m_out) << ex.getMsg() << std::endl;
00294         return -1;
00295       }
00296       if (!satisfied) {
00297         // throw RdbException("Table::insertRow Row to be inserted is not valid");
00298         (*m_out) << "Table::insertRow Row to be inserted is not valid " 
00299                   << std::endl;
00300         m_out->flush();
00301         return -1;
00302       }
00303     }
00304     // Insert and exit
00305     std::vector<std::string> colNames;
00306     std::vector<std::string> colValues;
00307     std::vector<std::string> nullCols;
00308 
00309     row.regroup(colNames, colValues, nullCols);
00310     bool ok = m_connect->insertRow(m_name, colNames, colValues,
00311                                    serial, &nullCols);
00312     return (ok) ?  0 : -1;
00313   }    

bool rdbModel::Table::isSupersedable std::string  oldKeyStr  )  const [private]
 

Service routine for supersedeRow. Check supersedable condition.

bool rdbModel::Table::isSupersedable std::string  oldKeyStr  )  const [private]
 

Service routine for supersedeRow. Check supersedable condition.

00607                                                       {
00608     // Make a copy of supersedable condition
00609     Row emptyRow;
00610     Assertion::Operator* onlyIf = 
00611       new Assertion::Operator((m_sup->getOnlyIf())->getOperator(), 
00612                               &emptyRow);
00613     // Make operator for key == oldKey
00614     Assertion::Operator* ser =
00615       new Assertion::Operator(OPTYPEequal,  m_primaryKeyCol,
00616                               oldKeyStr, FIELDTYPEold, FIELDTYPElit);
00617     std::vector<Assertion::Operator*> children;
00618     children.push_back(onlyIf);
00619     children.push_back(ser);
00620     Assertion::Operator* whereOp = 
00621       new Assertion::Operator(OPTYPEand, children);
00622 
00623     std::vector<std::string> queryCols;
00624     queryCols.push_back(m_primaryKeyCol);
00625     Assertion* where = new Assertion(whereOp);
00626     ResultHandle* results = m_connect->select(m_name, queryCols, queryCols,
00627                                               where);
00628     delete where;
00629 
00630     return (results->getNRows() > 0);
00631   }

void rdbModel::Table::setConnection Connection connect  ) 
 

void rdbModel::Table::setConnection Connection connect  ) 
 

00049                                                {
00050     m_connect = connect;
00051     m_out = connect->getOut();
00052     m_err = connect->getErrOut();
00053   }

const std::string& rdbModel::Table::setPrimaryKeyCol  )  [private]
 

Service routine for supersedeRow. Need to know table's primary key.

const std::string & rdbModel::Table::setPrimaryKeyCol  )  [private]
 

Service routine for supersedeRow. Need to know table's primary key.

00594                                            {
00595     static const std::string empty("");
00596     if (m_primaryKeyCol.size() > 0) return m_primaryKeyCol;
00597 
00598     for (unsigned iCol = 0; iCol < m_cols.size(); iCol++) {
00599       if (m_cols[iCol]->isPrimaryKey()) {
00600         m_primaryKeyCol = m_cols[iCol]->getName();
00601         return m_primaryKeyCol;
00602       }
00603     }
00604     return empty;
00605   }

void rdbModel::Table::setValidRow Assertion v  )  [inline, private]
 

00098 {m_validRow = v;}

void rdbModel::Table::setValidRow Assertion v  )  [inline, private]
 

00098 {m_validRow = v;}

void rdbModel::Table::sortColumns  ) 
 

void rdbModel::Table::sortColumns  ) 
 

00129                            {
00130     if (m_sorted) return;
00131     m_sortedCols = m_cols;
00132 
00133     ColCompare  cmpObject;
00134 
00135     // Keep around original set so that rdbGUI will display them in
00136     // this order
00137     std::sort (m_sortedCols.begin(), m_sortedCols.end(), cmpObject); 
00138     m_sorted = true;
00139 
00140   }

int rdbModel::Table::supersedeRow Row row,
int  oldKey,
int *  newKey = 0
const
 

Given some input values and primary key of an existing row, insert a new row which will supersede the old, according to prescription laid down in <supersede> element of the xml description of the dbs. Good return value is 0

int rdbModel::Table::supersedeRow Row row,
int  oldKey,
int *  newKey = 0
const
 

Given some input values and primary key of an existing row, insert a new row which will supersede the old, according to prescription laid down in <supersede> element of the xml description of the dbs. Good return value is 0

00315                                                                  {
00316     std::string oldKeyStr;
00317     facilities::Util::itoa(oldKey, oldKeyStr);
00318 
00319     if (m_primaryKeyCol.size() == 0) {
00320       throw RdbException("Table::supersedeRow No primary key column!");
00321     }
00322 
00323     // Confirm that row does not contain any of the fixed or oldForced columns
00324     row.rowSort();
00325     const std::vector<std::string>& forced = m_sup->getForced();
00326     for (unsigned i = 0; i < forced.size(); i++) {
00327       if (row.find(forced[i])) {
00328         //        throw RdbException
00329         //          (std::string("Table::supersedeRow bad column in input row ") +
00330         // forced[i]);
00331         (*m_out) << "Table::supersedeRow bad column in input row '"
00332                  << forced[i] << "'" << std::endl;
00333         m_out->flush();
00334         return -1;
00335       }
00336     }
00337     const std::vector<FieldVal>& fixed = m_sup->getFixed();
00338     for (unsigned i = 0; i < fixed.size(); i++) {
00339       if (row.find(fixed[i].m_colname)) {
00340         //        throw RdbException
00341         //          (std::string("Table::supersedeRow bad column in input row ") +
00342         //           fixed[i].m_colname);
00343         (*m_out) << "Table::supersedeRow bad column in input row " <<
00344           fixed[i].m_colname;
00345         m_out->flush();
00346         return -1;
00347       }
00348     }
00349 
00350     // Check that old row is supersedable
00351     if (!isSupersedable(oldKeyStr)) {
00352       *m_out << "Row " << oldKey << " is not supersedable" << std::endl;
00353       m_out->flush();
00354       return -1;
00355     }
00356     
00357     // Fill in fixed fields
00358     const std::vector<std::string>& fixedInterp = m_sup->getFixedInterp();
00359     for (unsigned i = 0; i < fixed.size(); i++) {
00360 
00361       FieldVal fv = fixed[i];
00362       if (fixedInterp[i].size() > 0) {
00363         Column* c = getColumnByName(fixed[i].m_colname);
00364         c->interpret(fixedInterp[i], fv.m_val);
00365       }
00366       row.addField(fv);
00367     }
00368     row.rowSort();
00369 
00370     // Fetch needed fields from row to be superseded (oldKey)
00371     Assertion::Operator* whereOp = 
00372       new Assertion::Operator(OPTYPEequal, m_primaryKeyCol,
00373                               oldKeyStr, FIELDTYPEold, FIELDTYPElit);
00374     Assertion* where = new Assertion(whereOp);
00375 
00376     std::vector<std::string> noCols;
00377     const std::vector<std::string>& fromOld = m_sup->getFromOld();
00378     noCols.clear();
00379     ResultHandle* results = m_connect->select(m_name, fromOld, 
00380                                               noCols, where);
00381     //    std::vector<std::string> vals;
00382     //    results->getRow(vals);
00383     std::vector<std::string*> vals;
00384     results->getRowPtrs(vals);
00385     // Merge as needed into our row.  First bunch may already be in the row
00386     unsigned nDef = m_sup->getOldDefaulted().size();
00387     for (unsigned i = 0; i < nDef; i++) {
00388       if (!(row.find(fromOld[i])) ) {
00389         if (vals[i] == 0) {
00390           row.addField(FieldVal(fromOld[i], "", true));
00391         }
00392         else {
00393           row.addField(FieldVal(fromOld[i], *vals[i]));
00394         }
00395         row.rowSort();
00396       }
00397     }
00398     // Remainder definitely have to be merged in
00399     for (unsigned i = nDef; i < fromOld.size(); i++) {
00400       if (vals[i] == 0) {
00401         row.addField(FieldVal(fromOld[i], "", true));
00402       }
00403       else {
00404         row.addField(FieldVal(fromOld[i], *vals[i]));
00405       }
00406     }
00407     results->cleanFieldPtrs(vals);
00408     
00409     // Insert the row and update old row
00410     int insRet;
00411     try {
00412       insRet = insertRow(row, serial);
00413     }
00414     catch (RdbException ex) {
00415       (*m_out) << ex.getMsg() << std::endl;
00416       insRet = -1;
00417     }
00418 
00419     if (insRet) { // something went wrong
00420       delete where;
00421       return insRet;
00422     }
00423 
00424     // Do the update of old row
00425     const std::vector<Set*>& setOld = m_sup->getSetOld();
00426     std::vector<FieldVal> oldFields;
00427     oldFields.reserve(setOld.size());
00428     for (unsigned i = 0; i < setOld.size(); i++) {
00429       std::string src = setOld[i]->getSrcValue();
00430       std::string col = setOld[i]->getDestColName();
00431       if (setOld[i]->hasInterp() ) {
00432         Column* c = getColumnByName(col);
00433         c->interpret(setOld[i]->getInterp(), src);
00434       }
00435       oldFields.push_back(FieldVal(col, src));
00436     }
00437     Row updateArg(oldFields);
00438     try {
00439       int iUpdated = updateRows(updateArg, where);
00440       if (iUpdated == 1) return 0;
00441       return -1;
00442     }
00443     catch (RdbException uEx) {
00444       (*m_out) << uEx.getMsg() << std::endl;
00445       return -1;
00446     }
00447   }

int rdbModel::Table::updateRows Row row,
Assertion where
const
 

Silently fills in "service" fields as well as requested updates Good return value is 0

int rdbModel::Table::updateRows Row row,
Assertion where
const
 

Silently fills in "service" fields as well as requested updates Good return value is 0

00449                                                         {
00450 
00451     if (!m_connect) {
00452       throw RdbException("Table::insertLatest Need matching connection");
00453     }
00454     row.rowSort();
00455 
00456     // Fill in columns in m_programCols list
00457     fillProgramCols(row, false);
00458 
00459     std::vector<std::string> colNames;
00460     std::vector<std::string> colValues;
00461     std::vector<std::string> nullCols;
00462 
00463     row.regroup(colNames, colValues, nullCols);
00464 
00465     return m_connect->update(m_name, colNames, colValues, where, &nullCols);
00466   }


Friends And Related Function Documentation

rdbModel::Rdb [friend]
 

rdbModel::XercesBuilder [friend]
 


Member Data Documentation

std::vector<Assertion* > rdbModel::Table::m_asserts [private]
 

std::vector<Assertion* > rdbModel::Table::m_asserts [private]
 

std::vector<Column* > rdbModel::Table::m_cols [private]
 

std::vector<Column* > rdbModel::Table::m_cols [private]
 

std::string rdbModel::Table::m_comment [private]
 

Connection* rdbModel::Table::m_connect [private]
 

Connection* rdbModel::Table::m_connect [private]
 

std::ostream* rdbModel::Table::m_err [private]
 

std::ostream* rdbModel::Table::m_err [private]
 

std::vector<Index* > rdbModel::Table::m_indices [private]
 

std::vector<Index* > rdbModel::Table::m_indices [private]
 

InsertNew* rdbModel::Table::m_iNew [private]
 

InsertNew* rdbModel::Table::m_iNew [private]
 

std::vector<Column*> rdbModel::Table::m_mayDefault [private]
 

Subset of columns with defaults (includes those defaulting to null).

std::vector<Column*> rdbModel::Table::m_mayDefault [private]
 

Subset of columns with defaults (includes those defaulting to null).

std::string rdbModel::Table::m_name [private]
 

unsigned rdbModel::Table::m_nEndUser [private]
 

std::ostream* rdbModel::Table::m_out [private]
 

std::ostream* rdbModel::Table::m_out [private]
 

std::string rdbModel::Table::m_primaryKeyCol [private]
 

std::vector<Column* > rdbModel::Table::m_programCols [private]
 

Subset of columns which are responsibility of Program (us) to fill.

std::vector<Column* > rdbModel::Table::m_programCols [private]
 

Subset of columns which are responsibility of Program (us) to fill.

bool rdbModel::Table::m_sorted [private]
 

std::vector<Column* > rdbModel::Table::m_sortedCols [private]
 

std::vector<Column* > rdbModel::Table::m_sortedCols [private]
 

Supersede* rdbModel::Table::m_sup [private]
 

Supersede* rdbModel::Table::m_sup [private]
 

std::vector<Column* > rdbModel::Table::m_userCols [private]
 

Subset of columns which user *must* supply.

std::vector<Column* > rdbModel::Table::m_userCols [private]
 

Subset of columns which user *must* supply.

Assertion* rdbModel::Table::m_validRow [private]
 

Assertion* rdbModel::Table::m_validRow [private]
 

std::string rdbModel::Table::m_version [private]
 


The documentation for this class was generated from the following files:
Generated on Wed Feb 2 19:22:51 2011 for BOSS6.5.5 by  doxygen 1.3.9.1