#ifndef __JDB_JDBTOOLKIT__ #define __JDB_JDBTOOLKIT__ #include #include #include #include #include "JLang/JException.hh" #include "JLang/JLangToolkit.hh" #include "JLang/JPredicate.hh" #include "JDB/JDB.hh" #include "JDB/JDetectors.hh" #include "JDB/JCLBID.hh" #include "JDB/JUPI.hh" #include "JDB/JUPI_t.hh" #include "JDB/JSelector.hh" #include "JDB/JSelectorSupportkit.hh" /** * \author mdejong */ namespace JDATABASE {}; namespace JPP { using namespace JDATABASE; } /** * Auxiliary classes and methods for database I/O. */ namespace JDATABASE { using JLANG::JValueOutOfRange; using JLANG::JDatabaseException; using JLANG::JType; /** * Auxiliary class for mapping serial number and object identifier of detectors. */ struct JDetectorsHelper : public std::vector { /** * Initialise. */ void initialise() { ResultSet& rs = JDB::get()->StreamDS(getTable(), JSelector()); for (JDetectors parameters; rs >> parameters; ) { this->push_back(parameters); } rs.Close(); } /** * Get detector. * * \param detid object identifier * \return detector */ const JDetectors& operator[](const std::string& detid) { using namespace std; using namespace JPP; if (this->empty()) { this->initialise(); } const_iterator p = find_if(this->begin(), this->end(), make_predicate(&JDetectors::OID, detid)); if (p != this->end()) return *p; else THROW(JDatabaseException, "Invalid detector identifier " << detid); } /** * Get detector. * * \param id serial number * \return detector */ const JDetectors& operator[](const int id) { using namespace std; using namespace JPP; if (this->empty()) { this->initialise(); } const_iterator p = find_if(this->begin(), this->end(), make_predicate(&JDetectors::SERIALNUMBER, id)); if (p != this->end()) return *p; else THROW(JDatabaseException, "Invalid detector identifier " << id); } /** * Get detector serial number. * * \param detid object identifier * \return serial number */ int operator()(const std::string& detid) { return (*this)[detid].SERIALNUMBER; } /** * Get detector identifier. * * \param id serial number * \return object identifier */ inline std::string operator()(const int id) { return (*this)[id].OID; } /** * Get serial number according given data type. * * \param detid object identifier or serial number * \param type data type * \return object identifier */ int operator()(const std::string& detid, const JType& type) { using namespace JPP; if (is_integer(detid)) return to_value(detid); else return (*this)(detid); } /** * Get detector identifier according given data type. * * \param detid object identifier or serial number * \param type data type * \return object identifier */ std::string operator()(const std::string& detid, const JType& type) { using namespace JPP; if (is_integer(detid)) return (*this)(to_value(detid)); else return detid; } /** * Helper object. */ static JDetectorsHelper helper; }; /** * Auxiliary class for mapping %UPI of central-logic board to module identifier. */ struct JCLBIDHelper : public std::vector { /** * Initialise. */ void initialise() { ResultSet& rs = JDB::get()->StreamDS(getTable(), getSelector()); for (JCLBID parameters; rs >> parameters; ) { this->push_back(parameters); } rs.Close(); } /** * Get module identifier. * * \param upi %UPI * \return module identifier */ int operator()(const JUPI_t& upi) { using namespace std; using namespace JPP; if (this->empty()) { this->initialise(); } const_iterator p = find_if(this->begin(), this->end(), make_predicate(&JCLBID::CLBUPI, upi)); if (p != this->end()) return p->CLBID; else THROW(JDatabaseException, "Invalid UPI " << upi); } /** * Get %UPI. * * \param id module identifier * \return %UPI */ JUPI_t operator()(const int id) { using namespace std; using namespace JPP; if (this->empty()) { this->initialise(); } const_iterator p = find_if(this->begin(), this->end(), make_predicate(&JCLBID::CLBID, id)); if (p != this->end()) return p->CLBUPI; else THROW(JDatabaseException, "Invalid module identifier " << id); } /** * Helper object. */ static JCLBIDHelper helper; }; /** * Auxiliary class for mapping %PBS and serial number of product to %UPI. */ struct JUPIHelper : public std::map > { /** * Initialise. * * \param pbs %PBS */ void initialise(const JPBS_t& pbs) { ResultSet& rs = JDB::get()->StreamDS(getTable(), getSelector(pbs)); for (JUPI parameters; rs >> parameters; ) { const JUPI_t upi(parameters.PBS, parameters.VARIANT, parameters.VERSION, parameters.SERIALNUMBER); (*this)[pbs][parameters.SERIALNUMBER] = upi; } rs.Close(); } /** * Get %UPI. * * \param pbs %PBS * \param number serial number * \return %UPI */ JUPI_t operator()(const JPBS_t& pbs, const int number) { const_iterator p = this->find(pbs); if (p == this->end()) { initialise(pbs); p = this->find(pbs); } if (p != this->end()) { typename mapped_type::const_iterator q = p->second.find(number); if (q != p->second.end()) { return q->second; } else { THROW(JValueOutOfRange, "Invalid serial number " << number); } } else { THROW(JDatabaseException, "Invalid PBS " << pbs); } } /** * Helper object. */ static JUPIHelper helper; }; /** * Wrapper data structure for initialisation of fuction objects. * * The fuction objects will expand on the fly making a corresponding query to the database.\n * To avoid making a query within another query, a given function object can a priori * be initialised using the static method JDBToolkit::initialise. */ struct JDBToolkit { /** * Initialise. * * \param helper helper object * \param args values */ template static void initialise(JHelper_t& helper, const Args& ...args) { helper.initialise(args...); } /** * Initialise. * * \param pF helper function * \param args values */ template static void initialise(JDetectorsHelper& (*pF)(), const Args& ...args) { JDetectorsHelper::helper.initialise(args...); } /** * Initialise. * * \param pF helper function * \param args values */ template static void initialise(JHelper_t& (*pF)(), const Args& ...args) { JHelper_t::helper.initialise(args...); } }; /** * Auxiliary function for helper object initialisation. * * \return helper object */ inline JDetectorsHelper& getDetector() { return JDetectorsHelper::helper; } /** * Get detector identifier or serial number, depending on template data type. * * \param detid object identifier or serial number * \return object identifier or serial number */ template inline T getDetector(const std::string& detid) { return JDetectorsHelper::helper(detid, JType()); } /** * Get detector serial number. * * \param detid object identifier * \return serial number */ inline int getDetector(const std::string& detid) { return JDetectorsHelper::helper(detid); } /** * Get detector identifier. * * \param id serial number * \return object identifier */ inline std::string getDetector(const int id) { return JDetectorsHelper::helper(id); } /** * Auxiliary function for helper object initialisation. * * \return helper */ inline JCLBIDHelper& getCLBID() { return JCLBIDHelper::helper; } /** * Get module identifier. * * \param upi %UPI * \return module identifier */ inline int getCLBID(const JUPI_t& upi) { return JCLBIDHelper::helper(upi); } /** * Auxiliary function for helper object initialisation. * * \return helper */ inline JCLBIDHelper& getCLBUPI() { return JCLBIDHelper::helper; } /** * Get %UPI. * * \param id module identifier * \return %UPI */ inline JUPI_t getCLBUPI(const int id) { return JCLBIDHelper::helper(id); } /** * Auxiliary function for helper object initialisation. * * \return helper */ inline JUPIHelper& getUPI() { return JUPIHelper::helper; } /** * Get %UPI. * * \param pbs %PBS * \param number serial number * \return %UPI */ inline JUPI_t getUPI(const JPBS_t& pbs, const int number) { return JUPIHelper::helper(pbs, number); } } #endif