00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #ifdef __ICC
00015
00016
00017 #pragma warning(disable:2259)
00018 #endif
00019
00020
00021 #include "GaudiPoolDb/PoolDbEvtSelector.h"
00022 #include "GaudiPoolDb/PoolDbAddress.h"
00023 #include "GaudiPoolDb/IPoolDbMgr.h"
00024
00025 #include "GaudiKernel/ClassID.h"
00026 #include "GaudiKernel/MsgStream.h"
00027 #include "GaudiKernel/SvcFactory.h"
00028 #include "GaudiKernel/Tokenizer.h"
00029 #include "GaudiKernel/IDataManagerSvc.h"
00030 #include "POOLCore/Token.h"
00031 #include "StorageSvc/DbSelect.h"
00032 #include "StorageSvc/DbInstanceCount.h"
00033
00034 DECLARE_SERVICE_FACTORY(PoolDbEvtSelector)
00035
00036
00041 class PoolDbContext : public IEvtSelector::Context {
00042 public:
00043 typedef std::list<std::string> ListName;
00044 private:
00045 const PoolDbEvtSelector* m_pSelector;
00046 mutable pool::DbSelect* m_iterator;
00047 mutable pool::Token* m_token;
00048 ListName m_files;
00049 std::string m_criteria;
00050 ListName::const_iterator m_fileIterator;
00051 std::string m_currentInput;
00052
00053 public:
00055 PoolDbContext(const PoolDbEvtSelector* pSelector);
00057 virtual ~PoolDbContext();
00058 const std::string& currentInput() const {
00059 return m_currentInput;
00060 }
00061 void setCurrentInput(const std::string& v) {
00062 m_currentInput = v;
00063 }
00064 ListName& files() {
00065 return m_files;
00066 }
00067 virtual void* identifier() const {
00068 return (void*)m_pSelector;
00069 }
00070 void setCriteria(const std::string& crit) {
00071 m_criteria = crit;
00072 }
00073 pool::Token* token() const {
00074 return m_token;
00075 }
00076 void setToken(pool::Token* p) {
00077 pool::releasePtr(m_token);
00078 m_token = p;
00079 }
00080 ListName::const_iterator fileIterator() {
00081 return m_fileIterator;
00082 }
00083 void setFileIterator(ListName::const_iterator new_iter) {
00084 m_fileIterator = new_iter;
00085 }
00086 pool::DbSelect* iterator() const {
00087 return m_iterator;
00088 }
00089 void setIterator(pool::DbSelect* new_iter) {
00090 pool::deletePtr(m_iterator);
00091 m_iterator = new_iter;
00092 }
00093 pool::DbSelect* selectInput(IPoolDbMgr* mgr,
00094 const std::string& sel,
00095 const std::string& input,
00096 const std::string& cnt);
00097 };
00098
00099
00100 static pool::DbInstanceCount::Counter* s_countPoolDbContext =
00101 pool::DbInstanceCount::getCounter(typeid(PoolDbContext));
00102
00103 PoolDbContext::~PoolDbContext() {
00104 pool::deletePtr(m_iterator);
00105 pool::releasePtr(m_token);
00106 s_countPoolDbContext->decrement();
00107 }
00108
00109 PoolDbContext::PoolDbContext(const PoolDbEvtSelector* pSelector)
00110 : m_pSelector(pSelector), m_iterator(0), m_token(0)
00111 {
00112 s_countPoolDbContext->increment();
00113 }
00114
00115 pool::DbSelect*
00116 PoolDbContext::selectInput( IPoolDbMgr* mgr,
00117 const std::string& sel,
00118 const std::string& input,
00119 const std::string& cnt)
00120 {
00121 setIterator(mgr->createSelect(sel,input,cnt));
00122 iterator() ? setCurrentInput(input) : setCurrentInput("");
00123 return iterator();
00124 }
00125
00126 PoolDbEvtSelector::PoolDbEvtSelector(const std::string& name,
00127 ISvcLocator* svcloc )
00128 : base_class( name, svcloc),
00129 m_rootCLID(CLID_NULL)
00130 {
00131 declareProperty("CnvService", m_cnvSvcName);
00132 pool::DbInstanceCount::increment(this);
00133 }
00134
00135 PoolDbEvtSelector::~PoolDbEvtSelector() {
00136 pool::DbInstanceCount::decrement(this);
00137 }
00138
00140 StatusCode PoolDbEvtSelector::initialize() {
00141
00142 StatusCode status = Service::initialize();
00143 MsgStream log(msgSvc(), name());
00144 if ( !status.isSuccess() ) {
00145 log << MSG::ERROR << "Error initializing base class Service!" << endmsg;
00146 return status;
00147 }
00148
00149 m_dbMgr = serviceLocator()->service(m_cnvSvcName);
00150 if( !m_dbMgr.isValid() ) {
00151 log << MSG::ERROR
00152 << "Unable to localize interface IPoolDbMgr from service:"
00153 << m_cnvSvcName << endmsg;
00154 return StatusCode::FAILURE;
00155 }
00156
00157 SmartIF<IDataManagerSvc> eds(serviceLocator()->service("EventDataSvc"));
00158 if( !eds.isValid() ) {
00159 log << MSG::ERROR
00160 << "Unable to localize interface IDataManagerSvc "
00161 << "from service EventDataSvc"
00162 << endmsg;
00163 return status;
00164 }
00165 m_rootCLID = eds->rootCLID();
00166 m_rootName = eds->rootName();
00167 log << MSG::DEBUG << "Selection root:" << m_rootName
00168 << " CLID:" << m_rootCLID << endmsg;
00169 return status;
00170 }
00171
00173 StatusCode PoolDbEvtSelector::finalize() {
00174
00175 MsgStream log(msgSvc(), name());
00176 m_dbMgr = 0;
00177 StatusCode status = Service::finalize();
00178 if ( !status.isSuccess() ) {
00179 log << MSG::ERROR << "Error initializing base class Service!" << endmsg;
00180 }
00181 return status;
00182 }
00183
00184 StatusCode
00185 PoolDbEvtSelector::createContext(Context*& refpCtxt) const
00186 {
00187 refpCtxt = new PoolDbContext(this);
00188 return StatusCode::SUCCESS;
00189 }
00190
00192 StatusCode PoolDbEvtSelector::last(Context& ) const {
00193 return StatusCode::FAILURE;
00194 }
00195
00196 StatusCode
00197 PoolDbEvtSelector::next(Context& ctxt) const
00198 {
00199 PoolDbContext* pCtxt = dynamic_cast<PoolDbContext*>(&ctxt);
00200 if ( pCtxt != 0 ) {
00201 pool::DbSelect* it = pCtxt->iterator();
00202 if ( !it ) {
00203 PoolDbContext::ListName::const_iterator fileit = pCtxt->fileIterator();
00204 if ( pCtxt->currentInput().length() > 0 ) {
00205 pCtxt->setToken(0);
00206 m_dbMgr->disconnect(pCtxt->currentInput());
00207 }
00208 if ( fileit != pCtxt->files().end() ) {
00209 std::string input = *fileit;
00210 pCtxt->setFileIterator(++fileit);
00211 it = pCtxt->selectInput(m_dbMgr, "", input, m_rootName);
00212 }
00213 }
00214 if ( it ) {
00215 pool::Token* token = 0;
00216 if ( it->next(token).isSuccess() ) {
00217 pCtxt->setToken(token);
00218 if( 0 == pCtxt->token() ) {
00219 pCtxt->setIterator(0);
00220 return next(ctxt);
00221 }
00222 return StatusCode::SUCCESS;
00223 }
00224 return StatusCode::FAILURE;
00225 }
00226 }
00227 if ( pCtxt ) {
00228 if ( pCtxt->currentInput().length() > 0 ) {
00229 m_dbMgr->disconnect( pCtxt->currentInput() );
00230 }
00231 pCtxt->setToken(0);
00232 pCtxt->setIterator(0);
00233 pCtxt->setCurrentInput("");
00234 pCtxt->setFileIterator(pCtxt->files().end());
00235 }
00236 return StatusCode::FAILURE;
00237 }
00238
00239 StatusCode
00240 PoolDbEvtSelector::next(Context& ctxt,int jump) const
00241 {
00242 if ( jump > 0 ) {
00243 for ( int i = 0; i < jump; ++i ) {
00244 StatusCode status = next(ctxt);
00245 if ( !status.isSuccess() ) {
00246 return status;
00247 }
00248 }
00249 return StatusCode::SUCCESS;
00250 }
00251 return StatusCode::FAILURE;
00252 }
00253
00254 StatusCode
00255 PoolDbEvtSelector::previous(Context& ) const
00256 {
00257 MsgStream log(msgSvc(), name());
00258 log << MSG::FATAL
00259 << " EventSelector Iterator, operator -- not supported " << endmsg;
00260 return StatusCode::FAILURE;
00261 }
00262
00263 StatusCode
00264 PoolDbEvtSelector::previous(Context& ctxt, int jump) const
00265 {
00266 if ( jump > 0 ) {
00267 for ( int i = 0; i < jump; ++i ) {
00268 StatusCode status = previous(ctxt);
00269 if ( !status.isSuccess() ) {
00270 return status;
00271 }
00272 }
00273 return StatusCode::SUCCESS;
00274 }
00275 return StatusCode::FAILURE;
00276 }
00277
00278 StatusCode
00279 PoolDbEvtSelector::rewind(Context& ctxt) const
00280 {
00281 PoolDbContext* pCtxt = dynamic_cast<PoolDbContext*>(&ctxt);
00282 if ( pCtxt ) {
00283 if ( pCtxt->currentInput().length() > 0 ) {
00284 m_dbMgr->disconnect( pCtxt->currentInput() );
00285 }
00286 pCtxt->setToken(0);
00287 pCtxt->setIterator(0);
00288 pCtxt->setCurrentInput("");
00289 pCtxt->setFileIterator(pCtxt->files().begin());
00290 return StatusCode::SUCCESS;
00291 }
00292 return StatusCode::FAILURE;
00293 }
00294
00295 StatusCode
00296 PoolDbEvtSelector::createAddress(const Context& ctxt, IOpaqueAddress*& pAddr) const
00297 {
00298 const PoolDbContext* pctxt = dynamic_cast<const PoolDbContext*>(&ctxt);
00299 if ( pctxt ) {
00300 pool::Token* tok = pctxt->token();
00301 if ( 0 != tok ) {
00302 PoolDbAddress* pA = 0;
00303 if ( m_dbMgr->createAddress(tok, &pA).isSuccess() ) {
00304 pAddr = pA;
00305 return StatusCode::SUCCESS;
00306 }
00307 pool::releasePtr(tok);
00308 }
00309 }
00310 pAddr = 0;
00311 return StatusCode::FAILURE;
00312 }
00313
00314 StatusCode
00315 PoolDbEvtSelector::releaseContext(Context*& ctxt) const
00316 {
00317 PoolDbContext* pCtxt = dynamic_cast<PoolDbContext*>(ctxt);
00318 if ( pCtxt ) {
00319 pool::deletePtr(pCtxt);
00320 return StatusCode::SUCCESS;
00321 }
00322 return StatusCode::FAILURE;
00323 }
00324
00325 StatusCode
00326 PoolDbEvtSelector::resetCriteria(const std::string& criteria,
00327 Context& context) const
00328 {
00329 MsgStream log(msgSvc(), name());
00330 PoolDbContext* ctxt = dynamic_cast<PoolDbContext*>(&context);
00331 std::string db, typ, item, sel, stmt, aut, addr;
00332 if ( ctxt ) {
00333 if ( criteria.substr(0,5) == "FILE " ) {
00334
00335
00336 db = criteria.substr(5);
00337 }
00338 else {
00339 Tokenizer tok(true);
00340 tok.analyse(criteria," ","","","=","'","'");
00341 for(Tokenizer::Items::iterator i=tok.items().begin(); i!=tok.items().end();i++) {
00342 std::string tmp = (*i).tag().substr(0,3);
00343 if(tmp=="DAT") {
00344 db = (*i).value();
00345 }
00346 if(tmp=="OPT") {
00347 if((*i).value() != "REA") {
00348 log << MSG::ERROR << "Option:\"" << (*i).value() << "\" not valid" << endmsg;
00349 return StatusCode::FAILURE;
00350 }
00351 }
00352 if (tmp=="TYP") {
00353 typ = (*i).value();
00354 }
00355 if(tmp=="ADD") {
00356 item = (*i).value();
00357 }
00358 if(tmp=="SEL") {
00359 sel = (*i).value();
00360 }
00361 if(tmp=="FUN") {
00362 stmt = (*i).value();
00363 }
00364 if(tmp=="AUT") {
00365 aut = (*i).value();
00366 }
00367 if(tmp=="COL") {
00368 addr = (*i).value();
00369 }
00370 }
00371 }
00372
00373
00374
00375
00376 std::string rest = db;
00377 ctxt->files().clear();
00378 while(true) {
00379 int ipos = rest.find_first_not_of(" ,");
00380 if (ipos == -1 ) break;
00381 rest = rest.substr(ipos, std::string::npos);
00382 int lpos = rest.find_first_of(" ,");
00383 ctxt->files().push_back( rest.substr(0,lpos ));
00384 if (lpos == -1 ) break;
00385 rest = rest.substr(lpos, std::string::npos);
00386 }
00387 ctxt->setFileIterator(ctxt->files().begin());
00388 ctxt->setCriteria(criteria);
00389 return StatusCode::SUCCESS;
00390 }
00391 log << MSG::ERROR << "Invalid iteration context." << endmsg;
00392 return StatusCode::FAILURE;
00393 }
00394