00001 /******************************************************************************/ 00002 /* */ 00003 /* POLiTe - Persistent Object Library Test */ 00004 /* Ph.D. Thesis by Mgr. Michal Kopecky */ 00005 /* */ 00006 /* Charles University Prague */ 00007 /* */ 00008 /******************************************************************************/ 00009 /* */ 00010 /* File name: ... cDatabase.cpp */ 00011 /* Module: ...... Database Abstraction Layer */ 00012 /* */ 00013 /******************************************************************************/ 00014 00015 // Standard Header(s) 00016 #include <malloc.h> 00017 #include <string.h> 00018 00019 // Common POLiTe Header(s) 00020 #include <lDefs.h> 00021 #include <lTypes.h> 00022 #include <lTrace.h> 00023 00024 // Own Header 00025 #include <cDatabase.h> 00026 00027 // Parent Header(s) 00028 00029 // Other POLiTe Header(s) 00030 #include <cConnection.h> 00031 #include <cObjectBuffer.h> 00032 00033 extern class ObjectBuffer _ObjectBuffer_; 00034 00035 Connection *Database::_AllConnections[MAX_CONNECTION]; 00036 int Database::_FreeAllConnections[MAX_CONNECTION]; 00037 int Database::_FirstFreeAllConnection; 00038 00039 bool Database::_FindFreeConnectionHandles(int &LocHandle, int &GlobHandle) 00040 { 00041 LocHandle = GlobHandle = -1; 00042 if (_FirstFreeConnection < 0) 00043 return false; 00044 if (_FirstFreeAllConnection < 0) 00045 return false; 00046 LocHandle = _FirstFreeConnection; 00047 _FirstFreeConnection = _FreeConnections[_FirstFreeConnection]; 00048 GlobHandle = _FirstFreeAllConnection; 00049 _FirstFreeAllConnection = _FreeAllConnections[_FirstFreeAllConnection]; 00050 return true; 00051 }; 00052 00053 void Database::_DisposeConnectionHandles(int &LocHandle, int &GlobHandle) 00054 { 00055 if (LocHandle >= 0) { 00056 _Connections[LocHandle] = NULL; 00057 _FreeConnections[LocHandle] = _FirstFreeConnection; 00058 _FirstFreeConnection = LocHandle; 00059 }; 00060 if (GlobHandle >= 0) { 00061 _AllConnections[GlobHandle] = NULL; 00062 _FreeAllConnections[GlobHandle] = _FirstFreeAllConnection; 00063 _FirstFreeAllConnection = GlobHandle; 00064 }; 00065 LocHandle = GlobHandle = -1; 00066 return; 00067 } 00068 00069 Database::Database(const char *ConnectString) 00070 //Creates a Database object assigned to a real database 00071 { 00072 int i; 00073 #ifdef C_DATABASE_TRACE 00074 if (ConnectString) 00075 logmsg("Database::Database(\"%s\") invoked", ConnectString); 00076 else 00077 logmsg("Database::Database() invoked"); 00078 #endif 00079 _Strategies = ObjectCache._Strategies; 00080 _ConnectString = NULL; 00081 for (i = 0; i < MAX_CONNECTION_PER_DATABASE; i++) 00082 _Connections[i] = NULL; 00083 for (i = 0; i < MAX_CONNECTION_PER_DATABASE-1; i++) 00084 _FreeConnections[i] = (i+1); 00085 _FreeConnections[MAX_CONNECTION_PER_DATABASE] = -1; 00086 _FirstFreeConnection = 0; 00087 if (ConnectString) 00088 Assign(ConnectString); 00089 }; 00090 00091 Database::~Database() 00092 //Database object destructor 00093 { 00094 int i; 00095 #ifdef C_DATABASE_TRACE 00096 logmsg("Database::~Database() invoked"); 00097 #endif 00098 for (i = 0; i < MAX_CONNECTION_PER_DATABASE; i++) 00099 if (_Connections[i] != NULL) 00100 _Connections[i]->Disconnect(); 00101 StrFree(_ConnectString); 00102 } 00103 00104 bool Database::Assign(const char *ConnectString) 00105 { 00106 #ifdef C_DATABASE_TRACE 00107 logmsg("Database::Assign(\"%s\") invoked", ConnectString); 00108 #endif 00109 StrCpy(_ConnectString,ConnectString); 00110 return true; 00111 }; 00112 00113 bool Database::Commit() 00114 //Commit all connections on the database, after storing modified objects 00115 { 00116 int i; 00117 bool result = true; 00118 #ifdef C_DATABASE_TRACE 00119 logmsg("Database::Commit() invoked"); 00120 #endif 00121 for (i = 0; i < MAX_CONNECTION_PER_DATABASE; i++) 00122 if (_Connections[i] != NULL) 00123 result = result && _Connections[i]->Commit(); 00124 return(result); 00125 }; 00126 00127 bool Database::_Commit() 00128 //Commit all connections on the database, none storing of modified objects 00129 { 00130 int i; 00131 bool result = true; 00132 #ifdef C_DATABASE_TRACE 00133 logmsg("Database::_Commit() invoked"); 00134 #endif 00135 for (i = 0; i < MAX_CONNECTION_PER_DATABASE; i++) 00136 if (_Connections[i] != NULL) 00137 result = result && _Connections[i]->_Commit(); 00138 return(result); 00139 }; 00140 00141 bool Database::Rollback() 00142 //Rollback all connections on the database, then destroy all copies in memory 00143 { 00144 int i; 00145 bool result = true; 00146 #ifdef C_DATABASE_TRACE 00147 logmsg("Database::Rollback() invoked"); 00148 #endif 00149 for (i = 0; i < MAX_CONNECTION_PER_DATABASE; i++) 00150 if (_Connections[i] != NULL) 00151 result = result && _Connections[i]->Rollback(); 00152 return(result); 00153 }; 00154 00155 bool Database::_Rollback() 00156 //Rollback all connections on the database only 00157 { 00158 int i; 00159 bool result = true; 00160 #ifdef C_DATABASE_TRACE 00161 logmsg("Database::_Rollback() invoked"); 00162 #endif 00163 for (i = 0; i < MAX_CONNECTION_PER_DATABASE; i++) 00164 if (_Connections[i] != NULL) 00165 result = result && _Connections[i]->_Rollback(); 00166 return(result); 00167 }; 00168 00169 class Connection *Database::Connect( 00170 const char * const/*UserName*/, 00171 const char * const/*Password*/) 00172 { 00173 #ifdef C_DATABASE_TRACE 00174 logmsg("Database::Connect() invoked"); 00175 #endif 00176 return(NULL); 00177 }; 00178 00179 // Set corresponging patrs of attribute _Strategies 00180 // that holds all concurency strategies 00181 bool Database::SetUpdatingStrategy(enum UpdatingStrategy anUpdatingStrategy) 00182 { 00183 #ifdef C_DATABASE_TRACE 00184 logmsg("bool Database::SetUpdatingStrategy(...) invoked"); 00185 #endif 00186 if (anUpdatingStrategy==US_Current) 00187 ; 00188 else if (anUpdatingStrategy==US_Default) 00189 _Strategies = _Strategies & ~US_MASK | DEFAULT_UPDATING_STRATEGY; 00190 else 00191 _Strategies = _Strategies & ~US_MASK | (unsigned int)anUpdatingStrategy; 00192 #ifdef C_OBJREF_TRACE 00193 logmsg("bool Database::SetUpdatingStrategy(...) finished"); 00194 #endif 00195 return true; 00196 }; 00197 bool Database::SetWaitingStrategy(enum WaitingStrategy aWaitingStrategy) 00198 { 00199 #ifdef C_DATABASE_TRACE 00200 logmsg("bool Database::SetWaitingStrategy(...) invoked"); 00201 #endif 00202 if (aWaitingStrategy==WS_Current) 00203 ; 00204 else if (aWaitingStrategy==WS_Default) 00205 _Strategies = _Strategies & ~WS_MASK | DEFAULT_WAITING_STRATEGY; 00206 else 00207 _Strategies = _Strategies & ~WS_MASK | (unsigned int)aWaitingStrategy; 00208 #ifdef C_DATABASE_TRACE 00209 logmsg("bool Database::SetWaitingStrategy(...) finished"); 00210 #endif 00211 return true; 00212 }; 00213 bool Database::SetLockingStrategy(enum LockingStrategy aLockingStrategy) 00214 { 00215 #ifdef C_DATABASE_TRACE 00216 logmsg("bool Database::SetLockingStrategy(...) invoked"); 00217 #endif 00218 if (aLockingStrategy==LS_Current) 00219 ; 00220 else if (aLockingStrategy==LS_Default) 00221 _Strategies = _Strategies & ~LS_MASK | DEFAULT_LOCKING_STRATEGY; 00222 else 00223 _Strategies = _Strategies & ~LS_MASK | (unsigned int)aLockingStrategy; 00224 #ifdef C_DATABASE_TRACE 00225 logmsg("bool Database::SetLockingStrategy(...) finished"); 00226 #endif 00227 return true; 00228 }; 00229 bool Database::SetReadingStrategy(enum ReadingStrategy aReadingStrategy) 00230 { 00231 #ifdef C_DATABASE_TRACE 00232 logmsg("bool Database::SetReadingStrategy(...) invoked"); 00233 #endif 00234 if (aReadingStrategy==RS_Current) 00235 ; 00236 else if (aReadingStrategy==RS_Default) 00237 _Strategies = _Strategies & ~RS_MASK | DEFAULT_READING_STRATEGY; 00238 else 00239 _Strategies = _Strategies & ~RS_MASK | (unsigned int)aReadingStrategy; 00240 #ifdef C_DATABASE_TRACE 00241 logmsg("bool Database::SetReadingStrategy(...) finished"); 00242 #endif 00243 return true; 00244 };