CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/CondTools/L1Trigger/interface/OMDSReader.h

Go to the documentation of this file.
00001 #ifndef CondTools_L1Trigger_OMDSReader_h
00002 #define CondTools_L1Trigger_OMDSReader_h
00003 // -*- C++ -*-
00004 //
00005 // Package:     L1Trigger
00006 // Class  :     OMDSReader
00007 //
00016 //
00017 // Original Author:  Werner Sun
00018 //         Created:  Sun Mar  2 01:36:06 CET 2008
00019 // $Id: OMDSReader.h,v 1.14 2010/04/12 20:29:23 wsun Exp $
00020 //
00021 
00022 // system include files
00023 #include <memory>
00024 #include "boost/shared_ptr.hpp"
00025 
00026 // user include files
00027 #include "CondTools/L1Trigger/interface/DataManager.h"
00028 #include "RelationalAccess/IQuery.h"
00029 #include "CoralBase/AttributeList.h"
00030 #include "CoralBase/AttributeSpecification.h"
00031 #include "CoralBase/Attribute.h"
00032 
00033 #include "RelationalAccess/ITable.h"
00034 #include "RelationalAccess/IView.h"
00035 #include "RelationalAccess/ISchema.h"
00036 #include "RelationalAccess/ISessionProxy.h"
00037 #include "RelationalAccess/ICursor.h"
00038 
00039 // forward declarations
00040 
00041 namespace l1t
00042 {
00043 
00044   class OMDSReader : public DataManager
00045   {
00046 
00047   public:
00048     // std::vector< std::string > is the list of attribute names.
00049     // We need to store the column names because there is no way to ask
00050     // AttributeList for this information.  We have a vector of AttributeLists
00051     // because the query may return more than one row, each of which is
00052     // encapsulated in an AttributeList.
00053     class QueryResults
00054         {
00055         public:
00056           QueryResults() {}
00057           QueryResults( const std::vector< std::string >& columnNames,
00058                         const std::vector< coral::AttributeList >& attLists )
00059             : m_columnNames( columnNames), m_attributeLists( attLists ) {}
00060 
00061           virtual ~QueryResults() {}
00062 
00063           const std::vector< std::string >& columnNames() const
00064             { return m_columnNames ; }
00065           const std::vector< coral::AttributeList >& attributeLists() const
00066             { return m_attributeLists ; }
00067           bool queryFailed() const { return m_attributeLists.size() == 0 ; }
00068           int numberRows() const { return m_attributeLists.size() ; }
00069 
00070           // Return value is false if variable is null.
00071           template< class T >
00072             bool fillVariable( const std::string& columnName,
00073                                T& outputVariable ) const ;
00074 
00075           template< class T >
00076             bool fillVariableFromRow( const std::string& columnName,
00077                                       int rowNumber,
00078                                       T& outputVariable ) const ;
00079 
00080           // If there is only one column, no need to give column name
00081           template< class T >
00082             bool fillVariable( T& outputVariable ) const ;
00083 
00084           template< class T >
00085             bool fillVariableFromRow( int rowNumber,
00086                                       T& outputVariable ) const ;
00087 
00088         private:
00089           std::vector< std::string > m_columnNames ;
00090           std::vector< coral::AttributeList > m_attributeLists ;
00091         } ;
00092 
00093     OMDSReader() ;
00094 
00095     OMDSReader( const std::string& connectString,
00096                 const std::string& authenticationPath ) ;
00097 
00098     virtual ~OMDSReader();
00099 
00100       // ---------- const member functions ---------------------
00101 
00102       // These functions encapsulate basic SQL queries of the form
00103       //
00104       // SELECT <columns> FROM <schema.table> WHERE <conditionLHS> = <conditionRHS>
00105       //
00106       // where
00107       //
00108       // <columns> can be one or many column names
00109       // <conditionRHS> can be a string or the result of another query
00110 
00111       // Assume data type of condition RHS is std::string
00112       const QueryResults basicQuery(
00113         const std::vector< std::string >& columnNames,
00114         const std::string& schemaName, // for nominal schema, use ""
00115         const std::string& tableName,
00116         const std::string& conditionLHS = "",
00117         const QueryResults conditionRHS = QueryResults(),
00118                                                    // must have only one row
00119         const std::string& conditionRHSName = ""
00120                          // if empty, conditionRHS must have only one column
00121         ) const ;
00122 
00123       // Assume data type of condition RHS is std::string
00124       const QueryResults basicQuery(
00125         const std::string& columnName,
00126         const std::string& schemaName, // for nominal schema, use ""
00127         const std::string& tableName,
00128         const std::string& conditionLHS = "",
00129         const QueryResults conditionRHS = QueryResults(),
00130                                                    // must have only one row
00131         const std::string& conditionRHSName = ""
00132                          // if empty, conditionRHS must have only one column
00133         ) const ;
00134 
00135 
00136       // Assume data type of condition RHS is std::string
00137       const QueryResults basicQueryView(
00138     const std::vector< std::string >& columnNames,
00139     const std::string& schemaName, // for nominal schema, use ""
00140     const std::string& viewName,
00141     const std::string& conditionLHS = "",
00142     const QueryResults conditionRHS = QueryResults(),
00143                                                // must have only one row
00144     const std::string& conditionRHSName = ""
00145                      // if empty, conditionRHS must have only one column
00146     ) const ;
00147 
00148       // Assume data type of condition RHS is std::string
00149       const QueryResults basicQueryView(
00150     const std::string& columnName,
00151     const std::string& schemaName, // for nominal schema, use ""
00152     const std::string& viewName,
00153     const std::string& conditionLHS = "",
00154     const QueryResults conditionRHS = QueryResults(),
00155                                                // must have only one row
00156     const std::string& conditionRHSName = ""
00157                      // if empty, conditionRHS must have only one column
00158     ) const ;
00159 
00160       // For any data type of condition RHS.
00161       // Example usage, for an int key:
00162       //   results = omdsReader.basicQueryGenericKey<int>(...) ;
00163       template< class T >
00164         const QueryResults basicQueryGenericKey(
00165           const std::vector< std::string >& columnNames,
00166           const std::string& schemaName, // for nominal schema, use ""
00167           const std::string& tableName,
00168           const std::string& conditionLHS = "",
00169           const QueryResults conditionRHS = QueryResults(),
00170                                                     // must have only one row
00171           const std::string& conditionRHSName = ""
00172                             // if empty, conditionRHS must have only one column
00173           ) const ;
00174 
00175       // For any data type of condition RHS.
00176       // Example usage, for an int key:
00177       //   results = omdsReader.basicQueryGenericKey<int>(...) ;
00178       template< class T >
00179         const QueryResults basicQueryGenericKey(
00180           const std::string& columnName,
00181           const std::string& schemaName, // for nominal schema, use ""
00182           const std::string& tableName,
00183           const std::string& conditionLHS = "",
00184           const QueryResults conditionRHS = QueryResults(),
00185                                                    // must have only one row
00186           const std::string& conditionRHSName = ""
00187                          // if empty, conditionRHS must have only one column
00188           ) const ;
00189 
00190       template< class T >
00191         const QueryResults singleAttribute( const T& data ) const ;
00192 
00193       std::vector< std::string > columnNames(
00194         const std::string& schemaName, // for nominal schema, use ""
00195         const std::string& tableName ) const ;
00196 
00197       std::vector< std::string > columnNamesView(
00198     const std::string& schemaName, // for nominal schema, use ""
00199     const std::string& viewName ) const ;
00200 
00201       // ---------- static member functions --------------------
00202 
00203       // ---------- member functions ---------------------------
00204 
00205       void connect( const std::string& connectString,
00206                     const std::string& authenticationPath ) ;
00207 
00208    private:
00209       OMDSReader(const OMDSReader&); // stop default
00210 
00211       const OMDSReader& operator=(const OMDSReader&); // stop default
00212 
00213       // ---------- member data --------------------------------
00214 };
00215 
00216   template< class T > const OMDSReader::QueryResults
00217   OMDSReader::basicQueryGenericKey(
00218     const std::vector< std::string >& columnNames,
00219     const std::string& schemaName,
00220     const std::string& tableName,
00221     const std::string& conditionLHS,
00222     const QueryResults conditionRHS,
00223     const std::string& conditionRHSName ) const
00224   {
00225     coral::ISchema& schema = schemaName.empty() ?
00226       session->nominalSchema() :
00227       session->schema( schemaName ) ;
00228 
00229     coral::ITable& table = schema.tableHandle( tableName ) ;
00230 
00231     // Pointer is deleted automatically at end of function.
00232     boost::shared_ptr< coral::IQuery > query( table.newQuery() ) ;
00233 
00234     // Construct query
00235     std::vector< std::string >::const_iterator it = columnNames.begin() ;
00236     std::vector< std::string >::const_iterator end = columnNames.end() ;
00237     for( ; it != end ; ++it )
00238       {
00239         query->addToOutputList( *it ) ;
00240       }
00241 
00242     // Only apply condition if RHS has one row.
00243     if( !conditionLHS.empty() && conditionRHS.numberRows() == 1 )
00244       {
00245         if( !conditionRHSName.empty() )
00246           {
00247             // Use type of dummyVariable to determine type of condition RHS
00248             coral::AttributeList attList ;
00249             attList.extend( conditionRHSName, typeid( T ) ) ;
00250             T tmp ;
00251             conditionRHS.fillVariable( conditionRHSName, tmp ) ;
00252             attList[ conditionRHSName ].data< T >() = tmp ;
00253 
00254             query->setCondition( conditionLHS + " = :" + conditionRHSName,
00255                                  attList ) ;
00256           }
00257         else if( conditionRHS.columnNames().size() == 1 )
00258           // check for only one column
00259           {
00260             query->setCondition( conditionLHS + " = :" +
00261                                    conditionRHS.columnNames().front(),
00262                                  conditionRHS.attributeLists().front() ) ;
00263           }
00264       }
00265 
00266     coral::ICursor& cursor = query->execute() ;
00267 
00268     // Copy AttributeLists for external use because the cursor is deleted
00269     // when the query goes out of scope.
00270     std::vector< coral::AttributeList > atts ;
00271     while( cursor.next() )
00272       {
00273         atts.push_back( cursor.currentRow() ) ;
00274       } ;
00275 
00276     return QueryResults( columnNames, atts ) ;
00277   }
00278 
00279   template< class T > const OMDSReader::QueryResults
00280   OMDSReader::basicQueryGenericKey(
00281     const std::string& columnName,
00282     const std::string& schemaName,
00283     const std::string& tableName,
00284     const std::string& conditionLHS,
00285     const QueryResults conditionRHS,
00286     const std::string& conditionRHSName ) const
00287   {
00288     std::vector< std::string > columnNames ;
00289     columnNames.push_back( columnName ) ;
00290     return basicQueryGenericKey< T >( columnNames, schemaName, tableName,
00291                                  conditionLHS, conditionRHS, conditionRHSName);
00292   }
00293 
00294   template< class T > const OMDSReader::QueryResults
00295   OMDSReader::singleAttribute( const T& data ) const
00296   {
00297     std::vector< std::string > names ;
00298     names.push_back( "dummy" ) ;
00299 
00300     coral::AttributeList attList ;
00301     attList.extend( "dummy", typeid( T ) ) ;
00302     attList[ "dummy" ].data< T >() = data ;
00303 
00304     std::vector< coral::AttributeList > atts ;
00305     atts.push_back( attList ) ;
00306 
00307     return QueryResults( names, atts ) ;
00308   }
00309 
00310   template< class T > bool
00311     OMDSReader::QueryResults::fillVariable(
00312       const std::string& columnName,
00313       T& outputVariable ) const
00314     {
00315       return fillVariableFromRow( columnName, 0, outputVariable ) ;
00316     }
00317 
00318   template< class T > bool
00319     OMDSReader::QueryResults::fillVariableFromRow(
00320       const std::string& columnName,
00321       int rowNumber,
00322       T& outputVariable ) const
00323     {
00324       // Check index in bounds
00325       if( rowNumber < 0 || rowNumber >= numberRows() ) return false ;
00326       const coral::AttributeList& row = m_attributeLists[ rowNumber ] ;
00327       if( row[ columnName ].isNull() ) return false ;
00328       outputVariable = row[ columnName ].template data< T >() ;
00329       return true ;
00330     }
00331 
00332   template< class T > bool
00333     OMDSReader::QueryResults::fillVariable( T& outputVariable ) const
00334     {
00335       return fillVariableFromRow( 0, outputVariable ) ;
00336     }
00337 
00338   template< class T > bool
00339     OMDSReader::QueryResults::fillVariableFromRow( int rowNumber,
00340                                                    T& outputVariable ) const
00341     {
00342       // Check index in bounds and only one column
00343       if( rowNumber < 0 || rowNumber >= numberRows() ||
00344           m_columnNames.size() != 1 ) return false ;
00345       const coral::AttributeList& row = m_attributeLists[ rowNumber ] ;
00346       if( row[ m_columnNames.front() ].isNull() ) return false ;
00347       outputVariable = row[ m_columnNames.front() ].template data< T >() ;
00348       return true ;
00349     }
00350 
00351 }
00352 #endif