00001 #include "MappingRules.h"
00002
00003 #include <sstream>
00004 #include <vector>
00005 #include <cctype>
00006
00007 #include "Reflex/Type.h"
00008
00009 std::string ora::MappingRules::sequenceNameForContainerId(){
00010 static std::string s_sequenceName("CONTAINER_ID");
00011 return s_sequenceName;
00012 }
00013
00014 std::string ora::MappingRules::sequenceNameForContainer( const std::string& containerName ){
00015 std::string ret("C_");
00016 return ret+containerName;
00017 }
00018
00019 std::string
00020 ora::MappingRules::sequenceNameForDependentClass( const std::string& containerName,
00021 const std::string& className ){
00022 std::string ret("D_");
00023 ret+=containerName;
00024 ret+="_";
00025 ret+=className;
00026 return ret;
00027 }
00028
00029 std::string ora::MappingRules::sequenceNameForMapping(){
00030 static std::string s_mappingSequenceName("MAPPING_ELEMENT_ID");
00031 return s_mappingSequenceName;
00032 }
00033
00034 std::string
00035 ora::MappingRules::mappingPropertyNameInDictionary()
00036 {
00037 static std::string s_propertyName("mapping");
00038 return s_propertyName;
00039 }
00040
00041 bool
00042 ora::MappingRules::isMappedToBlob(const std::string& mappingProperty){
00043 return (mappingProperty == "Blob" || mappingProperty == "blob" || mappingProperty == "BLOB" );
00044 }
00045
00046 std::string
00047 ora::MappingRules::persistencyPropertyNameInDictionary(){
00048 static std::string s_propertyName("persistency");
00049 return s_propertyName;
00050 }
00051
00052 bool
00053 ora::MappingRules::isLooseOnReading(const std::string& persistencyProperty){
00054 return (persistencyProperty == "loose_on_reading" || persistencyProperty == "LOOSE_ON_READING" );
00055 }
00056
00057 bool
00058 ora::MappingRules::isLooseOnWriting(const std::string& persistencyProperty){
00059 return (persistencyProperty == "loose_on_writing" || persistencyProperty == "LOOSE_ON_WRITING" );
00060 }
00061
00062 std::string
00063 ora::MappingRules::classId( const std::string& className,
00064 const std::string& classVersion ){
00065 return className+".V"+classVersion;
00066 }
00067
00068 std::string ora::MappingRules::classVersionFromId( const std::string& classId ){
00069 std::string ret("");
00070 size_t idx = classId.find('.');
00071 if( idx != std::string::npos ){
00072 ret = classId.substr( idx+2 );
00073 }
00074 return ret;
00075 }
00076
00077 std::string
00078 ora::MappingRules::baseIdForClass( const std::string& className ){
00079 return className+"."+baseClassVersion();
00080 }
00081
00082 std::string
00083 ora::MappingRules::baseClassVersion()
00084 {
00085 static std::string classVersion("BASE");
00086 return classVersion;
00087 }
00088
00089 std::pair<bool,std::string> ora::MappingRules::classNameFromBaseId( const std::string& classId ){
00090 std::pair<bool,std::string> ret(false,"");
00091 size_t cut = classId.find("."+baseClassVersion() );
00092 if( cut != std::string::npos ){
00093 ret.first = true;
00094 ret.second = classId.substr(0,cut);
00095 }
00096 return ret;
00097 }
00098
00099 std::string
00100 ora::MappingRules::defaultClassVersion(const std::string& className)
00101 {
00102 std::string classVersion(className);
00103 classVersion.append("_default");
00104 return classVersion;
00105 }
00106
00107 std::string
00108 ora::MappingRules::classVersionPropertyNameInDictionary()
00109 {
00110 static std::string s_propertyName("class_version");
00111 return s_propertyName;
00112
00113 }
00114
00115 std::string
00116 ora::MappingRules::newMappingVersion( const std::string& itemName,
00117 int iteration,
00118 char versionTrailer ){
00119 std::ostringstream os;
00120 os << itemName;
00121 os << "_" << versionTrailer;
00122 if ( iteration > 0 ) {
00123 if ( iteration < 10 ) os << "0";
00124 if ( iteration < 100 ) os << "0";
00125 os << iteration;
00126 } else {
00127 os << "000";
00128 }
00129 return os.str();
00130 }
00131
00132 std::string
00133 ora::MappingRules::newMappingVersionForContainer( const std::string& containerName,
00134 int iteration ){
00135 return newMappingVersion( containerName, iteration, 'M' );
00136 }
00137
00138 std::string
00139 ora::MappingRules::newMappingVersionForDependentClass( const std::string& containerName,
00140 const std::string& className,
00141 int iteration )
00142 {
00143 std::string contDependencyName = containerName+"_"+className;
00144 return newMappingVersion( contDependencyName, iteration, 'D' );
00145 }
00146
00147 std::string
00148 ora::MappingRules::scopedVariableName( const std::string& variableName,
00149 const std::string& scope ){
00150 std::stringstream scopedName;
00151 if(!scope.empty()) scopedName << scope << "::";
00152 scopedName << variableName;
00153 return scopedName.str();
00154 }
00155
00156 std::string
00157 ora::MappingRules::variableNameForArrayIndex( const std::string& arrayVariable,
00158 unsigned int index ){
00159 std::ostringstream arrayElementLabel;
00160 arrayElementLabel << arrayVariable << "[" << index << "]";
00161 return arrayElementLabel.str();
00162 }
00163
00164 std::string
00165 ora::MappingRules::variableNameForArrayColumn( unsigned int arrayIndex ){
00166 std::ostringstream arrayElementLabel;
00167 arrayElementLabel << "I" << arrayIndex;
00168 return arrayElementLabel.str();
00169 }
00170
00171 std::string
00172 ora::MappingRules::variableNameForArrayColumn( const Reflex::Type& array ){
00173 std::stringstream contentTypeName;
00174 contentTypeName << "A" << array.ArrayLength();
00175 return contentTypeName.str();
00176 }
00177
00178 std::string ora::MappingRules::variableNameForContainerValue(){
00179 static std::string s_cv("CV");
00180 return s_cv;
00181 }
00182
00183 std::string ora::MappingRules::variableNameForContainerKey(){
00184 static std::string s_ck("CK");
00185 return s_ck;
00186 }
00187
00188 std::string
00189 ora::MappingRules::scopedVariableForSchemaObjects( const std::string& variableName,
00190 const std::string& scope ){
00191 std::stringstream scopedName;
00192 if(!scope.empty()) scopedName << formatName(scope, ClassNameLengthForSchema) << "_";
00193 scopedName << variableName;
00194 return scopedName.str();
00195 }
00196
00198 #include "CondCore/ORA/interface/Exception.h"
00199 namespace ora {
00200 static std::string validChars("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_-0123456789");
00201 void checkString( const std::string& s, int code, bool thro=true){
00202 for( size_t i=0;i<s.size();i++){
00203 if( validChars.find( s[i])==std::string::npos ) {
00204 std::stringstream mess;
00205 mess <<" code="<<code<<" in string ["<<s<<"] found a wrong char=["<<s[i]<<"].";
00206 if( thro ) throwException( mess.str(),"validChars");
00207 }
00208 }
00209 }
00210
00211 }
00212
00213 std::string
00214 ora::MappingRules::newNameForSchemaObject( const std::string& initialName,
00215 unsigned int index,
00216 size_t maxLength,
00217 char indexTrailer){
00218 unsigned int digitsForPostfix = 3;
00219 if(index<10) digitsForPostfix = 2;
00220 size_t newSize = initialName.size()+digitsForPostfix;
00221 if(newSize > maxLength) newSize = maxLength;
00222 unsigned int cutSize = newSize - digitsForPostfix;
00223 std::stringstream newStr("");
00224 if( initialName[cutSize-1]=='_' ) cutSize -= 1;
00225 std::string cutString = initialName.substr(0, cutSize );
00226 newStr << cutString << "_";
00227 if( indexTrailer !=0 ) newStr<< indexTrailer;
00228 newStr<< index;
00229
00230 return newStr.str();
00231 }
00232
00233 std::string
00234 ora::MappingRules::newNameForDepSchemaObject( const std::string& initialName,
00235 unsigned int index,
00236 size_t maxLength)
00237 {
00238 return newNameForSchemaObject( initialName, index, maxLength, 'D' );
00239 }
00240
00241 std::string
00242 ora::MappingRules::newNameForArraySchemaObject( const std::string& initialName,
00243 unsigned int index,
00244 size_t maxL)
00245 {
00246 return newNameForSchemaObject( initialName, index, maxL, 'A' );
00247 }
00248
00249 std::string
00250 ora::MappingRules::nameForSchema( const std::string& variableName ){
00251 std::string varName( variableName );
00252
00253 MappingRules::ToUpper up(std::locale::classic());
00254 std::transform(varName.begin(), varName.end(),varName.begin(),up);
00255 size_t cutPoint = varName.size();
00256 if(cutPoint && varName[varName.size()-1] == '_' ) cutPoint -= 1;
00257 if(!cutPoint) return "";
00258 size_t start = 0;
00259 if(varName.size() && varName[0]== '_' ) start = 1;
00260 return varName.substr(start,cutPoint);
00261 }
00262
00263 std::string ora::MappingRules::shortNameByUpperCase( const std::string& className,
00264 size_t maxL ){
00265 if( !maxL ) return "";
00266 if( className.size() < maxL ) return className;
00267 std::vector< size_t> uppers;
00268 for( size_t i=0;i<className.size();i++) {
00269 if(::isupper(className[i]) || ::isdigit(className[i]) ) uppers.push_back(i);
00270 }
00271 std::stringstream shName;
00272 size_t usize = uppers.size();
00273 if( usize < maxL ){
00274 size_t start = 0;
00275 size_t cut = maxL-usize;
00276 if( usize && (cut > uppers[0]) ) cut = uppers[0];
00277 shName << className.substr( start, cut );
00278 size_t left = maxL-cut-usize;
00279 if( usize > 1) left = 0;
00280 size_t curs = 0;
00281 for( size_t i=0; i<usize;i++){
00282 size_t st = uppers[i];
00283 curs = st+left+1;
00284 shName << className.substr(st,left+1);
00285 left = 0;
00286 }
00287 size_t maxIndex = className.size();
00288 if( shName.str().size()<maxL && curs < maxIndex ){
00289 size_t more = maxL - shName.str().size();
00290 size_t max = curs+more;
00291 if(max > className.size()) max = className.size();
00292 for( size_t j=curs;j<max-1;j++ ){
00293 shName << className[j];
00294 }
00295 }
00296
00297
00298 } else {
00299 shName << className[0];
00300 for(size_t i=0 ;i<maxL-1;i++) {
00301 if( uppers[i] != 0 ) shName << className[uppers[i]];
00302 }
00303
00304 }
00306 return shName.str();
00307 }
00308
00309 std::string ora::MappingRules::shortScopedName( const std::string& scopedClassName,
00310 size_t maxLength ){
00311 if( !maxLength ) return "";
00312 std::string cn = scopedClassName;
00313 std::string sn("");
00314 size_t ns = cn.rfind("::");
00315 if( ns!= std::string::npos ){
00316 cn = scopedClassName.substr( ns+2 );
00317 sn = scopedClassName.substr( 0, ns );
00318 }
00319
00320 ns = cn.find(" ");
00321 while( ns != std::string::npos ){
00322 cn = cn.replace( ns, 1, "_");
00323 ns = cn.find(" ");
00324 }
00325
00326 ns = sn.find("::");
00327 if( ns == 0 ){
00328 sn = sn.substr( 2 );
00329 ns = sn.find("::");
00330 }
00331 while( ns != std::string::npos ){
00332 sn = sn.replace( ns, 2, "_");
00333 ns = sn.find("::");
00334 }
00335
00336 if( sn[sn.size()-1]=='_' ) sn = sn.substr(0,sn.size()-1);
00337
00338 if( sn == "std" ) sn = "";
00339
00340 size_t currSize = sn.size()+cn.size()+1;
00341 if( currSize > maxLength+1 ){
00342
00343 size_t maxScopeLen = maxLength/3;
00344 if( maxScopeLen ==0 ) maxScopeLen = 1;
00345 if( maxScopeLen > 1 ) maxScopeLen -= 1;
00346 if( sn.size() > maxScopeLen ){
00347 sn = sn.substr( 0,maxScopeLen );
00348 }
00349 size_t availableSize = maxLength-sn.size();
00350 if( sn.size() ) availableSize -= 1;
00351 cn =shortNameByUpperCase( cn, availableSize );
00352 }
00353 std::string ret = sn;
00354 if(!ret.empty()) ret += "_";
00355 ret += cn;
00356
00357 return ret;
00358 }
00359
00360 std::string ora::MappingRules::nameFromTemplate( const std::string& templateClassName,
00361 size_t maxLength ){
00362 if( !maxLength ) return "";
00363 std::string tempClassName(templateClassName);
00364 size_t indComas = tempClassName.find(',',0);
00365 std::vector<size_t> vComas;
00366 while(indComas != std::string::npos) {
00367 vComas.push_back(indComas);
00368 indComas = tempClassName.find(',',indComas+1);
00369 }
00370 typedef std::vector<size_t>::const_iterator vSizeIter;
00371 vSizeIter vBegin = vComas.begin();
00372 vSizeIter vEnd = vComas.end();
00373 for(vSizeIter i = vBegin; i != vEnd; ++i) {
00374 tempClassName.replace(*i, 1, 1, '_');
00375 }
00376 std::string newName("");
00377 size_t ind0 = tempClassName.find('<',0);
00378 if( ind0 != std::string::npos ){
00379 size_t ind1 = tempClassName.rfind('>');
00380 std::string templArg = tempClassName.substr( ind0+1, ind1-ind0-1 );
00381 std::string prefix = shortScopedName( tempClassName.substr( 0, ind0 ), maxLength );
00382 size_t currSize = templArg.size()+prefix.size()+1;
00383 if( currSize > maxLength+1 ){
00384
00385 size_t prefixL = maxLength/3;
00386 if( prefixL == 0 ) prefixL = 1;
00387 if( prefixL >1 ) prefixL -=1;
00388 prefix = shortScopedName( prefix, prefixL );
00389 }
00390 size_t templMaxSize = maxLength-prefix.size()-1;
00391 templArg = nameFromTemplate( templArg, templMaxSize );
00392 newName = prefix+"_"+ templArg;
00393 } else {
00394 newName = shortScopedName( tempClassName, maxLength );
00395 }
00396
00397 return newName;
00398 }
00399
00400 std::string
00401 ora::MappingRules::tableNameForItem( const std::string& itemName )
00402 {
00403 return "ORA_C_"+nameForSchema(formatName( itemName, MaxTableNameLength-5 ));
00404 }
00405
00406 std::string
00407 ora::MappingRules::columnNameForId()
00408 {
00409 return std::string("ID");
00410 }
00411
00412 std::string
00413 ora::MappingRules::columnNameForRefColumn()
00414 {
00415 return std::string("REF_ID");
00416 }
00417
00418 std::string
00419 ora::MappingRules::columnNameForVariable( const std::string& variableName,
00420 const std::string& scopeName,
00421 bool forData )
00422 {
00423 std::ostringstream totalString;
00424 int scopeMaxSize = MaxColumnNameLength/4-1;
00425 int extraSize = MaxColumnNameLength-variableName.size()-2;
00426 if( extraSize>0 && extraSize>scopeMaxSize ) scopeMaxSize = extraSize;
00427 if( !scopeName.empty() ) {
00428 size_t scopeCut = scopeName.size();
00429 if( scopeCut> (size_t)scopeMaxSize ) scopeCut = scopeMaxSize;
00430 totalString << scopeName.substr(0,scopeCut);
00431 totalString << "_";
00432 }
00433 size_t varMaxSize = MaxColumnNameLength-totalString.str().size();
00434
00435 size_t fp = variableName.find('[');
00436 if( fp != std::string::npos ){
00437
00438 std::string arrayVar = variableName.substr(0,fp);
00439 std::string indexVar = variableName.substr(fp);
00440 for( size_t ind = 0; ind!=std::string::npos; ind=indexVar.find('[',ind+1 ) ){
00441 indexVar = indexVar.replace(ind,1,"I");
00442 }
00443 for( size_t ind = indexVar.find(']'); ind!=std::string::npos; ind=indexVar.find(']',ind+1 ) ){
00444 indexVar = indexVar.replace(ind,1,"_");
00445 }
00446 size_t arrayVarCut = 0;
00447 size_t varCut = variableName.size()+1;
00448 if( varCut>varMaxSize ) varCut = varMaxSize;
00449 if( varCut>(indexVar.size()+1) ) arrayVarCut = varCut-indexVar.size()-1;
00450 totalString << arrayVar.substr(0,arrayVarCut);
00451 totalString << "_" << indexVar;
00452 } else {
00453 size_t varCut = variableName.size();
00454 if( varCut>varMaxSize ) varCut = varMaxSize;
00455
00456 totalString << variableName.substr(0,varCut);
00457 }
00458
00459 std::stringstream ret;
00460 if(forData) ret << "D";
00461 ret << nameForSchema(totalString.str());
00462
00463 return formatName(ret.str(),MaxColumnNameLength);
00464 }
00465
00466 std::string
00467 ora::MappingRules::columnNameForOID( const std::string& variableName,
00468 const std::string& scope,
00469 unsigned int index )
00470 {
00471 std::stringstream ret;
00472 ret << "R" << columnNameForVariable( variableName, scope, false )<<"_OID"<<index;
00473 return ret.str();
00474 }
00475
00476 std::string
00477 ora::MappingRules::columnNameForNamedReference( const std::string& variableName,
00478 const std::string& scope )
00479 {
00480 std::stringstream ret;
00481 ret << "R" << columnNameForVariable( variableName, scope, false )<<"_NAME";
00482 return ret.str();
00483 }
00484
00485 std::string
00486 ora::MappingRules::columnNameForRefMetadata( const std::string& variableName,
00487 const std::string& scope )
00488 {
00489 std::stringstream ret;
00490 ret << "M" << columnNameForVariable( variableName, scope, false );
00491 return ret.str();
00492 }
00493
00494 std::string
00495 ora::MappingRules::columnNameForRefId( const std::string& variableName,
00496 const std::string& scope )
00497 {
00498 std::stringstream ret;
00499 ret << "RID_" << columnNameForVariable( variableName, scope, false );
00500 return ret.str();
00501 }
00502
00503 std::string
00504 ora::MappingRules::columnNameForPosition()
00505 {
00506 return std::string("POS");
00507 }
00508
00509 std::string
00510 ora::MappingRules::columnNameForBlobMetadata( const std::string& dataColumnName ){
00511 std::string prefix("M");
00512 return prefix + dataColumnName.substr(1);
00513 }
00514
00515 std::string
00516 ora::MappingRules::fkNameForIdentity( const std::string& tableName, int index )
00517 {
00518 std::stringstream ret;
00519 ret << tableName <<"_ID_FK";
00520 if( index ) ret << "_"<<index;
00521 return ret.str();
00522 }
00523
00524 std::string ora::MappingRules::formatName( const std::string& variableName,
00525 size_t maxLength ){
00526 return nameFromTemplate( variableName, maxLength );
00527 }
00528