00001 #ifndef CDBBDB_SCHEMA_UTILS_HH 00002 #define CDBBDB_SCHEMA_UTILS_HH 00003 00004 // File and Version Information: 00005 // $Id: CdbBdbSchemaUtils.hh,v 1.4 2004/10/21 20:35:52 gapon Exp $ 00006 00007 #include "CdbBase/CdbCommon.hh" 00008 00009 #include <oo.h> 00010 00011 #include <string> 00012 #include <vector> 00013 #include <map> 00014 00015 /// This class provides Objectivity/DB schema services 00016 /** 00017 * These services are either missing or inproperly implemented in the standard 00018 * Objectivity/DB C++ API. The current implementation of this class uses the 00019 * Active Schema API. 00020 * 00021 * This class is implemented as the singleton with lazy instantiation.to extract 00022 * schema information from the federation. 00023 * 00024 * The class does _NOT_ do its own transction management. Therefore its client must supply 00025 * proper transaction environment (READ) when using this class's methods. 00026 */ 00027 class CdbBdbSchemaUtils { 00028 00029 public: 00030 00031 /// The internal type identifier 00032 /** 00033 * This type is used in the implementation of the current class as a replacement for 00034 * the non-contigous ooTypeNumber. 00035 */ 00036 typedef unsigned int LocalTypeID; 00037 00038 /// The node class in the dependency tree 00039 /** 00040 * Each class (type number) is represented by an instance of the Node class 00041 * having biderectional pointers onto its subclasses and superclasses. 00042 */ 00043 class Node { 00044 00045 private: 00046 00047 // Prohibited constructors 00048 00049 Node( ); 00050 Node( const Node&); 00051 Node& operator=( const Node&); 00052 00053 public: 00054 00055 Node( const ooTypeNumber theTypeNumber ); 00056 00057 public: 00058 00059 const ooTypeNumber typeNumber; 00060 00061 std::map<ooTypeNumber, Node* > subclasses; 00062 std::map<ooTypeNumber, Node* > superclasses; 00063 }; 00064 00065 /// Dependency tree class 00066 00067 class Tree { 00068 00069 friend class CdbBdbSchemaUtils; 00070 00071 private: 00072 00073 // Prohibited constructors 00074 00075 Tree( const Tree&); 00076 Tree& operator=( const Tree&); 00077 00078 public: 00079 00080 Tree( ); 00081 ~Tree( ); 00082 00083 inline bool isLoaded( ) { return _isLoaded; } 00084 00085 const Node* type_to_node( const ooTypeNumber theTypeNumber ) const; 00086 00087 private: 00088 00089 void reset( ); 00090 00091 bool load( const std::map<ooTypeNumber, std::vector<ooTypeNumber> >& thePartialTree, 00092 bool debugModeFlag = false ); 00093 00094 Node* type_to_node( const std::map<ooTypeNumber, std::vector<ooTypeNumber> >& thePartialTree, 00095 const ooTypeNumber theTypeNumber, 00096 bool debugModeFlag ); 00097 private: 00098 00099 bool _isLoaded; 00100 00101 public: 00102 00103 // The following map represents entries for all classes to be processed 00104 // by the algorithm. 00105 // 00106 // IMPORTANT NOTE: This data structures has ownership over all the dynamically 00107 // allocated by the current algorithm nodes. 00108 00109 std::map<ooTypeNumber, Node*> all; 00110 00111 // The "very base" classes which do not have any base classes. 00112 // This data structure represents the result of the 00113 00114 std::map<ooTypeNumber, Node*> root; 00115 }; 00116 00117 public: 00118 00119 /// Accessor for the singleton 00120 /** 00121 * The very first call to the accessor would instantiate the singleton. 00122 */ 00123 static CdbBdbSchemaUtils& instance( ); 00124 00125 private: 00126 00127 /// The default constructor 00128 /** 00129 * Will load the schema information into the local cache. 00130 */ 00131 CdbBdbSchemaUtils( ); 00132 00133 /// The copy constructor (NOT IMPLEMENTED) 00134 /** 00135 * Is disabled... 00136 */ 00137 CdbBdbSchemaUtils( const CdbBdbSchemaUtils& theObject ); 00138 00139 /// The destructor 00140 /** 00141 * Would clear up the cache. 00142 */ 00143 virtual ~CdbBdbSchemaUtils( ); 00144 00145 /// The assignment operator (NOT IMPLEMENTED) 00146 /** 00147 * Is disabled... 00148 */ 00149 CdbBdbSchemaUtils& operator=( const CdbBdbSchemaUtils& theObject ); 00150 00151 public: 00152 00153 /// Check if one class (specified by its type number) derives from another one 00154 /** 00155 * If either of the passed type number is unknown to the current federation's 00156 * schema then negative result will always be returned. 00157 * 00158 * If both types parameters have the same value than positive results always gets 00159 * returned unless the type number is unknown. 00160 * 00161 * @returns a result of the comparision 00162 */ 00163 bool isA( const ooTypeNumber theDerivedTypeNumber, /**< the derived type identifier */ 00164 const ooTypeNumber theBaseTypeNumber /**< its potential base type */ 00165 ) const; 00166 00167 /// Translate a type number into its class name 00168 /** 00169 * The method will return "false" if specified type number is unknown or 00170 * does not correspond to the class. 00171 */ 00172 bool typeNumberToClassName( const ooTypeNumber theTypeNumber, /**< the type number in question */ 00173 std::string& theClassName /**< its class name */ 00174 ) const; 00175 00176 /// Translate a class name into its type number 00177 /** 00178 * The method will return "false" if specified class name is unknown. 00179 */ 00180 bool classNameToTypeNumber( const char* theClassName, /**< the class name in question */ 00181 ooTypeNumber& theTypeNumber /**< its type number */ 00182 ) const; 00183 00184 /// Get dependency tree for all known type numbers 00185 /** 00186 * The method (if successfull) would set up a user supplied object with 00187 * the full tree. 00188 * 00189 * @see CdbBdbSchemaUtils::Node 00190 * @see CdbBdbSchemaUtils::Tree 00191 */ 00192 bool loadDependencyTree( Tree& theTree ) const; 00193 00194 /// Update class information from the federation's schema 00195 /** 00196 * This method will drop the current object's cache and reload 00197 * it fresh from the federation. 00198 * 00199 * The method will return "false' should any problem occure durinig 00200 * its execution. 00201 */ 00202 bool update( ); 00203 00204 private: 00205 00206 /// Clear current cache 00207 00208 void clearCache( ); 00209 00210 /// Register specified class indictionaries 00211 00212 void registerClass( const LocalTypeID theLocalTypeId, 00213 const char* theClassName, 00214 const ooTypeNumber theTypeNumber 00215 ); 00216 00217 public: 00218 00219 // The parameters of the class 00220 00221 static bool debugMode; 00222 00223 private: 00224 00225 // These dictionaries provide bi-directional translation 00226 // between class names and Objectivity/DB type numbers. 00227 00228 std::map<std::string, ooTypeNumber> _nameToTypeNumber; 00229 std::map<ooTypeNumber, std::string> _typeNumberToName; 00230 00231 // These dictionaries poivide bi-directional translation 00232 // between local (used by the current class) type identifiers 00233 // and Objectivity/DB type numbers. 00234 00235 std::map<LocalTypeID, ooTypeNumber> _localTypeIdToTypeNumber; 00236 std::map<ooTypeNumber, LocalTypeID> _typeNumberToLocalTypeId; 00237 00238 // A dependency tree of classes 00239 00240 std::map<ooTypeNumber, std::vector<ooTypeNumber> > _dependencyTree; 00241 00242 // A square matrix representing the "derived<->base" class relationship graph. 00243 // This data structure is good for quick finding both direct and indirect base 00244 // classes (when answering the IS_A questions). However, unlike the dependency 00245 // tree, it does not reflect original relationship information. 00246 // 00247 // - indeces of the matrix have the same type: LocalTypeID 00248 // - the first index of the matrix is the derived class 00249 // - the second index is the base class identifier 00250 // - only classes (including internal Objectivity/DB classes) are included 00251 // - the current size of the matrix is defined through a special variable 00252 00253 bool** _derivedVsBase; 00254 LocalTypeID _derivedVsBaseSize; 00255 }; 00256 00257 #endif // CDBBDB_SCHEMA_UTILS_HH
1.3-rc3