From 0f0d3c62e608287cdf77f1a3239371b521ecb40b Mon Sep 17 00:00:00 2001 From: wei <> Date: Sat, 14 Apr 2007 05:02:29 +0000 Subject: Refactor ActiveRecordGateway to use TDataGatewayCommand --- .../Data/ActiveRecord/TActiveRecordGateway.php | 249 ++++++++++++--------- 1 file changed, 140 insertions(+), 109 deletions(-) (limited to 'framework/Data/ActiveRecord/TActiveRecordGateway.php') diff --git a/framework/Data/ActiveRecord/TActiveRecordGateway.php b/framework/Data/ActiveRecord/TActiveRecordGateway.php index be9731c5..9c480ad0 100644 --- a/framework/Data/ActiveRecord/TActiveRecordGateway.php +++ b/framework/Data/ActiveRecord/TActiveRecordGateway.php @@ -22,8 +22,9 @@ class TActiveRecordGateway extends TComponent { private $_manager; - private $_tables=array(); //meta data cache. - + private $_tables=array(); //table cache + private $_meta=array(); //meta data cache. + private $_commandBuilders=array(); /** * Constant name for specifying optional table name in TActiveRecord. */ @@ -52,7 +53,7 @@ class TActiveRecordGateway extends TComponent * @param TActiveRecord active record instance * @return string table name for the given record class. */ - public function getTableName(TActiveRecord $record) + protected function getRecordTableName(TActiveRecord $record) { $class = new ReflectionClass($record); if($class->hasConstant(self::TABLE_CONST)) @@ -68,70 +69,65 @@ class TActiveRecordGateway extends TComponent } /** - * @param TActiveRecord active record. - * @return TDbMetaData table meta data, null if not found. + * Returns table information, trys the application cache first. + * @param TActiveRecord $record + * @return TDbTableInfo table information. */ - protected function getCachedMetaData($record) + public function getRecordTableInfo(TActiveRecord $record) { - $type=get_class($record); - if(isset($this->_tables[$type])) - return $this->_tables[$type]; - if(($cache=$this->getManager()->getCache())!==null) - { - //force loading of the table inspector to load the required classes - // before unserializing cached meta data. - $this->getManager()->getTableInspector($record->getDbConnection()); - $data = $cache->get($this->getMetaDataCacheKey($record)); - if($data !== false && $data !== null) - { - $this->_tables[$type] = $data; - return $data; - } - } + $tableName = $this->getRecordTableName($record); + return $this->getTableInfo($record->getDbConnection(), $tableName); } /** - * @param TActiveRecord active record. - * @return string cache key, using connection string + record class name + * Returns table information for table in the database connection. + * @param TDbConnection database connection + * @param string table name + * @return TDbTableInfo table details. */ - protected function getMetaDataCacheKey($record) + public function getTableInfo($connection, $tableName) { - $conn = $record->getDbConnection()->getConnectionString(); - return $conn.':'.get_class($record); - } - - /** - * Cache the meta data, tries the application cache if applicable. - * @param TActiveRecord active record. - * @param TDbMetaData table meta data - * @return TDbMetaData table meta data. - */ - protected function cacheMetaData($record,$data) - { - $type = get_class($record); - if(($cache=$this->getManager()->getCache())!==null) - $cache->set($this->getMetaDataCacheKey($record), $data); - $this->_tables[$type] = $data; - return $data; + $connStr = $connection->getConnectionString(); + $key = $connStr.$tableName; + if(!isset($this->_tables[$key])) + { + $tableInfo = null; + if(($cache=$this->getManager()->getCache())!==null) + $tableInfo = $cache->get($key); + if($tableInfo===null) + { + if(!isset($this->_meta[$connStr])) + { + Prado::using('System.Data.Common.TDbMetaData'); + $this->_meta[$connStr] = TDbMetaData::getMetaData($connection); + } + $tableInfo = $this->_meta[$connStr]->getTableInfo($tableName); + } + $this->_tables[$key] = $tableInfo; + if($cache!==null) + $cache->set($key, $tableInfo); + } + return $this->_tables[$key]; } /** - * Gets the meta data for given database and table. + * @param TActiveRecord $record + * @return TDataGatewayCommand */ - public function getMetaData(TActiveRecord $record) + public function getCommand(TActiveRecord $record) { - $type=get_class($record); - if(!($data = $this->getCachedMetaData($record))) + $conn = $record->getDbConnection(); + $connStr = $conn->getConnectionString(); + $tableInfo = $this->getRecordTableInfo($record); + if(!isset($this->_commandBuilders[$connStr])) { - $conn = $record->getDbConnection(); - $inspector = $this->getManager()->getTableInspector($conn); - $table = $this->getTableName($record); - $meta = $inspector->getTableMetaData($table); - if(count($meta->getColumns()) == 0) - throw new TActiveRecordException('ar_invalid_table', $table); - $data = $this->cacheMetaData($record,$meta); + $builder = $tableInfo->createCommandBuilder($record->getDbConnection()); + Prado::using('System.Data.DataGateway.TDataGatewayCommand'); + $this->_commandBuilders[$connStr] = new TDataGatewayCommand($builder); } - return $data; + $this->_commandBuilders[$connStr]->getBuilder()->setTableInfo($tableInfo); + + return $this->_commandBuilders[$connStr]; } /** @@ -143,11 +139,7 @@ class TActiveRecordGateway extends TComponent */ public function findRecordByPK(TActiveRecord $record,$keys) { - $meta = $this->getMetaData($record); - $command = $meta->getFindByPkCommand($record->getDbConnection(),$keys); - $this->raiseCommandEvent(TActiveRecordStatementType::Select,$command,$record,$keys); - Prado::trace(get_class($record).'::FindRecordByPk('.var_export($keys,true).')', 'System.Data.ActiveRecord'); - return $meta->postQueryRow($command->queryRow()); + return $this->getCommand($record)->findByPk($keys); } /** @@ -158,11 +150,7 @@ class TActiveRecordGateway extends TComponent */ public function findRecordsByPks(TActiveRecord $record, $keys) { - $meta = $this->getMetaData($record); - $command = $meta->getFindInPksCommand($record->getDbConnection(), $keys); - $this->raiseCommandEvent(TActiveRecordStatementType::Select,$command,$record,$keys); - Prado::trace(get_class($record).'::FindRecordsByPks('.var_export($keys,true).')', 'System.Data.ActiveRecord'); - return $meta->postQuery($command->query()); + return $this->getCommand($record)->findAllByPk($keys); } @@ -176,27 +164,21 @@ class TActiveRecordGateway extends TComponent */ public function findRecordsByCriteria(TActiveRecord $record, $criteria, $iterator=false) { - $meta = $this->getMetaData($record); - $command = $meta->getFindByCriteriaCommand($record->getDbConnection(),$criteria); - $this->raiseCommandEvent(TActiveRecordStatementType::Select,$command,$record,$criteria); - Prado::trace(get_class($record).'::FindRecordsByCriteria('.((string)$criteria).')', 'System.Data.ActiveRecord'); - return $iterator ? $meta->postQuery($command->query()) : $meta->postQueryRow($command->queryRow()); + if($iterator) + return $this->getCommand($record)->findAll($criteria); + else + return $this->getCommand($record)->find($criteria); } /** * Return record data from sql query. * @param TActiveRecord active record finder instance. - * @param string SQL string - * @param array query parameters. + * @param TActiveRecordCriteria sql query * @return TDbDataReader result iterator. */ - public function findRecordsBySql(TActiveRecord $record, $sql,$parameters=array()) + public function findRecordsBySql(TActiveRecord $record, $criteria) { - $meta = $this->getMetaData($record); - $command = $meta->getFindBySqlCommand($record->getDbConnection(),$sql,$parameters); - $this->raiseCommandEvent(TActiveRecordStatementType::Select,$command,$record,$parameters); - Prado::trace(get_class($record).'::FindRecordsBySql('.var_export($parameters,true).')', 'System.Data.ActiveRecord'); - return $meta->postQuery($command->query()); + return $this->getCommand($record)->findBySql($criteria); } /** @@ -207,11 +189,7 @@ class TActiveRecordGateway extends TComponent */ public function countRecords(TActiveRecord $record, $criteria) { - $meta = $this->getMetaData($record); - $command = $meta->getCountRecordsCommand($record->getDbConnection(),$criteria); - $this->raiseCommandEvent(TActiveRecordStatementType::Select,$command,$record,$criteria); - Prado::trace(get_class($record).'::CountRecords('.((string)$criteria).')', 'System.Data.ActiveRecord'); - return intval($command->queryScalar()); + return $this->getCommand($record)->count($criteria); } /** @@ -221,14 +199,46 @@ class TActiveRecordGateway extends TComponent */ public function insert(TActiveRecord $record) { - $meta = $this->getMetaData($record); - $command = $meta->getInsertCommand($record->getDbConnection(),$record); - $this->raiseCommandEvent(TActiveRecordStatementType::Insert,$command,$record); - Prado::trace(get_class($record).'::Insert()', 'System.Data.ActiveRecord'); - $rowsAffected = $command->execute(); - if($rowsAffected===1) - $meta->updatePostInsert($record->getDbConnection(),$record); - return $rowsAffected; + $result = $this->getCommand($record)->insert($this->getInsertValues($record)); + if($result) + $this->updatePostInsert($record); + return $result; + } + + protected function updatePostInsert($record) + { + $command = $this->getCommand($record); + $tableInfo = $command->getTableInfo(); + foreach($tableInfo->getColumns() as $name => $column) + { + if($column->hasSequence()) + $record->{$name} = $command->getLastInsertID($column->getSequenceName()); + } + } + + /** + * @param TActiveRecord record + * @return array insert values. + */ + protected function getInsertValues(TActiveRecord $record) + { + $values=array(); + $tableInfo = $this->getCommand($record)->getTableInfo(); + foreach($tableInfo->getColumns() as $name=>$column) + { + if($column->getIsExcluded()) + continue; + $value = $record->{$name}; + if(!$column->getAllowNull() && $value===null && !$column->hasSequence()) + { + throw new TActiveRecordException( + 'ar_value_must_not_be_null', get_class($record), + $tableInfo->getTableFullName(), $name); + } + if($value!==null) + $values[$name] = $value; + } + return $values; } /** @@ -238,11 +248,32 @@ class TActiveRecordGateway extends TComponent */ public function update(TActiveRecord $record) { - $meta = $this->getMetaData($record); - $command = $meta->getUpdateCommand($record->getDbConnection(),$record); - $this->raiseCommandEvent(TActiveRecordStatementType::Update,$command,$record); - Prado::trace(get_class($record).'::Update()', 'System.Data.ActiveRecord'); - return $command->execute(); + list($data, $keys) = $this->getUpdateValues($record); + return $this->getCommand($record)->updateByPk($data, $keys); + } + + protected function getUpdateValues(TActiveRecord $record) + { + $values=array(); + $tableInfo = $this->getCommand($record)->getTableInfo(); + $primary=array(); + foreach($tableInfo->getColumns() as $name=>$column) + { + if($column->getIsExcluded()) + continue; + $value = $record->{$name}; + if(!$column->getAllowNull() && $value===null) + { + throw new TActiveRecordException( + 'ar_value_must_not_be_null', get_class($record), + $tableInfo->getTableFullName(), $name); + } + if($column->getIsPrimaryKey()) + $primary[] = $value; + else + $values[$name] = $value; + } + return array($values,$primary); } /** @@ -252,11 +283,19 @@ class TActiveRecordGateway extends TComponent */ public function delete(TActiveRecord $record) { - $meta = $this->getMetaData($record); - $command = $meta->getDeleteCommand($record->getDbConnection(),$record); - $this->raiseCommandEvent(TActiveRecordStatementType::Delete,$command,$record); - Prado::trace(get_class($record).'::Delete()', 'System.Data.ActiveRecord'); - return $command->execute(); + return $this->getCommand($record)->deleteByPk($this->getPrimaryKeyValues($record)); + } + + protected function getPrimaryKeyValues(TActiveRecord $record) + { + $tableInfo = $this->getCommand($record)->getTableInfo(); + $primary=array(); + foreach($tableInfo->getColumns() as $name=>$column) + { + if($column->getIsPrimaryKey()) + $primary[$name] = $record->{$name}; + } + return $primary; } /** @@ -266,11 +305,7 @@ class TActiveRecordGateway extends TComponent */ public function deleteRecordsByPk(TActiveRecord $record, $keys) { - $meta = $this->getMetaData($record); - $command = $meta->getDeleteByPkCommand($record->getDBConnection(),$keys); - $this->raiseCommandEvent(TActiveRecordStatementType::Delete,$command,$record,$keys); - Prado::trace(get_class($record).'::DeleteRecordsByPk('.var_export($keys,true).')', 'System.Data.ActiveRecord'); - return $command->execute(); + return $this->getCommand($record)->deleteByPk($keys); } /** @@ -281,11 +316,7 @@ class TActiveRecordGateway extends TComponent */ public function deleteRecordsByCriteria(TActiveRecord $record, $criteria) { - $meta = $this->getMetaData($record); - $command = $meta->getDeleteByCriteriaCommand($record->getDBConnection(),$criteria); - $this->raiseCommandEvent(TActiveRecordStatementType::Delete,$command,$record,$criteria); - Prado::trace(get_class($record).'::DeleteRecordsByCriteria('.((string)$criteria).')', 'System.Data.ActiveRecord'); - return $command->execute(); + return $this->getCommand($record)->delete($criteria); } /** -- cgit v1.2.3