Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

cRefBase.cpp

Go to the documentation of this file.
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 /* An instance of RefBase descendants                                         */
00016 /* points to one object in one specific database.                             */
00017 /* Thus it includes both connection and object identification.                */
00018 /* During the access to the object, the object is automatically dereferenced  */
00019 /* and the object is retrieved (if necessary) from database                   */
00020 /* and placed into the memory.                                                */
00021 /* To minimise the amount of database accesses all persistent objects         */
00022 /* contained currently in memory are registered by the library object buffer  */
00023 /*                                                                            */
00024 /******************************************************************************/
00025 
00026 // Own Header
00027 #include <cRefBase.h>   // RefBase class header
00028 
00029 // Other POLiTe Header(s)
00030 #include <cObjectIdentification.h>
00031 #include <cObjectBuffer.h>
00032 #include <cObject.h>
00033 #include <cClassRegister.h>
00034 
00035 const class RefBase DBNULL;
00036 
00038 // RefBase constructor:
00039 // Create the RefBase object with the appropriate (NULL)initialization.
00040 
00041 RefBase::RefBase()
00042 : _ObjectIdentification()
00043 {
00044         #ifdef C_REFBASE_TRACE
00045                 logmsg("RefBase::RefBase() invoked and finished");
00046         #endif
00047         _Connection = NULL;
00048         _Strategies = ObjectCache._Strategies;
00049 }
00050 
00052 // RefBase constructor:
00053 // Create the RefBase object with the appropriate initialization.
00054 
00055 RefBase::RefBase(
00056                 class Connection *aConnection,
00057                 class ProtoBase *aPrototype,
00058                 char *aSelectKeyValues,
00059                 unsigned short aStrategies
00060                 )
00061 : _ObjectIdentification(aPrototype, aSelectKeyValues)
00062 {
00063         _Connection = aConnection;
00064         _Strategies = aStrategies;
00065         #ifdef C_REFBASE_TRACE
00066                 logmsg("RefBase::RefBase(DatabaseConnection *, Object *, char *) invoked and finished");
00067         #endif
00068 }
00069 
00070 RefBase::RefBase(
00071         const RefBase &Dbp
00072         )
00073 : _ObjectIdentification(Dbp._ObjectIdentification)
00074 {
00075         _Connection = Dbp._Connection;
00076         _Strategies = Dbp._Strategies;
00077         #ifdef C_REFBASE_TRACE
00078                 logmsg("RefBase::RefBase(RefBase &) invoked and finished");
00079         #endif
00080 };
00081 
00082 RefBase::RefBase(
00083         const Object * const DbObj
00084         )
00085 : _ObjectIdentification(DbObj)
00086 {
00087         _Connection = NULL;
00088         if (DbObj)
00089                 _Strategies = DbObj->_Strategies;
00090         else
00091                 _Strategies = ObjectCache._Strategies;
00092         #ifdef C_REFBASE_TRACE
00093                 logmsg("RefBase::RefBase(Object *) invoked and finished");
00094         #endif
00095 };
00096 
00097 
00098 bool RefBase::Init(
00099                 class Connection *aConnection,
00100                 class ProtoBase *aPrototype,
00101                 char *aSelectKeyValues)
00102 {
00103         _Connection = aConnection;
00104         #ifdef C_REFBASE_TRACE
00105                 logmsg("RefBase::_Init(DatabaseConnection *, Object *, char *) invoked and finished");
00106         #endif
00107         return _ObjectIdentification._Init(aPrototype, aSelectKeyValues);
00108 }
00109 
00110 RefBase::RefBase(
00111                 class Connection *aConnection,
00112                 ObjectIdentification *anIdentification
00113                 )
00114 : _ObjectIdentification(*anIdentification)
00115 {
00116         _Connection = aConnection;
00117         #ifdef C_REFBASE_TRACE
00118                 logmsg("RefBase::RefBase(DatabaseConnection *, ObjectIdentification *) invoked and finished");
00119         #endif
00120 }
00121 
00122 RefBase::RefBase(
00123         class Connection *aConnection,
00124         const long anOid,
00125         class ProtoBase *aPrototype
00126         )
00127 : _ObjectIdentification(anOid, aPrototype)
00128 {
00129         _Connection = aConnection;
00130         #ifdef C_REFBASE_TRACE
00131                 logmsg("RefBase::RefBase(DatabaseConnection *, long, ProtoBase *) invoked and finished");
00132         #endif
00133 }
00134 
00136 // RefBase destructor:
00137 // Delete the RefBase object with the appropriate de-initialization.
00138 
00139 RefBase::~RefBase()
00140 {
00141   #ifdef C_REFBASE_TRACE
00142         logmsg("RefBase::~RefBase() invoked and finished");
00143         #endif
00144 }
00145 
00147 // Typecasts RefBase to class A to RefBase to
00148 // correct A's subclass B. Does nothing in other derived classes.
00149 class RefBase &RefBase::_Virtualise()
00150 {
00151         char class_name[MAX_CLASS_NAME_LEN + 1];
00152         char *sqlcmd = NULL;
00153         class ProtoBase *prot;
00154         class Connection *dbc;
00155         bool okay = true;
00156         #ifdef C_REFBASE_TRACE
00157                 logmsg("RefBase::Virtualise() invoked");
00158                 if (!Prototype()->IsPersistentObject())
00159                         logmsg(
00160                                 TL_WARNING,
00161                                 "RefBase::Virtualise() used for non PersistentObject based pointer"
00162                                 );
00163         #endif
00164         if (
00165                 Prototype()
00166                 && Prototype()->IsPersistentObject()
00167                 && ((dbc = Connection()) != NULL)
00168                 && (_ObjectIdentification._SelectKeyValues != NULL)
00169                 )
00170         {
00171                 StrCat(sqlcmd,2,
00172                         "SELECT CLASS_NAME FROM " PERSISTENT_OBJECT_TABLE " WHERE OID = ",
00173                         _ObjectIdentification._SelectKeyValues
00174                         );
00175                 okay = okay
00176                         && dbc->_Open()
00177                         && dbc->_Prepare(sqlcmd)
00178                         && dbc->_Execute()
00179                         && dbc->_PreFetchBind(
00180                                 1,
00181                                 (void *)class_name,
00182                                 MAX_CLASS_NAME_LEN,
00183                                 TYPE_STRING
00184                                 )
00185                         && dbc->_FetchNext();
00186                 okay = dbc->_Close() && okay;
00187                 StrFree(sqlcmd);
00188                 if (okay)
00189                 {
00190                         if ((prot = Class[class_name]) != NULL)
00191                         {
00192                                 // change pointer to the found prototype
00193                                 _ObjectIdentification._prototype = prot;
00194                         }
00195                         #ifdef C_REFBASE_TRACE
00196                         else
00197                         {
00198                                 logmsg(
00199                                         TL_WARNING,
00200                                         "No prototype for class \"%s\" were found",
00201                                         class_name
00202                                         );
00203                         }
00204                         #endif
00205                         ;
00206                 };
00207         };
00208         return *this;
00209 };
00210 
00212 //Returns the reference to the pointed object which will be read from the database,
00213 //if the object is not present in memory yet.
00214 
00215 Object &RefBase::ReferencedObject() const
00216 {
00217         #ifdef C_REFBASE_TRACE
00218                 logmsg("Object &RefBase::ReferencedObject() invoked");
00219         #endif
00220 
00221         if (*this == DBNULL)
00222                 throw ObjLibException_NotFound();
00223         return IsPersistent() ? *ObjectCache.GetReferencedObject(*this) : *(Object *)_ObjectIdentification._object;
00224 };
00225 
00226 /*
00228 //Returns reference to the pointed object which will be read from the database,
00229 //if object is not present in memory. To load the object a predefined locking
00230 //strategy will be used instead of default one.
00231 
00232 Object &RefBase::ReferencedObject(
00233         const enum LockingStrategy _Locking_Strategy
00234         ) const
00235 {
00236 
00237         #ifdef C_REFBASE_TRACE
00238                 logmsg("Object &RefBase::ReferencedObject(enum LockingStrategy _Locking_Strategy) invoked");
00239         #endif
00240 
00241         if (*this == DBNULL)
00242                 throw ObjLibException_NotFound();
00243         if (Connection() != NULL)
00244                 return *ObjectCache.GetReferencedObject(*this,_Locking_Strategy);
00245         return *(Object*)_ObjectIdentification._object;
00246 }
00247 */
00248 
00250 //Gives the pointer to the identification of the pointed object (unique in the
00251 //content of the database).
00252 
00253 ObjectIdentification RefBase::ObjectID() const
00254 {
00255   #ifdef C_REFBASE_TRACE
00256         logmsg("ObjectIdentification RefBase::ObjectID() invoked and finished");
00257         #endif
00258 
00259   return _ObjectIdentification;
00260 }
00261 
00263 //Access to the object with the tests whether the object is loaded into the
00264 //memory. It returns the pointer to the object in the memory (if he is loaded
00265 //in the memory) or NULL otherwise.
00266 
00267 Object* RefBase::IsInMemory() const
00268 {
00269   #ifdef C_REFBASE_TRACE
00270         logmsg("Object* RefBase::IsInMemory() invoked and finished");
00271         #endif
00272 
00273         if (*this == DBNULL)
00274                 return NULL;
00275         if (Connection() != NULL)
00276                 return ObjectCache.IsInMemory(*this);
00277         return (Object*)_ObjectIdentification._object;
00278 }
00279 
00281 class ProtoBase *RefBase::Prototype() const
00282 {
00283   #ifdef C_REFBASE_TRACE
00284         logmsg("RefBase::Prototype() invoked and finished");
00285         #endif
00286         if (*this == DBNULL)
00287                 return NULL;
00288         return _ObjectIdentification.Prototype();
00289 };
00290 
00292 bool RefBase::IsDirty() const
00293 {
00294         Object *MyDbObject;
00295         return (MyDbObject=IsInMemory())==NULL ? false : MyDbObject->IsDirty();
00296 };
00297 
00299 bool RefBase::MarkAsDirty()
00300 {
00301         Object *MyDbObject;
00302         return (MyDbObject=IsInMemory())== NULL ? true : MyDbObject->MarkAsDirty();
00303 };
00304 
00306 bool RefBase::_MarkAsClean()
00307 {
00308         Object *MyDbObject;
00309         return (MyDbObject=IsInMemory())== NULL ? true : MyDbObject->_MarkAsClean();
00310 };
00311 
00313 //Refreshes the pointed object, if it occurs in the memory. Otherwise it does nothing.
00314 
00315 bool RefBase::Refresh()
00316 {
00317         #ifdef C_REFBASE_TRACE
00318                 logmsg("bool RefBase::Refresh() invoked");
00319         #endif
00320 
00321         Object* MyDbObject;
00322         return (MyDbObject=IsInMemory())== NULL ? true : MyDbObject->Refresh();
00323 };
00324 
00325 
00327 // Updates the pointed object, if it occurs in the memory. Otherwise it does nothing.
00328 
00329 bool RefBase::Update()
00330 {
00331         #ifdef C_REFBASE_TRACE
00332                 logmsg("bool RefBase::Update() invoked");
00333         #endif
00334 
00335         Object* MyDbObject;
00336         return (MyDbObject=IsInMemory())== NULL ? true : MyDbObject->Update();
00337 };
00338 
00339 
00341 //Frees the pointed object from the memory, if it occurs there. Otherwise it
00342 //does nothing.
00343 
00344 bool RefBase::Free()
00345 {
00346         #ifdef C_REFBASE_TRACE
00347                 logmsg("bool RefBase::Free() invoked");
00348         #endif
00349 
00350         Object* MyDbObject;
00351         return( (MyDbObject=IsInMemory()) == NULL ? true : MyDbObject->Free());
00352 };
00353 
00354 
00356 bool RefBase::_Free()
00357 {
00358         #ifdef C_REFBASE_TRACE
00359                 logmsg("bool RefBase::_Free() invoked");
00360         #endif
00361         Object* MyDbObject;
00362         return( (MyDbObject=IsInMemory()) == NULL ? true : MyDbObject->_Free());
00363 };
00364 
00365 
00367 //Tries to destroy the referenced object from memory, as well as from database.
00368 //Succeed, if all the tests (for example, if object is not locked) are passed
00369 //successfully.
00370 
00371 bool RefBase::Delete()
00372 {
00373         #ifdef C_REFBASE_TRACE
00374                 logmsg("bool RefBase::Delete() invoked");
00375         #endif
00376 
00377         Object* MyDbObject;
00378         bool _retval;
00379 
00380         if ((MyDbObject=IsInMemory()) != NULL)
00381                 return MyDbObject -> Delete();
00382         if (IsTransient())                                      //Object is transient
00383                 return true;
00384         _retval = Prototype()->_DeleteAll(this);
00385 
00386         #ifdef C_REFBASE_TRACE
00387                 logmsg("bool RefBase::Delete() finished");
00388         #endif
00389 
00390         return _retval;
00391 };
00392 
00393 
00395 //Locks a persistent object. Multiple locks
00396 //can be placed on the object. The object can be
00397 //removed from memory only when all the locks are
00398 //released.
00399 
00400 Object *RefBase::MemoryLock()
00401 {
00402         #ifdef C_REFBASE_TRACE
00403                 logmsg("Object *RefBase::MemoryLock() invoked and finished");
00404         #endif
00405 
00406         return this->ReferencedObject().MemoryLock();
00407 };
00408 
00410 //Unlocks a persistent object in memory. See MemoryLock.
00411 //covered external events:
00412 //· Unlock object in memory
00413 
00414 bool RefBase::MemoryUnlock()
00415 {
00416         Object *MemPtr;
00417         bool retval;
00418 
00419         #ifdef C_REFBASE_TRACE
00420                 logmsg("bool RefBase::MemoryUnlock() invoked");
00421         #endif
00422 
00423         retval = ((MemPtr = IsInMemory()) != NULL) ?
00424                 MemPtr -> MemoryUnlock() :
00425                 false;
00426 
00427         #ifdef C_REFBASE_TRACE
00428                 logmsg("bool RefBase::MemoryUnlock() finished");
00429         #endif
00430 
00431         return retval;
00432 };
00433 
00435 //Returns the number of memory locks on receiver or zero
00436 //if it is not locked.
00437 
00438 unsigned int RefBase::MemoryLocked() const
00439 {
00440         unsigned int retval;
00441         Object *MemPtr;
00442 
00443         #ifdef C_REFBASE_TRACE
00444                 logmsg("unsigned int RefBase::MemoryLocked() invoked");
00445         #endif
00446 
00447         retval = (
00448                 ((MemPtr = IsInMemory()) == NULL)
00449                 ? 0
00450                 : MemPtr -> MemoryLocked()
00451                 );
00452 
00453         #ifdef C_REFBASE_TRACE
00454                 logmsg("unsigned int RefBase::MemoryLocked() finished");
00455         #endif
00456 
00457         return retval;
00458 };
00459 
00461 //Removes all memory locks existing in the GEN.LIB
00462 
00463 bool RefBase::RemoveAllMemoryLocks()
00464 {
00465         bool retval;
00466         Object *MemPtr;
00467 
00468         #ifdef C_REFBASE_TRACE
00469                 logmsg("bool RefBase::RemoveAllMemoryLocks() invoked");
00470         #endif
00471 
00472         retval = (
00473                 ((MemPtr = IsInMemory()) == NULL)
00474                 ? true
00475                 : MemPtr -> RemoveAllMemoryLocks()
00476                 );
00477 
00478         #ifdef C_REFBASE_TRACE
00479                 logmsg("bool RefBase::RemoveAllMemoryLocks() finished");
00480         #endif
00481 
00482         return retval;
00483 }
00484 
00486 
00487 bool RefBase::operator == (
00488         const class RefBase &DbPtr
00489         ) const
00490 {
00491         return (this->_Connection == DbPtr._Connection)
00492                 &&(this->_ObjectIdentification == DbPtr._ObjectIdentification);
00493 };
00494 
00495 bool RefBase::operator != (
00496         const class RefBase &DbPtr
00497         ) const
00498 {
00499         return (this->_Connection != DbPtr._Connection)
00500                 ||(this->_ObjectIdentification != DbPtr._ObjectIdentification);
00501 };

Generated on Sun Jul 14 20:51:15 2002 for POLiTe by doxygen1.2.16