diff options
author | ctrlaltca <> | 2012-07-12 11:21:01 +0000 |
---|---|---|
committer | ctrlaltca <> | 2012-07-12 11:21:01 +0000 |
commit | 903ae8a581fac1e6917fc3e31d2ad8fb91df80c3 (patch) | |
tree | e08bf04f0823650a231227ac3499121270172a23 /framework/Data/SqlMap/Statements | |
parent | 3e4e6e66aeb3f8fea4e1eb4237498ef9d2358f63 (diff) |
standardize the use of unix eol; use svn properties to enforce native eol
Diffstat (limited to 'framework/Data/SqlMap/Statements')
12 files changed, 1831 insertions, 1831 deletions
diff --git a/framework/Data/SqlMap/Statements/IMappedStatement.php b/framework/Data/SqlMap/Statements/IMappedStatement.php index dc628c9e..15f61fad 100644 --- a/framework/Data/SqlMap/Statements/IMappedStatement.php +++ b/framework/Data/SqlMap/Statements/IMappedStatement.php @@ -1,82 +1,82 @@ -<?php
-/**
- * IMappedStatement interface file.
- *
- * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
- * @version $Id$
- * @package System.Data.SqlMap.Statements
- */
-
-/**
- * Interface for all mapping statements.
- *
- * @author Wei Zhuo <weizho[at]gmail[dot]com>
- * @version $Id$
- * @package System.Data.SqlMap.Statements
- * @since 3.1
- */
-interface IMappedStatement
-{
- /**
- * @return string Name used to identify the MappedStatement amongst the others.
- */
- public function getID();
-
- /**
- * @return TSqlMapStatement The SQL statment used by this TMappedStatement.
- */
- public function getStatement();
-
- /**
- * @return TSqlMap The TSqlMap used by this TMappedStatement
- */
- public function getManager();
-
- /**
- * Executes the SQL and retuns all rows selected in a map that is keyed on
- * the property named in the <tt>$keyProperty</tt> parameter. The value at
- * each key will be the value of the property specified in the
- * <tt>$valueProperty</tt> parameter. If <tt>$valueProperty</tt> is
- * <tt>null</tt>, the entire result object will be entered.
- * @param IDbConnection database connection to execute the query
- * @param mixed The object used to set the parameters in the SQL.
- * @param string The property of the result object to be used as the key.
- * @param string The property of the result object to be used as the value (or null)
- * @return TMap A map of object containing the rows keyed by <tt>$keyProperty</tt>.
- */
- public function executeQueryForMap($connection, $parameter, $keyProperty, $valueProperty=null);
-
-
- /**
- * Execute an update statement. Also used for delete statement. Return the
- * number of row effected.
- * @param IDbConnection database connection to execute the query
- * @param mixed The object used to set the parameters in the SQL.
- * @return integer The number of row effected.
- */
- public function executeUpdate($connection, $parameter);
-
-
- /**
- * Executes the SQL and retuns a subset of the rows selected.
- * @param IDbConnection database connection to execute the query
- * @param mixed The object used to set the parameters in the SQL.
- * @param TList A list to populate the result with.
- * @param integer The number of rows to skip over.
- * @param integer The maximum number of rows to return.
- * @return TList A TList of result objects.
- */
- public function executeQueryForList($connection, $parameter, $result=null, $skip=-1, $max=-1);
-
-
- /**
- * Executes an SQL statement that returns a single row as an object
- * of the type of the <tt>$result</tt> passed in as a parameter.
- * @param IDbConnection database connection to execute the query
- * @param mixed The object used to set the parameters in the SQL.
- * @param object The result object.
- * @return object result.
- */
- public function executeQueryForObject($connection,$parameter, $result=null);
-}
-
+<?php +/** + * IMappedStatement interface file. + * + * @author Wei Zhuo <weizhuo[at]gmail[dot]com> + * @version $Id$ + * @package System.Data.SqlMap.Statements + */ + +/** + * Interface for all mapping statements. + * + * @author Wei Zhuo <weizho[at]gmail[dot]com> + * @version $Id$ + * @package System.Data.SqlMap.Statements + * @since 3.1 + */ +interface IMappedStatement +{ + /** + * @return string Name used to identify the MappedStatement amongst the others. + */ + public function getID(); + + /** + * @return TSqlMapStatement The SQL statment used by this TMappedStatement. + */ + public function getStatement(); + + /** + * @return TSqlMap The TSqlMap used by this TMappedStatement + */ + public function getManager(); + + /** + * Executes the SQL and retuns all rows selected in a map that is keyed on + * the property named in the <tt>$keyProperty</tt> parameter. The value at + * each key will be the value of the property specified in the + * <tt>$valueProperty</tt> parameter. If <tt>$valueProperty</tt> is + * <tt>null</tt>, the entire result object will be entered. + * @param IDbConnection database connection to execute the query + * @param mixed The object used to set the parameters in the SQL. + * @param string The property of the result object to be used as the key. + * @param string The property of the result object to be used as the value (or null) + * @return TMap A map of object containing the rows keyed by <tt>$keyProperty</tt>. + */ + public function executeQueryForMap($connection, $parameter, $keyProperty, $valueProperty=null); + + + /** + * Execute an update statement. Also used for delete statement. Return the + * number of row effected. + * @param IDbConnection database connection to execute the query + * @param mixed The object used to set the parameters in the SQL. + * @return integer The number of row effected. + */ + public function executeUpdate($connection, $parameter); + + + /** + * Executes the SQL and retuns a subset of the rows selected. + * @param IDbConnection database connection to execute the query + * @param mixed The object used to set the parameters in the SQL. + * @param TList A list to populate the result with. + * @param integer The number of rows to skip over. + * @param integer The maximum number of rows to return. + * @return TList A TList of result objects. + */ + public function executeQueryForList($connection, $parameter, $result=null, $skip=-1, $max=-1); + + + /** + * Executes an SQL statement that returns a single row as an object + * of the type of the <tt>$result</tt> passed in as a parameter. + * @param IDbConnection database connection to execute the query + * @param mixed The object used to set the parameters in the SQL. + * @param object The result object. + * @return object result. + */ + public function executeQueryForObject($connection,$parameter, $result=null); +} + diff --git a/framework/Data/SqlMap/Statements/TCachingStatement.php b/framework/Data/SqlMap/Statements/TCachingStatement.php index 54664e37..cac84458 100644 --- a/framework/Data/SqlMap/Statements/TCachingStatement.php +++ b/framework/Data/SqlMap/Statements/TCachingStatement.php @@ -1,108 +1,108 @@ -<?php
-/**
- * TCachingStatement class file.
- *
- * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
- * @link http://www.pradosoft.com/
- * @copyright Copyright © 2005-2012 PradoSoft
- * @license http://www.pradosoft.com/license/
- * @version $Id$
- * @package System.Data.SqlMap.Statements
- */
-
-/**
- * TCacheingStatement class.
- *
- * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
- * @version $Id$
- * @package System.Data.SqlMap.Statements
- * @since 3.1
- */
-class TCachingStatement extends TComponent implements IMappedStatement
-{
- private $_mappedStatement;
-
- public function __construct(TMappedStatement $statement)
- {
- $this->_mappedStatement = $statement;
- }
-
- public function getID()
- {
- return $this->_mappedStatement->getID();
- }
-
- public function getStatement()
- {
- return $this->_mappedStatement->getStatement();
- }
-
- public function getManager()
- {
- return $this->_mappedStatement->getManager();
- }
-
- public function executeQueryForMap($connection, $parameter,$keyProperty, $valueProperty=null, $skip=-1, $max=-1,$delegate=null)
- {
- $sql = $this->createCommand($connection, $parameter, $skip, $max);
- $key = $this->getCacheKey(array(clone($sql), $keyProperty, $valueProperty,$skip, $max));
- $map = $this->getStatement()->getCache()->get($key);
- if($map===null)
- {
- $map = $this->_mappedStatement->runQueryForMap(
- $connection, $parameter, $sql, $keyProperty, $valueProperty, $delegate);
- $this->getStatement()->getCache()->set($key, $map);
- }
- return $map;
- }
-
- public function executeUpdate($connection, $parameter)
- {
- return $this->_mappedStatement->executeUpdate($connection, $parameter);
- }
-
- public function executeInsert($connection, $parameter)
- {
- return $this->executeInsert($connection, $parameter);
- }
-
- public function executeQueryForList($connection, $parameter, $result=null, $skip=-1, $max=-1, $delegate=null)
- {
- $sql = $this->createCommand($connection, $parameter, $skip, $max);
- $key = $this->getCacheKey(array(clone($sql), $parameter, $skip, $max));
- $list = $this->getStatement()->getCache()->get($key);
- if($list===null)
- {
- $list = $this->_mappedStatement->runQueryForList(
- $connection, $parameter, $sql, $result, $delegate);
- $this->getStatement()->getCache()->set($key, $list);
- }
- return $list;
- }
-
- public function executeQueryForObject($connection, $parameter, $result=null)
- {
- $sql = $this->createCommand($connection, $parameter);
- $key = $this->getCacheKey(array(clone($sql), $parameter));
- $object = $this->getStatement()->getCache()->get($key);
- if($object===null)
- {
- $object = $this->_mappedStatement->runQueryForObject($connection, $sql, $result);
- $this->getStatement()->getCache()->set($key, $object);
- }
- return $object;
- }
-
- protected function getCacheKey($object)
- {
- $cacheKey = new TSqlMapCacheKey($object);
- return $cacheKey->getHash();
- }
-
- protected function createCommand($connection, $parameter, $skip=null, $max=null)
- {
- return $this->_mappedStatement->getCommand()->create($this->getManager(),
- $connection, $this->getStatement(), $parameter, $skip, $max);
- }
-}
-
+<?php +/** + * TCachingStatement class file. + * + * @author Wei Zhuo <weizhuo[at]gmail[dot]com> + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2012 PradoSoft + * @license http://www.pradosoft.com/license/ + * @version $Id$ + * @package System.Data.SqlMap.Statements + */ + +/** + * TCacheingStatement class. + * + * @author Wei Zhuo <weizhuo[at]gmail[dot]com> + * @version $Id$ + * @package System.Data.SqlMap.Statements + * @since 3.1 + */ +class TCachingStatement extends TComponent implements IMappedStatement +{ + private $_mappedStatement; + + public function __construct(TMappedStatement $statement) + { + $this->_mappedStatement = $statement; + } + + public function getID() + { + return $this->_mappedStatement->getID(); + } + + public function getStatement() + { + return $this->_mappedStatement->getStatement(); + } + + public function getManager() + { + return $this->_mappedStatement->getManager(); + } + + public function executeQueryForMap($connection, $parameter,$keyProperty, $valueProperty=null, $skip=-1, $max=-1,$delegate=null) + { + $sql = $this->createCommand($connection, $parameter, $skip, $max); + $key = $this->getCacheKey(array(clone($sql), $keyProperty, $valueProperty,$skip, $max)); + $map = $this->getStatement()->getCache()->get($key); + if($map===null) + { + $map = $this->_mappedStatement->runQueryForMap( + $connection, $parameter, $sql, $keyProperty, $valueProperty, $delegate); + $this->getStatement()->getCache()->set($key, $map); + } + return $map; + } + + public function executeUpdate($connection, $parameter) + { + return $this->_mappedStatement->executeUpdate($connection, $parameter); + } + + public function executeInsert($connection, $parameter) + { + return $this->executeInsert($connection, $parameter); + } + + public function executeQueryForList($connection, $parameter, $result=null, $skip=-1, $max=-1, $delegate=null) + { + $sql = $this->createCommand($connection, $parameter, $skip, $max); + $key = $this->getCacheKey(array(clone($sql), $parameter, $skip, $max)); + $list = $this->getStatement()->getCache()->get($key); + if($list===null) + { + $list = $this->_mappedStatement->runQueryForList( + $connection, $parameter, $sql, $result, $delegate); + $this->getStatement()->getCache()->set($key, $list); + } + return $list; + } + + public function executeQueryForObject($connection, $parameter, $result=null) + { + $sql = $this->createCommand($connection, $parameter); + $key = $this->getCacheKey(array(clone($sql), $parameter)); + $object = $this->getStatement()->getCache()->get($key); + if($object===null) + { + $object = $this->_mappedStatement->runQueryForObject($connection, $sql, $result); + $this->getStatement()->getCache()->set($key, $object); + } + return $object; + } + + protected function getCacheKey($object) + { + $cacheKey = new TSqlMapCacheKey($object); + return $cacheKey->getHash(); + } + + protected function createCommand($connection, $parameter, $skip=null, $max=null) + { + return $this->_mappedStatement->getCommand()->create($this->getManager(), + $connection, $this->getStatement(), $parameter, $skip, $max); + } +} + diff --git a/framework/Data/SqlMap/Statements/TDeleteMappedStatement.php b/framework/Data/SqlMap/Statements/TDeleteMappedStatement.php index a3cbaadb..562720ed 100644 --- a/framework/Data/SqlMap/Statements/TDeleteMappedStatement.php +++ b/framework/Data/SqlMap/Statements/TDeleteMappedStatement.php @@ -1,24 +1,24 @@ -<?php
-/**
- * TDeleteMappedStatement class file.
- *
- * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
- * @link http://www.pradosoft.com/
+<?php +/** + * TDeleteMappedStatement class file. + * + * @author Wei Zhuo <weizhuo[at]gmail[dot]com> + * @link http://www.pradosoft.com/ * @copyright Copyright © 2005-2012 PradoSoft - * @license http://www.pradosoft.com/license/
- * @version $Id$
- * @package System.Data.SqlMap.Statements
- */
-
-/**
- * TDeleteMappedStatement class.
- *
- * @author Wei Zhuo <weizho[at]gmail[dot]com>
- * @version $Id$
- * @package System.Data.SqlMap.Statements
- * @since 3.1
- */
-class TDeleteMappedStatement extends TUpdateMappedStatement
-{
-}
-
+ * @license http://www.pradosoft.com/license/ + * @version $Id$ + * @package System.Data.SqlMap.Statements + */ + +/** + * TDeleteMappedStatement class. + * + * @author Wei Zhuo <weizho[at]gmail[dot]com> + * @version $Id$ + * @package System.Data.SqlMap.Statements + * @since 3.1 + */ +class TDeleteMappedStatement extends TUpdateMappedStatement +{ +} + diff --git a/framework/Data/SqlMap/Statements/TInsertMappedStatement.php b/framework/Data/SqlMap/Statements/TInsertMappedStatement.php index c7cd6ff6..e91ca3aa 100644 --- a/framework/Data/SqlMap/Statements/TInsertMappedStatement.php +++ b/framework/Data/SqlMap/Statements/TInsertMappedStatement.php @@ -1,49 +1,49 @@ -<?php
-/**
- * TInsertMappedStatement class file.
- *
- * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
- * @link http://www.pradosoft.com/
+<?php +/** + * TInsertMappedStatement class file. + * + * @author Wei Zhuo <weizhuo[at]gmail[dot]com> + * @link http://www.pradosoft.com/ * @copyright Copyright © 2005-2012 PradoSoft - * @license http://www.pradosoft.com/license/
- * @version $Id$
- * @package System.Data.SqlMap.Statements
- */
-
-/**
- * TInsertMappedStatement class.
- *
- * @author Wei Zhuo <weizho[at]gmail[dot]com>
- * @version $Id$
- * @package System.Data.SqlMap.Statements
- * @since 3.1
- */
-class TInsertMappedStatement extends TMappedStatement
-{
- public function executeQueryForMap($connection, $parameter,
- $keyProperty, $valueProperty=null)
- {
- throw new TSqlMapExecutionException(
- 'sqlmap_cannot_execute_query_for_map', get_class($this), $this->getID());
- }
-
- public function executeUpdate($connection, $parameter)
- {
- throw new TSqlMapExecutionException(
- 'sqlmap_cannot_execute_update', get_class($this), $this->getID());
- }
-
- public function executeQueryForList($connection, $parameter, $result=null,
- $skip=-1, $max=-1)
- {
- throw new TSqlMapExecutionException(
- 'sqlmap_cannot_execute_query_for_list', get_class($this), $this->getID());
- }
-
- public function executeQueryForObject($connection, $parameter, $result=null)
- {
- throw new TSqlMapExecutionException(
- 'sqlmap_cannot_execute_query_for_object', get_class($this), $this->getID());
- }
-}
-
+ * @license http://www.pradosoft.com/license/ + * @version $Id$ + * @package System.Data.SqlMap.Statements + */ + +/** + * TInsertMappedStatement class. + * + * @author Wei Zhuo <weizho[at]gmail[dot]com> + * @version $Id$ + * @package System.Data.SqlMap.Statements + * @since 3.1 + */ +class TInsertMappedStatement extends TMappedStatement +{ + public function executeQueryForMap($connection, $parameter, + $keyProperty, $valueProperty=null) + { + throw new TSqlMapExecutionException( + 'sqlmap_cannot_execute_query_for_map', get_class($this), $this->getID()); + } + + public function executeUpdate($connection, $parameter) + { + throw new TSqlMapExecutionException( + 'sqlmap_cannot_execute_update', get_class($this), $this->getID()); + } + + public function executeQueryForList($connection, $parameter, $result=null, + $skip=-1, $max=-1) + { + throw new TSqlMapExecutionException( + 'sqlmap_cannot_execute_query_for_list', get_class($this), $this->getID()); + } + + public function executeQueryForObject($connection, $parameter, $result=null) + { + throw new TSqlMapExecutionException( + 'sqlmap_cannot_execute_query_for_object', get_class($this), $this->getID()); + } +} + diff --git a/framework/Data/SqlMap/Statements/TMappedStatement.php b/framework/Data/SqlMap/Statements/TMappedStatement.php index 0dbc8def..ee54df95 100644 --- a/framework/Data/SqlMap/Statements/TMappedStatement.php +++ b/framework/Data/SqlMap/Statements/TMappedStatement.php @@ -1,1242 +1,1242 @@ -<?php
-/**
- * TMappedStatement and related classes.
- *
- * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
- * @link http://www.pradosoft.com/
- * @copyright Copyright © 2005-2012 PradoSoft
- * @license http://www.pradosoft.com/license/
- * @version $Id$
- * @package System.Data.SqlMap.Statements
- */
-
-/**
- * TMappedStatement class executes SQL mapped statements. Mapped Statements can
- * hold any SQL statement and use Parameter Maps and Result Maps for input and output.
- *
- * This class is usualy instantiated during SQLMap configuration by TSqlDomBuilder.
- *
- * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
- * @version $Id$
- * @package System.Data.SqlMap.Statements
- * @since 3.0
- */
-class TMappedStatement extends TComponent implements IMappedStatement
-{
- /**
- * @var TSqlMapStatement current SQL statement.
- */
- private $_statement;
-
- /**
- * @var TPreparedCommand SQL command prepareer
- */
- private $_command;
-
- /**
- * @var TSqlMapper sqlmap used by this mapper.
- */
- private $_manager;
-
- /**
- * @var TPostSelectBinding[] post select statement queue.
- */
- private $_selectQueue=array();
-
- /**
- * @var boolean true when data is mapped to a particular row.
- */
- private $_IsRowDataFound = false;
-
- /**
- * @var TSQLMapObjectCollectionTree group by object collection tree
- */
- private $_groupBy;
-
- /**
- * @var Post select is to query for list.
- */
- const QUERY_FOR_LIST = 0;
-
- /**
- * @var Post select is to query for list.
- */
- const QUERY_FOR_ARRAY = 1;
-
- /**
- * @var Post select is to query for object.
- */
- const QUERY_FOR_OBJECT = 2;
-
- /**
- * @return string Name used to identify the TMappedStatement amongst the others.
- * This the name of the SQL statement by default.
- */
- public function getID()
- {
- return $this->_statement->ID;
- }
-
- /**
- * @return TSqlMapStatement The SQL statment used by this MappedStatement
- */
- public function getStatement()
- {
- return $this->_statement;
- }
-
- /**
- * @return TSqlMapper The SqlMap used by this MappedStatement
- */
- public function getManager()
- {
- return $this->_manager;
- }
-
- /**
- * @return TPreparedCommand command to prepare SQL statements.
- */
- public function getCommand()
- {
- return $this->_command;
- }
-
- /**
- * Empty the group by results cache.
- */
- protected function initialGroupByResults()
- {
- $this->_groupBy = new TSqlMapObjectCollectionTree();
- }
-
- /**
- * Creates a new mapped statement.
- * @param TSqlMapper an sqlmap.
- * @param TSqlMapStatement An SQL statement.
- */
- public function __construct(TSqlMapManager $sqlMap, TSqlMapStatement $statement)
- {
- $this->_manager = $sqlMap;
- $this->_statement = $statement;
- $this->_command = new TPreparedCommand();
- $this->initialGroupByResults();
- }
-
- public function getSqlString()
- {
- return $this->getStatement()->getSqlText()->getPreparedStatement()->getPreparedSql();
- }
-
- /**
- * Execute SQL Query.
- * @param IDbConnection database connection
- * @param array SQL statement and parameters.
- * @return mixed record set if applicable.
- * @throws TSqlMapExecutionException if execution error or false record set.
- * @throws TSqlMapQueryExecutionException if any execution error
- */
-/* protected function executeSQLQuery($connection, $sql)
- {
- try
- {
- if(!($recordSet = $connection->execute($sql['sql'],$sql['parameters'])))
- {
- throw new TSqlMapExecutionException(
- 'sqlmap_execution_error_no_record', $this->getID(),
- $connection->ErrorMsg());
- }
- return $recordSet;
- }
- catch (Exception $e)
- {
- throw new TSqlMapQueryExecutionException($this->getStatement(), $e);
- }
- }*/
-
- /**
- * Execute SQL Query with limits.
- * @param IDbConnection database connection
- * @param array SQL statement and parameters.
- * @return mixed record set if applicable.
- * @throws TSqlMapExecutionException if execution error or false record set.
- * @throws TSqlMapQueryExecutionException if any execution error
- */
- protected function executeSQLQueryLimit($connection, $command, $max, $skip)
- {
- if($max>-1 || $skip > -1)
- {
- $maxStr=$max>0?' LIMIT '.$max:'';
- $skipStr=$skip>0?' OFFSET '.$skip:'';
- $command->setText($command->getText().$maxStr.$skipStr);
- }
- $connection->setActive(true);
- return $command->query();
-
- /*//var_dump($command);
- try
- {
- $recordSet = $connection->selectLimit($sql['sql'],$max,$skip,$sql['parameters']);
- if(!$recordSet)
- {
- throw new TSqlMapExecutionException(
- 'sqlmap_execution_error_query_for_list',
- $connection->ErrorMsg());
- }
- return $recordSet;
- }
- catch (Exception $e)
- {
- throw new TSqlMapQueryExecutionException($this->getStatement(), $e);
- }*/
- }
-
- /**
- * Executes the SQL and retuns a List of result objects.
- * @param IDbConnection database connection
- * @param mixed The object used to set the parameters in the SQL.
- * @param object result collection object.
- * @param integer The number of rows to skip over.
- * @param integer The maximum number of rows to return.
- * @return array a list of result objects
- * @param callback row delegate handler
- * @see executeQueryForList()
- */
- public function executeQueryForList($connection, $parameter, $result=null, $skip=-1, $max=-1, $delegate=null)
- {
- $sql = $this->_command->create($this->_manager, $connection, $this->_statement, $parameter,$skip,$max);
- return $this->runQueryForList($connection, $parameter, $sql, $result, $delegate);
- }
-
- /**
- * Executes the SQL and retuns a List of result objects.
- *
- * This method should only be called by internal developers, consider using
- * <tt>executeQueryForList()</tt> first.
- *
- * @param IDbConnection database connection
- * @param mixed The object used to set the parameters in the SQL.
- * @param array SQL string and subsititution parameters.
- * @param object result collection object.
- * @param integer The number of rows to skip over.
- * @param integer The maximum number of rows to return.
- * @param callback row delegate handler
- * @return array a list of result objects
- * @see executeQueryForList()
- */
- public function runQueryForList($connection, $parameter, $sql, $result, $delegate=null)
- {
- $registry=$this->getManager()->getTypeHandlers();
- $list = $result instanceof ArrayAccess ? $result :
- $this->_statement->createInstanceOfListClass($registry);
- $connection->setActive(true);
- $reader = $sql->query();
- //$reader = $this->executeSQLQueryLimit($connection, $sql, $max, $skip);
- if($delegate!==null)
- {
- foreach($reader as $row)
- {
- $obj = $this->applyResultMap($row);
- $param = new TResultSetListItemParameter($obj, $parameter, $list);
- $this->raiseRowDelegate($delegate, $param);
- }
- }
- else
- {
- //var_dump($sql,$parameter);
- foreach($reader as $row)
- {
-// var_dump($row);
- $list[] = $this->applyResultMap($row);
- }
- }
-
- if(!$this->_groupBy->isEmpty())
- {
- $list = $this->_groupBy->collect();
- $this->initialGroupByResults();
- }
-
- $this->executePostSelect($connection);
- $this->onExecuteQuery($sql);
-
- return $list;
- }
-
- /**
- * Executes the SQL and retuns all rows selected in a map that is keyed on
- * the property named in the keyProperty parameter. The value at each key
- * will be the value of the property specified in the valueProperty parameter.
- * If valueProperty is null, the entire result object will be entered.
- * @param IDbConnection database connection
- * @param mixed The object used to set the parameters in the SQL.
- * @param string The property of the result object to be used as the key.
- * @param string The property of the result object to be used as the value (or null).
- * @param callback row delegate handler
- * @return array An array of object containing the rows keyed by keyProperty.
- */
- public function executeQueryForMap($connection, $parameter, $keyProperty, $valueProperty=null, $skip=-1, $max=-1, $delegate=null)
- {
- $sql = $this->_command->create($this->_manager, $connection, $this->_statement, $parameter, $skip, $max);
- return $this->runQueryForMap($connection, $parameter, $sql, $keyProperty, $valueProperty, $delegate);
- }
-
- /**
- * Executes the SQL and retuns all rows selected in a map that is keyed on
- * the property named in the keyProperty parameter. The value at each key
- * will be the value of the property specified in the valueProperty parameter.
- * If valueProperty is null, the entire result object will be entered.
- *
- * This method should only be called by internal developers, consider using
- * <tt>executeQueryForMap()</tt> first.
- *
- * @param IDbConnection database connection
- * @param mixed The object used to set the parameters in the SQL.
- * @param array SQL string and subsititution parameters.
- * @param string The property of the result object to be used as the key.
- * @param string The property of the result object to be used as the value (or null).
- * @param callback row delegate, a callback function
- * @return array An array of object containing the rows keyed by keyProperty.
- * @see executeQueryForMap()
- */
- public function runQueryForMap($connection, $parameter, $command, $keyProperty, $valueProperty=null, $delegate=null)
- {
- $map = array();
- //$recordSet = $this->executeSQLQuery($connection, $sql);
- $connection->setActive(true);
- $reader = $command->query();
- if($delegate!==null)
- {
- //while($row = $recordSet->fetchRow())
- foreach($reader as $row)
- {
- $obj = $this->applyResultMap($row);
- $key = TPropertyAccess::get($obj, $keyProperty);
- $value = ($valueProperty===null) ? $obj :
- TPropertyAccess::get($obj, $valueProperty);
- $param = new TResultSetMapItemParameter($key, $value, $parameter, $map);
- $this->raiseRowDelegate($delegate, $param);
- }
- }
- else
- {
- //while($row = $recordSet->fetchRow())
- foreach($reader as $row)
- {
- $obj = $this->applyResultMap($row);
- $key = TPropertyAccess::get($obj, $keyProperty);
- $map[$key] = ($valueProperty===null) ? $obj :
- TPropertyAccess::get($obj, $valueProperty);
- }
- }
- $this->onExecuteQuery($command);
- return $map;
- }
-
- /**
- * Raises delegate handler.
- * This method is invoked for each new list item. It is the responsibility
- * of the handler to add the item to the list.
- * @param object event parameter
- */
- protected function raiseRowDelegate($handler, $param)
- {
- if(is_string($handler))
- {
- call_user_func($handler,$this,$param);
- }
- else if(is_callable($handler,true))
- {
- // an array: 0 - object, 1 - method name/path
- list($object,$method)=$handler;
- if(is_string($object)) // static method call
- call_user_func($handler,$this,$param);
- else
- {
- if(($pos=strrpos($method,'.'))!==false)
- {
- $object=$this->getSubProperty(substr($method,0,$pos));
- $method=substr($method,$pos+1);
- }
- $object->$method($this,$param);
- }
- }
- else
- throw new TInvalidDataValueException('sqlmap_invalid_delegate', $this->getID(), $handler);
- }
-
- /**
- * Executes an SQL statement that returns a single row as an object of the
- * type of the <tt>$result</tt> passed in as a parameter.
- * @param IDbConnection database connection
- * @param mixed The parameter data (object, arrary, primitive) used to set the parameters in the SQL
- * @param mixed The result object.
- * @return ${return}
- */
- public function executeQueryForObject($connection, $parameter, $result=null)
- {
- $sql = $this->_command->create($this->_manager, $connection, $this->_statement, $parameter);
- return $this->runQueryForObject($connection, $sql, $result);
- }
-
- /**
- * Executes an SQL statement that returns a single row as an object of the
- * type of the <tt>$result</tt> passed in as a parameter.
- *
- * This method should only be called by internal developers, consider using
- * <tt>executeQueryForObject()</tt> first.
- *
- * @param IDbConnection database connection
- * @param array SQL string and subsititution parameters.
- * @param object The result object.
- * @return object the object.
- * @see executeQueryForObject()
- */
- public function runQueryForObject($connection, $command, &$result)
- {
- $object = null;
- $connection->setActive(true);
- foreach($command->query() as $row)
- $object = $this->applyResultMap($row, $result);
-
- if(!$this->_groupBy->isEmpty())
- {
- $list = $this->_groupBy->collect();
- $this->initialGroupByResults();
- $object = $list[0];
- }
-
- $this->executePostSelect($connection);
- $this->onExecuteQuery($command);
-
- return $object;
- }
-
- /**
- * Execute an insert statement. Fill the parameter object with the ouput
- * parameters if any, also could return the insert generated key.
- * @param IDbConnection database connection
- * @param mixed The parameter object used to fill the statement.
- * @return string the insert generated key.
- */
- public function executeInsert($connection, $parameter)
- {
- $generatedKey = $this->getPreGeneratedSelectKey($connection, $parameter);
-
- $command = $this->_command->create($this->_manager, $connection, $this->_statement, $parameter);
-// var_dump($command,$parameter);
- $result = $command->execute();
-
- if($generatedKey===null)
- $generatedKey = $this->getPostGeneratedSelectKey($connection, $parameter);
-
- $this->executePostSelect($connection);
- $this->onExecuteQuery($command);
- return $generatedKey;
- }
-
- /**
- * Gets the insert generated ID before executing an insert statement.
- * @param IDbConnection database connection
- * @param mixed insert statement parameter.
- * @return string new insert ID if pre-select key statement was executed, null otherwise.
- */
- protected function getPreGeneratedSelectKey($connection, $parameter)
- {
- if($this->_statement instanceof TSqlMapInsert)
- {
- $selectKey = $this->_statement->getSelectKey();
- if(($selectKey!==null) && !$selectKey->getIsAfter())
- return $this->executeSelectKey($connection, $parameter, $selectKey);
- }
- }
-
- /**
- * Gets the inserted row ID after executing an insert statement.
- * @param IDbConnection database connection
- * @param mixed insert statement parameter.
- * @return string last insert ID, null otherwise.
- */
- protected function getPostGeneratedSelectKey($connection, $parameter)
- {
- if($this->_statement instanceof TSqlMapInsert)
- {
- $selectKey = $this->_statement->getSelectKey();
- if(($selectKey!==null) && $selectKey->getIsAfter())
- return $this->executeSelectKey($connection, $parameter, $selectKey);
- }
- }
-
- /**
- * Execute the select key statement, used to obtain last insert ID.
- * @param IDbConnection database connection
- * @param mixed insert statement parameter
- * @param TSqlMapSelectKey select key statement
- * @return string last insert ID.
- */
- protected function executeSelectKey($connection, $parameter, $selectKey)
- {
- $mappedStatement = $this->getManager()->getMappedStatement($selectKey->getID());
- $generatedKey = $mappedStatement->executeQueryForObject(
- $connection, $parameter, null);
- if(strlen($prop = $selectKey->getProperty()) > 0)
- TPropertyAccess::set($parameter, $prop, $generatedKey);
- return $generatedKey;
- }
-
- /**
- * Execute an update statement. Also used for delete statement.
- * Return the number of rows effected.
- * @param IDbConnection database connection
- * @param mixed The object used to set the parameters in the SQL.
- * @return integer The number of rows effected.
- */
- public function executeUpdate($connection, $parameter)
- {
- $sql = $this->_command->create($this->getManager(),$connection, $this->_statement, $parameter);
- $affectedRows = $sql->execute();
- //$this->executeSQLQuery($connection, $sql);
- $this->executePostSelect($connection);
- $this->onExecuteQuery($sql);
- return $affectedRows;
- }
-
- /**
- * Process 'select' result properties
- * @param IDbConnection database connection
- */
- protected function executePostSelect($connection)
- {
- while(count($this->_selectQueue))
- {
- $postSelect = array_shift($this->_selectQueue);
- $method = $postSelect->getMethod();
- $statement = $postSelect->getStatement();
- $property = $postSelect->getResultProperty()->getProperty();
- $keys = $postSelect->getKeys();
- $resultObject = $postSelect->getResultObject();
-
- if($method == self::QUERY_FOR_LIST || $method == self::QUERY_FOR_ARRAY)
- {
- $values = $statement->executeQueryForList($connection, $keys, null);
-
- if($method == self::QUERY_FOR_ARRAY)
- $values = $values->toArray();
- TPropertyAccess::set($resultObject, $property, $values);
- }
- else if($method == self::QUERY_FOR_OBJECT)
- {
- $value = $statement->executeQueryForObject($connection, $keys, null);
- TPropertyAccess::set($resultObject, $property, $value);
- }
- }
- }
-
- /**
- * Raise the execute query event.
- * @param array prepared SQL statement and subsititution parameters
- */
- public function onExecuteQuery($sql)
- {
- $this->raiseEvent('OnExecuteQuery', $this, $sql);
- }
-
- /**
- * Apply result mapping.
- * @param array a result set row retrieved from the database
- * @param object the result object, will create if necessary.
- * @return object the result filled with data, null if not filled.
- */
- protected function applyResultMap($row, &$resultObject=null)
- {
- if($row === false) return null;
-
- $resultMapName = $this->_statement->getResultMap();
- $resultClass = $this->_statement->getResultClass();
-
- $obj=null;
- if($this->getManager()->getResultMaps()->contains($resultMapName))
- $obj = $this->fillResultMap($resultMapName, $row, null, $resultObject);
- else if(strlen($resultClass) > 0)
- $obj = $this->fillResultClass($resultClass, $row, $resultObject);
- else
- $obj = $this->fillDefaultResultMap(null, $row, $resultObject);
- if(class_exists('TActiveRecord',false) && $obj instanceof TActiveRecord)
- //Create a new clean active record.
- $obj=TActiveRecord::createRecord(get_class($obj),$obj);
- return $obj;
- }
-
- /**
- * Fill the result using ResultClass, will creates new result object if required.
- * @param string result object class name
- * @param array a result set row retrieved from the database
- * @param object the result object, will create if necessary.
- * @return object result object filled with data
- */
- protected function fillResultClass($resultClass, $row, $resultObject)
- {
- if($resultObject===null)
- {
- $registry = $this->getManager()->getTypeHandlers();
- $resultObject = $this->_statement->createInstanceOfResultClass($registry,$row);
- }
-
- if($resultObject instanceOf ArrayAccess)
- return $this->fillResultArrayList($row, $resultObject);
- else if(is_object($resultObject))
- return $this->fillResultObjectProperty($row, $resultObject);
- else
- return $this->fillDefaultResultMap(null, $row, $resultObject);
- }
-
- /**
- * Apply the result to a TList or an array.
- * @param array a result set row retrieved from the database
- * @param object result object, array or list
- * @return object result filled with data.
- */
- protected function fillResultArrayList($row, $resultObject)
- {
- if($resultObject instanceof TList)
- foreach($row as $v)
- $resultObject[] = $v;
- else
- foreach($row as $k => $v)
- $resultObject[$k] = $v;
- return $resultObject;
- }
-
- /**
- * Apply the result to an object.
- * @param array a result set row retrieved from the database
- * @param object result object, array or list
- * @return object result filled with data.
- */
- protected function fillResultObjectProperty($row, $resultObject)
- {
- $index = 0;
- $registry=$this->getManager()->getTypeHandlers();
- foreach($row as $k=>$v)
- {
- $property = new TResultProperty;
- if(is_string($k) && strlen($k) > 0)
- $property->setColumn($k);
- $property->setColumnIndex(++$index);
- $type = gettype(TPropertyAccess::get($resultObject,$k));
- $property->setType($type);
- $value = $property->getPropertyValue($registry,$row);
- TPropertyAccess::set($resultObject, $k,$value);
- }
- return $resultObject;
- }
-
- /**
- * Fills the result object according to result mappings.
- * @param string result map name.
- * @param array a result set row retrieved from the database
- * @param object result object to fill, will create new instances if required.
- * @return object result object filled with data.
- */
- protected function fillResultMap($resultMapName, $row, $parentGroup=null, &$resultObject=null)
- {
- $resultMap = $this->getManager()->getResultMap($resultMapName);
- $registry = $this->getManager()->getTypeHandlers();
- $resultMap = $resultMap->resolveSubMap($registry,$row);
-
- if($resultObject===null)
- $resultObject = $resultMap->createInstanceOfResult($registry);
-
- if(is_object($resultObject))
- {
- if(strlen($resultMap->getGroupBy()) > 0)
- return $this->addResultMapGroupBy($resultMap, $row, $parentGroup, $resultObject);
- else
- foreach($resultMap->getColumns() as $property)
- $this->setObjectProperty($resultMap, $property, $row, $resultObject);
- }
- else
- {
- $resultObject = $this->fillDefaultResultMap($resultMap, $row, $resultObject);
- }
- return $resultObject;
- }
-
- /**
- * ResultMap with GroupBy property. Save object collection graph in a tree
- * and collect the result later.
- * @param TResultMap result mapping details.
- * @param array a result set row retrieved from the database
- * @param object the result object
- * @return object result object.
- */
- protected function addResultMapGroupBy($resultMap, $row, $parent, &$resultObject)
- {
- $group = $this->getResultMapGroupKey($resultMap, $row);
-
- if(empty($parent))
- {
- $rootObject = array('object'=>$resultObject, 'property' => null);
- $this->_groupBy->add(null, $group, $rootObject);
- }
-
- foreach($resultMap->getColumns() as $property)
- {
- //set properties.
- $this->setObjectProperty($resultMap, $property, $row, $resultObject);
- $nested = $property->getResultMapping();
-
- //nested property
- if($this->getManager()->getResultMaps()->contains($nested))
- {
- $nestedMap = $this->getManager()->getResultMap($nested);
- $groupKey = $this->getResultMapGroupKey($nestedMap, $row);
-
- //add the node reference first
- if(empty($parent))
- $this->_groupBy->add($group, $groupKey, '');
-
- //get the nested result mapping value
- $value = $this->fillResultMap($nested, $row, $groupKey);
-
- //add it to the object tree graph
- $groupObject = array('object'=>$value, 'property' => $property->getProperty());
- if(empty($parent))
- $this->_groupBy->add($group, $groupKey, $groupObject);
- else
- $this->_groupBy->add($parent, $groupKey, $groupObject);
- }
- }
- return $resultObject;
- }
-
- /**
- * Gets the result 'group by' groupping key for each row.
- * @param TResultMap result mapping details.
- * @param array a result set row retrieved from the database
- * @return string groupping key.
- */
- protected function getResultMapGroupKey($resultMap, $row)
- {
- $groupBy = $resultMap->getGroupBy();
- if(isset($row[$groupBy]))
- return $resultMap->getID().$row[$groupBy];
- else
- return $resultMap->getID().crc32(serialize($row));
- }
-
- /**
- * Fill the result map using default settings. If <tt>$resultMap</tt> is null
- * the result object returned will be guessed from <tt>$resultObject</tt>.
- * @param TResultMap result mapping details.
- * @param array a result set row retrieved from the database
- * @param object the result object
- * @return mixed the result object filled with data.
- */
- protected function fillDefaultResultMap($resultMap, $row, $resultObject)
- {
- if($resultObject===null)
- $resultObject='';
-
- if($resultMap!==null)
- $result = $this->fillArrayResultMap($resultMap, $row, $resultObject);
- else
- $result = $row;
-
- //if scalar result types
- if(count($result) == 1 && ($type = gettype($resultObject))!= 'array')
- return $this->getScalarResult($result, $type);
- else
- return $result;
- }
-
- /**
- * Retrieve the result map as an array.
- * @param TResultMap result mapping details.
- * @param array a result set row retrieved from the database
- * @param object the result object
- * @return array array list of result objects.
- */
- protected function fillArrayResultMap($resultMap, $row, $resultObject)
- {
- $result = array();
- $registry=$this->getManager()->getTypeHandlers();
- foreach($resultMap->getColumns() as $column)
- {
- if(($column->getType()===null)
- && ($resultObject!==null) && !is_object($resultObject))
- $column->setType(gettype($resultObject));
- $result[$column->getProperty()] = $column->getPropertyValue($registry,$row);
- }
- return $result;
- }
-
- /**
- * Converts the first array value to scalar value of given type.
- * @param array list of results
- * @param string scalar type.
- * @return mixed scalar value.
- */
- protected function getScalarResult($result, $type)
- {
- $scalar = array_shift($result);
- settype($scalar, $type);
- return $scalar;
- }
-
- /**
- * Set a property of the result object with appropriate value.
- * @param TResultMap result mapping details.
- * @param TResultProperty the result property to fill.
- * @param array a result set row retrieved from the database
- * @param object the result object
- */
- protected function setObjectProperty($resultMap, $property, $row, &$resultObject)
- {
- $select = $property->getSelect();
- $key = $property->getProperty();
- $nested = $property->getNestedResultMap();
- $registry=$this->getManager()->getTypeHandlers();
- if($key === '')
- {
- $resultObject = $property->getPropertyValue($registry,$row);
- }
- else if(strlen($select) == 0 && ($nested===null))
- {
- $value = $property->getPropertyValue($registry,$row);
-
- $this->_IsRowDataFound = $this->_IsRowDataFound || ($value != null);
- if(is_array($resultObject) || is_object($resultObject))
- TPropertyAccess::set($resultObject, $key, $value);
- else
- $resultObject = $value;
- }
- else if($nested!==null)
- {
- if($property->instanceOfListType($resultObject) || $property->instanceOfArrayType($resultObject))
- {
- if(strlen($resultMap->getGroupBy()) <= 0)
- throw new TSqlMapExecutionException(
- 'sqlmap_non_groupby_array_list_type', $resultMap->getID(),
- get_class($resultObject), $key);
- }
- else
- {
- $obj = $nested->createInstanceOfResult($this->getManager()->getTypeHandlers());
- if($this->fillPropertyWithResultMap($nested, $row, $obj) == false)
- $obj = null;
- TPropertyAccess::set($resultObject, $key, $obj);
- }
- }
- else //'select' ResultProperty
- {
- $this->enquequePostSelect($select, $resultMap, $property, $row, $resultObject);
- }
- }
-
- /**
- * Add nested result property to post select queue.
- * @param string post select statement ID
- * @param TResultMap current result mapping details.
- * @param TResultProperty current result property.
- * @param array a result set row retrieved from the database
- * @param object the result object
- */
- protected function enquequePostSelect($select, $resultMap, $property, $row, $resultObject)
- {
- $statement = $this->getManager()->getMappedStatement($select);
- $key = $this->getPostSelectKeys($resultMap, $property, $row);
- $postSelect = new TPostSelectBinding;
- $postSelect->setStatement($statement);
- $postSelect->setResultObject($resultObject);
- $postSelect->setResultProperty($property);
- $postSelect->setKeys($key);
-
- if($property->instanceOfListType($resultObject))
- {
- $values = null;
- if($property->getLazyLoad())
- {
- $values = TLazyLoadList::newInstance($statement, $key,
- $resultObject, $property->getProperty());
- TPropertyAccess::set($resultObject, $property->getProperty(), $values);
- }
- else
- $postSelect->setMethod(self::QUERY_FOR_LIST);
- }
- else if($property->instanceOfArrayType($resultObject))
- $postSelect->setMethod(self::QUERY_FOR_ARRAY);
- else
- $postSelect->setMethod(self::QUERY_FOR_OBJECT);
-
- if(!$property->getLazyLoad())
- $this->_selectQueue[] = $postSelect;
- }
-
- /**
- * Finds in the post select property the SQL statement primary selection keys.
- * @param TResultMap result mapping details
- * @param TResultProperty result property
- * @param array current row data.
- * @return array list of primary key values.
- */
- protected function getPostSelectKeys($resultMap, $property,$row)
- {
- $value = $property->getColumn();
- if(is_int(strpos($value.',',0)) || is_int(strpos($value, '=',0)))
- {
- $keys = array();
- foreach(explode(',', $value) as $entry)
- {
- $pair =explode('=',$entry);
- $keys[trim($pair[0])] = $row[trim($pair[1])];
- }
- return $keys;
- }
- else
- {
- $registry=$this->getManager()->getTypeHandlers();
- return $property->getPropertyValue($registry,$row);
- }
- }
-
- /**
- * Fills the property with result mapping results.
- * @param TResultMap nested result mapping details.
- * @param array a result set row retrieved from the database
- * @param object the result object
- * @return boolean true if the data was found, false otherwise.
- */
- protected function fillPropertyWithResultMap($resultMap, $row, &$resultObject)
- {
- $dataFound = false;
- foreach($resultMap->getColumns() as $property)
- {
- $this->_IsRowDataFound = false;
- $this->setObjectProperty($resultMap, $property, $row, $resultObject);
- $dataFound = $dataFound || $this->_IsRowDataFound;
- }
- $this->_IsRowDataFound = $dataFound;
- return $dataFound;
- }
-
- public function __wakeup()
- {
- parent::__wakeup();
- if (is_null($this->_selectQueue)) $this->_selectQueue = array();
- }
-
- public function __sleep()
- {
- $exprops = array(); $cn = __CLASS__;
- if (!count($this->_selectQueue)) $exprops[] = "\0$cn\0_selectQueue";
- if (is_null($this->_groupBy)) $exprops[] = "\0$cn\0_groupBy";
- if (!$this->_IsRowDataFound) $exprops[] = "\0$cn\0_IsRowDataFound";
- return array_diff(parent::__sleep(),$exprops);
- }
-}
-
-/**
- * TPostSelectBinding class.
- *
- * @author Wei Zhuo <weizho[at]gmail[dot]com>
- * @version $Id$
- * @package System.Data.SqlMap.Statements
- * @since 3.1
- */
-class TPostSelectBinding
-{
- private $_statement=null;
- private $_property=null;
- private $_resultObject=null;
- private $_keys=null;
- private $_method=TMappedStatement::QUERY_FOR_LIST;
-
- public function getStatement(){ return $this->_statement; }
- public function setStatement($value){ $this->_statement = $value; }
-
- public function getResultProperty(){ return $this->_property; }
- public function setResultProperty($value){ $this->_property = $value; }
-
- public function getResultObject(){ return $this->_resultObject; }
- public function setResultObject($value){ $this->_resultObject = $value; }
-
- public function getKeys(){ return $this->_keys; }
- public function setKeys($value){ $this->_keys = $value; }
-
- public function getMethod(){ return $this->_method; }
- public function setMethod($value){ $this->_method = $value; }
-}
-
-/**
- * TSQLMapObjectCollectionTree class.
- *
- * Maps object collection graphs as trees. Nodes in the collection can
- * be {@link add} using parent relationships. The object collections can be
- * build using the {@link collect} method.
- *
- * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
- * @version $Id$
- * @package System.Data.SqlMap.Statements
- * @since 3.1
- */
-class TSqlMapObjectCollectionTree extends TComponent
-{
- /**
- * @var array object graph as tree
- */
- private $_tree = array();
- /**
- * @var array tree node values
- */
- private $_entries = array();
- /**
- * @var array resulting object collection
- */
- private $_list = array();
-
- /**
- * @return boolean true if the graph is empty
- */
- public function isEmpty()
- {
- return count($this->_entries) == 0;
- }
-
- /**
- * Add a new node to the object tree graph.
- * @param string parent node id
- * @param string new node id
- * @param mixed node value
- */
- public function add($parent, $node, $object='')
- {
- if(isset($this->_entries[$parent]) && ($this->_entries[$parent]!==null)
- && isset($this->_entries[$node]) && ($this->_entries[$node]!==null))
- {
- $this->_entries[$node] = $object;
- return;
- }
- $this->_entries[$node] = $object;
- if(empty($parent))
- {
- if(isset($this->_entries[$node]))
- return;
- $this->_tree[$node] = array();
- }
- $found = $this->addNode($this->_tree, $parent, $node);
- if(!$found && !empty($parent))
- {
- $this->_tree[$parent] = array();
- if(!isset($this->_entries[$parent]) || $object !== '')
- $this->_entries[$parent] = $object;
- $this->addNode($this->_tree, $parent, $node);
- }
- }
-
- /**
- * Find the parent node and add the new node as its child.
- * @param array list of nodes to check
- * @param string parent node id
- * @param string new node id
- * @return boolean true if parent node is found.
- */
- protected function addNode(&$childs, $parent, $node)
- {
- $found = false;
- reset($childs);
- for($i = 0, $k = count($childs); $i < $k; $i++)
- {
- $key = key($childs);
- next($childs);
- if($key == $parent)
- {
- $found = true;
- $childs[$key][$node] = array();
- }
- else
- {
- $found = $found || $this->addNode($childs[$key], $parent, $node);
- }
- }
- return $found;
- }
-
- /**
- * @return array object collection
- */
- public function collect()
- {
- while(count($this->_tree) > 0)
- $this->collectChildren(null, $this->_tree);
- return $this->getCollection();
- }
-
- /**
- * @param array list of nodes to check
- * @return boolean true if all nodes are leaf nodes, false otherwise
- */
- protected function hasChildren(&$nodes)
- {
- $hasChildren = false;
- foreach($nodes as $node)
- if(count($node) != 0)
- return true;
- return $hasChildren;
- }
-
- /**
- * Visit all the child nodes and collect them by removing.
- * @param string parent node id
- * @param array list of child nodes.
- */
- protected function collectChildren($parent, &$nodes)
- {
- $noChildren = !$this->hasChildren($nodes);
- $childs = array();
- for(reset($nodes); $key = key($nodes);)
- {
- next($nodes);
- if($noChildren)
- {
- $childs[] = $key;
- unset($nodes[$key]);
- }
- else
- $this->collectChildren($key, $nodes[$key]);
- }
- if(count($childs) > 0)
- $this->onChildNodesVisited($parent, $childs);
- }
-
- /**
- * Set the object properties for all the child nodes visited.
- * @param string parent node id
- * @param array list of child nodes visited.
- */
- protected function onChildNodesVisited($parent, $nodes)
- {
- if(empty($parent) || empty($this->_entries[$parent]))
- return;
-
- $parentObject = $this->_entries[$parent]['object'];
- $property = $this->_entries[$nodes[0]]['property'];
-
- $list = TPropertyAccess::get($parentObject, $property);
-
- foreach($nodes as $node)
- {
- if($list instanceof TList)
- $parentObject->{$property}[] = $this->_entries[$node]['object'];
- else if(is_array($list))
- $list[] = $this->_entries[$node]['object'];
- else
- throw new TSqlMapExecutionException(
- 'sqlmap_property_must_be_list');
- }
-
- if(is_array($list))
- TPropertyAccess::set($parentObject, $property, $list);
-
- if($this->_entries[$parent]['property'] === null)
- $this->_list[] = $parentObject;
- }
-
- /**
- * @return array object collection.
- */
- protected function getCollection()
- {
- return $this->_list;
- }
-
- public function __sleep()
- {
- $exprops = array(); $cn = __CLASS__;
- if (!count($this->_tree)) $exprops[] = "\0$cn\0_tree";
- if (!count($this->_entries)) $exprops[] = "\0$cn\0_entries";
- if (!count($this->_list)) $exprops[] = "\0$cn\0_list";
- return array_diff(parent::__sleep(),$exprops);
- }
-}
-
-/**
- * TResultSetListItemParameter class
- *
- * @author Wei Zhuo <weizho[at]gmail[dot]com>
- * @version $Id$
- * @package System.Data.SqlMap.Statements
- * @since 3.1
- */
-class TResultSetListItemParameter extends TComponent
-{
- private $_resultObject;
- private $_parameterObject;
- private $_list;
-
- public function __construct($result, $parameter, &$list)
- {
- $this->_resultObject = $result;
- $this->_parameterObject = $parameter;
- $this->_list = &$list;
- }
-
- public function getResult()
- {
- return $this->_resultObject;
- }
-
- public function getParameter()
- {
- return $this->_parameterObject;
- }
-
- public function &getList()
- {
- return $this->_list;
- }
-}
-
-/**
- * TResultSetMapItemParameter class.
- *
- * @author Wei Zhuo <weizho[at]gmail[dot]com>
- * @version $Id$
- * @package System.Data.SqlMap.Statements
- * @since 3.1
- */
-class TResultSetMapItemParameter extends TComponent
-{
- private $_key;
- private $_value;
- private $_parameterObject;
- private $_map;
-
- public function __construct($key, $value, $parameter, &$map)
- {
- $this->_key = $key;
- $this->_value = $value;
- $this->_parameterObject = $parameter;
- $this->_map = &$map;
- }
-
- public function getKey()
- {
- return $this->_key;
- }
-
- public function getValue()
- {
- return $this->_value;
- }
-
- public function getParameter()
- {
- return $this->_parameterObject;
- }
-
- public function &getMap()
- {
- return $this->_map;
- }
-}
-
+<?php +/** + * TMappedStatement and related classes. + * + * @author Wei Zhuo <weizhuo[at]gmail[dot]com> + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2012 PradoSoft + * @license http://www.pradosoft.com/license/ + * @version $Id$ + * @package System.Data.SqlMap.Statements + */ + +/** + * TMappedStatement class executes SQL mapped statements. Mapped Statements can + * hold any SQL statement and use Parameter Maps and Result Maps for input and output. + * + * This class is usualy instantiated during SQLMap configuration by TSqlDomBuilder. + * + * @author Wei Zhuo <weizhuo[at]gmail[dot]com> + * @version $Id$ + * @package System.Data.SqlMap.Statements + * @since 3.0 + */ +class TMappedStatement extends TComponent implements IMappedStatement +{ + /** + * @var TSqlMapStatement current SQL statement. + */ + private $_statement; + + /** + * @var TPreparedCommand SQL command prepareer + */ + private $_command; + + /** + * @var TSqlMapper sqlmap used by this mapper. + */ + private $_manager; + + /** + * @var TPostSelectBinding[] post select statement queue. + */ + private $_selectQueue=array(); + + /** + * @var boolean true when data is mapped to a particular row. + */ + private $_IsRowDataFound = false; + + /** + * @var TSQLMapObjectCollectionTree group by object collection tree + */ + private $_groupBy; + + /** + * @var Post select is to query for list. + */ + const QUERY_FOR_LIST = 0; + + /** + * @var Post select is to query for list. + */ + const QUERY_FOR_ARRAY = 1; + + /** + * @var Post select is to query for object. + */ + const QUERY_FOR_OBJECT = 2; + + /** + * @return string Name used to identify the TMappedStatement amongst the others. + * This the name of the SQL statement by default. + */ + public function getID() + { + return $this->_statement->ID; + } + + /** + * @return TSqlMapStatement The SQL statment used by this MappedStatement + */ + public function getStatement() + { + return $this->_statement; + } + + /** + * @return TSqlMapper The SqlMap used by this MappedStatement + */ + public function getManager() + { + return $this->_manager; + } + + /** + * @return TPreparedCommand command to prepare SQL statements. + */ + public function getCommand() + { + return $this->_command; + } + + /** + * Empty the group by results cache. + */ + protected function initialGroupByResults() + { + $this->_groupBy = new TSqlMapObjectCollectionTree(); + } + + /** + * Creates a new mapped statement. + * @param TSqlMapper an sqlmap. + * @param TSqlMapStatement An SQL statement. + */ + public function __construct(TSqlMapManager $sqlMap, TSqlMapStatement $statement) + { + $this->_manager = $sqlMap; + $this->_statement = $statement; + $this->_command = new TPreparedCommand(); + $this->initialGroupByResults(); + } + + public function getSqlString() + { + return $this->getStatement()->getSqlText()->getPreparedStatement()->getPreparedSql(); + } + + /** + * Execute SQL Query. + * @param IDbConnection database connection + * @param array SQL statement and parameters. + * @return mixed record set if applicable. + * @throws TSqlMapExecutionException if execution error or false record set. + * @throws TSqlMapQueryExecutionException if any execution error + */ +/* protected function executeSQLQuery($connection, $sql) + { + try + { + if(!($recordSet = $connection->execute($sql['sql'],$sql['parameters']))) + { + throw new TSqlMapExecutionException( + 'sqlmap_execution_error_no_record', $this->getID(), + $connection->ErrorMsg()); + } + return $recordSet; + } + catch (Exception $e) + { + throw new TSqlMapQueryExecutionException($this->getStatement(), $e); + } + }*/ + + /** + * Execute SQL Query with limits. + * @param IDbConnection database connection + * @param array SQL statement and parameters. + * @return mixed record set if applicable. + * @throws TSqlMapExecutionException if execution error or false record set. + * @throws TSqlMapQueryExecutionException if any execution error + */ + protected function executeSQLQueryLimit($connection, $command, $max, $skip) + { + if($max>-1 || $skip > -1) + { + $maxStr=$max>0?' LIMIT '.$max:''; + $skipStr=$skip>0?' OFFSET '.$skip:''; + $command->setText($command->getText().$maxStr.$skipStr); + } + $connection->setActive(true); + return $command->query(); + + /*//var_dump($command); + try + { + $recordSet = $connection->selectLimit($sql['sql'],$max,$skip,$sql['parameters']); + if(!$recordSet) + { + throw new TSqlMapExecutionException( + 'sqlmap_execution_error_query_for_list', + $connection->ErrorMsg()); + } + return $recordSet; + } + catch (Exception $e) + { + throw new TSqlMapQueryExecutionException($this->getStatement(), $e); + }*/ + } + + /** + * Executes the SQL and retuns a List of result objects. + * @param IDbConnection database connection + * @param mixed The object used to set the parameters in the SQL. + * @param object result collection object. + * @param integer The number of rows to skip over. + * @param integer The maximum number of rows to return. + * @return array a list of result objects + * @param callback row delegate handler + * @see executeQueryForList() + */ + public function executeQueryForList($connection, $parameter, $result=null, $skip=-1, $max=-1, $delegate=null) + { + $sql = $this->_command->create($this->_manager, $connection, $this->_statement, $parameter,$skip,$max); + return $this->runQueryForList($connection, $parameter, $sql, $result, $delegate); + } + + /** + * Executes the SQL and retuns a List of result objects. + * + * This method should only be called by internal developers, consider using + * <tt>executeQueryForList()</tt> first. + * + * @param IDbConnection database connection + * @param mixed The object used to set the parameters in the SQL. + * @param array SQL string and subsititution parameters. + * @param object result collection object. + * @param integer The number of rows to skip over. + * @param integer The maximum number of rows to return. + * @param callback row delegate handler + * @return array a list of result objects + * @see executeQueryForList() + */ + public function runQueryForList($connection, $parameter, $sql, $result, $delegate=null) + { + $registry=$this->getManager()->getTypeHandlers(); + $list = $result instanceof ArrayAccess ? $result : + $this->_statement->createInstanceOfListClass($registry); + $connection->setActive(true); + $reader = $sql->query(); + //$reader = $this->executeSQLQueryLimit($connection, $sql, $max, $skip); + if($delegate!==null) + { + foreach($reader as $row) + { + $obj = $this->applyResultMap($row); + $param = new TResultSetListItemParameter($obj, $parameter, $list); + $this->raiseRowDelegate($delegate, $param); + } + } + else + { + //var_dump($sql,$parameter); + foreach($reader as $row) + { +// var_dump($row); + $list[] = $this->applyResultMap($row); + } + } + + if(!$this->_groupBy->isEmpty()) + { + $list = $this->_groupBy->collect(); + $this->initialGroupByResults(); + } + + $this->executePostSelect($connection); + $this->onExecuteQuery($sql); + + return $list; + } + + /** + * Executes the SQL and retuns all rows selected in a map that is keyed on + * the property named in the keyProperty parameter. The value at each key + * will be the value of the property specified in the valueProperty parameter. + * If valueProperty is null, the entire result object will be entered. + * @param IDbConnection database connection + * @param mixed The object used to set the parameters in the SQL. + * @param string The property of the result object to be used as the key. + * @param string The property of the result object to be used as the value (or null). + * @param callback row delegate handler + * @return array An array of object containing the rows keyed by keyProperty. + */ + public function executeQueryForMap($connection, $parameter, $keyProperty, $valueProperty=null, $skip=-1, $max=-1, $delegate=null) + { + $sql = $this->_command->create($this->_manager, $connection, $this->_statement, $parameter, $skip, $max); + return $this->runQueryForMap($connection, $parameter, $sql, $keyProperty, $valueProperty, $delegate); + } + + /** + * Executes the SQL and retuns all rows selected in a map that is keyed on + * the property named in the keyProperty parameter. The value at each key + * will be the value of the property specified in the valueProperty parameter. + * If valueProperty is null, the entire result object will be entered. + * + * This method should only be called by internal developers, consider using + * <tt>executeQueryForMap()</tt> first. + * + * @param IDbConnection database connection + * @param mixed The object used to set the parameters in the SQL. + * @param array SQL string and subsititution parameters. + * @param string The property of the result object to be used as the key. + * @param string The property of the result object to be used as the value (or null). + * @param callback row delegate, a callback function + * @return array An array of object containing the rows keyed by keyProperty. + * @see executeQueryForMap() + */ + public function runQueryForMap($connection, $parameter, $command, $keyProperty, $valueProperty=null, $delegate=null) + { + $map = array(); + //$recordSet = $this->executeSQLQuery($connection, $sql); + $connection->setActive(true); + $reader = $command->query(); + if($delegate!==null) + { + //while($row = $recordSet->fetchRow()) + foreach($reader as $row) + { + $obj = $this->applyResultMap($row); + $key = TPropertyAccess::get($obj, $keyProperty); + $value = ($valueProperty===null) ? $obj : + TPropertyAccess::get($obj, $valueProperty); + $param = new TResultSetMapItemParameter($key, $value, $parameter, $map); + $this->raiseRowDelegate($delegate, $param); + } + } + else + { + //while($row = $recordSet->fetchRow()) + foreach($reader as $row) + { + $obj = $this->applyResultMap($row); + $key = TPropertyAccess::get($obj, $keyProperty); + $map[$key] = ($valueProperty===null) ? $obj : + TPropertyAccess::get($obj, $valueProperty); + } + } + $this->onExecuteQuery($command); + return $map; + } + + /** + * Raises delegate handler. + * This method is invoked for each new list item. It is the responsibility + * of the handler to add the item to the list. + * @param object event parameter + */ + protected function raiseRowDelegate($handler, $param) + { + if(is_string($handler)) + { + call_user_func($handler,$this,$param); + } + else if(is_callable($handler,true)) + { + // an array: 0 - object, 1 - method name/path + list($object,$method)=$handler; + if(is_string($object)) // static method call + call_user_func($handler,$this,$param); + else + { + if(($pos=strrpos($method,'.'))!==false) + { + $object=$this->getSubProperty(substr($method,0,$pos)); + $method=substr($method,$pos+1); + } + $object->$method($this,$param); + } + } + else + throw new TInvalidDataValueException('sqlmap_invalid_delegate', $this->getID(), $handler); + } + + /** + * Executes an SQL statement that returns a single row as an object of the + * type of the <tt>$result</tt> passed in as a parameter. + * @param IDbConnection database connection + * @param mixed The parameter data (object, arrary, primitive) used to set the parameters in the SQL + * @param mixed The result object. + * @return ${return} + */ + public function executeQueryForObject($connection, $parameter, $result=null) + { + $sql = $this->_command->create($this->_manager, $connection, $this->_statement, $parameter); + return $this->runQueryForObject($connection, $sql, $result); + } + + /** + * Executes an SQL statement that returns a single row as an object of the + * type of the <tt>$result</tt> passed in as a parameter. + * + * This method should only be called by internal developers, consider using + * <tt>executeQueryForObject()</tt> first. + * + * @param IDbConnection database connection + * @param array SQL string and subsititution parameters. + * @param object The result object. + * @return object the object. + * @see executeQueryForObject() + */ + public function runQueryForObject($connection, $command, &$result) + { + $object = null; + $connection->setActive(true); + foreach($command->query() as $row) + $object = $this->applyResultMap($row, $result); + + if(!$this->_groupBy->isEmpty()) + { + $list = $this->_groupBy->collect(); + $this->initialGroupByResults(); + $object = $list[0]; + } + + $this->executePostSelect($connection); + $this->onExecuteQuery($command); + + return $object; + } + + /** + * Execute an insert statement. Fill the parameter object with the ouput + * parameters if any, also could return the insert generated key. + * @param IDbConnection database connection + * @param mixed The parameter object used to fill the statement. + * @return string the insert generated key. + */ + public function executeInsert($connection, $parameter) + { + $generatedKey = $this->getPreGeneratedSelectKey($connection, $parameter); + + $command = $this->_command->create($this->_manager, $connection, $this->_statement, $parameter); +// var_dump($command,$parameter); + $result = $command->execute(); + + if($generatedKey===null) + $generatedKey = $this->getPostGeneratedSelectKey($connection, $parameter); + + $this->executePostSelect($connection); + $this->onExecuteQuery($command); + return $generatedKey; + } + + /** + * Gets the insert generated ID before executing an insert statement. + * @param IDbConnection database connection + * @param mixed insert statement parameter. + * @return string new insert ID if pre-select key statement was executed, null otherwise. + */ + protected function getPreGeneratedSelectKey($connection, $parameter) + { + if($this->_statement instanceof TSqlMapInsert) + { + $selectKey = $this->_statement->getSelectKey(); + if(($selectKey!==null) && !$selectKey->getIsAfter()) + return $this->executeSelectKey($connection, $parameter, $selectKey); + } + } + + /** + * Gets the inserted row ID after executing an insert statement. + * @param IDbConnection database connection + * @param mixed insert statement parameter. + * @return string last insert ID, null otherwise. + */ + protected function getPostGeneratedSelectKey($connection, $parameter) + { + if($this->_statement instanceof TSqlMapInsert) + { + $selectKey = $this->_statement->getSelectKey(); + if(($selectKey!==null) && $selectKey->getIsAfter()) + return $this->executeSelectKey($connection, $parameter, $selectKey); + } + } + + /** + * Execute the select key statement, used to obtain last insert ID. + * @param IDbConnection database connection + * @param mixed insert statement parameter + * @param TSqlMapSelectKey select key statement + * @return string last insert ID. + */ + protected function executeSelectKey($connection, $parameter, $selectKey) + { + $mappedStatement = $this->getManager()->getMappedStatement($selectKey->getID()); + $generatedKey = $mappedStatement->executeQueryForObject( + $connection, $parameter, null); + if(strlen($prop = $selectKey->getProperty()) > 0) + TPropertyAccess::set($parameter, $prop, $generatedKey); + return $generatedKey; + } + + /** + * Execute an update statement. Also used for delete statement. + * Return the number of rows effected. + * @param IDbConnection database connection + * @param mixed The object used to set the parameters in the SQL. + * @return integer The number of rows effected. + */ + public function executeUpdate($connection, $parameter) + { + $sql = $this->_command->create($this->getManager(),$connection, $this->_statement, $parameter); + $affectedRows = $sql->execute(); + //$this->executeSQLQuery($connection, $sql); + $this->executePostSelect($connection); + $this->onExecuteQuery($sql); + return $affectedRows; + } + + /** + * Process 'select' result properties + * @param IDbConnection database connection + */ + protected function executePostSelect($connection) + { + while(count($this->_selectQueue)) + { + $postSelect = array_shift($this->_selectQueue); + $method = $postSelect->getMethod(); + $statement = $postSelect->getStatement(); + $property = $postSelect->getResultProperty()->getProperty(); + $keys = $postSelect->getKeys(); + $resultObject = $postSelect->getResultObject(); + + if($method == self::QUERY_FOR_LIST || $method == self::QUERY_FOR_ARRAY) + { + $values = $statement->executeQueryForList($connection, $keys, null); + + if($method == self::QUERY_FOR_ARRAY) + $values = $values->toArray(); + TPropertyAccess::set($resultObject, $property, $values); + } + else if($method == self::QUERY_FOR_OBJECT) + { + $value = $statement->executeQueryForObject($connection, $keys, null); + TPropertyAccess::set($resultObject, $property, $value); + } + } + } + + /** + * Raise the execute query event. + * @param array prepared SQL statement and subsititution parameters + */ + public function onExecuteQuery($sql) + { + $this->raiseEvent('OnExecuteQuery', $this, $sql); + } + + /** + * Apply result mapping. + * @param array a result set row retrieved from the database + * @param object the result object, will create if necessary. + * @return object the result filled with data, null if not filled. + */ + protected function applyResultMap($row, &$resultObject=null) + { + if($row === false) return null; + + $resultMapName = $this->_statement->getResultMap(); + $resultClass = $this->_statement->getResultClass(); + + $obj=null; + if($this->getManager()->getResultMaps()->contains($resultMapName)) + $obj = $this->fillResultMap($resultMapName, $row, null, $resultObject); + else if(strlen($resultClass) > 0) + $obj = $this->fillResultClass($resultClass, $row, $resultObject); + else + $obj = $this->fillDefaultResultMap(null, $row, $resultObject); + if(class_exists('TActiveRecord',false) && $obj instanceof TActiveRecord) + //Create a new clean active record. + $obj=TActiveRecord::createRecord(get_class($obj),$obj); + return $obj; + } + + /** + * Fill the result using ResultClass, will creates new result object if required. + * @param string result object class name + * @param array a result set row retrieved from the database + * @param object the result object, will create if necessary. + * @return object result object filled with data + */ + protected function fillResultClass($resultClass, $row, $resultObject) + { + if($resultObject===null) + { + $registry = $this->getManager()->getTypeHandlers(); + $resultObject = $this->_statement->createInstanceOfResultClass($registry,$row); + } + + if($resultObject instanceOf ArrayAccess) + return $this->fillResultArrayList($row, $resultObject); + else if(is_object($resultObject)) + return $this->fillResultObjectProperty($row, $resultObject); + else + return $this->fillDefaultResultMap(null, $row, $resultObject); + } + + /** + * Apply the result to a TList or an array. + * @param array a result set row retrieved from the database + * @param object result object, array or list + * @return object result filled with data. + */ + protected function fillResultArrayList($row, $resultObject) + { + if($resultObject instanceof TList) + foreach($row as $v) + $resultObject[] = $v; + else + foreach($row as $k => $v) + $resultObject[$k] = $v; + return $resultObject; + } + + /** + * Apply the result to an object. + * @param array a result set row retrieved from the database + * @param object result object, array or list + * @return object result filled with data. + */ + protected function fillResultObjectProperty($row, $resultObject) + { + $index = 0; + $registry=$this->getManager()->getTypeHandlers(); + foreach($row as $k=>$v) + { + $property = new TResultProperty; + if(is_string($k) && strlen($k) > 0) + $property->setColumn($k); + $property->setColumnIndex(++$index); + $type = gettype(TPropertyAccess::get($resultObject,$k)); + $property->setType($type); + $value = $property->getPropertyValue($registry,$row); + TPropertyAccess::set($resultObject, $k,$value); + } + return $resultObject; + } + + /** + * Fills the result object according to result mappings. + * @param string result map name. + * @param array a result set row retrieved from the database + * @param object result object to fill, will create new instances if required. + * @return object result object filled with data. + */ + protected function fillResultMap($resultMapName, $row, $parentGroup=null, &$resultObject=null) + { + $resultMap = $this->getManager()->getResultMap($resultMapName); + $registry = $this->getManager()->getTypeHandlers(); + $resultMap = $resultMap->resolveSubMap($registry,$row); + + if($resultObject===null) + $resultObject = $resultMap->createInstanceOfResult($registry); + + if(is_object($resultObject)) + { + if(strlen($resultMap->getGroupBy()) > 0) + return $this->addResultMapGroupBy($resultMap, $row, $parentGroup, $resultObject); + else + foreach($resultMap->getColumns() as $property) + $this->setObjectProperty($resultMap, $property, $row, $resultObject); + } + else + { + $resultObject = $this->fillDefaultResultMap($resultMap, $row, $resultObject); + } + return $resultObject; + } + + /** + * ResultMap with GroupBy property. Save object collection graph in a tree + * and collect the result later. + * @param TResultMap result mapping details. + * @param array a result set row retrieved from the database + * @param object the result object + * @return object result object. + */ + protected function addResultMapGroupBy($resultMap, $row, $parent, &$resultObject) + { + $group = $this->getResultMapGroupKey($resultMap, $row); + + if(empty($parent)) + { + $rootObject = array('object'=>$resultObject, 'property' => null); + $this->_groupBy->add(null, $group, $rootObject); + } + + foreach($resultMap->getColumns() as $property) + { + //set properties. + $this->setObjectProperty($resultMap, $property, $row, $resultObject); + $nested = $property->getResultMapping(); + + //nested property + if($this->getManager()->getResultMaps()->contains($nested)) + { + $nestedMap = $this->getManager()->getResultMap($nested); + $groupKey = $this->getResultMapGroupKey($nestedMap, $row); + + //add the node reference first + if(empty($parent)) + $this->_groupBy->add($group, $groupKey, ''); + + //get the nested result mapping value + $value = $this->fillResultMap($nested, $row, $groupKey); + + //add it to the object tree graph + $groupObject = array('object'=>$value, 'property' => $property->getProperty()); + if(empty($parent)) + $this->_groupBy->add($group, $groupKey, $groupObject); + else + $this->_groupBy->add($parent, $groupKey, $groupObject); + } + } + return $resultObject; + } + + /** + * Gets the result 'group by' groupping key for each row. + * @param TResultMap result mapping details. + * @param array a result set row retrieved from the database + * @return string groupping key. + */ + protected function getResultMapGroupKey($resultMap, $row) + { + $groupBy = $resultMap->getGroupBy(); + if(isset($row[$groupBy])) + return $resultMap->getID().$row[$groupBy]; + else + return $resultMap->getID().crc32(serialize($row)); + } + + /** + * Fill the result map using default settings. If <tt>$resultMap</tt> is null + * the result object returned will be guessed from <tt>$resultObject</tt>. + * @param TResultMap result mapping details. + * @param array a result set row retrieved from the database + * @param object the result object + * @return mixed the result object filled with data. + */ + protected function fillDefaultResultMap($resultMap, $row, $resultObject) + { + if($resultObject===null) + $resultObject=''; + + if($resultMap!==null) + $result = $this->fillArrayResultMap($resultMap, $row, $resultObject); + else + $result = $row; + + //if scalar result types + if(count($result) == 1 && ($type = gettype($resultObject))!= 'array') + return $this->getScalarResult($result, $type); + else + return $result; + } + + /** + * Retrieve the result map as an array. + * @param TResultMap result mapping details. + * @param array a result set row retrieved from the database + * @param object the result object + * @return array array list of result objects. + */ + protected function fillArrayResultMap($resultMap, $row, $resultObject) + { + $result = array(); + $registry=$this->getManager()->getTypeHandlers(); + foreach($resultMap->getColumns() as $column) + { + if(($column->getType()===null) + && ($resultObject!==null) && !is_object($resultObject)) + $column->setType(gettype($resultObject)); + $result[$column->getProperty()] = $column->getPropertyValue($registry,$row); + } + return $result; + } + + /** + * Converts the first array value to scalar value of given type. + * @param array list of results + * @param string scalar type. + * @return mixed scalar value. + */ + protected function getScalarResult($result, $type) + { + $scalar = array_shift($result); + settype($scalar, $type); + return $scalar; + } + + /** + * Set a property of the result object with appropriate value. + * @param TResultMap result mapping details. + * @param TResultProperty the result property to fill. + * @param array a result set row retrieved from the database + * @param object the result object + */ + protected function setObjectProperty($resultMap, $property, $row, &$resultObject) + { + $select = $property->getSelect(); + $key = $property->getProperty(); + $nested = $property->getNestedResultMap(); + $registry=$this->getManager()->getTypeHandlers(); + if($key === '') + { + $resultObject = $property->getPropertyValue($registry,$row); + } + else if(strlen($select) == 0 && ($nested===null)) + { + $value = $property->getPropertyValue($registry,$row); + + $this->_IsRowDataFound = $this->_IsRowDataFound || ($value != null); + if(is_array($resultObject) || is_object($resultObject)) + TPropertyAccess::set($resultObject, $key, $value); + else + $resultObject = $value; + } + else if($nested!==null) + { + if($property->instanceOfListType($resultObject) || $property->instanceOfArrayType($resultObject)) + { + if(strlen($resultMap->getGroupBy()) <= 0) + throw new TSqlMapExecutionException( + 'sqlmap_non_groupby_array_list_type', $resultMap->getID(), + get_class($resultObject), $key); + } + else + { + $obj = $nested->createInstanceOfResult($this->getManager()->getTypeHandlers()); + if($this->fillPropertyWithResultMap($nested, $row, $obj) == false) + $obj = null; + TPropertyAccess::set($resultObject, $key, $obj); + } + } + else //'select' ResultProperty + { + $this->enquequePostSelect($select, $resultMap, $property, $row, $resultObject); + } + } + + /** + * Add nested result property to post select queue. + * @param string post select statement ID + * @param TResultMap current result mapping details. + * @param TResultProperty current result property. + * @param array a result set row retrieved from the database + * @param object the result object + */ + protected function enquequePostSelect($select, $resultMap, $property, $row, $resultObject) + { + $statement = $this->getManager()->getMappedStatement($select); + $key = $this->getPostSelectKeys($resultMap, $property, $row); + $postSelect = new TPostSelectBinding; + $postSelect->setStatement($statement); + $postSelect->setResultObject($resultObject); + $postSelect->setResultProperty($property); + $postSelect->setKeys($key); + + if($property->instanceOfListType($resultObject)) + { + $values = null; + if($property->getLazyLoad()) + { + $values = TLazyLoadList::newInstance($statement, $key, + $resultObject, $property->getProperty()); + TPropertyAccess::set($resultObject, $property->getProperty(), $values); + } + else + $postSelect->setMethod(self::QUERY_FOR_LIST); + } + else if($property->instanceOfArrayType($resultObject)) + $postSelect->setMethod(self::QUERY_FOR_ARRAY); + else + $postSelect->setMethod(self::QUERY_FOR_OBJECT); + + if(!$property->getLazyLoad()) + $this->_selectQueue[] = $postSelect; + } + + /** + * Finds in the post select property the SQL statement primary selection keys. + * @param TResultMap result mapping details + * @param TResultProperty result property + * @param array current row data. + * @return array list of primary key values. + */ + protected function getPostSelectKeys($resultMap, $property,$row) + { + $value = $property->getColumn(); + if(is_int(strpos($value.',',0)) || is_int(strpos($value, '=',0))) + { + $keys = array(); + foreach(explode(',', $value) as $entry) + { + $pair =explode('=',$entry); + $keys[trim($pair[0])] = $row[trim($pair[1])]; + } + return $keys; + } + else + { + $registry=$this->getManager()->getTypeHandlers(); + return $property->getPropertyValue($registry,$row); + } + } + + /** + * Fills the property with result mapping results. + * @param TResultMap nested result mapping details. + * @param array a result set row retrieved from the database + * @param object the result object + * @return boolean true if the data was found, false otherwise. + */ + protected function fillPropertyWithResultMap($resultMap, $row, &$resultObject) + { + $dataFound = false; + foreach($resultMap->getColumns() as $property) + { + $this->_IsRowDataFound = false; + $this->setObjectProperty($resultMap, $property, $row, $resultObject); + $dataFound = $dataFound || $this->_IsRowDataFound; + } + $this->_IsRowDataFound = $dataFound; + return $dataFound; + } + + public function __wakeup() + { + parent::__wakeup(); + if (is_null($this->_selectQueue)) $this->_selectQueue = array(); + } + + public function __sleep() + { + $exprops = array(); $cn = __CLASS__; + if (!count($this->_selectQueue)) $exprops[] = "\0$cn\0_selectQueue"; + if (is_null($this->_groupBy)) $exprops[] = "\0$cn\0_groupBy"; + if (!$this->_IsRowDataFound) $exprops[] = "\0$cn\0_IsRowDataFound"; + return array_diff(parent::__sleep(),$exprops); + } +} + +/** + * TPostSelectBinding class. + * + * @author Wei Zhuo <weizho[at]gmail[dot]com> + * @version $Id$ + * @package System.Data.SqlMap.Statements + * @since 3.1 + */ +class TPostSelectBinding +{ + private $_statement=null; + private $_property=null; + private $_resultObject=null; + private $_keys=null; + private $_method=TMappedStatement::QUERY_FOR_LIST; + + public function getStatement(){ return $this->_statement; } + public function setStatement($value){ $this->_statement = $value; } + + public function getResultProperty(){ return $this->_property; } + public function setResultProperty($value){ $this->_property = $value; } + + public function getResultObject(){ return $this->_resultObject; } + public function setResultObject($value){ $this->_resultObject = $value; } + + public function getKeys(){ return $this->_keys; } + public function setKeys($value){ $this->_keys = $value; } + + public function getMethod(){ return $this->_method; } + public function setMethod($value){ $this->_method = $value; } +} + +/** + * TSQLMapObjectCollectionTree class. + * + * Maps object collection graphs as trees. Nodes in the collection can + * be {@link add} using parent relationships. The object collections can be + * build using the {@link collect} method. + * + * @author Wei Zhuo <weizhuo[at]gmail[dot]com> + * @version $Id$ + * @package System.Data.SqlMap.Statements + * @since 3.1 + */ +class TSqlMapObjectCollectionTree extends TComponent +{ + /** + * @var array object graph as tree + */ + private $_tree = array(); + /** + * @var array tree node values + */ + private $_entries = array(); + /** + * @var array resulting object collection + */ + private $_list = array(); + + /** + * @return boolean true if the graph is empty + */ + public function isEmpty() + { + return count($this->_entries) == 0; + } + + /** + * Add a new node to the object tree graph. + * @param string parent node id + * @param string new node id + * @param mixed node value + */ + public function add($parent, $node, $object='') + { + if(isset($this->_entries[$parent]) && ($this->_entries[$parent]!==null) + && isset($this->_entries[$node]) && ($this->_entries[$node]!==null)) + { + $this->_entries[$node] = $object; + return; + } + $this->_entries[$node] = $object; + if(empty($parent)) + { + if(isset($this->_entries[$node])) + return; + $this->_tree[$node] = array(); + } + $found = $this->addNode($this->_tree, $parent, $node); + if(!$found && !empty($parent)) + { + $this->_tree[$parent] = array(); + if(!isset($this->_entries[$parent]) || $object !== '') + $this->_entries[$parent] = $object; + $this->addNode($this->_tree, $parent, $node); + } + } + + /** + * Find the parent node and add the new node as its child. + * @param array list of nodes to check + * @param string parent node id + * @param string new node id + * @return boolean true if parent node is found. + */ + protected function addNode(&$childs, $parent, $node) + { + $found = false; + reset($childs); + for($i = 0, $k = count($childs); $i < $k; $i++) + { + $key = key($childs); + next($childs); + if($key == $parent) + { + $found = true; + $childs[$key][$node] = array(); + } + else + { + $found = $found || $this->addNode($childs[$key], $parent, $node); + } + } + return $found; + } + + /** + * @return array object collection + */ + public function collect() + { + while(count($this->_tree) > 0) + $this->collectChildren(null, $this->_tree); + return $this->getCollection(); + } + + /** + * @param array list of nodes to check + * @return boolean true if all nodes are leaf nodes, false otherwise + */ + protected function hasChildren(&$nodes) + { + $hasChildren = false; + foreach($nodes as $node) + if(count($node) != 0) + return true; + return $hasChildren; + } + + /** + * Visit all the child nodes and collect them by removing. + * @param string parent node id + * @param array list of child nodes. + */ + protected function collectChildren($parent, &$nodes) + { + $noChildren = !$this->hasChildren($nodes); + $childs = array(); + for(reset($nodes); $key = key($nodes);) + { + next($nodes); + if($noChildren) + { + $childs[] = $key; + unset($nodes[$key]); + } + else + $this->collectChildren($key, $nodes[$key]); + } + if(count($childs) > 0) + $this->onChildNodesVisited($parent, $childs); + } + + /** + * Set the object properties for all the child nodes visited. + * @param string parent node id + * @param array list of child nodes visited. + */ + protected function onChildNodesVisited($parent, $nodes) + { + if(empty($parent) || empty($this->_entries[$parent])) + return; + + $parentObject = $this->_entries[$parent]['object']; + $property = $this->_entries[$nodes[0]]['property']; + + $list = TPropertyAccess::get($parentObject, $property); + + foreach($nodes as $node) + { + if($list instanceof TList) + $parentObject->{$property}[] = $this->_entries[$node]['object']; + else if(is_array($list)) + $list[] = $this->_entries[$node]['object']; + else + throw new TSqlMapExecutionException( + 'sqlmap_property_must_be_list'); + } + + if(is_array($list)) + TPropertyAccess::set($parentObject, $property, $list); + + if($this->_entries[$parent]['property'] === null) + $this->_list[] = $parentObject; + } + + /** + * @return array object collection. + */ + protected function getCollection() + { + return $this->_list; + } + + public function __sleep() + { + $exprops = array(); $cn = __CLASS__; + if (!count($this->_tree)) $exprops[] = "\0$cn\0_tree"; + if (!count($this->_entries)) $exprops[] = "\0$cn\0_entries"; + if (!count($this->_list)) $exprops[] = "\0$cn\0_list"; + return array_diff(parent::__sleep(),$exprops); + } +} + +/** + * TResultSetListItemParameter class + * + * @author Wei Zhuo <weizho[at]gmail[dot]com> + * @version $Id$ + * @package System.Data.SqlMap.Statements + * @since 3.1 + */ +class TResultSetListItemParameter extends TComponent +{ + private $_resultObject; + private $_parameterObject; + private $_list; + + public function __construct($result, $parameter, &$list) + { + $this->_resultObject = $result; + $this->_parameterObject = $parameter; + $this->_list = &$list; + } + + public function getResult() + { + return $this->_resultObject; + } + + public function getParameter() + { + return $this->_parameterObject; + } + + public function &getList() + { + return $this->_list; + } +} + +/** + * TResultSetMapItemParameter class. + * + * @author Wei Zhuo <weizho[at]gmail[dot]com> + * @version $Id$ + * @package System.Data.SqlMap.Statements + * @since 3.1 + */ +class TResultSetMapItemParameter extends TComponent +{ + private $_key; + private $_value; + private $_parameterObject; + private $_map; + + public function __construct($key, $value, $parameter, &$map) + { + $this->_key = $key; + $this->_value = $value; + $this->_parameterObject = $parameter; + $this->_map = &$map; + } + + public function getKey() + { + return $this->_key; + } + + public function getValue() + { + return $this->_value; + } + + public function getParameter() + { + return $this->_parameterObject; + } + + public function &getMap() + { + return $this->_map; + } +} + diff --git a/framework/Data/SqlMap/Statements/TPreparedCommand.php b/framework/Data/SqlMap/Statements/TPreparedCommand.php index 1d4a7088..7aa249ee 100644 --- a/framework/Data/SqlMap/Statements/TPreparedCommand.php +++ b/framework/Data/SqlMap/Statements/TPreparedCommand.php @@ -1,67 +1,67 @@ -<?php
-/**
- * TPreparedCommand class file.
- *
- * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
- * @link http://www.pradosoft.com/
+<?php +/** + * TPreparedCommand class file. + * + * @author Wei Zhuo <weizhuo[at]gmail[dot]com> + * @link http://www.pradosoft.com/ * @copyright Copyright © 2005-2012 PradoSoft - * @license http://www.pradosoft.com/license/
- * @version $Id$
- * @package System.Data.SqlMap.Statements
- */
-
-Prado::using('System.Data.Common.TDbMetaData');
-Prado::using('System.Data.Common.TDbCommandBuilder');
-
-/**
- * TPreparedCommand class.
- *
- * @author Wei Zhuo <weizho[at]gmail[dot]com>
- * @version $Id$
- * @package System.Data.SqlMap.Statements
- * @since 3.1
- */
-class TPreparedCommand
-{
- public function create(TSqlMapManager $manager, $connection, $statement, $parameterObject,$skip=null,$max=null)
- {
- $sqlText = $statement->getSQLText();
-
- $prepared = $sqlText->getPreparedStatement($parameterObject);
- $connection->setActive(true);
- $sql = $prepared->getPreparedSql();
-
- if($sqlText instanceof TSimpleDynamicSql)
- $sql = $sqlText->replaceDynamicParameter($sql, $parameterObject);
-
- if($max!==null || $skip!==null)
- {
- $builder = TDbMetaData::getInstance($connection)->createCommandBuilder();
- $sql = $builder->applyLimitOffset($sql,$max,$skip);
- }
- $command = $connection->createCommand($sql);
- $this->applyParameterMap($manager, $command, $prepared, $statement, $parameterObject);
-
- return $command;
- }
-
- protected function applyParameterMap($manager,$command,$prepared, $statement, $parameterObject)
- {
- $properties = $prepared->getParameterNames();
- $parameters = $prepared->getParameterValues();
- $registry=$manager->getTypeHandlers();
- for($i = 0, $k=$properties->getCount(); $i<$k; $i++)
- {
- $property = $statement->parameterMap()->getProperty($i);
- $value = $statement->parameterMap()->getPropertyValue($registry,$property, $parameterObject);
- $dbType = $property->getDbType();
- if($dbType=='') //relies on PHP lax comparison
- $command->bindValue($i+1,$value, TDbCommandBuilder::getPdoType($value));
- else if(strpos($dbType, 'PDO::')===0)
- $command->bindValue($i+1,$value, constant($property->getDbType())); //assumes PDO types, e.g. PDO::PARAM_INT
- else
- $command->bindValue($i+1,$value);
- }
- }
-}
-
+ * @license http://www.pradosoft.com/license/ + * @version $Id$ + * @package System.Data.SqlMap.Statements + */ + +Prado::using('System.Data.Common.TDbMetaData'); +Prado::using('System.Data.Common.TDbCommandBuilder'); + +/** + * TPreparedCommand class. + * + * @author Wei Zhuo <weizho[at]gmail[dot]com> + * @version $Id$ + * @package System.Data.SqlMap.Statements + * @since 3.1 + */ +class TPreparedCommand +{ + public function create(TSqlMapManager $manager, $connection, $statement, $parameterObject,$skip=null,$max=null) + { + $sqlText = $statement->getSQLText(); + + $prepared = $sqlText->getPreparedStatement($parameterObject); + $connection->setActive(true); + $sql = $prepared->getPreparedSql(); + + if($sqlText instanceof TSimpleDynamicSql) + $sql = $sqlText->replaceDynamicParameter($sql, $parameterObject); + + if($max!==null || $skip!==null) + { + $builder = TDbMetaData::getInstance($connection)->createCommandBuilder(); + $sql = $builder->applyLimitOffset($sql,$max,$skip); + } + $command = $connection->createCommand($sql); + $this->applyParameterMap($manager, $command, $prepared, $statement, $parameterObject); + + return $command; + } + + protected function applyParameterMap($manager,$command,$prepared, $statement, $parameterObject) + { + $properties = $prepared->getParameterNames(); + $parameters = $prepared->getParameterValues(); + $registry=$manager->getTypeHandlers(); + for($i = 0, $k=$properties->getCount(); $i<$k; $i++) + { + $property = $statement->parameterMap()->getProperty($i); + $value = $statement->parameterMap()->getPropertyValue($registry,$property, $parameterObject); + $dbType = $property->getDbType(); + if($dbType=='') //relies on PHP lax comparison + $command->bindValue($i+1,$value, TDbCommandBuilder::getPdoType($value)); + else if(strpos($dbType, 'PDO::')===0) + $command->bindValue($i+1,$value, constant($property->getDbType())); //assumes PDO types, e.g. PDO::PARAM_INT + else + $command->bindValue($i+1,$value); + } + } +} + diff --git a/framework/Data/SqlMap/Statements/TPreparedStatement.php b/framework/Data/SqlMap/Statements/TPreparedStatement.php index d091861f..3abd7442 100644 --- a/framework/Data/SqlMap/Statements/TPreparedStatement.php +++ b/framework/Data/SqlMap/Statements/TPreparedStatement.php @@ -1,57 +1,57 @@ -<?php
-/**
- * TPreparedStatement class file.
- *
- * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
- * @link http://www.pradosoft.com/
+<?php +/** + * TPreparedStatement class file. + * + * @author Wei Zhuo <weizhuo[at]gmail[dot]com> + * @link http://www.pradosoft.com/ * @copyright Copyright © 2005-2012 PradoSoft - * @license http://www.pradosoft.com/license/
- * @version $Id$
- * @package System.Data.SqlMap.Statements
- */
-
-/**
- * TpreparedStatement class.
- *
- * @author Wei Zhuo <weizho[at]gmail[dot]com>
- * @version $Id$
- * @package System.Data.SqlMap.Statements
- * @since 3.1
- */
-class TPreparedStatement extends TComponent
-{
- private $_sqlString='';
- private $_parameterNames;
- private $_parameterValues;
-
- public function __construct()
- {
- $this->_parameterNames=new TList;
- $this->_parameterValues=new TMap;
- }
-
- public function getPreparedSql(){ return $this->_sqlString; }
- public function setPreparedSql($value){ $this->_sqlString = $value; }
-
- public function getParameterNames(){ return $this->_parameterNames; }
- public function setParameterNames($value){ $this->_parameterNames = $value; }
-
- public function getParameterValues(){ return $this->_parameterValues; }
- public function setParameterValues($value){ $this->_parameterValues = $value; }
-
- public function __wakeup()
- {
- parent::__wakeup();
- if (!$this->_parameterNames) $this->_parameterNames = new TList;
- if (!$this->_parameterValues) $this->_parameterValues = new TMap;
- }
-
- public function __sleep()
- {
- $exprops = array(); $cn = __CLASS__;
- if (!$this->_parameterNames->getCount()) $exprops[] = "\0$cn\0_parameterNames";
- if (!$this->_parameterValues->getCount()) $exprops[] = "\0$cn\0_parameterValues";
- return array_diff(parent::__sleep(),$exprops);
- }
-}
-
+ * @license http://www.pradosoft.com/license/ + * @version $Id$ + * @package System.Data.SqlMap.Statements + */ + +/** + * TpreparedStatement class. + * + * @author Wei Zhuo <weizho[at]gmail[dot]com> + * @version $Id$ + * @package System.Data.SqlMap.Statements + * @since 3.1 + */ +class TPreparedStatement extends TComponent +{ + private $_sqlString=''; + private $_parameterNames; + private $_parameterValues; + + public function __construct() + { + $this->_parameterNames=new TList; + $this->_parameterValues=new TMap; + } + + public function getPreparedSql(){ return $this->_sqlString; } + public function setPreparedSql($value){ $this->_sqlString = $value; } + + public function getParameterNames(){ return $this->_parameterNames; } + public function setParameterNames($value){ $this->_parameterNames = $value; } + + public function getParameterValues(){ return $this->_parameterValues; } + public function setParameterValues($value){ $this->_parameterValues = $value; } + + public function __wakeup() + { + parent::__wakeup(); + if (!$this->_parameterNames) $this->_parameterNames = new TList; + if (!$this->_parameterValues) $this->_parameterValues = new TMap; + } + + public function __sleep() + { + $exprops = array(); $cn = __CLASS__; + if (!$this->_parameterNames->getCount()) $exprops[] = "\0$cn\0_parameterNames"; + if (!$this->_parameterValues->getCount()) $exprops[] = "\0$cn\0_parameterValues"; + return array_diff(parent::__sleep(),$exprops); + } +} + diff --git a/framework/Data/SqlMap/Statements/TPreparedStatementFactory.php b/framework/Data/SqlMap/Statements/TPreparedStatementFactory.php index 0d8286fa..9e70ba00 100644 --- a/framework/Data/SqlMap/Statements/TPreparedStatementFactory.php +++ b/framework/Data/SqlMap/Statements/TPreparedStatementFactory.php @@ -1,49 +1,49 @@ -<?php
-/**
- * TPreparedStatementFactory class file.
- *
- * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
- * @link http://www.pradosoft.com/
- * @copyright Copyright © 2005-2012 PradoSoft
- * @license http://www.pradosoft.com/license/
- * @version $Id$
- * @package System.Data.SqlMap.Statements
- */
-
-/**
- * TPreparedStatementFactory class.
- *
- * @author Wei Zhuo <weizho[at]gmail[dot]com>
- * @version $Id$
- * @package System.Data.SqlMap.Statements
- * @since 3.1
- */
-class TPreparedStatementFactory
-{
- private $_statement;
- private $_preparedStatement;
- private $_parameterPrefix = 'param';
- private $_commandText;
-
- public function __construct($statement, $sqlString)
- {
- $this->_statement = $statement;
- $this->_commandText = $sqlString;
- }
-
- public function prepare()
- {
- $this->_preparedStatement = new TPreparedStatement();
- $this->_preparedStatement->setPreparedSql($this->_commandText);
- if($this->_statement->parameterMap()!==null)
- $this->createParametersForTextCommand();
- return $this->_preparedStatement;
- }
-
- protected function createParametersForTextCommand()
- {
- foreach($this->_statement->ParameterMap()->getProperties() as $prop)
- $this->_preparedStatement->getParameterNames()->add($prop->getProperty());
- }
-}
-
+<?php +/** + * TPreparedStatementFactory class file. + * + * @author Wei Zhuo <weizhuo[at]gmail[dot]com> + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2012 PradoSoft + * @license http://www.pradosoft.com/license/ + * @version $Id$ + * @package System.Data.SqlMap.Statements + */ + +/** + * TPreparedStatementFactory class. + * + * @author Wei Zhuo <weizho[at]gmail[dot]com> + * @version $Id$ + * @package System.Data.SqlMap.Statements + * @since 3.1 + */ +class TPreparedStatementFactory +{ + private $_statement; + private $_preparedStatement; + private $_parameterPrefix = 'param'; + private $_commandText; + + public function __construct($statement, $sqlString) + { + $this->_statement = $statement; + $this->_commandText = $sqlString; + } + + public function prepare() + { + $this->_preparedStatement = new TPreparedStatement(); + $this->_preparedStatement->setPreparedSql($this->_commandText); + if($this->_statement->parameterMap()!==null) + $this->createParametersForTextCommand(); + return $this->_preparedStatement; + } + + protected function createParametersForTextCommand() + { + foreach($this->_statement->ParameterMap()->getProperties() as $prop) + $this->_preparedStatement->getParameterNames()->add($prop->getProperty()); + } +} + diff --git a/framework/Data/SqlMap/Statements/TSelectMappedStatement.php b/framework/Data/SqlMap/Statements/TSelectMappedStatement.php index 4b1e5c65..5a2b25f0 100644 --- a/framework/Data/SqlMap/Statements/TSelectMappedStatement.php +++ b/framework/Data/SqlMap/Statements/TSelectMappedStatement.php @@ -1,36 +1,36 @@ -<?php
-/**
- * TSelectMappedStatement class.
- *
- * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
- * @link http://www.pradosoft.com/
+<?php +/** + * TSelectMappedStatement class. + * + * @author Wei Zhuo <weizhuo[at]gmail[dot]com> + * @link http://www.pradosoft.com/ * @copyright Copyright © 2005-2012 PradoSoft - * @license http://www.pradosoft.com/license/
- * @version $Id$
- * @package System.Data.SqlMap.Statements
- */
-
-/**
- * TSelectMappedStatment class.
- *
- * @author Wei Zhuo <weizho[at]gmail[dot]com>
- * @version $Id$
- * @package System.Data.SqlMap.Statements
- * @since 3.1
- */
-class TSelectMappedStatement extends TMappedStatement
-{
- public function executeInsert($connection, $parameter)
- {
- throw new TSqlMapExecutionException(
- 'sqlmap_cannot_execute_insert', get_class($this), $this->getID());
- }
-
- public function executeUpdate($connection, $parameter)
- {
- throw new TSqlMapExecutionException(
- 'sqlmap_cannot_execute_update', get_class($this), $this->getID());
- }
-
-}
-
+ * @license http://www.pradosoft.com/license/ + * @version $Id$ + * @package System.Data.SqlMap.Statements + */ + +/** + * TSelectMappedStatment class. + * + * @author Wei Zhuo <weizho[at]gmail[dot]com> + * @version $Id$ + * @package System.Data.SqlMap.Statements + * @since 3.1 + */ +class TSelectMappedStatement extends TMappedStatement +{ + public function executeInsert($connection, $parameter) + { + throw new TSqlMapExecutionException( + 'sqlmap_cannot_execute_insert', get_class($this), $this->getID()); + } + + public function executeUpdate($connection, $parameter) + { + throw new TSqlMapExecutionException( + 'sqlmap_cannot_execute_update', get_class($this), $this->getID()); + } + +} + diff --git a/framework/Data/SqlMap/Statements/TSimpleDynamicSql.php b/framework/Data/SqlMap/Statements/TSimpleDynamicSql.php index 81ae4d76..377563ed 100644 --- a/framework/Data/SqlMap/Statements/TSimpleDynamicSql.php +++ b/framework/Data/SqlMap/Statements/TSimpleDynamicSql.php @@ -1,40 +1,40 @@ -<?php
-/**
- * TSimpleDynamicSql class file.
- *
- * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
- * @link http://www.pradosoft.com/
+<?php +/** + * TSimpleDynamicSql class file. + * + * @author Wei Zhuo <weizhuo[at]gmail[dot]com> + * @link http://www.pradosoft.com/ * @copyright Copyright © 2005-2012 PradoSoft - * @license http://www.pradosoft.com/license/
- * @version $Id$
- * @package System.Data.SqlMap.Statements
- */
-
-/**
- * TSimpleDynamicSql class.
- *
- * @author Wei Zhuo <weizho[at]gmail[dot]com>
- * @version $Id$
- * @package System.Data.SqlMap.Statements
- * @since 3.1
- */
-class TSimpleDynamicSql extends TStaticSql
-{
- private $_mappings=array();
-
- public function __construct($mappings)
- {
- $this->_mappings = $mappings;
- }
-
- public function replaceDynamicParameter($sql, $parameter)
- {
- foreach($this->_mappings as $property)
- {
- $value = TPropertyAccess::get($parameter, $property);
- $sql = preg_replace('/'.TSimpleDynamicParser::DYNAMIC_TOKEN.'/', str_replace('$', '\$', $value), $sql, 1);
- }
- return $sql;
- }
-}
-
+ * @license http://www.pradosoft.com/license/ + * @version $Id$ + * @package System.Data.SqlMap.Statements + */ + +/** + * TSimpleDynamicSql class. + * + * @author Wei Zhuo <weizho[at]gmail[dot]com> + * @version $Id$ + * @package System.Data.SqlMap.Statements + * @since 3.1 + */ +class TSimpleDynamicSql extends TStaticSql +{ + private $_mappings=array(); + + public function __construct($mappings) + { + $this->_mappings = $mappings; + } + + public function replaceDynamicParameter($sql, $parameter) + { + foreach($this->_mappings as $property) + { + $value = TPropertyAccess::get($parameter, $property); + $sql = preg_replace('/'.TSimpleDynamicParser::DYNAMIC_TOKEN.'/', str_replace('$', '\$', $value), $sql, 1); + } + return $sql; + } +} + diff --git a/framework/Data/SqlMap/Statements/TStaticSql.php b/framework/Data/SqlMap/Statements/TStaticSql.php index e6949c35..6374745d 100644 --- a/framework/Data/SqlMap/Statements/TStaticSql.php +++ b/framework/Data/SqlMap/Statements/TStaticSql.php @@ -1,36 +1,36 @@ -<?php
-/**
- * TStaticSql class file.
- *
- * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
- * @link http://www.pradosoft.com/
+<?php +/** + * TStaticSql class file. + * + * @author Wei Zhuo <weizhuo[at]gmail[dot]com> + * @link http://www.pradosoft.com/ * @copyright Copyright © 2005-2012 PradoSoft - * @license http://www.pradosoft.com/license/
- * @version $Id$
- * @package System.Data.SqlMap.Statements
- */
-
-/**
- * TStaticSql class.
- *
- * @author Wei Zhuo <weizho[at]gmail[dot]com>
- * @version $Id$
- * @package System.Data.SqlMap.Statements
- * @since 3.1
- */
-class TStaticSql extends TComponent
-{
- private $_preparedStatement;
-
- public function buildPreparedStatement($statement, $sqlString)
- {
- $factory = new TPreparedStatementFactory($statement, $sqlString);
- $this->_preparedStatement = $factory->prepare();
- }
-
- public function getPreparedStatement($parameter=null)
- {
- return $this->_preparedStatement;
- }
-}
-
+ * @license http://www.pradosoft.com/license/ + * @version $Id$ + * @package System.Data.SqlMap.Statements + */ + +/** + * TStaticSql class. + * + * @author Wei Zhuo <weizho[at]gmail[dot]com> + * @version $Id$ + * @package System.Data.SqlMap.Statements + * @since 3.1 + */ +class TStaticSql extends TComponent +{ + private $_preparedStatement; + + public function buildPreparedStatement($statement, $sqlString) + { + $factory = new TPreparedStatementFactory($statement, $sqlString); + $this->_preparedStatement = $factory->prepare(); + } + + public function getPreparedStatement($parameter=null) + { + return $this->_preparedStatement; + } +} + diff --git a/framework/Data/SqlMap/Statements/TUpdateMappedStatement.php b/framework/Data/SqlMap/Statements/TUpdateMappedStatement.php index 76bc8ae5..af300a0e 100644 --- a/framework/Data/SqlMap/Statements/TUpdateMappedStatement.php +++ b/framework/Data/SqlMap/Statements/TUpdateMappedStatement.php @@ -1,49 +1,49 @@ -<?php
-/**
- * TUpdateMappedStatement class file.
- *
- * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
- * @link http://www.pradosoft.com/
+<?php +/** + * TUpdateMappedStatement class file. + * + * @author Wei Zhuo <weizhuo[at]gmail[dot]com> + * @link http://www.pradosoft.com/ * @copyright Copyright © 2005-2012 PradoSoft - * @license http://www.pradosoft.com/license/
- * @version $Id$
- * @package System.Data.SqlMap.Statements
- */
-
-/**
- * TUpdateMappedStatement class.
- *
- * @author Wei Zhuo <weizho[at]gmail[dot]com>
- * @version $Id$
- * @package System.Data.SqlMap.Statements
- * @since 3.1
- */
-class TUpdateMappedStatement extends TMappedStatement
-{
- public function executeInsert($connection, $parameter)
- {
- throw new TSqlMapExecutionException(
- 'sqlmap_cannot_execute_insert', get_class($this), $this->getID());
- }
-
- public function executeQueryForMap($connection, $parameter, $keyProperty,
- $valueProperty=null)
- {
- throw new TSqlMapExecutionException(
- 'sqlmap_cannot_execute_query_for_map', get_class($this), $this->getID());
- }
-
- public function executeQueryForList($connection, $parameter, $result=null,
- $skip=-1, $max=-1)
- {
- throw new TSqlMapExecutionException(
- 'sqlmap_cannot_execute_query_for_list', get_class($this), $this->getID());
- }
-
- public function executeQueryForObject($connection, $parameter, $result=null)
- {
- throw new TSqlMapExecutionException(
- 'sqlmap_cannot_execute_query_for_object', get_class($this), $this->getID());
- }
-}
-
+ * @license http://www.pradosoft.com/license/ + * @version $Id$ + * @package System.Data.SqlMap.Statements + */ + +/** + * TUpdateMappedStatement class. + * + * @author Wei Zhuo <weizho[at]gmail[dot]com> + * @version $Id$ + * @package System.Data.SqlMap.Statements + * @since 3.1 + */ +class TUpdateMappedStatement extends TMappedStatement +{ + public function executeInsert($connection, $parameter) + { + throw new TSqlMapExecutionException( + 'sqlmap_cannot_execute_insert', get_class($this), $this->getID()); + } + + public function executeQueryForMap($connection, $parameter, $keyProperty, + $valueProperty=null) + { + throw new TSqlMapExecutionException( + 'sqlmap_cannot_execute_query_for_map', get_class($this), $this->getID()); + } + + public function executeQueryForList($connection, $parameter, $result=null, + $skip=-1, $max=-1) + { + throw new TSqlMapExecutionException( + 'sqlmap_cannot_execute_query_for_list', get_class($this), $this->getID()); + } + + public function executeQueryForObject($connection, $parameter, $result=null) + { + throw new TSqlMapExecutionException( + 'sqlmap_cannot_execute_query_for_object', get_class($this), $this->getID()); + } +} + |