4#include "rdbModel/Tables/Table.h"
5#include "facilities/Timestamp.h"
6#include "facilities/Util.h"
7#include "rdbModel/Db/Connection.h"
8#include "rdbModel/Db/ResultHandle.h"
9#include "rdbModel/RdbException.h"
10#include "rdbModel/Tables/Assertion.h"
11#include "rdbModel/Tables/Column.h"
12#include "rdbModel/Tables/Index.h"
13#include "rdbModel/Tables/InsertNew.h"
14#include "rdbModel/Tables/InterRow.h"
15#include "rdbModel/Tables/Query.h"
16#include "rdbModel/Tables/Set.h"
17#include "rdbModel/Tables/Supersede.h"
22 : m_primaryKeyCol(
"" )
30 m_programCols.clear();
38 while ( m_cols.size() )
45 while ( m_asserts.size() )
52 while ( m_indices.size() )
54 Index* i = m_indices.back();
68 unsigned nCol = m_sortedCols.size();
72 unsigned guess = maxI / 2;
73 unsigned oldGuess = nCol;
75 int cmp = name.compare( m_sortedCols[guess]->
getName() );
79 if ( guess == oldGuess )
return 0;
90 guess = ( minI + maxI ) / 2;
91 cmp = name.compare( m_sortedCols[guess]->
getName() );
93 return m_sortedCols[guess];
97 unsigned nIx = m_indices.size();
98 for (
unsigned iIx = 0; iIx < nIx; iIx++ )
100 Index* index = m_indices[iIx];
101 if ( index->
getName() == name )
return index;
107 unsigned nAssert = m_asserts.size();
108 for (
unsigned i = 0; i < nAssert; i++ )
111 if ( a->
getName() == name )
return a;
123 unsigned n = m_cols.size();
125 for (
unsigned i = 0; i <
n; i++ )
127 state = m_cols[i]->accept(
v );
131 n = m_indices.size();
132 for (
unsigned i = 0; i <
n; i++ )
134 state = m_indices[i]->accept(
v );
138 n = m_asserts.size();
139 for (
unsigned i = 0; i <
n; i++ )
141 state = m_asserts[i]->accept(
v );
148 if ( m_sorted )
return;
149 m_sortedCols = m_cols;
155 std::sort( m_sortedCols.begin(), m_sortedCols.end(), cmpObject );
159 void Table::addColumn(
Column* c ) {
160 m_cols.push_back( c );
166 { m_userCols.push_back( c ); }
167 else { m_mayDefault.push_back( c ); }
175 if ( !m_connect ) {
throw RdbException(
"Table::insertLatest Need matching connection" ); }
179 fillProgramCols( row,
true );
182 for (
unsigned i = 0; i < m_userCols.size(); i++ )
185 if ( ( !
f ) || (
f->m_null ) )
187 std::string msg(
"Table::insertLatest Row to be inserted missing req'd field " );
188 msg = msg + m_userCols[i]->getName();
196 const Assertion* cond = m_iNew->getInternal();
202 ( *m_out ) << ex.
getMsg() << std::endl;
206 if ( !satisfied )
return -1;
209 const Assertion* condO = m_iNew->getOfficial();
211 std::vector<std::string> colNames;
212 std::vector<std::string> colValues;
213 std::vector<std::string> nullCols;
215 row.
regroup( colNames, colValues, nullCols );
217 satisfied = condO->
verify( empty, row );
222 bool ok = m_connect->insertRow( m_name, colNames, colValues, serial, &nullCols );
223 return ( ok ) ? 0 : -1;
226 const std::vector<InterRow*>& inter = m_iNew->getInterRow();
228 unsigned nInter = inter.size();
230 for (
unsigned iInter = 0; iInter < nInter; iInter++ )
232 const Query*
q = inter[iInter]->getQuery();
233 const std::vector<std::string>& toSelect =
q->getToSelect();
237 subsAssert =
new Assertion(
q->getAssertion(), &row );
239 std::vector<std::string> orderCols;
241 ResultHandle* r = m_connect->select( m_name, toSelect, orderCols, subsAssert );
251 if ( inter[iInter]->getQuit() )
254 ( *m_out ) <<
"insert latest not done because of irreconcilable " << std::endl
255 <<
"conflict with existing rows" << std::endl;
261 std::vector<Set> sets = inter[iInter]->getSets();
263 bool iu = doInterUpdate( sets, subsAssert, row );
264 if ( !iu )
return -1;
267 bool ok = m_connect->insertRow( m_name, colNames, colValues, serial, &nullCols );
268 return ( ok ) ? 0 : -1;
273 if ( !m_connect ) {
throw RdbException(
"Table::insertRow Need matching connection" ); }
277 fillProgramCols( row,
true );
280 for (
unsigned i = 0; i < m_userCols.size(); i++ )
283 if ( ( !
f ) || (
f->m_null ) )
285 std::string msg(
"Table::insertRow Row to be inserted missing req'd field " );
286 msg = msg + m_userCols[i]->getName();
299 { satisfied = m_validRow->verify( row, row ); }
catch (
RdbException ex )
301 ( *m_out ) << ex.
getMsg() << std::endl;
307 ( *m_out ) <<
"Table::insertRow Row to be inserted is not valid " << std::endl;
313 std::vector<std::string> colNames;
314 std::vector<std::string> colValues;
315 std::vector<std::string> nullCols;
317 row.
regroup( colNames, colValues, nullCols );
318 bool ok = m_connect->insertRow( m_name, colNames, colValues, serial, &nullCols );
319 return ( ok ) ? 0 : -1;
323 std::string oldKeyStr;
326 if ( m_primaryKeyCol.size() == 0 )
327 {
throw RdbException(
"Table::supersedeRow No primary key column!" ); }
331 const std::vector<std::string>& forced = m_sup->getForced();
332 for (
unsigned i = 0; i < forced.size(); i++ )
334 if ( row.
find( forced[i] ) )
339 ( *m_out ) <<
"Table::supersedeRow bad column in input row '" << forced[i] <<
"'"
345 const std::vector<FieldVal>& fixed = m_sup->getFixed();
346 for (
unsigned i = 0; i < fixed.size(); i++ )
348 if ( row.
find( fixed[i].m_colname ) )
353 ( *m_out ) <<
"Table::supersedeRow bad column in input row " << fixed[i].m_colname;
360 if ( !isSupersedable( oldKeyStr ) )
362 *m_out <<
"Row " << oldKey <<
" is not supersedable" << std::endl;
368 const std::vector<std::string>& fixedInterp = m_sup->getFixedInterp();
369 for (
unsigned i = 0; i < fixed.size(); i++ )
373 if ( fixedInterp[i].size() > 0 )
387 std::vector<std::string> noCols;
388 const std::vector<std::string>& fromOld = m_sup->getFromOld();
390 ResultHandle* results = m_connect->select( m_name, fromOld, noCols, where );
393 std::vector<std::string*> vals;
396 unsigned nDef = m_sup->getOldDefaulted().size();
397 for (
unsigned i = 0; i < nDef; i++ )
399 if ( !( row.
find( fromOld[i] ) ) )
407 for (
unsigned i = nDef; i < fromOld.size(); i++ )
419 ( *m_out ) << ex.
getMsg() << std::endl;
430 const std::vector<Set*>& setOld = m_sup->getSetOld();
431 std::vector<FieldVal> oldFields;
432 oldFields.reserve( setOld.size() );
433 for (
unsigned i = 0; i < setOld.size(); i++ )
435 std::string src = setOld[i]->getSrcValue();
436 std::string col = setOld[i]->getDestColName();
437 if ( setOld[i]->hasInterp() )
440 c->
interpret( setOld[i]->getInterp(), src );
442 oldFields.push_back(
FieldVal( col, src ) );
444 Row updateArg( oldFields );
447 int iUpdated =
updateRows( updateArg, where );
448 if ( iUpdated == 1 )
return 0;
452 ( *m_out ) << uEx.
getMsg() << std::endl;
459 if ( !m_connect ) {
throw RdbException(
"Table::insertLatest Need matching connection" ); }
463 fillProgramCols( row,
false );
465 std::vector<std::string> colNames;
466 std::vector<std::string> colValues;
467 std::vector<std::string> nullCols;
469 row.
regroup( colNames, colValues, nullCols );
471 return m_connect->update( m_name, colNames, colValues, where, &nullCols );
474 bool Table::fillProgramCols(
Row& row,
bool newRow )
const {
477 for (
unsigned i = 0; i < m_programCols.size(); i++ )
479 Column* col = m_programCols[i];
485 val = std::string(
"$(USER)" );
487 val = std::string(
"$(USERNAME)" );
491 if ( nsub != 1 ) { val =
"no username"; }
496 if ( !newRow )
continue;
498 facilities::Timestamp curTime;
502 default:
return false;
513 FieldVal g( col->
getName(), val,
false );
521 void Table::fillDefaults(
Row& row )
const {
522 for (
unsigned i = 0; i < m_mayDefault.size(); i++ )
524 Column* hasDef = m_mayDefault[i];
525 FieldVal*
f = row.find( hasDef->getName() );
528 if ( ( hasDef->getDefault() ).size() > 0 )
530 FieldVal g( hasDef->getName(), hasDef->getDefault() );
535 FieldVal g( hasDef->getName(),
"",
true );
545 bool Table::doInterUpdate(
const std::vector<Set>& sets,
Assertion* subsAssert,
547 unsigned nSets = sets.size();
548 std::vector<FieldVal> fields;
549 fields.reserve( nSets );
551 for (
unsigned iSet = 0; iSet < sets.size(); iSet++ )
553 std::string col = sets[iSet].getDestColName();
556 FIELDTYPE srcType = sets[iSet].getSrcType();
559 src = sets[iSet].getSrcValue();
561 if ( sets[iSet].hasInterp() )
564 c->interpret( sets[iSet].getInterp(), src );
571 std::string toBeCol = sets[iSet].getSrcValue();
572 FieldVal*
f = toBe.find( toBeCol );
576 ( *m_out ) <<
"Table::InsertNew Row argument missing needed field" << toBeCol
586 FieldVal g( col, src );
587 fields.push_back( g );
591 fillProgramCols( row,
false );
593 std::vector<std::string> updateCols;
594 std::vector<std::string> updateVals;
595 std::vector<std::string> nullCols;
597 row.regroup( updateCols, updateVals, nullCols );
600 m_connect->update( m_name, updateCols, updateVals, subsAssert );
606 const std::string& Table::setPrimaryKeyCol() {
607 static const std::string empty(
"" );
608 if ( m_primaryKeyCol.size() > 0 )
return m_primaryKeyCol;
610 for (
unsigned iCol = 0; iCol < m_cols.size(); iCol++ )
612 if ( m_cols[iCol]->isPrimaryKey() )
614 m_primaryKeyCol = m_cols[iCol]->getName();
615 return m_primaryKeyCol;
621 bool Table::isSupersedable( std::string oldKeyStr )
const {
624 Assertion::Operator* onlyIf =
625 new Assertion::Operator( ( m_sup->getOnlyIf() )->getOperator(), &emptyRow );
627 Assertion::Operator* ser =
new Assertion::Operator(
629 std::vector<Assertion::Operator*> children;
630 children.push_back( onlyIf );
631 children.push_back( ser );
632 Assertion::Operator* whereOp =
new Assertion::Operator(
OPTYPEand, children );
634 std::vector<std::string> queryCols;
635 queryCols.push_back( m_primaryKeyCol );
636 Assertion* where =
new Assertion( whereOp );
637 ResultHandle* results = m_connect->select( m_name, queryCols, queryCols, where );
640 return ( results->getNRows() > 0 );
TFile f("ana_bhabha660a_dqa_mcPat_zy_old.root")
****INTEGER imax DOUBLE PRECISION m_pi *DOUBLE PRECISION m_amfin DOUBLE PRECISION m_Chfin DOUBLE PRECISION m_Xenph DOUBLE PRECISION m_sinw2 DOUBLE PRECISION m_GFermi DOUBLE PRECISION m_MfinMin DOUBLE PRECISION m_ta2 INTEGER m_out INTEGER m_KeyFSR INTEGER m_KeyQCD *COMMON c_Semalib $ !copy of input $ !CMS energy $ !beam mass $ !final mass $ !beam charge $ !final charge $ !smallest final mass $ !Z mass $ !Z width $ !EW mixing angle $ !Gmu Fermi $ alphaQED at q
**********Class see also m_nmax DOUBLE PRECISION m_amel DOUBLE PRECISION m_x2 DOUBLE PRECISION m_alfinv DOUBLE PRECISION m_Xenph INTEGER m_KeyWtm INTEGER m_idyfs DOUBLE PRECISION m_zini DOUBLE PRECISION m_q2 DOUBLE PRECISION m_Wt_KF DOUBLE PRECISION m_WtCut INTEGER m_KFfin *COMMON c_KarLud $ !Input CMS energy[GeV] $ !CMS energy after beam spread beam strahlung[GeV] $ !Beam energy spread[GeV] $ !z boost due to beam spread $ !electron beam mass *ff pair spectrum $ !minimum v
std::string getString() const
Return string representation of time, not including nanoseconds;.
static int expandEnvVar(std::string *toExpand, const std::string &openDel=std::string("$("), const std::string &closeDel=std::string(")"))
static const char * itoa(int val, std::string &outStr)
bool verify(Row &old, Row &toBe) const
const std::string & getName() const
Function object used to sort columns by column name.
CONTENTS getContentsType() const
const std::string & getDefault() const
const std::string & getName() const
FROM getSourceType() const
bool nullAllowed() const
Returns true if column may take on value NULL.
bool interpret(const std::string &interpType, std::string &val)
virtual std::ostream * getOut() const =0
virtual std::ostream * getErrOut() const =0
const std::string & getName() const
virtual std::string getMsg()
static void cleanFieldPtrs(std::vector< std::string * > &fields)
virtual bool getRowPtrs(std::vector< std::string * > &fields, unsigned int i=0, bool clear=true)=0
virtual unsigned int getNRows() const =0
Return number of rows in results.
FieldVal * find(std::string colname)
void regroup(std::vector< std::string > &colNames, std::vector< std::string > &colVals, std::vector< std::string > &nullCols) const
Reorder information suitable for Connection::insert.
void addField(const FieldVal &f)
Visitor::VisitorState accept(Visitor *v)
int insertRow(Row &row, int *serial=0) const
Index * getIndexByName(const std::string &name) const
const std::string & getName() const
int insertLatest(Row &row, int *serial=0) const
int supersedeRow(Row &row, int oldKey, int *newKey=0) const
Assertion * getAssertionByName(const std::string &name) const
int updateRows(Row &row, Assertion *where) const
Column * getColumnByName(const std::string &name) const
void setConnection(Connection *connect)