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