[line 202]
Basic function library for Bs_OoDb.class.php OoDb is the abriviation for "Object Oriented Database" For details on how to use ooDb see Bs_OoDb.class.php (or Bs_OoDbForMySql.class.php) The folling text will discribe details and concepts of the implementation.
I decided to explain this class unsing a FAQ list. FAQ: 0) INTRO
- a) How are the objetcts stored?
- b) What is a strong and weak reference?
- c) What does soft-Delete mean?
1) SCOPE
- a) What is a Scope?
- b) Where is the scope stored?
- c) Scope priority?
2) STORAGE TABLE CREATION/MODIFICATION 2 a) Are the storage-tables created automaticaly? 2 b) What happens if I add new field To the object?
3) PERSISTING (STORING) 3 a) If the object hasn't changed since the last fetch, does OoDb still write it to the storage? 3 b) Are the sub-objects ('has a'-relations) of an object also saved? 3 c) Are array of objects also supported? 3 d) Are values with NULL supported? 3 e) What happens, if objects happen to have the value NULL or are unSet? 3 f) What happens if I move a object from one 'Array of Objects' to an other 'Array of Objects'? 3 g) How are cyclic referencing objects handled?
4) UNPERSISTING (FETCHING) 4 b) What happens when I fetch the same object a few times? Do I get a copy?
0) INTRO
- a) How are the objects stored?
--------------------------------- Wrong question for this class, as it should not have any methods to store the data. It only has methods to help the underlying storage. (But we can assume that it's a table based relational Db). See Bs_OoDbForMySql.class.php and/or study the ABSTRACT functions part of Bs_OoDb.class.php
- b) What is a strong and weak reference?
--------------------------------------- During the work with objects that use other objects in a 'has a'-relation ooDb keeps track of 'Who's Using Who'. If an object has *no strong references*, ooDb will remove it from the storage. Well, when is a reverence strong and when weak? By default a reference to an other object is 'strong' unless: a) It's defined in the $_ooDbProperty['reference']='weak'. b) References to other scopes (Db's) are always 'weak'. And what is the use? SAMPLE: (Objects are braced with []) A [Firm] holding a *strong* reference to the 'Array of [Employee]' A [Telephone book] holding an *weak* reference to the 'Array of [Employee]' If the [Firm] fires an [Employee], the [Employee] would never be removed, because of the entry in the [Telephone book]. But because this reference is *weak* ooDb will removed a fired [Employee] anyway. NOTE: Always expect that a *weak* reference may be NULL on unpersist.
- c) What does soft-Delete mean?
-------------------------------- Read 0 b). Soft delete will remove object data that has *no strong references*, to it.
1) SCOPE
- a) What is a scope?
---------------------
- The scope is the area to store the data. As the underlying storage function
may use different techniques to store an object it's our believe, that all these
methods will use a 'scope' to identify the storage area.
For a SQL-dbs this would be the <dbName> and for a file-dbs this could be the directory.
- It's also used to build target- and source- keys of the object.
- It's also used for the $_persistTag of the pObjToPersist.
- b) Where is the scope stored?
-------------------------------- The scope-information is stored in 2 ways: a) By setting the default scope. That is the scope-info stored in this object (in $pDefaultScope). It is set as a mandatory parameter in persist() / unpersist() / delete() b) By setting the 'strong'-scope of the object. That is a scope attached to the object (in $this->pObjToPersist->_ooDbScope). See function setHardScope().
- c) Scope priority?
-------------------- 1: The 'strong'-scope of the $pObjToPersist is used. (If not empty) 2: The default-scope of this object is used. (If not empty) 3: If no scope is given, the data will be stored at the 'current' location. That is where the underlying storage handler currently is 'standing'.
2) STORAGE TABLE CREATION/MODIFICATION 2 a) Are the storage-tables created automatically? ------------------------------------------------- By default *NO*. There is a variable $pStorageAutoCreate that may be set to TRUE. The underlying storage will the create/modify the tables it needs *BUT* it's a performance killer! Turn it on during develop and the turn it back off. Better to used my tool Bs_OoDbAble.class.php
2 b) What happens if I add new field to the object? ---------------------------------------------------- This depends on the underlying storagehandler. In Bs_OoDbForMySql.class.php will add (but not delete) missing fields if $pStorageAutoCreate==TRUE. It will even try to change the fieldType if it changes. Better to used my tool Bs_OoDbAble.class.php
3) PERSISTING (STORING) 3 a) If the object hasn't changed since the last fetch, does OoDb still write it to the storage? --------------------------------------------------------------------------------------------- NO! To detect if the object has changed I'm using a md5-fingerpring. *BUT* to prepare and calculate the fingerprint I have to gather the data of the object, sort it, serialize it and finally md5 it. This cost CPU and in some cases where the object is complex I'm not sure if it's worth the effort. If for some reason you wish to force a save for the lonely-data of an object, you may call the function forceSave(&$object, $force=TRUE). But this shouldn't necessary.
3 b) Are the sub-objects ('has a'-relations) of an object also saved? --------------------------------------------------------------------- YES, *but* only the objects/object-arrays are saved that are marked as $_ooDbProperty['mode']='object' in the _ooDbProperty variable. The sub-object may then have an _ooDbProperty variable too. a.s.o.
3 c) Are array of objects also supported? ----------------------------------------- YES. If a variable is marked as object (see 3 b). ooDb will detect an array (hash or vector) and assume it's an 'Array of Object'. Or even an 'Array-tree of Objects' (array of array). NOTE: There are some limitation on how deep the tree may be and what happens if the array has cycling references. (See function _flattenObjArray).
3 d) Are values with NULL supported? ------------------------------------ NO! There are a few reasons *not* to support NULL values. 1) You don't really need it. It's 99.999% passable to find a substitute for NULL like -1 or -(2^16) or '' or 'NULL' ... 2) Can't have index on fields with NULL values. 3) Complicated (unperforming) to detect a NULL when unpersisting 4) Queries get very complicated.
3 e) What happens, if objects happen to have the value NULL or are unSet? ------------------------------------------------------------------------- It is ignored during the persist phase.
3 f) What happens if I move a object from one 'Array of Objects' to an other 'Array of Objects'? ------------------------------------------------------------------------------------------------ Quite often you will have a 'main'-object that handles many other objects; shuffling them around from on 'Array of Objects' to an other 'Array of Objects'. When you persist the 'main'-object now, the references are updated. Any objects that not referenced any more by the 'main'-object are soft-Deleted (See: 0 c) What does soft-Delete mean?). New objects or objects that have changed are stored/updated. (Assuming these objects are marked for persistence in the _ooDbProperty variable).
3 g) How are cyclic referencing objects handled? ------------------------------------------------- Cyclic referencing objects (direct or indirect) Sample for direct cycle: An object [A] containing an object [B] and [B] is pointing back to [A] The problem is that this could end in an endless loop. For this reason ooDb keeps track of which objects have been saved, by marking the saved object. The same object is only saved once.
4) UNPERSISTING (FETCHING) 4 b) What happens when I fetch the same object a few times? Do I get a copy? ---------------------------------------------------------------------------- During a unpersist *call* all fetched objects are cached. If the *same* object (*same* means: objectName, ID AND scope match) is fetched a second time the object will be taken from cash *by reference*. When the call has ended the cache is emptied. It's important to note that a second unpersist *call* would not know about the already fetched objects. So the answer is: A call to unpersist will not create multiple copies of the *same* object. Multiple calls to unpersist will.
Most data is hold by pointer, so changes to the data effect immediately *BUT* streamed data is an exception. Streams have to be prepared on every call. That's way caching is default FALSE;
Similar effect with the tag info, that depending on the current scope. The ID data must be set to the right tag-info.
Tags: