#include <Table.h>
Public Member Functions | |
Table () | |
~Table () | |
void | setConnection (Connection *connect) |
const std::string & | getName () const |
Column * | getColumnByName (const std::string &name) const |
Index * | getIndexByName (const std::string &name) const |
Assertion * | getAssertionByName (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 |
InsertNew * | getInsertNew () const |
Supersede * | getSupersede () 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::string & | setPrimaryKeyCol () |
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 |
Assertion * | m_validRow |
InsertNew * | m_iNew |
Supersede * | m_sup |
Connection * | m_connect |
std::ostream * | m_out |
std::ostream * | m_err |
Friends | |
class | rdbModel::XercesBuilder |
class | rdbModel::Rdb |
Definition at line 33 of file Table.h.
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 }
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] |
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] |
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 }
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 |
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] |
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] |
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] |
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 }
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 }
friend class rdbModel::Rdb [friend] |
friend class rdbModel::XercesBuilder [friend] |
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] |
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] |
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] |
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] |
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] |
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] |
std::string rdbModel::Table::m_version [private] |