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: ... */ 00011 /* Module: ...... */ 00012 /* */ 00013 /******************************************************************************/ 00014 00015 // Standard Header(s) 00016 #include <stdio.h> 00017 00018 // Common POLiTe Header(s) 00019 #include <lDefs.h> 00020 #include <lTrace.h> 00021 00022 // INCLUDE OWN HEADER 00023 #include <cResultBase.h> 00024 00025 // Other POLiTe Header(s) 00026 #include <cComplexQuery.h> 00027 #include <cConnection.h> 00028 #include <cCursor.h> 00029 #include <cObjectBuffer.h> 00030 #include <cProtoBase.h> 00031 00032 ResultBase::ResultBase() 00033 { 00034 #ifdef NO_DATABASE_PRESENT 00035 _row_counter = 0; 00036 #endif 00037 _query = NULL; 00038 _isValRef = false; 00039 _sql_select = NULL; 00040 _queryPrototype = NULL; 00041 _queryConnection = NULL; 00042 _cursor = NULL; 00043 }; 00044 00045 ResultBase::~ResultBase() 00046 { 00047 StrFree(_sql_select); 00048 if (_query) delete(_query); 00049 if (_cursor) 00050 { 00051 _cursor->_Close(); 00052 delete(_cursor); 00053 }; 00054 StrFree(_sql_select); 00055 }; 00056 00057 bool ResultBase::Open(){ 00058 #ifdef C_RESULTBASE_TRACE 00059 logmsg("ResultBase::Open() invoked"); 00060 #endif 00061 _isValRef = false; 00062 #ifdef NO_DATABASE_PRESENT 00063 _row_counter = 0; 00064 #endif 00065 if (_cursor == NULL) 00066 return false; 00067 if (!ObjectCache.UpdateAll(_cursor->_DatabaseConnection)) 00068 return(false); 00069 if ( 00070 _cursor->_Open() 00071 && _cursor->_Prepare(_sql_select) 00072 && _cursor->_Execute() 00073 ) 00074 { 00075 //BIND OUTPUT VARIABLES NOW! 00076 _queryPrototype->_BindPtr(_cursor); 00077 return true; 00078 } 00079 return false; 00080 }; 00081 00082 bool ResultBase::Close(){ 00083 #ifdef C_RESULTBASE_TRACE 00084 logmsg("ResultBase::Close() invoked"); 00085 #endif 00086 _isValRef = false; 00087 return _cursor == NULL ? false : _cursor->_Close(); 00088 }; 00089 00090 class ResultBase &ResultBase::operator++ () { 00091 #ifdef C_RESULTBASE_TRACE 00092 logmsg("ResultBase++ invoked"); 00093 #endif 00094 Next(); 00095 return *this; 00096 }; 00097 00098 class ResultBase &ResultBase::operator += (long int n) { 00099 #ifdef C_RESULTBASE_TRACE 00100 logmsg("ResultBase += long int invoked"); 00101 #endif 00102 while ((n-- > 0) && ((++(*this)) != DBNULL)) 00103 ; 00104 return *this; 00105 }; 00106 00107 bool ResultBase::operator== (const ResultBase &Q) const { 00108 #ifdef C_RESULTBASE_TRACE 00109 logmsg("ResultBase==invoked"); 00110 #endif 00111 return (this == &Q); 00112 }; 00113 00114 bool ResultBase::operator!= (const ResultBase &Q) const { 00115 #ifdef C_RESULTBASE_TRACE 00116 logmsg("ResultBase!=invoked"); 00117 #endif 00118 return (this != &Q); 00119 }; 00120 00121 bool ResultBase::Prev() { 00122 #ifdef C_RESULTBASE_TRACE 00123 logmsg("ResultBase::Prev() invoked"); 00124 #endif 00125 long i; 00126 if ((i = Position()) > 0) 00127 return GoToPosition(i-1); 00128 return true; 00129 }; 00130 00131 bool ResultBase::Next() { 00132 #ifdef C_RESULTBASE_TRACE 00133 logmsg("ResultBase::Next() invoked"); 00134 #endif 00135 _isValRef = false; 00136 bool _retval; 00137 if (_cursor == NULL) 00138 { 00139 _Connection=NULL; 00140 _ObjectIdentification._prototype=NULL; 00141 StrFree(_ObjectIdentification._SelectKeyValues); 00142 return false; 00143 }; 00144 #ifdef NO_DATABASE_PRESENT 00145 if (++_row_counter > MAX_FETCHES_FROM_DUMMY_DATABASE) 00146 { 00147 _Connection=NULL; 00148 _ObjectIdentification._prototype=NULL; 00149 StrFree(_ObjectIdentification._SelectKeyValues); 00150 return false; 00151 }; 00152 #else 00153 if (!(_cursor->_FetchNext())) 00154 { 00155 // No data were found. Make this reference equal to DBNULL 00156 _Connection=NULL; 00157 _ObjectIdentification._prototype=NULL; 00158 StrFree(_ObjectIdentification._SelectKeyValues); 00159 return false; 00160 }; 00161 #endif 00162 if (_queryPrototype->IsObject()) 00163 { 00164 // Object descendants create instances directly 00165 // pointer is set as transient pointer to that instance 00166 _Connection=NULL; 00167 _ObjectIdentification._object=_queryPrototype->New(); 00168 _retval = _queryPrototype->_ImportAttributes(*(Object *)(_ObjectIdentification._object)); 00169 } 00170 else 00171 { 00172 // Other classes set only database pointers 00173 _Connection=_queryConnection; 00174 _ObjectIdentification._prototype=_queryPrototype; 00175 _retval = _queryPrototype->_ImportKeyAttributes(*this); 00176 }; 00177 #ifdef AUTO_VIRTUAL_OBJECT_LOAD 00178 // set the prototype according to the class name for PersistentObject descendants 00179 if (_queryPrototype->IsPersistentObject()) 00180 { 00181 _ObjectIdentification._prototype=_queryPrototype->_PtrPrototype(); 00182 }; 00183 #endif //AUTO_VIRTUAL_OBJECT_LOAD 00184 _isValRef = _retval; 00185 return _retval; 00186 }; 00187 00188 bool ResultBase::First() { 00189 #ifdef C_RESULTBASE_TRACE 00190 logmsg("ResultBase::First() invoked"); 00191 #endif 00192 return Open() && Next(); 00193 }; 00194 00195 bool ResultBase::Last() { 00196 #ifdef C_RESULTBASE_TRACE 00197 logmsg("ResultBase::Last() invoked"); 00198 #endif 00199 while (Next()) 00200 ; 00201 return true; 00202 }; 00203 00204 long ResultBase::Count() { 00205 #ifdef C_RESULTBASE_TRACE 00206 logmsg("ResultBase::Count() invoked"); 00207 #endif 00208 long _p = Position(); 00209 Last(); 00210 long _retval = Position(); 00211 GoToPosition(_p); 00212 return _retval; 00213 }; 00214 00215 bool ResultBase::IsOnFirst() { 00216 #ifdef C_RESULTBASE_TRACE 00217 logmsg("ResultBase::IsOnFirst() invoked"); 00218 #endif 00219 return(Position() == 1); 00220 }; 00221 00222 00223 bool ResultBase::IsOnLast() { 00224 #ifdef C_RESULTBASE_TRACE 00225 logmsg("ResultBase::IsOnLast() invoked"); 00226 #endif 00227 return(Count() == Position()); 00228 }; 00229 00230 bool ResultBase::GoToPosition (long Pos) { 00231 #ifdef C_RESULTBASE_TRACE 00232 logmsg("ResultBase::GoToPosition() invoked"); 00233 #endif 00234 if (Pos < 1) 00235 return false; 00236 bool _retval = true; 00237 if (Pos < Position()) 00238 _retval = _retval && Open(); 00239 long i=Position(); 00240 for( ; i < Pos; i++) 00241 _retval = _retval && Next(); 00242 return(_retval); 00243 }; 00244 00245 long ResultBase::Position() { 00246 #ifdef C_RESULTBASE_TRACE 00247 logmsg("ResultBase::Position() invoked"); 00248 #endif 00249 return _cursor == NULL ? (long)-1 : _cursor->_Position(); 00250 }; 00251 00252 bool ResultBase::_SetSqlCommand(char *SQLcommand) { 00253 #ifdef C_RESULTBASE_TRACE 00254 logmsg("ResultBase::_SetSqlCommand() invoked"); 00255 #endif 00256 if (SQLcommand != NULL) 00257 StrCpy(_sql_select,SQLcommand); 00258 return true; 00259 }; 00260 00261 00262 bool ResultBase::operator == ( 00263 const class RefBase &DbPtr 00264 ) const 00265 { 00266 return (this->_Connection == DbPtr._Connection) 00267 &&(this->_ObjectIdentification == DbPtr._ObjectIdentification); 00268 }; 00269 00270 bool ResultBase::operator != ( 00271 const class RefBase &DbPtr 00272 ) const 00273 { 00274 return (this->_Connection != DbPtr._Connection) 00275 ||(this->_ObjectIdentification != DbPtr._ObjectIdentification); 00276 };