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