From c7d41e5bea4a5f96979a08da9cc9f79355edfe70 Mon Sep 17 00:00:00 2001 From: wei <> Date: Sun, 16 Jul 2006 06:19:36 +0000 Subject: Update Time Tracker demo. --- .../SQLMap/Configuration/TConfigDeserialize.php | 1 + .../SQLMap/Configuration/TDomSqlMapBuilder.php | 52 ++++++++++++++++--- .../SQLMap/Configuration/TParameterMap.php | 2 +- .../DataAccess/SQLMap/Configuration/TResultMap.php | 22 +++++++- .../SQLMap/Configuration/TSqlMapStatement.php | 8 +-- .../SQLMap/DataMapper/TPropertyAccess.php | 6 +-- .../SQLMap/DataMapper/TTypeHandlerFactory.php | 10 ++-- .../DataAccess/SQLMap/DataMapper/messages.txt | 13 +++-- .../SQLMap/Statements/TInsertMappedStatement.php | 8 +-- .../SQLMap/Statements/TMappedStatement.php | 60 ++++++++++++++++------ .../SQLMap/Statements/TSelectMappedStatement.php | 4 +- .../SQLMap/Statements/TUpdateMappedStatement.php | 8 +-- 12 files changed, 143 insertions(+), 51 deletions(-) (limited to 'framework/DataAccess') diff --git a/framework/DataAccess/SQLMap/Configuration/TConfigDeserialize.php b/framework/DataAccess/SQLMap/Configuration/TConfigDeserialize.php index ee8f1744..2441dedf 100644 --- a/framework/DataAccess/SQLMap/Configuration/TConfigDeserialize.php +++ b/framework/DataAccess/SQLMap/Configuration/TConfigDeserialize.php @@ -104,6 +104,7 @@ class TConfigDeserialize public function resultMap($node, $sqlMap, $file) { $resultMap = new TResultMap; + $resultMap->initialize($sqlMap); $this->loadConfiguration($resultMap, $node, $file); foreach($node->result as $result) { diff --git a/framework/DataAccess/SQLMap/Configuration/TDomSqlMapBuilder.php b/framework/DataAccess/SQLMap/Configuration/TDomSqlMapBuilder.php index d3059dd7..ba8323cc 100644 --- a/framework/DataAccess/SQLMap/Configuration/TDomSqlMapBuilder.php +++ b/framework/DataAccess/SQLMap/Configuration/TDomSqlMapBuilder.php @@ -63,6 +63,9 @@ class TDomSqlMapBuilder if(isset($document->settings) && isset($document->settings->setting)) $this->configureSettings($document->settings); + + if(isset($document->typeHandler)) + $this->loadTypeHandler($document, $this->_configFile); //load database provider if(isset($document->provider) && isset($document->provider->datasource)) @@ -157,11 +160,19 @@ class TDomSqlMapBuilder { //$id = (string)$node['id']; $class = (string)$providerNode['class']; - if(strlen($class) > 0 && class_exists($class,false)) + if(strlen($class) > 0) { - $provider = new $class; - $this->_deserialize->loadConfiguration($provider, $node,$file); - $this->_sqlMapper->setDataProvider($provider); + if(class_exists($class,false)) + { + $provider = new $class; + $this->_deserialize->loadConfiguration($provider, $node,$file); + $this->_sqlMapper->setDataProvider($provider); + } + else + { + throw new TSqlMapConfigurationException( + 'sqlmap_unable_find_provider_class_def', $file, $class); + } } else { @@ -170,11 +181,38 @@ class TDomSqlMapBuilder } //var_dump($node); } -/* - protected function loadTypeHandlers() + + protected function loadTypeHandler($nodes, $file) { + foreach($nodes->typeHandler as $node) + { + if(!is_null($node['type']) && !is_null($node['callback'])) + { + $type = (string)$node['type']; + $class = (string)$node['callback']; + if(class_exists('Prado', false)) + { + $handler = Prado::createComponent($class); + } + else + { + if(class_exists($class,false)) + $handler = new $class; + else + throw new TSqlMapConfigurationException( + 'sqlmap_type_handler_class_undef', $file, $class); + } + $factory = $this->_sqlMapper->getTypeHandlerFactory(); + $factory->register($type, $handler); + } + else + { + throw new TSqlMapConfigurationException( + 'sqlmap_type_handler_callback_undef', $file); + } + } } -*/ + protected function loadSqlMappingFiles($sqlmappings) { foreach($sqlmappings->sqlMap as $node) diff --git a/framework/DataAccess/SQLMap/Configuration/TParameterMap.php b/framework/DataAccess/SQLMap/Configuration/TParameterMap.php index 8e1c757d..b3c6ed6e 100644 --- a/framework/DataAccess/SQLMap/Configuration/TParameterMap.php +++ b/framework/DataAccess/SQLMap/Configuration/TParameterMap.php @@ -56,7 +56,7 @@ class TParameterMap extends TComponent $typeHandler = $mapping->getTypeHandler(); try { - $value = TPropertyAccess::get($parameterValue, $mapping->getProperty()); + $value = TPropertyAccess::get($parameterValue, $mapping->getProperty()); } catch (TInvalidPropertyException $e) { diff --git a/framework/DataAccess/SQLMap/Configuration/TResultMap.php b/framework/DataAccess/SQLMap/Configuration/TResultMap.php index 0f09a1ba..b8032c81 100644 --- a/framework/DataAccess/SQLMap/Configuration/TResultMap.php +++ b/framework/DataAccess/SQLMap/Configuration/TResultMap.php @@ -8,6 +8,7 @@ class TResultMap extends TComponent private $_extendMap=''; private $_groupBy=''; private $_discriminator=null; + private $_typeHandlerFactory=null; public function __construct() { @@ -32,6 +33,11 @@ class TResultMap extends TComponent public function getDiscriminator(){ return $this->_discriminator; } public function setDiscriminator($value){ $this->_discriminator = $value; } + public function initialize($sqlMap, $resultMap=null) + { + $this->_typeHandlerFactory = $sqlMap->getTypeHandlerFactory(); + } + public function addResultProperty(TResultProperty $property) { $this->_columns->add($property->getProperty(), $property); @@ -39,7 +45,21 @@ class TResultMap extends TComponent public function createInstanceOfResult() { - return TTypeHandlerFactory::createInstanceOf($this->getClass()); + $handler = $this->_typeHandlerFactory->getTypeHandler($this->getClass()); + + try + { + if(!is_null($handler)) + return $handler->createNewInstance(); + else + return TTypeHandlerFactory::createInstanceOf($this->getClass()); + } + catch (TDataMapperException $e) + { + throw new TSqlMapExecutionException( + 'sqlmap_unable_to_create_new_instance', + $this->getClass(), get_class($handler), $this->getID()); + } } public function resolveSubMap($row) diff --git a/framework/DataAccess/SQLMap/Configuration/TSqlMapStatement.php b/framework/DataAccess/SQLMap/Configuration/TSqlMapStatement.php index 228b37d6..414ad2f1 100644 --- a/framework/DataAccess/SQLMap/Configuration/TSqlMapStatement.php +++ b/framework/DataAccess/SQLMap/Configuration/TSqlMapStatement.php @@ -79,14 +79,14 @@ class TSqlMapStatement extends TComponent return array(); //new TList; } - protected function createInstanceOf($type) + protected function createInstanceOf($type,$row=null) { $handler = $this->_typeHandler->getTypeHandler($type); try { if(!is_null($handler)) - return $handler->createNewInstance(); + return $handler->createNewInstance($row); else return TTypeHandlerFactory::createInstanceOf($type); } @@ -99,10 +99,10 @@ class TSqlMapStatement extends TComponent } - public function createInstanceOfResultClass() + public function createInstanceOfResultClass($row) { if(strlen($type= $this->getResultClass()) > 0) - return $this->createInstanceOf($type); + return $this->createInstanceOf($type,$row); } } diff --git a/framework/DataAccess/SQLMap/DataMapper/TPropertyAccess.php b/framework/DataAccess/SQLMap/DataMapper/TPropertyAccess.php index 4bbe2cb5..e4f5c1fa 100644 --- a/framework/DataAccess/SQLMap/DataMapper/TPropertyAccess.php +++ b/framework/DataAccess/SQLMap/DataMapper/TPropertyAccess.php @@ -39,7 +39,7 @@ class TPropertyAccess */ public static function get($object,$path) { - if(!is_array($object) || !is_object($object)) + if(!is_array($object) && !is_object($object)) return $object; $properties = explode('.', $path); foreach($properties as $prop) @@ -49,7 +49,7 @@ class TPropertyAccess if(isset($object[$prop])) $object = $object[$prop]; else - throw new TInvalidPropertyException('sqlmap_invalid_property',$path); + throw new TInvalidPropertyException('sqlmap_invalid_property',$path); } else if(is_object($object)) { @@ -69,7 +69,7 @@ class TPropertyAccess public static function has($object, $path) { - if(!is_array($object) || !is_object($object)) + if(!is_array($object) && !is_object($object)) return false; $properties = explode('.', $path); foreach($properties as $prop) diff --git a/framework/DataAccess/SQLMap/DataMapper/TTypeHandlerFactory.php b/framework/DataAccess/SQLMap/DataMapper/TTypeHandlerFactory.php index fcadea28..55fb1f20 100644 --- a/framework/DataAccess/SQLMap/DataMapper/TTypeHandlerFactory.php +++ b/framework/DataAccess/SQLMap/DataMapper/TTypeHandlerFactory.php @@ -55,8 +55,10 @@ class TTypeHandlerFactory case 'integer': case 'int': return 0; case 'bool': case 'boolean': return false; } - - if(class_exists($type, false)) //NO auto loading + + if(class_exists('Prado', false)) + return Prado::createComponent($type); + else if(class_exists($type, false)) //NO auto loading return new $type; else throw new TDataMapperException('sqlmap_unable_to_find_class', $type); @@ -125,10 +127,10 @@ interface ITypeHandlerCallback * for this type (e.g. File type), you can simply return the String representation * as it was passed in. It is not recommended to return null, unless null was passed * in. - * @param string nullValue. + * @param array result row. * @return mixed */ - public function createNewInstance(); + public function createNewInstance($row=null); } ?> \ No newline at end of file diff --git a/framework/DataAccess/SQLMap/DataMapper/messages.txt b/framework/DataAccess/SQLMap/DataMapper/messages.txt index 6bf5f396..16be9c2b 100644 --- a/framework/DataAccess/SQLMap/DataMapper/messages.txt +++ b/framework/DataAccess/SQLMap/DataMapper/messages.txt @@ -17,6 +17,8 @@ map_item_unremovable = The item cannot be removed from the map. map_data_not_iterable = Data must be either an array or an object implementing Traversable interface. map_readonly = {0} is read-only. +sqlmap_type_handler_class_undef = Unable to find type handler class named '{1}' in sqlmap configuration file '{0}'. +sqlmap_type_handler_callback_undef = Attributes 'type' and 'callback' must be defined in typeHandler tag in configuration file '{0}'. sqlmap_contains_no_statement = Unable to find SQLMap statement '{0}'. sqlmap_already_contains_statement = Duplicate SQLMap statement found, '{0}' already exists. sqlmap_contains_no_result_map = Unable to find SQLMap result map '{0}'. @@ -27,6 +29,7 @@ sqlmap_connection_already_exists = SqlMap could not invoke OpenConnection(). A sqlmap_unable_to_close_null_connection = SqlMap could not invoke CloseConnection(). No connection was started. Call OpenConnection() first. sqlmap_undefined_attribute = {0} attribute '{1}' is not defined for {2} in file {3}. sqlmap_unable_find_provider_class = Unable to find a database provider in SQLMap configuration file {0}. +sqlmap_unable_find_provider_class_def = Unable to load class database provider '{1}' in SQLMap configuration file {0}. sqlmap_unable_to_find_parent_parameter_map = Unable to find parent parameter map extension '{0}' in file {1}. sqlmap_unable_to_find_parent_sql = Unable to find parent sql statement extension '{0}' in file {1}. sqlmap_unable_to_find_result_mapping = Unable to resolve SQLMap result mapping '{0}' in Result Map '{2}' using configuration file {1}. @@ -36,11 +39,11 @@ sqlmap_index_must_be_string_or_int = Invalid index '{0}', must be an integes or sqlmap_undefined_input_property = Undefined array index '{0}' in retrieving property in SQLMap parameter map '{1}'. sqlmap_unable_to_find_class = Unable to find result class '{0}' in TResultMap::createInstanceOfResult(). sqlmap_can_not_instantiate = Type handler '{0}' can not create new objects. -sqlmap_cannot_execute_query_for_map = SQLMap statement class {0} can not query for map. -sqlmap_cannot_execute_update = SQLMap statement class {0} can not execute update query. -sqlmap_cannot_execute_insert = SQLMap statement class {0} can not execute insert. -sqlmap_cannot_execute_query_for_list = SQLMap statement class {0} can not query for list. -sqlmap_cannot_execute_query_for_object = SQLMap statement class {0} can not query for object +sqlmap_cannot_execute_query_for_map = SQLMap statement class {0} can not query for map in statement '{1}'. +sqlmap_cannot_execute_update = SQLMap statement class {0} can not execute update query in statement '{1}'. +sqlmap_cannot_execute_insert = SQLMap statement class {0} can not execute insert in statement '{1}'. +sqlmap_cannot_execute_query_for_list = SQLMap statement class {0} can not query for list in statement '{1}'. +sqlmap_cannot_execute_query_for_object = SQLMap statement class {0} can not query for object in statement '{1}'. sqlmap_execution_error_no_record = No record set found in executing statement '{0}': '{1}'. sqlmap_unable_to_create_new_instance = Unable to create a new instance of '{0}' using type hander '{1}' for SQLMap statement with ID '{2}'. sqlmap_invalid_property = Invalid property getter path '{0}'. diff --git a/framework/DataAccess/SQLMap/Statements/TInsertMappedStatement.php b/framework/DataAccess/SQLMap/Statements/TInsertMappedStatement.php index 7a444c89..51731a5c 100644 --- a/framework/DataAccess/SQLMap/Statements/TInsertMappedStatement.php +++ b/framework/DataAccess/SQLMap/Statements/TInsertMappedStatement.php @@ -6,26 +6,26 @@ class TInsertMappedStatement extends TMappedStatement $keyProperty, $valueProperty=null) { throw new TSqlMapExecutionException( - 'sqlmap_cannot_execute_query_for_map', get_class($this)); + '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)); + 'sqlmap_cannot_execute_update', get_class($this), $this->getID()); } public function executeQueryForList($connection, $parameter, $result, $skip=-1, $max=-1) { throw new TSqlMapExecutionException( - 'sqlmap_cannot_execute_query_for_list', get_class($this)); + 'sqlmap_cannot_execute_query_for_list', get_class($this), $this->getID()); } public function executeQueryForObject($connection, $parameter, $result) { throw new TSqlMapExecutionException( - 'sqlmap_cannot_execute_query_for_object', get_class($this)); + 'sqlmap_cannot_execute_query_for_object', get_class($this), $this->getID()); } } diff --git a/framework/DataAccess/SQLMap/Statements/TMappedStatement.php b/framework/DataAccess/SQLMap/Statements/TMappedStatement.php index 483a315a..c621f285 100644 --- a/framework/DataAccess/SQLMap/Statements/TMappedStatement.php +++ b/framework/DataAccess/SQLMap/Statements/TMappedStatement.php @@ -375,18 +375,23 @@ class TMappedStatement extends TComponent implements IMappedStatement * @return object the object. * @see executeQueryForObject() */ - public function runQueryForObject($connection, $sql, $result) + public function runQueryForObject($connection, $sql, &$result) { $recordSet = $this->executeSQLQuery($connection, $sql); - $object = $this->applyResultMap($recordSet->fetchRow(), $result); - //get group by result + $object = null; + + while($row = $recordSet->fetchRow()) + $object = $this->applyResultMap($row, $result); + foreach($this->getGroupbyResults() as $group) $object = $group->updateProperties(); + $this->clearGroupByResults(); $this->executePostSelect($connection); $this->onExecuteQuery($sql); + return $object; } @@ -403,7 +408,7 @@ class TMappedStatement extends TComponent implements IMappedStatement $sql = $this->_command->create($connection, $this->_statement, $parameter); - $this->executeSQLQuery($connection, $sql); + $result = $this->executeSQLQuery($connection, $sql); if(is_null($generatedKey)) $generatedKey = $this->getPostGeneratedSelectKey($connection, $parameter); @@ -525,7 +530,7 @@ class TMappedStatement extends TComponent implements IMappedStatement * @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) + protected function applyResultMap($row, &$resultObject=null) { if($row === false) return null; @@ -550,7 +555,7 @@ class TMappedStatement extends TComponent implements IMappedStatement protected function fillResultClass($resultClass, $row, $resultObject) { if(is_null($resultObject)) - $resultObject = $this->_statement->createInstanceOfResultClass(); + $resultObject = $this->_statement->createInstanceOfResultClass($row); if($resultObject instanceOf ArrayAccess) return $this->fillResultArrayList($row, $resultObject); @@ -608,14 +613,13 @@ class TMappedStatement extends TComponent implements IMappedStatement * @param object result object to fill, will create new instances if required. * @return object result object filled with data. */ - protected function fillResultMap($resultMapName, $row, $resultObject) + protected function fillResultMap($resultMapName, $row, &$resultObject) { $resultMap = $this->_sqlMap->getResultMap($resultMapName); $resultMap = $resultMap->resolveSubMap($row); if(is_null($resultObject)) $resultObject = $resultMap->createInstanceOfResult(); - if(is_object($resultObject)) { if(strlen($resultMap->getGroupBy()) > 0) @@ -641,21 +645,41 @@ class TMappedStatement extends TComponent implements IMappedStatement * @see getGroupByResults() * @see runQueryForList() */ - protected function addResultMapGroupBy($resultMap, $row, $resultObject) + protected function addResultMapGroupBy($resultMap, $row, &$resultObject) { $group = $this->getResultMapGroupKey($resultMap, $row, $resultObject); + foreach($resultMap->getColumns() as $property) { - $this->setObjectProperty($resultMap, $property, $row, $resultObject); + $scalar = $this->setObjectProperty($resultMap, $property, $row, $resultObject); if(strlen($property->getResultMapping()) > 0) { $key = $property->getProperty(); - $value = TPropertyAccess::get($resultObject, $key); - $this->_groupBy[$group]->addValue($key, $value); + $value = $this->extractGroupByValue($property, $resultObject); + if(!empty($value)) + $this->_groupBy[$group]->addValue($key, $value); } } + return null; } + + /** + * Extract value from the object for later adding to a GroupBy collection. + * @param TResultProperty result property + * @param mixed result object + * @return mixed collection element + */ + protected function extractGroupByValue($property, $resultObject) + { + $key = $property->getProperty(); + $value = TPropertyAccess::get($resultObject, $key); + $type = strtolower($property->getType()); + if(($type == 'array' || $type == 'map') && is_array($value) && count($value) == 1) + return $value[0]; + else + return $value; + } /** * Gets the result 'group by' groupping key for each row. @@ -747,7 +771,7 @@ class TMappedStatement extends TComponent implements IMappedStatement * @param array a result set row retrieved from the database * @param object the result object */ - protected function setObjectProperty($resultMap, $property, $row, $resultObject) + protected function setObjectProperty($resultMap, $property, $row, &$resultObject) { $select = $property->getSelect(); $key = $property->getProperty(); @@ -756,8 +780,12 @@ class TMappedStatement extends TComponent implements IMappedStatement if(strlen($select) == 0 && is_null($nested)) { $value = $property->getDatabaseValue($row); - TPropertyAccess::set($resultObject, $key, $value); + $this->_IsRowDataFound = $this->_IsRowDataFound || ($value != null); + if(is_array($resultObject) || is_object($resultObject)) + TPropertyAccess::set($resultObject, $key, $value); + else + $resultObject = $value; } else if(!is_null($nested)) { @@ -844,12 +872,12 @@ class TMappedStatement extends TComponent implements IMappedStatement * @param object the result object * @return boolean true if the data was found, false otherwise. */ - protected function fillPropertyWithResultMap($resultMap, $row, $resultObject) + protected function fillPropertyWithResultMap($resultMap, $row, &$resultObject) { $dataFound = false; foreach($resultMap->getColumns() as $property) { - $this->_IsRowDataFound = false; + $this->_IsRowDataFound = false; $this->setObjectProperty($resultMap, $property, $row, $resultObject); $dataFound = $dataFound || $this->_IsRowDataFound; } diff --git a/framework/DataAccess/SQLMap/Statements/TSelectMappedStatement.php b/framework/DataAccess/SQLMap/Statements/TSelectMappedStatement.php index 1171e28f..b6f179c0 100644 --- a/framework/DataAccess/SQLMap/Statements/TSelectMappedStatement.php +++ b/framework/DataAccess/SQLMap/Statements/TSelectMappedStatement.php @@ -5,13 +5,13 @@ class TSelectMappedStatement extends TMappedStatement public function executeInsert($connection, $parameter) { throw new TSqlMapExecutionException( - 'sqlmap_cannot_execute_insert', get_class($this)); + 'sqlmap_cannot_execute_insert', get_class($this), $this->getID()); } public function executeUpdate($connection, $parameter) { throw new TSqlMapExecutionException( - 'sqlmap_cannot_execute_update', get_class($this)); + 'sqlmap_cannot_execute_update', get_class($this), $this->getID()); } } diff --git a/framework/DataAccess/SQLMap/Statements/TUpdateMappedStatement.php b/framework/DataAccess/SQLMap/Statements/TUpdateMappedStatement.php index cf16ee52..353f4b26 100644 --- a/framework/DataAccess/SQLMap/Statements/TUpdateMappedStatement.php +++ b/framework/DataAccess/SQLMap/Statements/TUpdateMappedStatement.php @@ -5,27 +5,27 @@ class TUpdateMappedStatement extends TMappedStatement public function executeInsert($connection, $parameter) { throw new TSqlMapExecutionException( - 'sqlmap_cannot_execute_insert', get_class($this)); + '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)); + 'sqlmap_cannot_execute_query_for_map', get_class($this), $this->getID()); } public function executeQueryForList($connection, $parameter, $result, $skip=-1, $max=-1) { throw new TSqlMapExecutionException( - 'sqlmap_cannot_execute_query_for_list', get_class($this)); + 'sqlmap_cannot_execute_query_for_list', get_class($this), $this->getID()); } public function executeQueryForObject($connection, $parameter, $result) { throw new TSqlMapExecutionException( - 'sqlmap_cannot_execute_query_for_object', get_class($this)); + 'sqlmap_cannot_execute_query_for_object', get_class($this), $this->getID()); } } -- cgit v1.2.3