rdbModel::Table Class Reference

#include <Table.h>

List of all members.

Public Member Functions

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

Private Member Functions

void setValidRow (Assertion *v)
void addColumn (Column *c)
 For use by builders.
void addAssert (Assertion *a)
 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 fillProgramCols (Row &row, bool newRow) const
void fillDefaults (Row &row) const
 Service routine when doing insert.
bool isSupersedable (std::string oldKeyStr) const
 Service routine for supersedeRow. Check supersedable condition.
const std::stringsetPrimaryKeyCol ()
 Service routine for supersedeRow. Need to know table's primary key.

Private Attributes

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

Friends

class rdbModel::XercesBuilder
class rdbModel::Rdb


Detailed Description

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

Definition at line 33 of file Table.h.


Constructor & Destructor Documentation

rdbModel::Table::Table (  ) 

Definition at line 20 of file Table.cxx.

References m_err, m_mayDefault, m_out, m_programCols, m_sortedCols, and m_userCols.

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 (  ) 

Definition at line 28 of file Table.cxx.

References genRecEmupikp::i, m_asserts, m_cols, and m_indices.

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   }


Member Function Documentation

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

Definition at line 102 of file Table.cxx.

References genRecEmupikp::i, m_asserts, m_cols, m_indices, v, rdbModel::Visitor::VBRANCHDONE, and rdbModel::Visitor::VCONTINUE.

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.

Definition at line 134 of file Table.h.

References m_asserts.

00134 {m_asserts.push_back(a);}

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

For use by builders.

Definition at line 142 of file Table.cxx.

References rdbModel::Column::FROMdefault, rdbModel::Column::FROMendUser, rdbModel::Column::FROMprogram, rdbModel::Column::getDefault(), rdbModel::Column::getSourceType(), m_cols, m_mayDefault, m_nEndUser, m_programCols, m_userCols, rdbModel::Column::nullAllowed(), and delete_small_size::size.

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.

Definition at line 136 of file Table.h.

References genRecEmupikp::i, and m_indices.

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.

Definition at line 538 of file Table.cxx.

References rdbModel::FIELDTYPElit, rdbModel::FIELDTYPElitDef, fillProgramCols(), rdbModel::Row::find(), getColumnByName(), rdbModel::Column::interpret(), m_connect, m_name, m_out, rdbModel::FieldVal::m_val, rdbModel::Row::regroup(), deljobs::string, and rdbModel::Connection::update().

Referenced by 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.

Definition at line 516 of file Table.cxx.

References rdbModel::Row::addField(), rdbModel::Row::find(), genRecEmupikp::i, m_mayDefault, rdbModel::Row::rowSort(), and delete_small_size::size.

Referenced by insertLatest(), and insertRow().

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).

Definition at line 468 of file Table.cxx.

References rdbModel::Row::addField(), rdbModel::Column::CONTENTSinsertTime, rdbModel::Column::CONTENTSserviceName, rdbModel::Column::CONTENTSupdateTime, rdbModel::Column::CONTENTSusername, rdbModel::Row::find(), facilities::Timestamp::getString(), genRecEmupikp::i, rdbModel::FieldVal::m_null, m_programCols, rdbModel::FieldVal::m_val, rdbModel::Row::rowSort(), and deljobs::string.

Referenced by doInterUpdate(), insertLatest(), insertRow(), and updateRows().

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

Definition at line 91 of file Table.cxx.

References genRecEmupikp::i, and m_asserts.

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

Definition at line 56 of file Table.cxx.

References getName(), and m_sortedCols.

Referenced by calibUtil::Metadata::checkNulls(), calibUtil::Metadata::checkValues(), doInterUpdate(), rdbModel::Rdb::getColumn(), supersedeRow(), and rdbModel::Assertion::Operator::validCompareOp().

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

Definition at line 82 of file Table.cxx.

References m_indices.

Referenced by rdbModel::Rdb::getIndex().

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]

Definition at line 87 of file Table.h.

References m_iNew.

00087 {return m_iNew;}

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

Definition at line 40 of file Table.h.

References m_name.

Referenced by getColumnByName(), rdbModel::Column::getTableName(), and rdbModel::MysqlConnection::visitTable().

00040 { return m_name;}

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

Definition at line 88 of file Table.h.

References m_sup.

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"

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.

Definition at line 162 of file Table.cxx.

References doInterUpdate(), fillDefaults(), fillProgramCols(), rdbModel::Row::find(), rdbModel::InsertNew::getInternal(), rdbModel::InsertNew::getInterRow(), rdbModel::RdbException::getMsg(), rdbModel::ResultHandle::getNRows(), rdbModel::InsertNew::getOfficial(), genRecEmupikp::i, rdbModel::Connection::insertRow(), m_connect, m_iNew, m_name, m_userCols, q, rdbModel::Row::regroup(), rdbModel::Row::rowSort(), rdbModel::Connection::select(), deljobs::string, and rdbModel::Assertion::verify().

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

Definition at line 261 of file Table.cxx.

References fillDefaults(), fillProgramCols(), rdbModel::Row::find(), rdbModel::RdbException::getMsg(), genRecEmupikp::i, rdbModel::Connection::insertRow(), m_connect, m_name, m_out, m_userCols, m_validRow, rdbModel::Row::regroup(), rdbModel::Row::rowSort(), deljobs::string, and rdbModel::Assertion::verify().

Referenced by supersedeRow().

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.

Definition at line 607 of file Table.cxx.

References rdbModel::FIELDTYPElit, rdbModel::FIELDTYPEold, rdbModel::ResultHandle::getNRows(), rdbModel::Supersede::getOnlyIf(), m_connect, m_name, m_primaryKeyCol, m_sup, rdbModel::OPTYPEand, rdbModel::OPTYPEequal, rdbModel::Connection::select(), and boss::where().

Referenced by supersedeRow().

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  ) 

Definition at line 49 of file Table.cxx.

References rdbModel::Connection::getErrOut(), rdbModel::Connection::getOut(), m_connect, m_err, and m_out.

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.

Definition at line 594 of file Table.cxx.

References m_cols, m_primaryKeyCol, and deljobs::string.

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]

Definition at line 98 of file Table.h.

References m_validRow, and v.

00098 {m_validRow = v;}

void rdbModel::Table::sortColumns (  ) 

Definition at line 129 of file Table.cxx.

References m_cols, m_sorted, and m_sortedCols.

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

Definition at line 315 of file Table.cxx.

References rdbModel::Row::addField(), rdbModel::ResultHandle::cleanFieldPtrs(), rdbModel::FIELDTYPElit, rdbModel::FIELDTYPEold, rdbModel::Row::find(), getColumnByName(), rdbModel::Supersede::getFixed(), rdbModel::Supersede::getFixedInterp(), rdbModel::Supersede::getForced(), rdbModel::Supersede::getFromOld(), rdbModel::RdbException::getMsg(), rdbModel::Supersede::getOldDefaulted(), rdbModel::ResultHandle::getRowPtrs(), rdbModel::Supersede::getSetOld(), genRecEmupikp::i, insertRow(), rdbModel::Column::interpret(), isSupersedable(), RawFileTools::itoa(), m_connect, m_name, m_out, m_primaryKeyCol, m_sup, rdbModel::OPTYPEequal, rdbModel::Row::rowSort(), rdbModel::Connection::select(), delete_small_size::size, deljobs::string, updateRows(), and boss::where().

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

Definition at line 449 of file Table.cxx.

References fillProgramCols(), m_connect, m_name, rdbModel::Row::regroup(), rdbModel::Row::rowSort(), rdbModel::Connection::update(), and boss::where().

Referenced by supersedeRow().

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

friend class rdbModel::Rdb [friend]

Definition at line 97 of file Table.h.

friend class rdbModel::XercesBuilder [friend]

Definition at line 96 of file Table.h.


Member Data Documentation

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

Definition at line 101 of file Table.h.

Referenced by accept(), addAssert(), getAssertionByName(), and ~Table().

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

Definition at line 99 of file Table.h.

Referenced by accept(), addColumn(), setPrimaryKeyCol(), sortColumns(), and ~Table().

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

Definition at line 115 of file Table.h.

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

Definition at line 126 of file Table.h.

Referenced by doInterUpdate(), insertLatest(), insertRow(), isSupersedable(), setConnection(), supersedeRow(), and updateRows().

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

Definition at line 128 of file Table.h.

Referenced by setConnection(), and Table().

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

Definition at line 102 of file Table.h.

Referenced by accept(), addIndex(), getIndexByName(), and ~Table().

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

Definition at line 123 of file Table.h.

Referenced by getInsertNew(), and insertLatest().

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

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

Definition at line 111 of file Table.h.

Referenced by addColumn(), fillDefaults(), and Table().

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

Definition at line 113 of file Table.h.

Referenced by doInterUpdate(), getName(), insertLatest(), insertRow(), isSupersedable(), supersedeRow(), and updateRows().

unsigned rdbModel::Table::m_nEndUser [private]

Definition at line 120 of file Table.h.

Referenced by addColumn().

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

Definition at line 127 of file Table.h.

Referenced by doInterUpdate(), insertRow(), setConnection(), supersedeRow(), and Table().

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

Definition at line 117 of file Table.h.

Referenced by isSupersedable(), setPrimaryKeyCol(), and supersedeRow().

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

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

Definition at line 105 of file Table.h.

Referenced by addColumn(), fillProgramCols(), and Table().

bool rdbModel::Table::m_sorted [private]

Definition at line 119 of file Table.h.

Referenced by sortColumns().

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

Definition at line 100 of file Table.h.

Referenced by getColumnByName(), sortColumns(), and Table().

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

Definition at line 124 of file Table.h.

Referenced by getSupersede(), isSupersedable(), and supersedeRow().

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

Subset of columns which user *must* supply.

Definition at line 108 of file Table.h.

Referenced by addColumn(), insertLatest(), insertRow(), and Table().

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

Definition at line 122 of file Table.h.

Referenced by insertRow(), and setValidRow().

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

Definition at line 114 of file Table.h.


Generated on Tue Nov 29 23:36:36 2016 for BOSS_7.0.2 by  doxygen 1.4.7