PtObject is a class which contains data members for object identity and link counts and the methods needed to assign objects to a database, store them, delete them, lock them, watch them, or manage the object's link count. Every persistent class that you declare inherits these - when PTXX encounters a persistent class it automatically derives it from PtObject. General guidelines for programming with persistent objects are given in the chapter "Persistent Objects." Methods that lock or unlock objects are described in the chapter "Locking." Methods that set or remove watches are described in the chapter "Event handling."
Files to include | Class declaration | Base class |
poet.hxx | ptobject.hxx | PtCallback |
constructor | PtObject(); |
destructor | virtual ~PtObject(); |
Activate | virtual void Activate(); |
Assign | virtual int Assign(PtBase* pObjBase); |
BeginCriticalSection | virtual void BeginCriticalSection(PtBase* pBase = 0) const; |
CheckIn | virtual int CheckIn(PtDepthMode Mode = PtDEEP); |
CheckOut | virtual int CheckOut(PtWorkspace* pws, PtDepthMode depthMode = PtDEEP, PtLockMode lockMode = PtLK_DELETEvWRITE); |
Delete | virtual int Delete(PtDepthMode Mode = PtSHALLOW); |
EndCriticalSection | virtual void EndCriticalSection(PtBase* pBase = 0) const; |
Forget | virtual PtWord Forget(); |
ForgetCycle | int ForgetCycle(PtDepthMode DepthMode); |
GetAddressPoint | virtual void* GetAddressPoint(const PtClassId& classid) const; |
GetBase | inline PtBase* GetBase() const; |
GetBaseAddress | virtual void* GetBaseAddress(); |
GetClassId | virtual PtClassId& GetClassId(); |
GetInfo | virtual void GetInfo(PtString* ) const; |
GetLinkCount | PtWord GetLinkCount() const; |
GetMetaType | virtual PtMetaPersClass* GetMetaType(); |
GetObjectInfo | virtual int GetObjectInfo(PtObjectStat& ) const; |
GetRef | PtRef& GetRef(PtRef& val) const; |
GetSurr | inline const PtObjId& GetSurr() const; |
IsAssigned | inline PtBool IsAssigned() const; |
IsStored | PtBool IsStored(); |
Lock | virtual int Lock(PtLockSpec* pSpec = 0); |
Make | static PtObject* Make(PtBase*, const PtString& PtObject); |
MarkModified | virtual int MarkModified(); |
Move | virtual int Move(PtBase* otherBase, PtDepthMode Mode); |
Refresh | virtual int Refresh(); |
Remember | virtual PtWord Remember(); |
SetSurr | inline void SetSurr(PtObjId& Surr); |
Store | virtual int Store(PtDepthMode Mode = PtDEEP); |
UnAssign | virtual int UnAssign(); |
Unlock | virtual int Unlock(PtLockSpec* pSpec = 0); |
UnsetWatch | virtual int UnsetWatch(PtWatchSpec* pSpec = 0); |
UpdateSource | virtual int UpdateSource(PtDepthMode dmode = PtDEEP, PtLockMode lkmode = PtLK_DELETEvWRITE); |
Watch | virtual int Watch(PtWatchSpec* pSpec = 0); |
operator = | virtual PtObject& operator = (PtObject& ThatObject); |
- PtObject::PtObject() PtObject::PtObject(PtBase* pObjBase) PtObject::PtObject(PtBase* pObjBase, PtObjId* surr, PtPtr2SurrTuple* info)
These are all constructors for a PtObject. You will not call any of these constructors directly. PTXX derives your persistent objects from PtObject, and their constructors each call a PtObject constructor. The second and third forms of the constructor automatically assign an object to the database.
The third form of the constructor is the factory table constructor which is used to build persistent objects when they are retrieved from the database. In early versions of POET, many programmers would override this function to add their own functionality when objects are read from the database. We suggest that you override PtObject::Activate() instead - it is called after the class factory constructor has finished, which means that the object is completely constructed before it is called.
- virtual PtObject::~PtObject()
Removes the object from RAM, but does not delete it from the database. Also removes the object's surrogate from the surrogate pointer table so that POET knows that it is no longer in RAM.
- virtual void PtObject::Activate()
Activate() is called immediately after POET reads an object from the database and builds it using the class factory constructor. You can override this function to do anything that needs to be done when a particular object is first read from the database. For instance, you could use Activate() to initialize transient fields, to maintain counts of objects in RAM, or to profile the database.
It is generally better to override Activate() instead of overriding the class factory constructor; you can be sure that the entire object has been built and all the data for the object has been read, problems in Activate() are more easily debugged than problems in the class factory constructor, and its parameters are also easier to remember and spell.
- virtual int PtObject::Assign(PtBase* pObjBase)
Gives the object an identity within the database, and sets a PtBase pointer in the object to tell it which database it belongs to. This object identity is used to resolve references within the database. An object may not be stored until it is assigned.
When an object is read from the database it retains its object identity; you can store the object repeatedly and it will simply update the existing object in the database. If you want to write a new object with the same values then you should create a new object using the new operator, then copy the values from the old object. Do not try to recycle the object by calling UnAssign() to remove the object identity; this will confuse POET if there are pointer references to or in the object.
PtBase* pObjBase | Pointer to the database object |
If pObjBase is not zero and does not point to a valid PtBase, Assign() will crash. If it is zero, Assign() will fail.
0 | Success |
ERR_PT_ALREADY_ASSIGNED | You may not assign an object if it has already been assigned. Create a new object with a copy constructor. |
ERR_PT_NOT_ASSIGNED | Could not assign (the PtBase pointer was probably zero). |
- virtual void PtObject::BeginCriticalSection( PtBase* pBase = 0 ) const
nters a critical section this is local to this object. If the critical section is already in use by a different thread, the function blocks until the other thread calls EndCriticalSection().
This function can be used to serialize access if you are using the same PtObject object in different threads simultaneously and you need to call more than one function sequentially. You do not need to call this function if you are using different PtObject objects in every thread.
PtBase* pBase | Pointer to the database object |
The parameter is ignored. Call this method without a parameter (use the default).
- virtual int PtObject::CheckIn(PtDepthMode Mode = PtDEEP)
Returns an object that has been checked out to a workspace back to the original database. Workspaces are associated with a particular database and are created with the PtBase method CreateWorkspace(). Checking objects out to a workspace is described in the Programmer's Guide. See also, CheckOut().
The depthMode determines whether referenced objects are also affected. The depth mode may be any of the following:
PtNO_ONDEMAND | The object and all referenced objects that are not ondemands are checked in |
PtDEEP | The object and all referenced objects are checked in |
0 | Success |
ERR_PT_ILLEGAL_PARAMETER | Only PtDEEP or PtNO_ONDEMAND depth modes are allowed, because PtObject*'s would be foreign after moving flat or shallow. |
- virtual int PtObject::CheckOut(PtWorkspace* pws, PtDepthMode depthMode = PtDEEP, PtLockMode lockMode = PtLK_DELETEvWRITE)
Places an object in a workspace. Workspaces are associated with a particular database and are created with the PtBase method CreateWorkspace(). Checked out objects are returned to the original database with CheckIn(). Checking objects out to a workspace is described in the Programmer's Guide.
The first parameter, pws, is a pointer to the desired workspace. Workspaces are created using the PtBase method CreateWorkspace(). A complete description of workspaces and checking objects out and in is given in the Programmer' Guide.
The depthMode determines whether referenced objects are also affected. The depth mode may be any of the following:
PtNO_ONDEMAND | The object and all referenced objects that are not ondemands are checked out |
PtDEEP | The object and all referenced objects are checked out |
The lock mode parameter tells POET how to lock the copies of the objects that remain in the original database. This is a persistent lock. It remains in effect even after the application that called CheckOut terminates.
0 | Success |
ERR_PT_NOT_ASSIGNED | The object must be assigned to a database. |
ERR_PT_ILLEGAL_PARAMETER | Only PtDEEP or PtNO_ONDEMAND depth modes are allowed, because PtObject*'s would be foreign after moving flat or shallow. This error is also returned if the workspace is the same as the object's current database. |
- virtual int PtObject::Delete(PtDepthMode Mode = PtSHALLOW)
Deletes the object from the database.
Depth modes determine whether referenced objects are also affected. The depth mode may be any of the following:
PtFLAT | Only the object itself is deleted |
PtSHALLOW | The object and its dependent objects are deleted |
PtNO_ONDEMAND | The object and all referenced objects that are not ondemands are deleted |
PtDEEP | The object and all referenced objects are deleted |
If the Delete() involves other objects, they may not reside in foreign databases. An attempt to Delete() across databases will fail. Delete() is an all-or-nothing operation. It uses internal transactions to ensure that everything can be undone if it does not succeed. Delete does not remove the object from RAM. Use PtObject:: Forget() or the object's destructor to remove it from RAM (see "Advanced Programming Issues" for details). The object is still assigned.
0 | Success |
ERR_PT_FOREIGN_REFERENCE | The Delete() includes objects from foreign databases. |
ERR_PT_NOT_ASSIGNED | The object has not been assigned to a database. |
- virtual void PtObjectSet::EndCriticalSection(PtBase* pBase = 0) const
leaves a critical section that is local to this object. After this call, other threads are able to begin a critical section for this object. See BeginCriticalSection().
PtBase* pBase | Pointer to the database object |
The parameter is ignored. Call this method without a parameter (use the default).
- virtual PtWord PtObject::Forget()
Decrements the object's link count and removes it from memory if the resulting link count is zero. The link count, described in the chapter "Persistent objects" in your Programmer's Guide, is used to maintain the number of references to an object. POET uses this to make sure that an object is not removed from memory if there are still pointers to it in RAM. If you are absolutely certain that existing pointers will not be used you can also remove the object using the C++ delete operator which POET handles correctly.
Returns the resulting link count.
- virtual int PtObject::ForgetCycle(PtDepthMode DepthMode)
ForgetCycle() is a method of PtObject, so it is inherited by all persistent objects. Like the Forget() method, ForgetCycle() decrements the link count of the object that calls it. Also, depending on the depth mode argument, ForgetCycle() can handle the link counts of some or all of an object's referenced objects.
The PtDepthMode parameter is an enumerated value and is one of: PtFLAT, PtSHALLOW, PtNO_ONDEMAND, or PtDEEP. (These are the same depth mode values that are used by the Store() method.) The following table describes the behavior for each of these depth mode values:
PtFLAT | The Forget() is applied to the object itself. |
PtSHALLOW | This is not allowed. It returns the error ERR_PT_ILLEGAL_PARAMETER, and does not change any link counts. |
PtNO_ONDEMAND | The Forget() is applied to the object and all referenced objects that are not ondemands. |
PtDEEP | The Forget() is applied to the object and all referenced objects. |
The return value of ForgetCycle() if positive (>= 0), is the resulting link-count for the object for which ForgetCycle() is called. Negative return values indicate an error. Possible error returns are:
ERR_PT_LINKCOUNT_TO_LOW -2096 | This error occurs if ForgetCycle encounters an object that has a link count less than the number of its references in the object-network. |
- virtual void* PtObject::GetAddressPoint(PtClassId& classid) const
This method can be used to perform a safe cast to an object's base class. The parameter is the class id of the base class. The return is a void pointer. You will need to cast this to the appropriate class type. If the object does not have a base class of the type specified by classid, this method returns NULL.
- inline PtBase* PtObject::GetBase() const
If the object is assigned to a database, returns a pointer to the PtBase to which it is assigned. Otherwise, returns 0.
- virtual void* PtObject::GetBaseAddress()
Returns a void pointer to the object.
When you program with generic objects, you may be using objects which are not real C++ objects, which is why the generic object interface works with void pointers. GetBaseAddress() allows you to use this void pointer interface safely with persistent objects.
- virtual PtClassId& PtObject::GetClassId()
Returns the class Id for the most specialized class to which the object belongs.
- virtual void PtObject::GetInfo(PtString* ) const
You can override this function to create a string containing the derived type of your object. The default implementation simply formats the object identity and disk location as a string.
- PtWord PtObject::GetLinkCount() const
Returns the link count for the object.
unsigned int The current link count for the object
- #ifdef PRINT_LINK_COUNTS
- cerr << "Current link count is: " << pObject->GetLinkCount() << endl;
- #endif
- virtual PtMetaPersClass* PtObject::GetMetaType()
Returns a pointer to the PtMetaPersClass which acts as the class description for the object. MetaTypes are used when you are working with the class dictionary.
- virtual int PtObject::GetObjectInfo(PtObjectStat& ) const
This function fills the PtObjectState with information on the requested object. The type of information depends on the full type of the PtObjectState. For instance, if you specify a PtObjStateMaxLock, you will receive information on the maximum lock for this object. PtObjStateLockList reports all locks. PtObjStateWatchList reports all active watches for each watched object, and pos iterates through only the watched objects. If you specify a PtObjStateObjectInfo, you will receive all available status information on the object.
- PtRef& PtObject::GetRef(PtRef& val) const
Returns the PtRef for the object. The PtRef contains the surrogate, the class Id, and the database Id for the object. Most applications will not use this function. See the class description for PtRef for details.
- inline const PtObjId& PtObject::GetSurr() const
Returns the Surrogate, which is the object identity for the object. Some applications may use this to display the object identity. See the class description for PtObjId for details.
- inline PtBool PtObject::IsAssigned() const
Returns zero if the object has not yet been assigned to a database and a non-zero value if it has.
- PtBool PtObject::IsStored()
Returns zero if the object has not yet been stored and a non-zero value if it has ever been stored in a database.
Note: if the object has been stored in a transaction and the transaction has not yet been committed to the database, IsStored() will return 0.
- virtual int PtObject::Lock(PtLockSpec* pSpec = 0)
Sets a lock on the object. If no lock specification is given then the default lock is used.
Locks and default locks are described in the chapter "Locking." If the object you are locking contains ondemand references to objects in a foreign database, Lock() can not set a lock using the foreign reference. Instead, you should lock the foreign objects separately. Lock() is an all-or-nothing operation. If the lock fails, everything is undone.
ERR_PT_FOREIGN_REFERENCE | The lock includes objects from foreign databases. |
ERR_PT_NO_DEFAULT | pSpec is 0, but there is no default lock |
ERR_PT_OBJECT_LOCKED | The object has already been locked by an other client |
ERR_PT_FOREIGN_REFERENCE | The lock would involve locking objects in a foreign database. |
- static PtObject* PtObject::Make(PtBase* pObjBase, const PtString& PtObject)
Creates a new object using the given class name. If you are working with generic objects, you may need to create an object without access to its constructor, which is why you would use Make(). Make() is a static function, so you do not need to create a PtObject to call this function.
- PtObject* p = PtObject::Make(base, "Person");
- virtual int PtObject::MarkModified()
The MarkModified method is used to set the object's dirty flag. This is used in the batch transaction model. Batch transactions are described in the Programmer's Guide and are also used in POET's ODMG implementation.
0 | Success |
ERR_PT_NOT_ASSIGNED | The marked object must be assigned to a database. |
- virtual int PtObject::Move(PtBase* otherBase, PtDepthMode Mode)
Moves an object to a different database.
Ondemand references to the object remain valid even after the object is moved. When an object is moved out of a database POET leaves a proxy object behind which allows ondemand references to find the object in the new database. Since pointer references may not span databases, pointer references to the moved object can no longer be resolved. In the local database, the object is removed from all AllSets and indexes that reference it (except for the PtObjectAllSet, which POET uses internally and is not accessible to the applications programmer).
PtObject:: Move( ) is an all-or-nothing operation. It uses internal transactions to ensure that everything is written to disk. If PtObject:: Move() fails, no objects have been moved.
Proxy objects are not intended to be used to check objects in and out of the database. There is no way to replace the proxy object with the original object if you move the object back into the local database.
- virtual int PtObject::Refresh()
Rereads the object from the database, replacing the object in memory. If the object contains pointers or references to other objects then the object in memory may have different references than the object on disk. If Refresh() removes a reference from the object then a Forget() is performed on the referenced object, if a reference is added to the object then a Remember() is performed on the referenced object. If the object has been stored in a transaction then the object is read from the transaction buffer instead of the database. This makes Refresh() very convenient when you want to restore the previous state of an object after aborting a transaction: first call TransactionAbort(), then call PtObject:: Refresh() to obtain the last version of the object that has been stored. Refresh() is also very useful when you want concurrency control without setting superfluous locks. To change an object safely, lock it first, then call Refresh(), rewrite the object, and unlock it. Note, however, that this does not work if you are in a transaction and the Refresh() reads the object from the transaction buffer instead of the database.
Refresh() has no effect on the watches or locks associated with an object. Refresh() will fail if the object does not exist in the database.
0 | Success |
ERR_PT_NOT_ASSIGNED | The object has not been assigned. |
ERR_PT_ALREADY_DELETED | The object has not been stored, or it has been deleted. |
- virtual PtWord PtObject::Remember();
Increments the object's link counter. See the chapter "Persistent objects" in your Programmer's Guide for details.
Returns the resulting link count.
- inline void PtObject::SetSurr(PtObjId& Surr)
SetSurr() sets the object identity for an object. In general, this is a dangerous thing to do, so we suggest that you avoid using this function.
- virtual int PtObject::Store(PtDepthMode Mode = PtDEEP)
Stores the object in the database.
If the object has already been stored in the database, Store() updates the object. If you want a new object with the same values, create a new object and use a copy constructor or assignment operator to copy the values from the original object.
Store() updates all indexes that are maintained for the object. Depth modes determine whether referenced objects are also stored. By referenced objects, we mean objects to which this object has pointers or ondemand references, or objects referenced in sets. The depth mode may be any of the following:
PtFLAT | Only the object itself is stored |
PtSHALLOW | The object and its dependent objects are stored |
PtNO_ONDEMAND | The object and all referenced objects that are not ondemands are stored |
PtDEEP | The object and all referenced objects are stored |
When Store() stores a referenced object, the same depth mode used to store this object is applied to the referenced object. Any referenced objects which are stored are assigned to the database if they do not yet have an object identity. If the object has an ondemand or an ondemand set which references an object which has an identity in a different database, each object will be stored in the database to which it belongs. If the object has a pointer reference to an object with an identity in a different database, Store() will fail.
Store() is an all-or-nothing operation. It uses internal transactions to ensure that everything can be undone if the Store() does not succeed. An error return usually means either that the object has not been assigned to a database. If you have forgotten to initialize pointers in the object your program may die when POET tries to access other objects that aren't there.
0 | Success |
ERR_PT_NOT_ASSIGNED | The object has not been assigned. |
ERR_PT_ACCESS_DENIED | Somebody has locked an object that you are trying to store. The entire Store() has failed. |
ERR_PT_OBJECT_LOCKED | You are trying to access an object or a class which is locked by another user. The entire Store() has failed. |
ERR_PT_DUPLICATE_KEY | You have declared a unique index, and adding this object would result in a duplicate value for the unique index. The Store() has failed, and the indexes are unchanged. |
ERR_PT_DISK_FULL | Your hard disk is full. The entire Store() has failed. |
- virtual int PtObject::UnAssign()
Removes an object's object identity. If you have stored an object and want to store another object with the same or similar values then you can unassign it and assign it again to give it a new identity. Since it now has a new identity a new object will be written in the database when the object is stored.
A non-zero return value indicates an error.
- virtual int PtObject::Unlock(PtLockSpec* pSpec = 0)
Removes a lock which has been set on the object. If no lock specification is given then the default lock is used.
Locks and default locks are described in the chapter "Locking."
0 | Success |
ERR_PT_NOT_ASSIGNED | The object has not been assigned |
ERR_PT_NO_DEFAULT | pSpec is 0, but no default lock is set |
ERR_PT_NOT_LOCKED | The object is not locked, or it has been deleted, or the lock mode does not match any lock which has been placed on the object. |
ERR_PT_FOREIGN_REFERENCE | The Unlock() would involve objects in other databases |
- virtual int PtObject::UnsetWatch(PtWatchSpec* pSpec = 0)
Removes a watch that has been set on the object. If no watch specification is given then the default watch is used.
Watches are discussed in the chapter "Event handling" in your Programmer's Guide.
0 | Success |
ERR_PT_NOT_ASSIGNED | The object has not been assigned |
ERR_PT_NO_DEFAULT | pSpec is 0, but no default watch is set |
ERR_PT_NOT_WATCHED | The object is not watched, or it has been deleted, or the watch mode does not match any watch which has been placed on the object. |
ERR_PT_FOREIGN_REFERENCE | The UnsetWatch() would involve objects in foreign databases |
- int PtObjectSet::UpdateSource(PtDepthMode dmode = PtDEEP, PtLockMode lkmode = PtLK_DELETEvWRITE)
Partially check-in the object. The checked out object is left in the workspace. The object in the original database will re-locked with 'lkmode'. PPPa
PtDepthMode dmode=PtDEEP | which subobjects belongs to this operation |
PtLockMode lkmode=PtLK_DELETEvWRITE | how the objects in the original base should be locked |
- virtual int PtObject::Watch(PtWatchSpec* pSpec = 0)
Sets a watch on the object. If no watch is given then the default watch is used.
Watches are discussed in the chapter "Event handling" in your Programmer's Guide.
ERR_PT_FOREIGN_REFERENCE | The watch includes objects from foreign databases. |
ERR_PT_NO_DEFAULT | pSpec is 0, but there is no default watch. |
ERR_PT_FOREIGN_REFERENCE | The watch would involve objects in a foreign database. |
- virtual PtObject& PtObject::operator = (PtObject& ThatObject);
Assignment operator for PtObject. Does not copy the object identity, which ensures that the object identity is never duplicated in RAM.
Copyright (c) 1996 POET Software, Inc. All rights reserved. Reproduction in whole or in part in any form or medium without the express permission of POET Software, Inc. is prohibited.