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