Class: Bs_SimpleObjPersister
Source Location: /core/storage/objectpersister/Bs_SimpleObjPersister.class.php
Bs_Object
|
--Bs_SimpleObjPersister
Bs_SimpleObjPersister.class.php is able to store and load an Object to a DB.
Author(s):
Version:
- 4.3.$Revision: 1.10 $ $Date: 2003/10/30 14:34:23 $
Copyright:
|
|
Inherited Variables
|
Inherited Methods
|
Class Details
[line 248]
Bs_SimpleObjPersister.class.php is able to store and load an Object to a DB. This class will do *most* off the work like creating the table and updating the tablesturcture. Storing, Loading and Deleting an Object. FEATURES: - Creates the table in the Db on the fly (if table is missing) and creates the corresponding table columns
for the class attributes that will be stored (=persisted).
- During development, you can upgrade an attribute to an other type
E.g. string(20) to string(40) / integer to blob a.s.o. (For security reasons downgrading must be done manually)
- Support for unique key names (string is generated by PHP's uniqid().)
- During development, you can add new class-attributes and the table columns are added *automatically* to the table.
(For security reasons no columns are deleted. Unneeded created columns must be deleted manually)
- Callback method to the persisted object before and after each load/store/delete.
Callback methods are methods to the persisted object that are called before and after a store or load of the object.
It's possible to handle relational things this way.
- Strong type-checking. (Can be turned off to save the CPU overhead but is on per default).
- Plugable crypting function. (With integrated default crypter).
- Support of index
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- NOTE: - You cannot use this class by itself. You must set a DB-Object as interface to 'talk' to the unterlying DB.
(See sample at the bottom of this code.)
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- CALLBACK METHODS: Callback methods are methods to the persisted object that are called before and after a store or load of the object. In this way the object is 'informed' of the current persisting state. For the callback to work, you must have one of the following methods defined in your class that will be called. (Will be ignored if omitted). If you return FALSE with bs_sop_preStore() or bs_sop_preDel() then the store/deletion will not be executed. This can be handy some times. STORE (before and after): - bs_sop_preStore($sopAgent, $varsToStore) // $varsToStore is an array of all class var names that are to be stored. no values.
- bs_sop_postStore($sopAgent, $status, $varsToStore) // $status of the DB query: success == TRUE otherwise FALSE
- bs_sop_getId($sopAgent) // Only used if primary type == 'callback'. In this case it's in the objects responsabillity to deliver the ID.
LOAD (before and after): - bs_sop_preLoad($sopAgent, $varsToLoad) // $varsToLoad is an array of all class vars names that are to be loaded.
- bs_sop_postLoad($sopAgent, $status) // $status of the DB query: success == TRUE otherwise FALSE
DELETE (before and after): - bs_sop_preDelete($sopAgent) // primary var must be set to know which record to delete.
- bs_sop_postDelete($sopAgent, $status) // $status of the DB query: success == TRUE otherwise FALSE
REGISTER - bs_sop_getHints($sopAgent) // Expects a hint-hash. Is used if you do not pass a hint-hash when you call register (See register())
NOTE for the advanced User: All callback functions have the $sopAgent (==$this)as last parameter. $sopAgent is the instance of this class. You may use the $sopAgent in 2 ways: A) store/load/delete an other object. B) Get the used dbObject by calling $sopAgent->getDbObject() and then using the dbObject to manibulate the DB directly. In either case the called object has the possabillity to do it's own DB-manipultions, without having to instanciate and init it's own DB-connection-object as interface. -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- REGISTER A CLASS: To store an object it is possable to register the class once before use, using the: Bs_SimpleObjPersister->register($objectName, $hitHash) USAGE: - (optional) You register a class at least once *before* you load or save an object.
MySimpleObjPersister->register($MyObject); // You may also pass the classname as string
- You may (but not recommended) set the hint-hash for the registered Object. But we strongly suggest
to define a callback methode bs_sop_getHints() in your object that returns the hint-hash.
See below for hint-hash-structure.
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
HINT STRUCTURE: (See sample at the bottom of this code.)
The hint-hash is holding the main info of the class vars that are to be loaded/stored.
Sample:
$hint_hash = array (
'table' => array ('name'=>'myDbTableName', 'create'=>TRUE,
),
'debug' => array ('checkHintSyntax'=>TRUE, 'checkClassVars'=>TRUE,
),
'props' => array ('ignoreData'=>FALSE,
),
(*) 'primary' => array ('uniqueKey' => array('name'=>'id', 'type'=>'uniqueStr13'),
),
(*) 'fields' => array ('myInt' => array('name'=>'aInt', 'metaType'=>'integer', 'index'=>TRUE),
'myString' => array('name'=>'aString', 'metaType'=>'string', 'size'=>500, 'fulltext'=>TRUE),
), );
*) Mandatory \____ ___/ \____ ___/ \__________ ____________________________________________________________/
V V V
Main Hint Parts Object Var Names Object Var Attributes used to create the right column types + some extra stuff.
The main parts are 'debug', 'table', 'primary' and 'fields' their attributes are:
'debug': (optional)
===================
KEY | VALUES | MEANING
=================+=======================+==============================================================================
checkHintSyntax | { TRUE | FALSE } | Default=TRUE - Check the given hint-hash for syntax error.
| [optional] | When your certain that systax is OK, you may turn this feature off; saving CPU.
| | See $this->hintsSyntaxCheck()
-----------------+-----------------------+------------------------------------------------------------------------------
checkClassVars | { TRUE | FALSE } | Default=TRUE - Check the given hint-hash against the given class.
| [optional] | When your certain that types are OK, you may turn this feature off; saving CPU.
| | See $this->classVarCheck()
-----------------+-----------------------+------------------------------------------------------------------------------
'table': (optional)
===================
KEY | VALUES | MEANING
============+=======================+==============================================================================
name | (string) | Default is classname - You may set the table name to use in the DB.
| [optional] |
------------+-----------------------+------------------------------------------------------------------------------
create | { TRUE | FALSE } | Default=TRUE - Allow this handler to create missing table AND/OR missing fields
| [optional] | AND/OR to upgraded field-types (e.g. from string(22) to string(42) ).
------------+-----------------------+------------------------------------------------------------------------------
'props': (optional)
===================
KEY | VALUES | MEANING
============+=======================+==============================================================================
ignoreData | { TRUE | FALSE } | Default=FALSE - (For the advanced user :) If TRUE, handle the object if it had
| [optional] | *no* fields BUT trigger the callback-methods. No attemt will be made to store,
| | load or delete any data and no table is generated for a object with this
| | attribute on. Has the same effect as when 'primary' and 'fields' where empty.
| | You may not see the use of this option until you do some relational stuff
| | - but it's very very hand then.
'primary': (mandatory)
======================
KEY | VALUES | MEANING
============+=======================+==============================================================================
name | (string) | Name of the field that will be used in the DB.
| | NOTE: Then names are case insensitive.
| | No spaces or special chars allowed.
| | There a set of reserved words. (1*)
| | (1*)Will be checked if 'checkHintSyntax' is ON (default); See 'debug' above
------------+-----------------------+------------------------------------------------------------------------------
type | auto_increment | - Use the DB-auto increment feature. Var must be of type integer.
| uniqueStr13 | - Generates a 13 char unique ID string uses PHP's uniqid(); See PHP-doc.
| uniqueStr23 | - Generates a 23 char unique ID string with additional "combined LCG" entropy.
| | (sinc PHP 4.0, 16-Nov-99) NOTE: Is faster then uniqueStr13!
| manual | - In this case the Object *must* have an unique ID set and you must use the method
| | insert() when adding *new* Objects (and store() when updating stored Objects)
| callback | - In this case the callback method bs_sop_getId() is called if ID is missing.
| | Expecting a string < 255 char. See "CALLBACK METHODS" above.
| |
| | How unique is uniqid()?
| | Statement of Rasmus Lerdorf (=one of the PHP gurus) on the 30-July-98:
| | "Unless you have some sort of massively fast multiprocessor machine I don't
| | think it can fail. In fact, even with such a massive box, I doubt it will."
| | NOTE: This statement was made *before* the PHP extended the uniqid() with
| | additional "combined LCG" entropy.
------------+-----------------------+------------------------------------------------------------------------------
prefix | (string) | If you use a auto generating string-type ID like uniqueStr13 or uniqueStr23
| | but not 'callback' (see type above) you can define a string as prefix.
------------+-----------------------+------------------------------------------------------------------------------
'fields': (mandatory)
=====================
KEY | VALUES | MEANING
============+=======================+==============================================================================
name | (string) | Name of the field that will be used in the DB.
| | NOTE: Then names are case insensitive.
| | No spaces or especial chars allowed.
| | There a set of reserved words. (1*)
| | (1*)Will be checked if 'checkHintSyntax' is ON (default); See option below
------------+-----------------------+------------------------------------------------------------------------------
metaType | boolean | - NOTE: Only use this type for 'real' booleans types (no ints or so).
| | Reason is: on load the value will be converted to ===TRUE or ===FALSE
| integer | - An signed integer.
| double | - Use all real / floating point numbers.
| string | - Any string that is shorter then 255 char! (1*)
| text | - For any string; case *Case-INsensitive*! (1*) (2*)
| blob | - For any string or bin-data; case *Case-Sensitive* (1*) (2*)
| serialize | - Same as blob but var is serialized before store and unserialized after load. (1*)
| | For conviniece.
| | (1*)Requires that you set the 'size'-key (see next key).
| | (2*)A TEXT is a *case-insensitive* BLOB.
------------+-----------------------+------------------------------------------------------------------------------
size | (integer) | Max size that you may want to use for the DB-field. Required only for:
| | { string | text | blob | serialize }
| | NOTE: This info is used for syntax checking and to use the optimal DB-field-type
| | in the DB. E.g. MySQL differs between BLOB(65k), MEDIUMBLOB(16M), LARGEBLOB(4G)
| | example for up to 65k: use the number 65565.
------------+-----------------------+------------------------------------------------------------------------------
index | { TRUE | FALSE } | Sets an index for this field. default=FALSE
| [optional] | NOTE: Depending on the DB(or DB-configuration) indexes on things like
| | BLOBs are limited or not possible. If index is TRUE we will try to set
| | the index.
------------+-----------------------+------------------------------------------------------------------------------
fulltext | { TRUE | FALSE } | MySQL special index-type to enable fulltext search in DB. default=FALSE
| [optional] |
------------+-----------------------+------------------------------------------------------------------------------
crypt | { TRUE | FALSE } | Defines if the var is to be decryptified on store and encryptified on load. default=FALSE
| [optional] | The en-/de-key is set in the option-hash (See below)
------------+-----------------------+------------------------------------------------------------------------------
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
FAQ:
Q) What is the difference between Bs_ObjPersister.class.php and Bs_SimpleObjPersister.class.php?
A) The short answer is: They do (more or less) the same thing. The main difference is that Bs_SimpleObjPersister
(that was written latter) is easier in use. Some features have been thrown out while other have come in.
It's recommended to use the Bs_SimpleObjPersister.
| Bs_ObjPersister.class.php | Bs_SimpleObjPersister.class.php
----------------+-------------------------------------------+---------------------------------------------------
Usage | Is an interface. Must use specialized | Is a normal Class. The DB-connection is pluged in
Classes like Bs_ObjPersisterForMySql with setDbObject().
One Bs_ObjPersister per object(!) One central Bs_SimpleObjPersister per DB in system.
Object is passed when crating the Class must be registered once.
Bs_ObjPersister
----------------+-------------------------------------------+---------------------------------------------------
Checking | Not strict, autodetection fuctions. | Very strict
Must add prfixes to table- and field-names Name-checks are made and force a warning msg on
to avoid conflict conflict. No need for prefixes in table- and field-names
----------------+-------------------------------------------+---------------------------------------------------
Performance | All checks can be turned of. Not slower.
----------------+-------------------------------------------+---------------------------------------------------
Primary Key Must be called ID is INT Primary can have any name. INT or STRING
Support for unique key names
----------------+-------------------------------------------+---------------------------------------------------
Crypt Has a only one cryper Plugable crypter, with one as default.
----------------+-------------------------------------------+---------------------------------------------------
Tags:
Class Methods
constructor Bs_SimpleObjPersister [line 296]
Bs_SimpleObjPersister Bs_SimpleObjPersister(
)
|
|
Constructor
method classVarCheck [line 1483]
(bool) classVarCheck(
mixed
$classname, mixed
$theHints)
|
|
Matches the class and the hint-hash for inconsistences
Tags:
method delete [line 1110]
(bool) delete(
&$theObject
&$theObject)
|
|
Delete an Object from the DB. NOTE: The object's primary key *must* be set.
Tags:
Parameters:
method getDbObject [line 359]
Get the db Interface. (An instance of Bs_Db) Used when the callback object needs the current used Db-Interface to do some direct DB modifictions (or queries)
Tags:
method hintsSyntaxCheck [line 1386]
(bool) hintsSyntaxCheck(
$theHints
$theHints, [$classname
$classname = 'UNKOWN CLASS'])
|
|
Will check the hint-hash for syntax errors ? == optional +#<nr> == mandetory only if #<nr> is set. array( 'table?' => array ('name?' => "{(string)}", 'create?' => "{TRUE|FLASE}", ), 'debug?' => array ( 'checkHintSyntax?' => "{TRUE|FLASE}", 'checkClassVars?' => "{TRUE|FLASE}", ), 'primary' => array ( '(string)' => array( 'name'=>"(string)", 'type'=>"{'auto_increment'|'unique13'|'unique23'}", 'prefix?'=>"{(string)|}" ), 'fields' => array ( '(string)' => array( 'name' => "(string)", 'metaType' => "{'boolean'|'integer'|'double'|'string#1'|'blob#1'|'text#1'|'serialize#1')", 'size+#1' => "(int)", 'index?' => {TRUE|FLASE}, 'fulltext?' => {TRUE|FLASE}, 'crypt?' => {TRUE|FLASE}, ), );
Tags:
Parameters:
method insert [line 874]
void insert(
&$theObject
&$theObject, [$varsToLoadList
$varsToStore = NULL])
|
|
Inserts a *new* Object into the DB. It *must* have an unique ID already set. Uses store() with $forceInsertWithCurrentID=TRUE
Tags:
Parameters:
method load [line 515]
bool load(
object
&$theObject, [mixed
$varsToLoad = NULL], array
$varsToLoadList)
|
|
Load the Object from the DB. With the 2nd param it's possible to control which vars are to be loaded by passing a list of obj-var names. Very handy when not all data is needed. NOTE: The object's primary key *must* be set for this method.
Tags:
Parameters:
method loadAll [line 701]
(hash) loadAll(
$classname
$classname, [$varsToLoadList
$varsToLoad = NULL])
|
|
Load all objects of the passed classname.
Tags:
Parameters:
method loadById [line 606]
(object) &loadById(
$classname
$classname, $id
$id, [$varsToLoadList
$varsToLoad = NULL])
|
|
Load single Objects from the DB using an ID.
Tags:
Parameters:
method loadByIds [line 561]
(hash) loadByIds(
$classname
$classname, $ids
$ids, [$varsToLoadList
$varsToLoad = NULL])
|
|
Load multiple Objects from the DB using an ID-list. - The primary-field is match against the ID-list and on match an object is instanceiated, loaded and
filled into hash (with ID as key).
- With the 2ed param it's possible to control which vars are to be loaded by passing a list of obj-var names.
Very handy when not all data is needed.
Tags:
Parameters:
method loadByWhere [line 673]
(hash) loadByWhere(
$classname
$classname, $whereClause
$whereClause, [$varsToLoadList
$varsToLoad = NULL])
|
|
Load multiple Objects from the DB using a SQL WHERE-clause. - The matched data will cause an object to be instanceiated, loaded and filled into hash (with ID as key).
- With the 2ed param it's possible to control which vars are to be loaded by passing a list of obj-var names.
Very handy when not all data is needed.
NOTE 1: $whereClause is appended to the SQL statement that is used to extract the data. The main idea is to use an 'WHERE'-expresion; but can also be an other SQL-expresion that the SQL systax allows: Samples: $whereClause = 'LIMIT 3' $whereClause = 'WHERE aInt < 10 LIMIT 3' NOTE 2: Potential varName-fieldName confusion: When setting the $whereClause you must keep in minde to use the *DB-fieldName*, while the $varsToLoad may only contain the *object-varName*. These 2 name-spaces can (but don't have to) differe, have a look at the hint-hash that is used when the class is registerd.
Tags:
Parameters:
method loadMeByWhere [line 630]
(bool) loadMeByWhere(
&$theObject
&$theObject, $varsToLoadList
$whereClause, [mixed
$varsToLoad = NULL])
|
|
Load first found Object from the DB using a WHERE clause With the 2ed param it's possible to control which vars are to be loaded by passing a list of obj-var names. Very handy when not all data is needed. NOTE 1: $whereClause is appended to the SQL statement that is used to extract the data. The main idea is to use an 'WHERE'-expresion; but can also be an other SQL-expresion that the SQL systax allows: Samples: $whereClause = 'LIMIT 3' $whereClause = 'WHERE aInt < 10 LIMIT 3' NOTE 2: Potential varName-fieldName confusion: When setting the $whereClause you must keep in minde to use the *DB-fieldName*, while the $varsToLoad may only contain the *object-varName*. These 2 name-spaces can (but don't have to) differe, have a look at the hint-hash that is used when the class is registerd.
Tags:
Parameters:
method register [line 377]
bool register(
mixed
$theObject, [array
$hints = NULL])
|
|
You can register the Objects *once* before making use of the SimpleObjPersister. recommended for newbies. The main debugging (if turned on) is run here. If you don't register, the object will be registered once on the first use of store(), load() or delete(). See text in header for detailed hint-hash syntax
Tags:
Parameters:
method setCrypt [line 314]
(bool) setCrypt(
$cryptKey
$cryptKey, [$crypter
$crypter = NULL])
|
|
When using the 'crypt'=>TRUE as attribute in the hint-hash, it's strongly recommended to set your own 'secreat' $cryptKey. By default the used crypter is symmetric (= same password for en- and de-crypting). For The Advanced User: You may plugin your own crypter-object by passing the crypter-object with the methods: $crypter->encrypt($cryptKey, $data) $crypter->decrypt($cryptKey, $data) This will replace the default crypter (instance of Bs_Rc4Crypt.class.php). You then allowed to set anything for the $cryptKey e.g. an Array containing an asymetric key-pair for instance.
Tags:
Parameters:
method setDbObject [line 346]
void setDbObject(
$dbObject
&$dbObject)
|
|
Set the db Interface. (An instance of Bs_Db) I recomment to use the DB-factory function "getDbObject()" in Bs_Db. See also the sample at the far end of this PHP-soure
Parameters:
method smartError [line 1643]
void smartError(
$hints
$hints)
|
|
Display the hint-hash with some explanation
Parameters:
method store [line 912]
(mixed) store(
&$theObject
&$theObject, [$varsToLoadList
$varsToStore = NULL], [$forceInsertWithCurrentID
$forceInsertWithCurrentID = FALSE])
|
|
Store the Object to the DB. With the 2ed param it's possible to control which vars are to be stored by passing a list of obj-var names. Very handy when not all data is needed to be stored. Behaver: If primary-var is *set* (=not empty) -------------------------------------- If the obj.-ID (=primary-var) is set, we assume the object is already stored and we run a DB UPDATE. BUT the Object to persist may be missing and the UPDATE would signal back no records where updated due to the missing obj.-ID in table. In this case we will run an INSERT to insert the full Object. To signal back wath we did, following returns have been defined: On SUCCESS return BS_SOP_STORE_OK - Normal Store return BS_SOP_STORE_INSERT_FORCED - UPDATE failed, but successfull INSERT using given obj-ID return BS_SOP_STORE_INSERT_FORCED_WITH_ID_CHANGE - UPDATE failed, but successfull INSERT using *new* obj-ID NOTE: - BS_SOP_STORE_INSERT_FORCED_WITH_ID_CHANGE happens only with primary-type=='auto_increment' We think this makes sens. - If primary type=='manual' we immediately return FALSE (because an ID must be "manually" given and can't be generated)
- If callback method bs_sop_preStore() exsists, the pre-callback is called 2x, in this case of
BS_SOP_STORE_INSERT_FORCED and BS_SOP_STORE_INSERT_FORCED_WITH_ID_CHANGE.
If primary-var is *empty* --------------------------- If the obj.-ID (=primary-var) is set, we assume the object has to be *totally* stored with an DB INSERT. 'Totally' means that all registered vars are taken (in other words: the $varsToStore is ignored) On SUCCESS return BS_SOP_STORE_OK
Tags:
Parameters:
method tableExists [line 1210]
(bool) tableExists(
$classname
$classname)
|
|
This function checks to see if the table exists in that we plan to persist this objects. Usually you will not need to check this, as the table is generated automatically if missing (unless the class hints tured this feature off). NOTE(!): If class or hints indecate a property of 'ignoreData' (= No data to read or store) this function will return TRUE! See also text in header for more info on 'ignoreData'.
Tags:
Parameters:
method updateTableStructure [line 1256]
(bool) updateTableStructure(
$classname
$classname)
|
|
This function will use the hints and options to set up a field-attribute hash, that is used by the db-Interface to update the object-table (or create it if not existing) This fuction is quite safe as is will not destroy any table columns and only extend field size (but never shorten it)
Tags:
Parameters:
method _generateSql [line 1167]
void _generateSql(
mixed
$classRegistry, mixed
$primaryHash, mixed
$fieldHash, mixed
$itsAnUpdate, mixed
$useOfAutoIncrement)
|
|
Helper to render the SQL string when storing
method _genericLoad [line 727]
(mixed) _genericLoad(
$theObject
&$theObject, [$whereClause
$varsToLoad = NULL], [$varsToLoadList
$whereClause = ''], [$singleLoad
$singleLoad = FALSE])
|
|
This is the central load method it's used by the other loads. I was able to write this generic load that serves the other loads here without doing a lot of quirks. It runs in 2 modes: A) Single load of an object that is passed by reference and is loaded with data. Returns TRUE on success B) Multiple object instanciation (based on the $whereClause). Return an hash of objects using the primary-key as key. mode (A) is assumed if $singleLoad===TRUE else mode (B)
Tags:
Parameters:
method _getClassName [line 1547]
string _getClassName(
mixed
$theObject)
|
|
Find out the classname and if it's in scope of an object or classname(string)
Tags:
Parameters:
method _getClassRegistry [line 1583]
array _getClassRegistry(
mixed
$theObject)
|
|
Pass a string or object and returns _classRegistry.
Tags:
Parameters:
method _getExpectedMetaTypes [line 1610]
void _getExpectedMetaTypes(
mixed
$phpType)
|
|
Helper used by classVarCheck()
|
|