From 4a2ebb333d239b58c19d09ee88646fa0e32e71ed Mon Sep 17 00:00:00 2001 From: wei <> Date: Mon, 16 Apr 2007 02:02:27 +0000 Subject: Updates to db stuff, removed js build from build.xml (no longer necessary) --- framework/Data/ActiveRecord/TActiveRecord.php | 83 ++++++++---- .../Data/ActiveRecord/TActiveRecordCriteria.php | 22 --- .../Data/ActiveRecord/TActiveRecordGateway.php | 149 ++++++++------------- .../Data/ActiveRecord/TActiveRecordManager.php | 66 ++------- 4 files changed, 127 insertions(+), 193 deletions(-) (limited to 'framework/Data/ActiveRecord') diff --git a/framework/Data/ActiveRecord/TActiveRecord.php b/framework/Data/ActiveRecord/TActiveRecord.php index 0400661d..1ea06a60 100644 --- a/framework/Data/ActiveRecord/TActiveRecord.php +++ b/framework/Data/ActiveRecord/TActiveRecord.php @@ -17,7 +17,10 @@ Prado::using('System.Data.ActiveRecord.TActiveRecordCriteria'); * Base class for active records. * * An active record creates an object that wraps a row in a database table - * or view, encapsulates the database access, and adds domain logic on that data. + * or view, encapsulates the database access, and adds domain logic on that data. + * + * Active record objects are stateful, this is main difference between the + * TActiveRecord implementation and the TTableGateway implementation. * * The essence of an Active Record is an object model of the * domain (e.g. products, items) that incorporates both behavior and @@ -140,7 +143,11 @@ abstract class TActiveRecord extends TComponent } /** - * Returns the instance of a active record finder for a particular class. + * Returns the instance of a active record finder for a particular class. + * The finder objects are static instances for each ActiveRecord class. + * This means that event handlers bound to these finder instances are class wide. + * Create a new instance of the ActiveRecord class if you wish to bound the + * event handlers to object instance. * @param string active record class name. * @return TActiveRecord active record finder instance. * @throws TActiveRecordException if class name equals 'TActiveRecord'. @@ -168,6 +175,14 @@ abstract class TActiveRecord extends TComponent public function getRecordManager() { return TActiveRecordManager::getInstance(); + } + + /** + * @return TActiveRecordGateway record table gateway. + */ + public function getRecordGateway() + { + return $this->getRecordManager()->getRecordGateway(); } /** @@ -266,15 +281,20 @@ abstract class TActiveRecord extends TComponent //try the cache (the cache object must be clean) if(!is_null($obj = $registry->getCachedInstance($data))) - return $obj; + return $obj; + + $gateway = $this->getRecordManager()->getRecordGateway(); //create and populate the object $obj = Prado::createComponent($type); - foreach($data as $name => $value) - $obj->{$name} = $value; + $tableInfo = $gateway->getRecordTableInfo($obj); + foreach($tableInfo->getColumns()->getKeys() as $name) + { + if(isset($data[$name])) + $obj->{$name} = $data[$name]; + } - $gateway = $this->getRecordManager()->getRecordGateway(); - $obj->_readOnly = $gateway->getRecordTableInfo($this)->getIsView(); + $obj->_readOnly = $tableInfo->getIsView(); //cache it return $registry->addCachedInstance($data,$obj); @@ -484,21 +504,38 @@ abstract class TActiveRecord extends TComponent else throw new TActiveRecordException('ar_invalid_criteria'); } + + /** + * Raised when a command is prepared and parameter binding is completed. + * The parameter object is TDataGatewayEventParameter of which the + * {@link TDataGatewayEventParameter::getCommand Command} property can be + * inspected to obtain the sql query to be executed. + * + * Note well that the finder objects obtained from ActiveRecord::finder() + * method are static objects. This means that the event handlers are + * bound to a static finder object and not to each distinct active record object. + * @param TDataGatewayEventParameter + */ + public function onCreateCommand($param) + { + $this->raiseEvent('OnCreateCommand', $this, $param); + } + + /** + * Raised when a command is executed and the result from the database was returned. + * The parameter object is TDataGatewayResultEventParameter of which the + * {@link TDataGatewayEventParameter::getResult Result} property contains + * the data return from the database. The data returned can be changed + * by setting the {@link TDataGatewayEventParameter::setResult Result} property. + * + * Note well that the finder objects obtained from ActiveRecord::finder() + * method are static objects. This means that the event handlers are + * bound to a static finder object and not to each distinct active record object. + * @param TDataGatewayResultEventParameter + */ + public function onExecuteCommand($param) + { + $this->raiseEvent('OnExecuteCommand', $this, $param); + } } - -/** - * TActiveRecordEventParameter class. - * - * @author Wei Zhuo - * @version $Id$ - * @package System.Data.ActiveRecord - * @since 3.1 - */ -class TActiveRecordEventParameter extends TEventParameter -{ - -} - - - ?> diff --git a/framework/Data/ActiveRecord/TActiveRecordCriteria.php b/framework/Data/ActiveRecord/TActiveRecordCriteria.php index cc4da7c8..8328b4a6 100644 --- a/framework/Data/ActiveRecord/TActiveRecordCriteria.php +++ b/framework/Data/ActiveRecord/TActiveRecordCriteria.php @@ -34,29 +34,7 @@ Prado::using('System.Data.DataGateway.TSqlCriteria'); */ class TActiveRecordCriteria extends TSqlCriteria { - /** - * This method is invoked before the object is deleted from the database. - * The method raises 'OnDelete' event. - * If you override this method, be sure to call the parent implementation - * so that the event handlers can be invoked. - * @param TActiveRecordEventParameter event parameter to be passed to the event handlers - */ - public function onDelete($param) - { - $this->raiseEvent('OnDelete', $this, $param); - } - /** - * This method is invoked before any select query is executed on the database. - * The method raises 'OnSelect' event. - * If you override this method, be sure to call the parent implementation - * so that the event handlers can be invoked. - * @param TActiveRecordEventParameter event parameter to be passed to the event handlers - */ - public function onSelect($param) - { - $this->raiseEvent('OnSelect', $this, $param); - } } ?> \ No newline at end of file diff --git a/framework/Data/ActiveRecord/TActiveRecordGateway.php b/framework/Data/ActiveRecord/TActiveRecordGateway.php index 9c480ad0..c3239c5c 100644 --- a/framework/Data/ActiveRecord/TActiveRecordGateway.php +++ b/framework/Data/ActiveRecord/TActiveRecordGateway.php @@ -1,6 +1,6 @@ * @link http://www.pradosoft.com/ @@ -25,6 +25,8 @@ class TActiveRecordGateway extends TComponent private $_tables=array(); //table cache private $_meta=array(); //meta data cache. private $_commandBuilders=array(); + private $_currentRecord; + /** * Constant name for specifying optional table name in TActiveRecord. */ @@ -99,7 +101,7 @@ class TActiveRecordGateway extends TComponent if(!isset($this->_meta[$connStr])) { Prado::using('System.Data.Common.TDbMetaData'); - $this->_meta[$connStr] = TDbMetaData::getMetaData($connection); + $this->_meta[$connStr] = TDbMetaData::getInstance($connection); } $tableInfo = $this->_meta[$connStr]->getTableInfo($tableName); } @@ -123,13 +125,52 @@ class TActiveRecordGateway extends TComponent { $builder = $tableInfo->createCommandBuilder($record->getDbConnection()); Prado::using('System.Data.DataGateway.TDataGatewayCommand'); - $this->_commandBuilders[$connStr] = new TDataGatewayCommand($builder); + $command = new TDataGatewayCommand($builder); + $command->OnCreateCommand[] = array($this, 'onCreateCommand'); + $command->OnExecuteCommand[] = array($this, 'onExecuteCommand'); + $this->_commandBuilders[$connStr] = $command; + } $this->_commandBuilders[$connStr]->getBuilder()->setTableInfo($tableInfo); - + $this->_currentRecord=$record; return $this->_commandBuilders[$connStr]; } + /** + * Raised when a command is prepared and parameter binding is completed. + * The parameter object is TDataGatewayEventParameter of which the + * {@link TDataGatewayEventParameter::getCommand Command} property can be + * inspected to obtain the sql query to be executed. + * This method also raises the OnCreateCommand event on the ActiveRecord + * object calling this gateway. + * @param TDataGatewayCommand originator $sender + * @param TDataGatewayEventParameter + */ + public function onCreateCommand($sender, $param) + { + $this->raiseEvent('OnCreateCommand', $this, $param); + if($this->_currentRecord!==null) + $this->_currentRecord->onCreateCommand($param); + } + + /** + * Raised when a command is executed and the result from the database was returned. + * The parameter object is TDataGatewayResultEventParameter of which the + * {@link TDataGatewayEventParameter::getResult Result} property contains + * the data return from the database. The data returned can be changed + * by setting the {@link TDataGatewayEventParameter::setResult Result} property. + * This method also raises the OnCreateCommand event on the ActiveRecord + * object calling this gateway. + * @param TDataGatewayCommand originator $sender + * @param TDataGatewayResultEventParameter + */ + public function onExecuteCommand($sender, $param) + { + $this->raiseEvent('OnExecuteCommand', $this, $param); + if($this->_currentRecord!==null) + $this->_currentRecord->onExecuteCommand($param); + } + /** * Returns record data matching the given primary key(s). If the table uses * composite key, specify the name value pairs as an array. @@ -139,7 +180,8 @@ class TActiveRecordGateway extends TComponent */ public function findRecordByPK(TActiveRecord $record,$keys) { - return $this->getCommand($record)->findByPk($keys); + $command = $this->getCommand($record); + return $command->findByPk($keys); } /** @@ -164,10 +206,8 @@ class TActiveRecordGateway extends TComponent */ public function findRecordsByCriteria(TActiveRecord $record, $criteria, $iterator=false) { - if($iterator) - return $this->getCommand($record)->findAll($criteria); - else - return $this->getCommand($record)->find($criteria); + $command = $this->getCommand($record); + return $iterator ? $command->findAll($criteria) : $command->find($criteria); } /** @@ -205,6 +245,10 @@ class TActiveRecordGateway extends TComponent return $result; } + /** + * Sets the last insert ID to the corresponding property of the record if available. + * @param TActiveRecord record for insertion + */ protected function updatePostInsert($record) { $command = $this->getCommand($record); @@ -324,91 +368,16 @@ class TActiveRecordGateway extends TComponent * @param string command type * @param TDbCommand sql command to be executed. * @param TActiveRecord active record - * @param mixed data for the command. + * @param TActiveRecordCriteria data for the command. */ - protected function raiseCommandEvent($type,$command,$record=null,$data=null) + protected function raiseCommandEvent($event,$command,$record,$criteria) { - $param = new TActiveRecordGatewayEventParameter($type,$command,$record,$data); + if(!($criteria instanceof TSqlCriteria)) + $criteria = new TActiveRecordCriteria(null,$criteria); + $param = new TActiveRecordEventParameter($command,$record,$criteria); $manager = $record->getRecordManager(); - $event = 'on'.$type; - if($data instanceof TActiveRecordCriteria) - $data->{$event}($param); $manager->{$event}($param); - } -} - -/** - * Command statement types. - * - * @author Wei Zhuo - * @version $Id$ - * @package System.Data.ActiveRecord - * @since 3.1 - */ -class TActiveRecordStatementType -{ - const Insert='Insert'; - const Update='Update'; - const Delete='Delete'; - const Select='Select'; -} - -/** - * Active Record command event parameter. - * - * @author Wei Zhuo - * @version $Id$ - * @package System.Data.ActiveRecord - * @since 3.1 - */ -class TActiveRecordGatewayEventParameter extends TActiveRecordEventParameter -{ - private $_type; - private $_command; - private $_record; - private $_data; - - /** - * New gateway command event parameter. - */ - public function __construct($type,$command,$record=null,$data=null) - { - $this->_type=$type; - $this->_command=$command; - $this->_data=$data; - $this->_record=$record; - } - - /** - * @return string TActiveRecordStateType - */ - public function getType() - { - return $this->_type; - } - - /** - * @return TDbCommand command to be executed. - */ - public function getCommand() - { - return $this->_command; - } - - /** - * @return TActiveRecord active record. - */ - public function getRecord() - { - return $this->_record; - } - - /** - * @return mixed command data. - */ - public function getData() - { - return $this->_data; + $record->{$event}($param); } } diff --git a/framework/Data/ActiveRecord/TActiveRecordManager.php b/framework/Data/ActiveRecord/TActiveRecordManager.php index 5e463d2d..ab6fe88d 100644 --- a/framework/Data/ActiveRecord/TActiveRecordManager.php +++ b/framework/Data/ActiveRecord/TActiveRecordManager.php @@ -20,20 +20,16 @@ Prado::using('System.Data.ActiveRecord.TActiveRecordStateRegistry'); * TActiveRecordManager provides the default DB connection, default object state * registry, default active record gateway, and table meta data inspector. * - * You can provide a different registry by overriding the {@link createObjectStateRegistry()} method. - * Similarly, override {@link createRecordGateway()} for default gateway and override - * {@link createMetaDataInspector() }for meta data inspector. - * * The default connection can be set as follows: * * TActiveRecordManager::getInstance()->setDbConnection($conn); * * All new active record created after setting the - * {@link DbConnection setDbConnection()} will use that connection. + * {@link DbConnection setDbConnection()} will use that connection unless + * the custom ActiveRecord class overrides the ActiveRecord::getDbConnection(). * - * The {@link onInsert()}, {@link onUpdate()}, - * {@link onDelete()} and {@link onSelect()} events are raised - * before their respective command are executed. + * Set the {@link setCache Cache} property to an ICache object to allow + * the active record gateway to cache the table meta data information. * * @author Wei Zhuo * @version $Id$ @@ -84,10 +80,12 @@ class TActiveRecordManager extends TComponent /** * @return TActiveRecordManager static instance of record manager. */ - public static function getInstance() + public static function getInstance($self=null) { static $instance; - if($instance===null) + if($self!==null) + $instance=$self; + else if($instance===null) $instance = new self; return $instance; } @@ -127,54 +125,6 @@ class TActiveRecordManager extends TComponent { return new TActiveRecordGateway($this); } - - /** - * This method is invoked before the object is inserted into the database. - * The method raises 'OnInsert' event. - * If you override this method, be sure to call the parent implementation - * so that the event handlers can be invoked. - * @param TActiveRecordEventParameter event parameter to be passed to the event handlers - */ - public function onInsert($param) - { - $this->raiseEvent('OnInsert', $this, $param); - } - - /** - * This method is invoked before the object is deleted from the database. - * The method raises 'OnDelete' event. - * If you override this method, be sure to call the parent implementation - * so that the event handlers can be invoked. - * @param TActiveRecordEventParameter event parameter to be passed to the event handlers - */ - public function onDelete($param) - { - $this->raiseEvent('OnDelete', $this, $param); - } - - /** - * This method is invoked before the object data is updated in the database. - * The method raises 'OnUpdate' event. - * If you override this method, be sure to call the parent implementation - * so that the event handlers can be invoked. - * @param TActiveRecordEventParameter event parameter to be passed to the event handlers - */ - public function onUpdate($param) - { - $this->raiseEvent('OnUpdate', $this, $param); - } - - /** - * This method is invoked before any select query is executed on the database. - * The method raises 'OnSelect' event. - * If you override this method, be sure to call the parent implementation - * so that the event handlers can be invoked. - * @param TActiveRecordEventParameter event parameter to be passed to the event handlers - */ - public function onSelect($param) - { - $this->raiseEvent('OnSelect', $this, $param); - } } -- cgit v1.2.3