00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "BaBar/BaBar.hh"
00010
00011 #include "CdbMySQL/CdbMySQLConditionAtFolder.hh"
00012 #include "CdbMySQL/CdbMySQLConnection.hh"
00013 #include "CdbMySQL/CdbMySQLSelectQuery.hh"
00014 #include "CdbMySQL/CdbMySQLQueryUtils.hh"
00015
00016 #include "CdbSQL/CdbSQLOrigin.hh"
00017 #include "CdbSQL/CdbSQLView.hh"
00018 #include "CdbSQL/CdbSQLFolder.hh"
00019
00020 #include "CdbBase/CdbConfigElement.hh"
00021 #include "CdbBase/CdbPathName.hh"
00022 #include "CdbBase/CdbTimeUtils.hh"
00023
00024 #include "RdbMySQL/RdbMySQLResult.hh"
00025
00026 #include <assert.h>
00027
00028 #include <iostream>
00029 using std::cerr;
00030 using std::endl;
00031
00032 #include <sstream>
00033 using std::ostringstream;
00034
00035 CdbMySQLConditionAtFolder::CdbMySQLConditionAtFolder( const CdbCPtr<CdbMySQLConnection>& theConnectionPtr,
00036 const CdbCPtr<CdbSQLFolder>& theParentFolderPtr,
00037 const CdbId& thePhysicalId,
00038 const std::string& theName,
00039 const BdbTime& theCreationTime,
00040 const std::string& theDescription ) :
00041 CdbSQLConditionAtFolder( theParentFolderPtr,
00042 thePhysicalId,
00043 theName,
00044 theCreationTime,
00045 theDescription ),
00046 _myConnectionObjectPtr(theConnectionPtr)
00047 {
00048 assert( !theConnectionPtr.isNull( ));
00049 }
00050
00051 CdbMySQLConditionAtFolder::CdbMySQLConditionAtFolder( const CdbMySQLConditionAtFolder& theOther ) :
00052 CdbSQLConditionAtFolder( theOther ),
00053 _myConnectionObjectPtr(theOther._myConnectionObjectPtr)
00054 { }
00055
00056 CdbMySQLConditionAtFolder::~CdbMySQLConditionAtFolder( )
00057 { }
00058
00059 CdbStatus
00060 CdbMySQLConditionAtFolder::find_config_element( CdbConfigElement& theElement,
00061 const BdbTime& theValidityTime )
00062 {
00063 const char* errorStr = "CdbMySQLConditionAtFolder::find_config_element() -- ERROR.";
00064
00065 CdbStatus result = CdbStatus::Error;
00066 do {
00067
00068
00069
00070 const unsigned short originId = parent( )->parentView( )->parent( )->id( );
00071 const unsigned short viewId = parent( )->parentView( )->id( );
00072
00073 std::string query;
00074 {
00075 ostringstream s;
00076 s << "SELECT "
00077 << "c.begin begin, c.end end, c.use_revision use_revision, c.partition_id partition_id, c.revision revision "
00078 << "FROM "
00079 << _myConnectionObjectPtr->database( ) << ".o" << originId << "_folders_conditions fc, "
00080 << _myConnectionObjectPtr->database( ) << ".o" << originId << "_conditions_configs c "
00081 << "WHERE "
00082 << "fc.view_id = " << viewId << " "
00083 << "AND "
00084 << "BINARY fc.path = '" << _myConnectionObjectPtr->translate_string_to_escaped( CdbPathName::separatorTerminated( parent( )->fullPathName( )))
00085 << _myConnectionObjectPtr->translate_string_to_escaped( name( )) << "' "
00086 << "AND "
00087 << "fc.entry_type = 'C' "
00088 << "AND "
00089 << "fc.id = c.entry_id "
00090 << "AND "
00091 << "c.begin <= " << CdbTimeUtils::to_nsec( theValidityTime ) << " "
00092 << "AND "
00093 << CdbTimeUtils::to_nsec( theValidityTime ) << " < c.end;";
00094 query = s.str( );
00095 }
00096
00097
00098
00099 CdbMySQLSelectQuery selectQuery( _myConnectionObjectPtr,
00100 query );
00101
00102 std::vector<CdbConfigElement> listOfElements;
00103
00104 if( !execute_query( selectQuery, listOfElements )) {
00105 cerr << errorStr << endl
00106 << " Failed to execute the query and/or translate its results." << endl
00107 << " QUERY : \"" << query.c_str( ) << "\"" << endl;
00108 break;
00109 }
00110 unsigned int numFound = listOfElements.size( );
00111 if( 1 != numFound) {
00112 if( 0 == numFound ) {
00113 result = CdbStatus::NotFound;
00114 break;
00115 }
00116 cerr << errorStr << endl
00117 << " The query executor returned unexpected number of rows." << endl
00118 << " The number of entries matching the query is " << numFound << "." << endl
00119 << " QUERY : \"" << query << "\"" << endl;
00120 break;
00121 }
00122
00123
00124
00125 theElement = listOfElements[0];
00126
00127 result = CdbStatus::Success;
00128
00129 } while( false );
00130
00131 return result;
00132 }
00133
00134 CdbStatus
00135 CdbMySQLConditionAtFolder::config_elements( std::vector<CdbConfigElement>& theList )
00136 {
00137 const char* errorStr = "CdbMySQLConditionAtFolder::config_elements() -- ERROR.";
00138
00139 CdbStatus result = CdbStatus::Error;
00140 do {
00141
00142
00143
00144 const unsigned short originId = parent( )->parentView( )->parent( )->id( );
00145 const unsigned short viewId = parent( )->parentView( )->id( );
00146
00147 std::string query;
00148 {
00149 ostringstream s;
00150 s << "SELECT "
00151 << "c.begin begin,c.end end, c.use_revision use_revision, c.partition_id partition_id, c.revision revision "
00152 << "FROM "
00153 << _myConnectionObjectPtr->database( ) << ".o" << originId << "_folders_conditions fc, "
00154 << _myConnectionObjectPtr->database( ) << ".o" << originId << "_conditions_configs c "
00155 << "WHERE "
00156 << "fc.view_id = " << viewId << " "
00157 << "AND "
00158 << "BINARY fc.path = '" << _myConnectionObjectPtr->translate_string_to_escaped( CdbPathName::separatorTerminated( parent( )->fullPathName( )))
00159 << _myConnectionObjectPtr->translate_string_to_escaped( name( )) << "' "
00160 << "AND "
00161 << "fc.entry_type = 'C' "
00162 << "AND "
00163 << "fc.id = c.entry_id "
00164 << "ORDER BY "
00165 << "c.begin;";
00166 query = s.str( );
00167 }
00168
00169 CdbMySQLSelectQuery selectQuery( _myConnectionObjectPtr,
00170 query );
00171
00172 if( !execute_query( selectQuery, theList )) {
00173 cerr << errorStr << "\n"
00174 << " Failed to execute the query and/or translate its results.\n"
00175 << " Query : \"" << query.c_str( ) << "\"" << endl;
00176 break;
00177 }
00178
00179
00180
00181 result = CdbStatus::Success;
00182
00183 } while( false );
00184
00185 return result;
00186 }
00187
00188 CdbStatus
00189 CdbMySQLConditionAtFolder::set_config( std::vector<CdbConfigElement>& theList,
00190 const bool patchOnlyFlag )
00191 {
00192 const char* errorStr = "CdbMySQLConditionAtFolder::set_config() -- ERROR.";
00193 const char* context = "CdbMySQLConditionAtFolder::set_config()";
00194
00195
00196
00197 std::vector<CdbConfigElement> savedConfigList;
00198 if( CdbStatus::Success != config_elements( savedConfigList )) {
00199 cerr << errorStr << "\n"
00200 << " Failed to get the current configuration." << endl;
00201 return CdbStatus::Error;
00202 }
00203
00204
00205
00206 std::string foldersConditionsTableName;
00207 std::string conditionConfigsTableName;
00208 {
00209 ostringstream s;
00210 s << _myConnectionObjectPtr->database( ) << ".o" << parent( )->parentView( )->parent( )->id ( );
00211 const std::string baseTableName = s.str( );
00212
00213 foldersConditionsTableName = baseTableName + "_folders_conditions";
00214 conditionConfigsTableName = baseTableName + "_conditions_configs";
00215 }
00216
00217
00218
00219
00220
00221 unsigned int entryId = 0;
00222 {
00223 ostringstream s;
00224 s << "SELECT id FROM " << foldersConditionsTableName
00225 << " WHERE view_id = " << parent( )->parentView( )->id( )
00226 << " AND BINARY path = '" << _myConnectionObjectPtr->translate_string_to_escaped( CdbPathName::separatorTerminated( parent( )->fullPathName( )))
00227 << _myConnectionObjectPtr->translate_string_to_escaped( name( )) << "'";
00228 const std::string query = s.str( );
00229
00230 CdbMySQLSelectQuery selectQuery( _myConnectionObjectPtr,
00231 query );
00232
00233 if( !execute_query( selectQuery, entryId )) {
00234 cerr << errorStr << "\n"
00235 << " Failed to execute the query and/or translate its results.\n"
00236 << " Query : \"" << query.c_str( ) << "\"" << endl;
00237 return CdbStatus::Error;
00238 }
00239 }
00240
00241
00242
00243 {
00244 ostringstream s;
00245 s << "DELETE FROM " << conditionConfigsTableName << " WHERE entry_id = " << entryId;
00246 const std::string query = s.str( );
00247
00248 CdbCPtr<RdbMySQLResult> resultPtr;
00249 if( CdbStatus::Success != CdbMySQLQueryUtils::execute_query( resultPtr,
00250 _myConnectionObjectPtr,
00251 query,
00252 context )) return CdbStatus::Error;
00253 }
00254
00255
00256
00257
00258 std::vector<CdbConfigElement> newConfigList;
00259 {
00260 if( patchOnlyFlag ) {
00261
00262 std::vector<CdbConfigElement>::const_iterator savedItr = savedConfigList.begin( );
00263 std::vector<CdbConfigElement>::const_iterator inputItr = theList.begin( );
00264
00265 BdbTime prevEnd = BdbTime::minusInfinity;
00266
00267 while( BdbTime::plusInfinity != prevEnd ) {
00268
00269 if( inputItr == theList.end( )) {
00270
00271
00272
00273
00274 for( ; savedItr != savedConfigList.end( ); ++savedItr ) {
00275
00276 CdbConfigElement saved = *savedItr;
00277
00278
00279
00280 if( saved.end <= prevEnd ) continue;
00281
00282
00283
00284
00285 BdbTime adjustedBeginTime = saved.begin;
00286 if( adjustedBeginTime < prevEnd ) adjustedBeginTime = prevEnd;
00287
00288 newConfigList.push_back( CdbConfigElement( saved.policy,
00289 adjustedBeginTime,
00290 saved.end ));
00291 prevEnd = saved.end;
00292 }
00293
00294
00295
00296 prevEnd = BdbTime::plusInfinity;
00297
00298 break;
00299
00300 } else {
00301
00302 CdbConfigElement input = *(inputItr++);
00303
00304
00305
00306
00307
00308 if( input.begin > prevEnd ) {
00309
00310 for( ; savedItr != savedConfigList.end( ); ++savedItr ) {
00311
00312 CdbConfigElement saved = *savedItr;
00313
00314
00315
00316
00317
00318
00319
00320
00321 if( saved.end <= prevEnd ) {
00322 assert( 0 );
00323 continue;
00324 }
00325
00326
00327
00328
00329 if( saved.begin > input.begin ) break;
00330
00331
00332
00333
00334
00335 BdbTime adjustedBeginTime = saved.begin;
00336 if( adjustedBeginTime < prevEnd ) adjustedBeginTime = prevEnd;
00337
00338 BdbTime adjustedEndTime = saved.end;
00339 if( adjustedEndTime > input.begin ) adjustedEndTime = input.begin;
00340
00341 assert( adjustedBeginTime <= adjustedEndTime );
00342
00343
00344
00345
00346 if( adjustedBeginTime < adjustedEndTime )
00347 newConfigList.push_back( CdbConfigElement( saved.policy,
00348 adjustedBeginTime,
00349 adjustedEndTime ));
00350 }
00351 }
00352
00353
00354
00355 newConfigList.push_back( input );
00356
00357 prevEnd = input.end;
00358 }
00359 }
00360
00361 } else {
00362 newConfigList = theList;
00363 }
00364 }
00365
00366
00367
00368 {
00369 const unsigned int num = newConfigList.size( );
00370 for( unsigned int i = 0; i < num; ++i ) {
00371 CdbConfigElement e = newConfigList[i];
00372 if( e.accessIsAllowed ) {
00373 ostringstream s;
00374 s << "INSERT INTO " << conditionConfigsTableName << " (entry_id,begin,end,use_revision,partition_id,revision ) VALUES ("
00375 << entryId << ","
00376 << CdbTimeUtils::to_nsec( e.begin ) << ","
00377 << CdbTimeUtils::to_nsec( e.end ) << ",'"
00378 << ( e.policy.useRevision( ) ? 'Y' : 'N' ) << "',"
00379 << e.policy.partitionId( ) << ","
00380 << CdbTimeUtils::to_nsec( e.policy.revisionId( )) << ")";
00381 const std::string query = s.str( );
00382
00383 CdbCPtr<RdbMySQLResult> resultPtr;
00384 if( CdbStatus::Success != CdbMySQLQueryUtils::execute_query( resultPtr,
00385 _myConnectionObjectPtr,
00386 query,
00387 context )) return CdbStatus::Error;
00388 }
00389 }
00390 }
00391 return CdbStatus::Success;
00392 }
00393
00394 CdbMySQLConditionAtFolder::CloneType*
00395 CdbMySQLConditionAtFolder::clone( ) const
00396 {
00397 return new CdbMySQLConditionAtFolder( *this );
00398 }
00399
00400 bool
00401 CdbMySQLConditionAtFolder::equals( const ComparedType& theOtherObject ) const
00402 {
00403 const char* warningStr = "CdbMySQLConditionAtFolder::equals() -- WARNING";
00404 cerr << warningStr << "\n"
00405 << " This operation is not implemented." << endl;
00406 return false;
00407 }
00408
00409 bool
00410 CdbMySQLConditionAtFolder::execute_query( CdbMySQLSelectQuery& theQuery,
00411 std::vector<CdbConfigElement>& theList )
00412 {
00413 const char* errorStr = "CdbMySQLConditionAtFolder::execute_query(folder) -- ERROR";
00414
00415 theList.clear( );
00416
00417
00418
00419 while( true ) {
00420
00421
00422
00423 CdbStatus status = theQuery.next_row( );
00424 if( CdbStatus::Success != status ) {
00425 if( CdbStatus::NotFound == status ) break;
00426
00427 cerr << errorStr << "\n"
00428 << " Failed to get result of the next row." << endl;
00429 return false;
00430 }
00431
00432
00433
00434
00435
00436
00437 BdbTime begin = BdbTime::minusInfinity;
00438 BdbTime end = BdbTime::minusInfinity;
00439 std::string use_revision = "";
00440 unsigned short partition_id = 0xFFFF;
00441 BdbTime revision = BdbTime::minusInfinity;
00442
00443 theQuery.get( begin, "begin" );
00444 theQuery.get( end, "end" );
00445 theQuery.get( use_revision, "use_revision" );
00446 theQuery.get( partition_id, "partition_id" );
00447 theQuery.get( revision, "revision" );
00448
00449
00450
00451
00452
00453
00454 theList.push_back( CdbConfigElement(( 'Y' == use_revision[0] ? CdbRevisionPolicy( revision, partition_id )
00455 : CdbRevisionPolicy( )),
00456 begin,
00457 end ));
00458 }
00459 return true;
00460 }
00461
00462 bool
00463 CdbMySQLConditionAtFolder::execute_query( CdbMySQLSelectQuery& theQuery,
00464 unsigned int& theId )
00465 {
00466 const char* errorStr = "CdbMySQLConditionAtFolder::execute_query(entry_id) -- ERROR";
00467
00468
00469
00470
00471
00472 CdbStatus status = theQuery.next_row( );
00473 if( CdbStatus::Success != status ) {
00474 if( CdbStatus::NotFound == status ) {
00475 cerr << errorStr << "\n"
00476 << " The contents of teh database has foumd not to be consistent.\n"
00477 << " There must be exactly one row in the set." << endl;
00478 } else {
00479 cerr << errorStr << "\n"
00480 << " Failed to get result of the next row." << endl;
00481 }
00482 return false;
00483 }
00484 theQuery.get( theId, "id" );
00485 return true;
00486 }
00487
00488
00489
00490