#ifndef __TSlowControlMySQLInterface__ #define __TSlowControlMySQLInterface__ #include #include #include #include #include #include #include #include #include "ISlowControlMySQLRow.hxx" #include "TSQLServer.h" #include "TSQLRow.h" #include "TSQLResult.h" #include "TUrl.h" #include "ICOMETLog.hxx" #include "EoaCore.hxx" namespace COMET { // General Slow Control Database exceptions OA_EXCEPTION(ESlowControlDatabase,COMET::EoaCore); // Exception for lost and unrecoverable MySQL connection OA_EXCEPTION(ELostGSCDatabaseConnection,ESlowControlDatabase); }; /// MySQL slow control interface. /// Written by Kandy Wong/Thomas Lindner, Sept 2008 /// This class provides access to the GSC slow control database. /// It handles all the calls to MySQL. /// For certain access methods, theinterface class also provides /// some local caching functionality; /// in particular, it can cache results locally using the ISlowControlMySQLRow class. /// Each method is optimized in a different way, with the optimization being principally /// relatied to speed and memory usage. You should examine in some detail the different /// access methods and decide which is most useful for what you are doing. class ISlowControlMySQLInterface { private: /// ROOT MySQL server object TSQLServer *fServer; TUrl fUrl; std::string fUsername; std::string fPasswd; // This is the map of cached MySQL results. std::map fCachedTables; // This is the last accessed table; ISlowControlMySQLRow* lastAccessedTable; /// Flag for whether to always disconnect from server. bool fFlagAlwaysDisconnect; /// Flag to control whether to try to reconnect to database. bool fFlagAlwaysRetry; /// This is the maximum amount of time that we attempt to retry /// connecting to the database (in seconds). int fMaxRetryTime; /// Helper method, to retrive long set of database results. std::vector > > ExecuteLongQuery(std::string alt_command, std::vector table_fields); /// This is the main routine for cached MySQL queries. It works as follows: /// 1) Request the last row in database which satisfies _i_time <= time. /// 2) Store the resulting row in ISlowControlMySQLRow object. /// 3) Query database a second time, in order to find the next row, to /// get the end time for the interval. /// The final option ('fast_query') controls whether or not to restrict the /// query to times within 1 hour of the requested time. This results in much faster /// data recovery for tables that are written often, but will fail for tables /// that are only written every couple days/months. Therefore, to ensure that /// the request always succeeds, we must make a fast query and then a slow query /// if the fast query fails. int MySQLQuery(int time, std::string table, bool fast_query); // Make a non-functional private copy constructor. Shouldn't be called!!! ISlowControlMySQLInterface(const ISlowControlMySQLInterface &){ COMETLog("ISlowControlMySQLInterface copy constructor is private. Shouldn't be called!!!"); } // Helper method to get server. Handles automatic reconnection, if needed. // If specified, the software will attempt to reconnect with an increasing // amount of time between reconnections (up to limit set in parameters file). TSQLServer* GetServer(); public: ISlowControlMySQLInterface(const char *username,const char *passwd, TUrl url); ~ISlowControlMySQLInterface(); /// List all tables in database void ShowTables(); // Print the contents for a particular table at a particular time. void PrintTable( int time, const char *table); /// Method returns the number of active connections to the GSC database host. /// If the log-level is set to verbose, the method also prints details about /// all the active connections. int GetNumberCurrentConnections(); /// Returns the number of tables that are currently cached locally. int GetNumberCachedTables(){ return fCachedTables.size();}; /// Returns the double value from a slow control table. double QueryShowFieldDouble( int time,const char *table, const char *fieldname){ return QueryShowField(time, table, fieldname); }; double QueryShowField( int time,const char *table, const char *fieldname); /// Returns the integer value from a slow control table. int QueryShowFieldInteger( int time,const char *table, const char *fieldname); /// Returns the string value from a slow control table. std::string QueryShowFieldString( int time,const char *table, const char *fieldname); /// Method returns a row from given table for this time. /// Method does not transfer ownership of object! /// ISlowControlMySQLInterface will delete this object the next time another /// row of this table is requested. Do not locally save this row! ISlowControlMySQLRow* GetTable(int time,const char *table); /// Return time interval that slow control value is valid over /// integer return value is a status == 1 if successful int GetFieldInterval(int time, const char *table, const char *fieldname, int &start_time, int &end_time); /// Return certain table fields for next XX number of database rows. /// The format of the returned vector 'result' is /// result[0].first = timestamp for first returned row /// result[0].second[0] = value of first field requested for this row /// result[0].second[1] = value of secon field requested for this row /// ... /// result[1].first = timestamp for second returned row /// result[1].second[0] = value of first field requested for this row /// /// Notes: /// - The times of the rows are all AFTER the time that was requested. /// ie, one gets the next row that is closest to requested time + subsequent rows. /// - This method does NOT client-side caching. std::vector > > QueryGetFieldNoCache(int time, const char *table_name, std::vector table_fields, int nrows); /// Similar to previous method, but returns just one row. std::pair > QueryGetFieldNoCache(int time, const char *table_name, std::vector table_fields); /// Similar to QueryGetFieldNoCache but with start and end times, not number of rows std::vector > > QueryGetFieldStartEndTime(const char *table_name, std::vector table_fields, int start_time, int end_time); /// Returns the last entry for a given table and variable. std::vector GetLastEntryNoCache(const char *table_name, std::vector table_fields); }; #endif