00001 #include "CondCore/ORA/interface/Exception.h"
00002 #include "RelationalOperation.h"
00003
00004 #include "CoralBase/Attribute.h"
00005 #include "CoralBase/Blob.h"
00006 #include "RelationalAccess/ISchema.h"
00007 #include "RelationalAccess/ITable.h"
00008 #include "RelationalAccess/ITableDataEditor.h"
00009 #include "RelationalAccess/IBulkOperation.h"
00010 #include "RelationalAccess/IQuery.h"
00011 #include "RelationalAccess/ICursor.h"
00012
00013 namespace ora {
00014
00015 int existAttribute(const std::string& attributeName,
00016 const coral::AttributeList& data){
00017 int ret = -1;
00018 int index = 0;
00019 for(coral::AttributeList::const_iterator iAttr = data.begin();
00020 iAttr!=data.end() && (ret==-1); ++iAttr){
00021 if( iAttr->specification().name() == attributeName ) ret = index;
00022 index++;
00023 }
00024 return ret;
00025 }
00026
00027 char* conditionOfType( ConditionType condType ){
00028 static char* cond[ 5 ] = { (char*)"=",(char*)">",(char*)"<",(char*)">=",(char*)"<=" };
00029 return cond[ condType ];
00030 }
00031
00032 }
00033
00034 ora::InputRelationalData::InputRelationalData():
00035 m_data(),
00036 m_setClause(""),
00037 m_whereClause(""){
00038 }
00039
00040 ora::InputRelationalData::~InputRelationalData(){
00041 }
00042
00043 int ora::InputRelationalData::addId(const std::string& columnName){
00044 int index = existAttribute( columnName, m_data );
00045 if(index == -1){
00046 m_data.extend<int>( columnName );
00047 index = m_data.size()-1;
00048 if(!m_setClause.empty()) m_setClause += ", ";
00049 m_setClause += ( columnName +"= :"+columnName );
00050 }
00051 return index;
00052 }
00053
00054 int ora::InputRelationalData::addData(const std::string& columnName,
00055 const std::type_info& columnType ){
00056 int index = existAttribute( columnName, m_data );
00057 if(index == -1){
00058 m_data.extend( columnName, columnType );
00059 index = m_data.size()-1;
00060 if(!m_setClause.empty()) m_setClause += ", ";
00061 m_setClause += ( columnName +"= :"+columnName );
00062 }
00063 return index;
00064 }
00065
00066 int ora::InputRelationalData::addBlobData(const std::string& columnName){
00067 int index = existAttribute( columnName, m_data );
00068 if(index == -1){
00069 m_data.extend<coral::Blob>( columnName );
00070 index = m_data.size()-1;
00071 if(!m_setClause.empty()) m_setClause += ", ";
00072 m_setClause += ( columnName +"= :"+columnName );
00073 }
00074 return index;
00075 }
00076
00077 int ora::InputRelationalData::addWhereId( const std::string& columnName ){
00078 int index = existAttribute( columnName, m_data );
00079 if(index == -1){
00080 m_data.extend<int>( columnName );
00081 index = m_data.size()-1;
00082 }
00083 if(!m_whereClause.empty()) m_whereClause += " AND ";
00084 m_whereClause += ( columnName +"= :"+columnName );
00085 return index;
00086 }
00087
00088 int ora::InputRelationalData::addWhereId( const std::string& columnName, ConditionType condType ){
00089 int index = existAttribute( columnName, m_data );
00090 if( index == -1 ){
00091 m_data.extend<int>( columnName );
00092 index = m_data.size()-1;
00093 if(!m_whereClause.empty()) m_whereClause += " AND ";
00094 m_whereClause += ( columnName +conditionOfType(condType)+" :"+columnName );
00095 }
00096 return index;
00097 }
00098
00099 coral::AttributeList& ora::InputRelationalData::data(){
00100 return m_data;
00101 }
00102
00103 coral::AttributeList& ora::InputRelationalData::whereData(){
00104
00105 return m_data;
00106 }
00107
00108 std::string& ora::InputRelationalData::updateClause(){
00109 return m_setClause;
00110 }
00111
00112 std::string& ora::InputRelationalData::whereClause(){
00113 return m_whereClause;
00114 }
00115
00116 ora::InsertOperation::InsertOperation( const std::string& tableName,
00117 coral::ISchema& schema ):
00118 InputRelationalData(),
00119 m_tableName( tableName ),
00120 m_schema( schema ){
00121 }
00122
00123 ora::InsertOperation::~InsertOperation(){
00124 }
00125
00126 bool
00127 ora::InsertOperation::isRequired(){
00128 return false;
00129 }
00130
00131 bool ora::InsertOperation::execute(){
00132 coral::ITable& table = m_schema.tableHandle( m_tableName );
00133 table.dataEditor().insertRow( data() );
00134 return true;
00135 }
00136
00137 void ora::InsertOperation::reset(){
00138 }
00139
00140 ora::BulkInsertOperation::BulkInsertOperation( const std::string& tableName,
00141 coral::ISchema& schema ):
00142 InputRelationalData(),
00143 m_tableName( tableName ),
00144 m_schema( schema ),
00145 m_bulkOperations(){
00146 }
00147
00148 ora::BulkInsertOperation::~BulkInsertOperation(){
00149 for( std::vector<coral::IBulkOperation*>::iterator iB = m_bulkOperations.begin();
00150 iB != m_bulkOperations.end(); ++iB ){
00151 delete *iB;
00152 }
00153 }
00154
00155 coral::IBulkOperation& ora::BulkInsertOperation::setUp( int rowCacheSize ){
00156 coral::ITable& table = m_schema.tableHandle( m_tableName );
00157
00158 m_bulkOperations.push_back( table.dataEditor().bulkInsert( data(), rowCacheSize ) );
00159 return *m_bulkOperations.back();
00160 }
00161
00162 bool
00163 ora::BulkInsertOperation::isRequired(){
00164 return false;
00165 }
00166
00167 bool ora::BulkInsertOperation::execute(){
00168 for( std::vector<coral::IBulkOperation*>::iterator iB = m_bulkOperations.begin();
00169 iB != m_bulkOperations.end(); ++iB ){
00170 (*iB)->flush();
00171 delete *iB;
00172 }
00173 m_bulkOperations.clear();
00174 return true;
00175 }
00176
00177 void ora::BulkInsertOperation::reset(){
00178 for( std::vector<coral::IBulkOperation*>::iterator iB = m_bulkOperations.begin();
00179 iB != m_bulkOperations.end(); ++iB ){
00180 delete *iB;
00181 }
00182 m_bulkOperations.clear();
00183 }
00184
00185 ora::UpdateOperation::UpdateOperation( const std::string& tableName,
00186 coral::ISchema& schema ):
00187 InputRelationalData(),
00188 m_tableName( tableName ),
00189 m_schema( schema ){
00190 }
00191
00192 ora::UpdateOperation::~UpdateOperation(){
00193 }
00194
00195 bool
00196 ora::UpdateOperation::isRequired(){
00197 return true;
00198 }
00199
00200 bool ora::UpdateOperation::execute(){
00201 bool ret = false;
00202 if( updateClause().size() && whereClause().size() ){
00203 coral::ITable& table = m_schema.tableHandle( m_tableName );
00204 long nr = table.dataEditor().updateRows( updateClause(), whereClause(), data() );
00205 ret = nr > 0;
00206 }
00207 return ret;
00208 }
00209
00210 void ora::UpdateOperation::reset(){
00211 }
00212
00213 ora::DeleteOperation::DeleteOperation( const std::string& tableName,
00214 coral::ISchema& schema ):
00215 InputRelationalData(),
00216 m_tableName( tableName ),
00217 m_schema( schema ){
00218 }
00219
00220 ora::DeleteOperation::~DeleteOperation(){
00221 }
00222
00223 bool
00224 ora::DeleteOperation::isRequired(){
00225 return false;
00226 }
00227
00228 bool ora::DeleteOperation::execute(){
00229 bool ret = false;
00230 if( whereClause().size() ){
00231 coral::ITable& table = m_schema.tableHandle( m_tableName );
00232 long nr = table.dataEditor().deleteRows( whereClause(), whereData() );
00233 ret = nr > 0;
00234 }
00235 return ret;
00236 }
00237
00238 void ora::DeleteOperation::reset(){
00239 }
00240
00241 ora::SelectOperation::SelectOperation( const std::string& tableName,
00242 coral::ISchema& schema ):
00243 m_spec( new coral::AttributeListSpecification ),
00244 m_whereData(),
00245 m_whereClause(""),
00246 m_orderByCols(),
00247 m_query(),
00248 m_cursor( 0 ),
00249 m_tableName( tableName ),
00250 m_schema( schema ){
00251 }
00252
00253 ora::SelectOperation::~SelectOperation(){
00254 m_spec->release();
00255 }
00256
00257 void ora::SelectOperation::addOrderId(const std::string& columnName){
00258 m_orderByCols.push_back( columnName );
00259 }
00260
00261 bool ora::SelectOperation::nextCursorRow(){
00262 bool ret = false;
00263 if( m_query.get() ){
00264 ret = m_cursor->next();
00265 if(!ret) clear();
00266 }
00267 return ret;
00268 }
00269
00270 void ora::SelectOperation::clear(){
00271 m_query.reset();
00272 m_cursor = 0;
00273 }
00274
00275 int ora::SelectOperation::addId(const std::string& columnName){
00276 int idx = m_spec->index( columnName );
00277 if( idx == -1){
00278 m_spec->extend< int >( columnName );
00279 idx = m_spec->size()-1;
00280 }
00281 return idx;
00282 }
00283
00284 int ora::SelectOperation::addData(const std::string& columnName,
00285 const std::type_info& columnType ){
00286 int idx = m_spec->index( columnName );
00287 if( idx == -1){
00288 m_spec->extend( columnName, columnType );
00289 idx = m_spec->size()-1;
00290 }
00291 return idx;
00292 }
00293
00294 int ora::SelectOperation::addBlobData(const std::string& columnName ){
00295 int idx = m_spec->index( columnName );
00296 if( idx == -1){
00297 m_spec->extend<coral::Blob>( columnName );
00298 idx = m_spec->size()-1;
00299 }
00300 return idx;
00301 }
00302
00303 int ora::SelectOperation::addWhereId( const std::string& columnName ){
00304 int index = existAttribute( columnName, m_whereData );
00305 if( index == -1){
00306 m_whereData.extend<int>( columnName );
00307 index = m_whereData.size()-1;
00308 if(!m_whereClause.empty()) m_whereClause += " AND ";
00309 m_whereClause += ( columnName +"= :"+columnName );
00310 }
00311 return index;
00312 }
00313
00314 coral::AttributeList& ora::SelectOperation::data(){
00315 if(!m_cursor) throwException( "Query on table "+m_tableName+" has not been executed.",
00316 "ora::ReadOperation::data" );
00317 return const_cast<coral::AttributeList&>(m_cursor->currentRow());
00318 }
00319
00320 coral::AttributeList& ora::SelectOperation::whereData(){
00321 return m_whereData;
00322 }
00323
00324 std::string& ora::SelectOperation::whereClause(){
00325 return m_whereClause;
00326 }
00327
00328 void ora::SelectOperation::execute(){
00329 m_cursor = 0;
00330 coral::ITable& table = m_schema.tableHandle( m_tableName );
00331 m_query.reset( table.newQuery() );
00332 for ( coral::AttributeListSpecification::const_iterator iSpec = m_spec->begin();
00333 iSpec != m_spec->end(); ++iSpec ) {
00334 m_query->addToOutputList( iSpec->name() );
00335 m_query->defineOutputType( iSpec->name(),iSpec->typeName());
00336 }
00337 for(std::vector<std::string>::iterator iCol = m_orderByCols.begin();
00338 iCol != m_orderByCols.end(); iCol++ ){
00339 m_query->addToOrderList( *iCol );
00340 }
00341 m_query->setCondition( m_whereClause, m_whereData );
00342 m_query->setRowCacheSize( 100 );
00343 m_cursor = &m_query->execute();
00344 }
00345
00346 coral::AttributeListSpecification& ora::SelectOperation::attributeListSpecification(){
00347 return *m_spec;
00348 }
00349