From 94e94e0a8566f23d16658a04c55b0bbfdd6689aa Mon Sep 17 00:00:00 2001 From: "godzilla80@gmx.net" <> Date: Sun, 14 Feb 2010 01:22:57 +0000 Subject: Merge Branches & Trunk /trunk:r2680,2692,2707-2736 /branches/3.1:r2682-2686,2694-2702,2705,2738-2762 --- .../Relations/TActiveRecordRelation.php | 4 +- framework/Data/Common/Mysql/TMysqlMetaData.php | 14 +- framework/Data/Common/TDbCommandBuilder.php | 154 +++++++++++++++++++-- framework/Data/Common/TDbTableInfo.php | 24 ++-- framework/Data/DataGateway/TDataGatewayCommand.php | 5 +- framework/Data/DataGateway/TSqlCriteria.php | 72 +++++++++- .../SqlMap/Configuration/TSqlMapCacheModel.php | 2 +- .../Configuration/TSqlMapXmlConfiguration.php | 2 +- framework/Data/SqlMap/DataMapper/TSqlMapCache.php | 80 ++++++++++- framework/Data/SqlMap/TSqlMapConfig.php | 43 +++--- framework/Data/TDbConnection.php | 53 +++++-- 11 files changed, 385 insertions(+), 68 deletions(-) (limited to 'framework/Data') diff --git a/framework/Data/ActiveRecord/Relations/TActiveRecordRelation.php b/framework/Data/ActiveRecord/Relations/TActiveRecordRelation.php index a3daf35c..7e584514 100644 --- a/framework/Data/ActiveRecord/Relations/TActiveRecordRelation.php +++ b/framework/Data/ActiveRecord/Relations/TActiveRecordRelation.php @@ -4,7 +4,7 @@ * * @author Wei Zhuo * @link http://www.pradosoft.com/ - * @copyright Copyright © 2005-2008 PradoSoft + * @copyright Copyright © 2005-2008 PradoSoft * @license http://www.pradosoft.com/license/ * @version $Id$ * @package System.Data.ActiveRecord.Relations @@ -85,6 +85,8 @@ abstract class TActiveRecordRelation } else if($results instanceof TActiveRecordRelation) $stack[] = $this; //call it later + else if($results === null || !$validArray) + $stacks=array(); return $results; } diff --git a/framework/Data/Common/Mysql/TMysqlMetaData.php b/framework/Data/Common/Mysql/TMysqlMetaData.php index ae552cf3..fad33cea 100644 --- a/framework/Data/Common/Mysql/TMysqlMetaData.php +++ b/framework/Data/Common/Mysql/TMysqlMetaData.php @@ -4,7 +4,7 @@ * * @author Wei Zhuo * @link http://www.pradosoft.com/ - * @copyright Copyright © 2005-2008 PradoSoft + * @copyright Copyright © 2005-2008 PradoSoft * @license http://www.pradosoft.com/license/ * @version $Id$ * @package System.Data.Common.Mysql @@ -110,7 +110,7 @@ class TMysqlMetaData extends TDbMetaData //find SET/ENUM values if($this->isEnumSetType($info['DbType'])) - $info['DbTypeValues'] = preg_split('/\s*,\s*|\s+/', preg_replace('/\'|"/', '', $match[1])); + $info['DbTypeValues'] = preg_split("/[',]/S", $match[1], -1, PREG_SPLIT_NO_EMPTY); //find column size, precision and scale $pscale = array(); @@ -212,9 +212,9 @@ class TMysqlMetaData extends TDbMetaData if($this->getServerVersion()<5.01) return false; if($schemaName!==null) - $sql = "SHOW FULL TABLES FROM `{$schemaName}` LIKE ':table'"; + $sql = "SHOW FULL TABLES FROM `{$schemaName}` LIKE :table"; else - $sql = "SHOW FULL TABLES LIKE ':table'"; + $sql = "SHOW FULL TABLES LIKE :table"; $command = $this->getDbConnection()->createCommand($sql); $command->bindValue(':table', $tableName); @@ -246,8 +246,8 @@ class TMysqlMetaData extends TDbMetaData if($row['Key_name']==='PRIMARY') $primary[] = $row['Column_name']; } - // MySQL version was increased to >=5.1.21 instead of 5.x - // due to a MySQL bug (http://bugs.mysql.com/bug.php?id=19588) + // MySQL version was increased to >=5.1.21 instead of 5.x + // due to a MySQL bug (http://bugs.mysql.com/bug.php?id=19588) if($this->getServerVersion() >= 5.121) $foreign = $this->getForeignConstraints($schemaName,$tableName); else @@ -353,4 +353,4 @@ EOD; return false; } } - + diff --git a/framework/Data/Common/TDbCommandBuilder.php b/framework/Data/Common/TDbCommandBuilder.php index 155a62f8..0dc13e7e 100644 --- a/framework/Data/Common/TDbCommandBuilder.php +++ b/framework/Data/Common/TDbCommandBuilder.php @@ -156,6 +156,147 @@ class TDbCommandBuilder extends TComponent return '('.implode(' AND ', $conditions).')'; } + /** + * + * Different behavior depends on type of passed data + * string + * usage without modification + * + * null + * will be expanded to full list of quoted table column names (quoting depends on database) + * + * array + * - Column names will be quoted if used as key or value of array + * + * array('col1', 'col2', 'col2') + * // SELECT `col1`, `col2`, `col3` FROM... + * + * + * - Column aliasing + * + * array('mycol1' => 'col1', 'mycol2' => 'COUNT(*)') + * // SELECT `col1` AS mycol1, COUNT(*) AS mycol2 FROM... + * + * + * - NULL and scalar values (strings will be quoted depending on database) + * + * array('col1' => 'my custom string', 'col2' => 1.0, 'col3' => 'NULL') + * // SELECT "my custom string" AS `col1`, 1.0 AS `col2`, NULL AS `col3` FROM... + * + * + * - If the *-wildcard char is used as key or value, add the full list of quoted table column names + * + * array('col1' => 'NULL', '*') + * // SELECT `col1`, `col2`, `col3`, NULL AS `col1` FROM... + * + * @param mixed $value + * @return array of generated fields - use implode(', ', $selectfieldlist) to collapse field list for usage + * @since 3.1.7 + * @todo add support for table aliasing + * @todo add support for quoting of column aliasing + */ + public function getSelectFieldList($data='*') { + if(is_scalar($data)) { + $tmp = explode(',', $data); + $result = array(); + foreach($tmp as $v) + $result[] = trim($v); + return $result; + } + + $bHasWildcard = false; + $result = array(); + if(is_array($data) || $data instanceof Traversable) { + $columns = $this->getTableInfo()->getColumns(); + foreach($data as $key=>$value) { + if($key==='*' || $value==='*') { + $bHasWildcard = true; + continue; + } + + if(strToUpper($key)==='NULL') { + $result[] = 'NULL'; + continue; + } + + if(strpos($key, '(')!==false && strpos($key, ')')!==false) { + $result[] = $key; + continue; + } + + if(stripos($key, 'AS')!==false) { + $result[] = $key; + continue; + } + + if(stripos($value, 'AS')!==false) { + $result[] = $value; + continue; + } + + $v = isset($columns[$value]); + $k = isset($columns[$key]); + if(is_integer($key) && $v) { + $key = $value; + $k = $v; + } + + if(strToUpper($value)==='NULL') { + if($k) + $result[] = 'NULL AS ' . $columns[$key]->getColumnName(); + else + $result[] = 'NULL' . (is_string($key) ? (' AS ' . (string)$key) : ''); + continue; + } + + if(strpos($value, '(')!==false && strpos($value, ')')!==false) { + if($k) + $result[] = $value . ' AS ' . $columns[$key]->getColumnName(); + else + $result[] = $value . (is_string($key) ? (' AS ' . (string)$key) : ''); + continue; + } + + if($v && $key==$value) { + $result[] = $columns[$value]->getColumnName(); + continue; + } + + if($k && $value==null) { + $result[] = $columns[$key]->getColumnName(); + continue; + } + + if(is_string($key) && $v) { + $result[] = $columns[$value]->getColumnName() . ' AS ' . $key; + continue; + } + + if(is_numeric($value) && $k) { + $result[] = $value . ' AS ' . $columns[$key]->getColumnName(); + continue; + } + + if(is_string($value) && $k) { + $result[] = $this->getDbConnection()->quoteString($value) . ' AS ' . $columns[$key]->getColumnName(); + continue; + } + + if(!$v && !$k && is_integer($key)) { + $result[] = is_numeric($value) ? $value : $this->getDbConnection()->quoteString((string)$value); + continue; + } + + $result[] = (is_numeric($value) ? $value : $this->getDbConnection()->quoteString((string)$value)) . ' AS ' . $key; + } + } + + if($data===null || count($result) == 0 || $bHasWildcard) + $result = $result = array_merge($this->getTableInfo()->getColumnNames(), $result); + + return $result; + } + /** * Appends the $where condition to the string "SELECT * FROM tableName WHERE ". * The tableName is obtained from the {@link setTableInfo TableInfo} property. @@ -163,10 +304,11 @@ class TDbCommandBuilder extends TComponent * @param array condition parameters. * @return TDbCommand query command. */ - public function createFindCommand($where='1=1', $parameters=array(), $ordering=array(), $limit=-1, $offset=-1) + public function createFindCommand($where='1=1', $parameters=array(), $ordering=array(), $limit=-1, $offset=-1, $select='*') { $table = $this->getTableInfo()->getTableFullName(); - $sql = "SELECT * FROM {$table}"; + $fields = implode(', ', $this -> getSelectFieldList($select)); + $sql = "SELECT {$fields} FROM {$table}"; if(!empty($where)) $sql .= " WHERE {$where}"; return $this->applyCriterias($sql, $parameters, $ordering, $limit, $offset); @@ -191,11 +333,7 @@ class TDbCommandBuilder extends TComponent */ public function createCountCommand($where='1=1', $parameters=array(),$ordering=array(), $limit=-1, $offset=-1) { - $table = $this->getTableInfo()->getTableFullName(); - $sql = "SELECT COUNT(*) FROM {$table}"; - if(!empty($where)) - $sql .= " WHERE {$where}"; - return $this->applyCriterias($sql, $parameters, $ordering, $limit, $offset); + return $this->createFindCommand($where, $parameters, $ordering, $limit, $offset, 'COUNT(*)'); } /** @@ -368,4 +506,4 @@ class TDbCommandBuilder extends TComponent } } -?> +?> \ No newline at end of file diff --git a/framework/Data/Common/TDbTableInfo.php b/framework/Data/Common/TDbTableInfo.php index e2aae3d0..455dbc33 100644 --- a/framework/Data/Common/TDbTableInfo.php +++ b/framework/Data/Common/TDbTableInfo.php @@ -27,7 +27,13 @@ class TDbTableInfo extends TComponent private $_columns; - private $_lowercase; + private $_lowercase; + + /** + * @var null|array + * @since 3.1.7 + */ + private $_names = null; /** * Sets the database table meta data information. @@ -118,11 +124,14 @@ class TDbTableInfo extends TComponent * @return array table column names (identifier quoted) */ public function getColumnNames() - { - $names=array(); - foreach($this->getColumns() as $column) - $names[] = $column->getColumnName(); - return $names; + { + if($this->_names===null) + { + $this->_names=array(); + foreach($this->getColumns() as $column) + $this->_names[] = $column->getColumnName(); + } + return $this->_names; } /** @@ -154,5 +163,4 @@ class TDbTableInfo extends TComponent } return $this->_lowercase; } -} - +} \ No newline at end of file diff --git a/framework/Data/DataGateway/TDataGatewayCommand.php b/framework/Data/DataGateway/TDataGatewayCommand.php index 7425e6c4..e290f457 100644 --- a/framework/Data/DataGateway/TDataGatewayCommand.php +++ b/framework/Data/DataGateway/TDataGatewayCommand.php @@ -148,7 +148,8 @@ class TDataGatewayCommand extends TComponent $ordering = $criteria->getOrdersBy(); $limit = $criteria->getLimit(); $offset = $criteria->getOffset(); - $command = $this->getBuilder()->createFindCommand($where,$parameters,$ordering,$limit,$offset); + $select = $criteria->getSelect(); + $command = $this->getBuilder()->createFindCommand($where,$parameters,$ordering,$limit,$offset,$select); $this->onCreateCommand($command, $criteria); return $command; } @@ -232,7 +233,7 @@ class TDataGatewayCommand extends TComponent throw new TDbException('dbtablegateway_missing_pk_values', $this->getTableInfo()->getTableFullName()); } - if($count>1 && !is_array($values[0])) + if($count>1 && (!isset($values[0]) || !is_array($values[0]))) $values = array($values); if($count > 1 && count($values[0]) !== $count) { diff --git a/framework/Data/DataGateway/TSqlCriteria.php b/framework/Data/DataGateway/TSqlCriteria.php index 4ebdeb48..14e37b35 100644 --- a/framework/Data/DataGateway/TSqlCriteria.php +++ b/framework/Data/DataGateway/TSqlCriteria.php @@ -31,6 +31,11 @@ */ class TSqlCriteria extends TComponent { + /** + * @var mixed + * @since 3.1.7 + */ + private $_select='*'; private $_condition; private $_parameters; private $_ordersBy; @@ -55,6 +60,60 @@ class TSqlCriteria extends TComponent $this->setCondition($condition); } + /** + * Gets the field list to be placed after the SELECT in the SQL. Default to '*' + * @return mixed + * @since 3.1.7 + */ + public function getSelect() + { + return $this->_select; + } + + /** + * Sets the field list to be placed after the SELECT in the SQL. + * + * Different behavior depends on type of assigned value + * string + * usage without modification + * + * null + * will be expanded to full list of quoted table column names (quoting depends on database) + * + * array + * - Column names will be quoted if used as key or value of array + * + * array('col1', 'col2', 'col2') + * // SELECT `col1`, `col2`, `col3` FROM... + * + * + * - Column aliasing + * + * array('mycol1' => 'col1', 'mycol2' => 'COUNT(*)') + * // SELECT `col1` AS mycol1, COUNT(*) AS mycol2 FROM... + * + * + * - NULL and scalar values (strings will be quoted depending on database) + * + * array('col1' => 'my custom string', 'col2' => 1.0, 'col3' => 'NULL') + * // SELECT "my custom string" AS `col1`, 1.0 AS `col2`, NULL AS `col3` FROM... + * + * + * - If the *-wildcard char is used as key or value, add the full list of quoted table column names + * + * array('col1' => 'NULL', '*') + * // SELECT `col1`, `col2`, `col3`, NULL AS `col1` FROM... + * + * + * @param mixed + * @since 3.1.7 + * @see TDbCommandBuilder::getSelectFieldList() + */ + public function setSelect($value) + { + $this->_select = $value; + } + /** * @return string search conditions. */ @@ -68,17 +127,17 @@ class TSqlCriteria extends TComponent * @param string search conditions. */ public function setCondition($value) - { + { if(empty($value)) { return; } - + // supporting the following SELECT-syntax: // [ORDER BY {col_name | expr | position} // [ASC | DESC], ...] // [LIMIT {[offset,] row_count | row_count OFFSET offset}] // See: http://dev.mysql.com/doc/refman/5.0/en/select.html - + if(preg_match('/ORDER\s+BY\s+(.*?)(?=LIMIT)|ORDER\s+BY\s+(.*?)$/i', $value, $matches) > 0) { // condition contains ORDER BY $value = str_replace($matches[0], '', $value); @@ -88,7 +147,7 @@ class TSqlCriteria extends TComponent $this->setOrdersBy($matches[2]); } } - + if(preg_match('/LIMIT\s+([\d\s,]+)/i', $value, $matches) > 0) { // condition contains limit $value = str_replace($matches[0], '', $value); // remove limit from query @@ -106,7 +165,7 @@ class TSqlCriteria extends TComponent $value = str_replace($matches[0], '', $value); // remove offset from query $this->_offset = (int)$matches[1]; // set offset in criteria } - + $this->_condition = trim($value); } @@ -222,5 +281,4 @@ class TSqlCriteria extends TComponent return $str; } } - -?> +?> \ No newline at end of file diff --git a/framework/Data/SqlMap/Configuration/TSqlMapCacheModel.php b/framework/Data/SqlMap/Configuration/TSqlMapCacheModel.php index d85148eb..540a3acd 100644 --- a/framework/Data/SqlMap/Configuration/TSqlMapCacheModel.php +++ b/framework/Data/SqlMap/Configuration/TSqlMapCacheModel.php @@ -97,7 +97,7 @@ class TSqlMapCacheModel extends TComponent public function initialize($cache=null) { if($cache===null) - $this->_cache= Prado::createComponent($this->getImplementationClass()); + $this->_cache= Prado::createComponent($this->getImplementationClass(), $this); else $this->_cache=$cache; } diff --git a/framework/Data/SqlMap/Configuration/TSqlMapXmlConfiguration.php b/framework/Data/SqlMap/Configuration/TSqlMapXmlConfiguration.php index f6e0acd5..c49a4219 100644 --- a/framework/Data/SqlMap/Configuration/TSqlMapXmlConfiguration.php +++ b/framework/Data/SqlMap/Configuration/TSqlMapXmlConfiguration.php @@ -710,7 +710,7 @@ class TSqlMapXmlMappingConfiguration extends TSqlMapXmlConfigBuilder if(in_array(strtolower($name), $properties)) $cacheModel->{'set'.$name}((string)$value); } - $cache = Prado::createComponent($cacheModel->getImplementationClass()); + $cache = Prado::createComponent($cacheModel->getImplementationClass(), $cacheModel); $this->setObjectPropFromNode($cache,$node,$properties); foreach($node->xpath('property') as $propertyNode) diff --git a/framework/Data/SqlMap/DataMapper/TSqlMapCache.php b/framework/Data/SqlMap/DataMapper/TSqlMapCache.php index 05b72e08..5262bdf8 100644 --- a/framework/Data/SqlMap/DataMapper/TSqlMapCache.php +++ b/framework/Data/SqlMap/DataMapper/TSqlMapCache.php @@ -4,7 +4,7 @@ * * @author Wei Zhuo * @link http://www.pradosoft.com/ - * @copyright Copyright © 2005-2008 PradoSoft + * @copyright Copyright © 2005-2008 PradoSoft * @license http://www.pradosoft.com/license/ * @version $Id$ * @package System.Data.SqlMap @@ -25,16 +25,17 @@ abstract class TSqlMapCache implements ICache protected $_keyList; protected $_cache; protected $_cacheSize = 100; + protected $_cacheModel = null; /** * Create a new cache with limited cache size. - * @param integer maxium number of items to cache. + * @param TSqlMapCacheModel $cacheModel. */ - public function __construct($cacheSize=100) + public function __construct($cacheModel=null) { $this->_cache = new TMap; - $this->_cacheSize = intval($cacheSize); $this->_keyList = new TList; + $this->_cacheModel=$cacheModel; } /** @@ -173,20 +174,71 @@ class TSqlMapLruCache extends TSqlMapCache */ class TSqlMapApplicationCache implements ICache { + protected $_cacheModel=null; + + /** + * Create a new cache with limited cache size. + * @param TSqlMapCacheModel $cacheModel. + */ + public function __construct($cacheModel=null) + { + $this->_cacheModel=$cacheModel; + } + + /** + * + * @return string a KeyListID for the cache model. + */ + protected function getKeyListId() + { + $id='keyList'; + if ($this->_cacheModel instanceof TSqlMapCacheModel) + $id.='_'.$this->_cacheModel->getId(); + return $id; + } + /** + * Retreive keylist from cache or create it if it doesn't exists + * @return TList + */ + protected function getKeyList() + { + if (($keyList=$this->getCache()->get($this->getKeyListId()))===false) + { + $keyList=new TList(); + $this->getCache()->set($this->getKeyListId(), $keyList); + } + return $keyList; + } + + protected function setKeyList($keyList) + { + $this->getCache()->set($this->getKeyListId(), $keyList); + } + /** * @param string item to be deleted. */ public function delete($key) { + $keyList=$this->getKeyList(); + $keyList->remove($key); $this->getCache()->delete($key); + $this->setKeyList($keyList); } /** - * Deletes all items in the cache. + * Deletes all items in the cache, only for data cached by sqlmap cachemodel */ public function flush() { - $this->getCache()->flush(); + $keyList=$this->getKeyList(); + $cache=$this->getCache(); + foreach ($keyList as $key) + { + $cache->delete($key); + } + // Remove the old keylist + $cache->delete($this->getKeyListId()); } /** @@ -195,6 +247,16 @@ class TSqlMapApplicationCache implements ICache public function get($key) { $result = $this->getCache()->get($key); + if ($result === false) + { + // if the key has not been found in cache (e.g expired), remove from keylist + $keyList=$this->getKeyList(); + if ($keyList->contains($key)) + { + $keyList->remove($key); + $this->setKeyList($keyList); + } + } return $result === false ? null : $result; } @@ -206,6 +268,12 @@ class TSqlMapApplicationCache implements ICache public function set($key, $value,$expire=0,$dependency=null) { $this->getCache()->set($key, $value, $expire,$dependency); + $keyList=$this->getKeyList(); + if (!$keyList->contains($key)) + { + $keyList->add($key); + $this->setKeyList($keyList); + } } /** diff --git a/framework/Data/SqlMap/TSqlMapConfig.php b/framework/Data/SqlMap/TSqlMapConfig.php index c57ab40e..c5f06ab8 100644 --- a/framework/Data/SqlMap/TSqlMapConfig.php +++ b/framework/Data/SqlMap/TSqlMapConfig.php @@ -52,6 +52,31 @@ class TSqlMapConfig extends TDataSourceConfig } } + /** + * Create and configure the data mapper using sqlmap configuration file. + * Or if cache is enabled and manager already cached load from cache. + * If cache is enabled, the data mapper instance is cached. + * + * @return TSqlMapManager SqlMap manager instance + * @since 3.1.7 + */ + public function getSqlMapManager() { + Prado::using('System.Data.SqlMap.TSqlMapManager'); + if(($manager = $this->loadCachedSqlMapManager())===null) + { + $manager = new TSqlMapManager($this->getDbConnection()); + if(strlen($file=$this->getConfigFile()) > 0) + { + $manager->configureXml($file); + $this->cacheSqlMapManager($manager); + } + } + elseif($this->getConnectionID() !== '') { + $manager->setDbConnection($this->getDbConnection()); + } + return $manager; + } + /** * Saves the current SqlMap manager to cache. * @return boolean true if SqlMap manager was cached, false otherwise. @@ -87,6 +112,7 @@ class TSqlMapConfig extends TDataSourceConfig return $manager; } } + return null; } /** @@ -134,26 +160,11 @@ class TSqlMapConfig extends TDataSourceConfig } /** - * Configure the data mapper using sqlmap configuration file. - * If cache is enabled, the data mapper instance is cached. * @return TSqlMapGateway SqlMap gateway instance. */ protected function createSqlMapGateway() { - Prado::using('System.Data.SqlMap.TSqlMapManager'); - if(($manager = $this->loadCachedSqlMapManager())===null) - { - $manager = new TSqlMapManager($this->getDbConnection()); - if(strlen($file=$this->getConfigFile()) > 0) - { - $manager->configureXml($file); - $this->cacheSqlMapManager($manager); - } - } - else { - $manager->setDbConnection($this->getDbConnection()); - } - return $manager->getSqlmapGateway(); + return $this->getSqlMapManager()->getSqlmapGateway(); } /** diff --git a/framework/Data/TDbConnection.php b/framework/Data/TDbConnection.php index 26d61883..4726083c 100644 --- a/framework/Data/TDbConnection.php +++ b/framework/Data/TDbConnection.php @@ -27,10 +27,10 @@ Prado::using('System.Data.TDbCommand'); * specifying {@link setConnectionString ConnectionString}, {@link setUsername Username} * and {@link setPassword Password}. * - * Since 3.1.2, the connection charset can be set (for MySQL and PostgreSQL databases only) + * Since 3.1.2, the connection charset can be set (for MySQL and PostgreSQL databases only) * using the {@link setCharset Charset} property. The value of this property is database dependant. - * e.g. for mysql, you can use 'latin1' for cp1252 West European, 'utf8' for unicode, ... - * + * e.g. for mysql, you can use 'latin1' for cp1252 West European, 'utf8' for unicode, ... + * * The following example shows how to create a TDbConnection instance and establish * the actual connection: * @@ -83,6 +83,12 @@ Prado::using('System.Data.TDbCommand'); */ class TDbConnection extends TComponent { + /** + * + * @since 3.1.7 + */ + const DEFAULT_TRANSACTION_CLASS = 'System.Data.TDbTransaction'; + private $_dsn=''; private $_username=''; private $_password=''; @@ -92,13 +98,19 @@ class TDbConnection extends TComponent private $_pdo=null; private $_transaction; + /** + * @var string + * @since 3.1.7 + */ + private $_transactionClass=self::DEFAULT_TRANSACTION_CLASS; + /** * Constructor. * Note, the DB connection is not established when this connection * instance is created. Set {@link setActive Active} property to true * to establish the connection. * Since 3.1.2, you can set the charset for MySql connection - * + * * @param string The Data Source Name, or DSN, contains the information required to connect to the database. * @param string The user name for the DSN string. * @param string The password for the DSN string. @@ -168,7 +180,7 @@ class TDbConnection extends TComponent { $this->_pdo=new PDO($this->getConnectionString(),$this->getUsername(), $this->getPassword(),$this->_attributes); - // This attribute is only useful for PDO::MySql driver. + // This attribute is only useful for PDO::MySql driver. // Ignore the warning if a driver doesn't understand this. @$this->_pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, true); $this->_pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); @@ -194,7 +206,7 @@ class TDbConnection extends TComponent /* * Set the database connection charset. - * Only MySql databases are supported for now. + * Only MySql databases are supported for now. * @since 3.1.2 */ protected function setConnectionCharset() @@ -204,7 +216,7 @@ class TDbConnection extends TComponent switch ($this->_pdo->getAttribute(PDO::ATTR_DRIVER_NAME)) { case 'mysql': - $stmt = $this->_pdo->prepare('SET CHARACTER SET ?'); + $stmt = $this->_pdo->prepare('SET NAMES ?'); break; case 'pgsql': $stmt = $this->_pdo->prepare('SET client_encoding TO ?'); @@ -212,7 +224,7 @@ class TDbConnection extends TComponent } $stmt->execute(array($this->_charset)); } - + /** * @return string The Data Source Name, or DSN, contains the information required to connect to the database. */ @@ -269,7 +281,7 @@ class TDbConnection extends TComponent { return $this->_charset; } - + /** * @param string the charset used for database connection */ @@ -278,7 +290,7 @@ class TDbConnection extends TComponent $this->_charset=$value; $this->setConnectionCharset(); } - + /** * @return PDO the PDO instance, null if the connection is not established yet */ @@ -324,12 +336,31 @@ class TDbConnection extends TComponent if($this->getActive()) { $this->_pdo->beginTransaction(); - return $this->_transaction=new TDbTransaction($this); + return $this->_transaction=Prado::createComponent($this->getTransactionClass(), $this); } else throw new TDbException('dbconnection_connection_inactive'); } + /** + * @return string Transaction class name to be created by calling {@link TDbConnection::beginTransaction}. Defaults to 'System.Data.TDbTransaction'. + * @since 3.1.7 + */ + public function getTransactionClass() + { + return $this->_transactionClass; + } + + + /** + * @param string Transaction class name to be created by calling {@link TDbConnection::beginTransaction}. + * @since 3.1.7 + */ + public function setTransactionClass($value) + { + $this->_transactionClass = (string)$value; + } + /** * Returns the ID of the last inserted row or sequence value. * @param string name of the sequence object (required by some DBMS) -- cgit v1.2.3