summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchristophe.boulain <>2011-01-19 14:56:01 +0000
committerchristophe.boulain <>2011-01-19 14:56:01 +0000
commit95b032891d6617525636cc7b680117dbb14afba7 (patch)
tree0b9a8adf92176592894cb4f3d981c8a2e0c4f5ec
parentf01b9699967b8959ce8721c1e0e3d6edeb309c52 (diff)
Merge last changes on "Data" from trunk
-rw-r--r--framework/Data/ActiveRecord/Relations/TActiveRecordRelation.php508
-rw-r--r--framework/Data/ActiveRecord/Scaffold/TScaffoldBase.php3
-rw-r--r--framework/Data/ActiveRecord/TActiveRecord.php3
-rw-r--r--framework/Data/ActiveRecord/TActiveRecordConfig.php2
-rw-r--r--framework/Data/ActiveRecord/TActiveRecordGateway.php7
-rw-r--r--framework/Data/Common/Mssql/TMssqlMetaData.php4
-rw-r--r--framework/Data/Common/Mysql/TMysqlMetaData.php4
-rw-r--r--framework/Data/Common/Oracle/TOracleMetaData.php2
-rw-r--r--framework/Data/Common/Oracle/TOracleTableInfo.php3
-rw-r--r--framework/Data/Common/TDbCommandBuilder.php3
-rw-r--r--framework/Data/Common/TDbMetaData.php3
-rw-r--r--framework/Data/Common/TDbTableColumn.php3
-rw-r--r--framework/Data/Common/TDbTableInfo.php315
-rw-r--r--framework/Data/DataGateway/TDataGatewayCommand.php4
-rw-r--r--framework/Data/DataGateway/TSqlCriteria.php3
-rw-r--r--framework/Data/SqlMap/Configuration/TParameterMap.php8
-rw-r--r--framework/Data/SqlMap/Configuration/TResultMap.php3
-rw-r--r--framework/Data/SqlMap/Configuration/TResultProperty.php3
-rw-r--r--framework/Data/SqlMap/Configuration/TSqlMapXmlConfiguration.php2
-rw-r--r--framework/Data/SqlMap/Statements/TMappedStatement.php3
-rw-r--r--framework/Data/SqlMap/Statements/TPreparedStatement.php3
-rw-r--r--framework/Data/SqlMap/Statements/TSimpleDynamicSql.php3
-rw-r--r--framework/Data/SqlMap/TSqlMapGateway.php7
-rw-r--r--framework/Data/SqlMap/TSqlMapManager.php3
-rw-r--r--framework/Data/TDataSourceConfig.php13
-rw-r--r--framework/Data/TDbCommand.php3
-rw-r--r--framework/Data/TDbConnection.php1270
-rw-r--r--framework/Data/TDbDataReader.php3
-rw-r--r--framework/Data/TDbTransaction.php3
-rw-r--r--framework/Exceptions/TErrorHandler.php802
-rw-r--r--framework/Exceptions/messages/messages-fr.txt7
-rw-r--r--framework/Exceptions/messages/messages-id.txt1
-rw-r--r--framework/Exceptions/messages/messages-zh.txt1
-rw-r--r--framework/Exceptions/messages/messages.txt19
34 files changed, 1537 insertions, 1487 deletions
diff --git a/framework/Data/ActiveRecord/Relations/TActiveRecordRelation.php b/framework/Data/ActiveRecord/Relations/TActiveRecordRelation.php
index 7e584514..b291cbf3 100644
--- a/framework/Data/ActiveRecord/Relations/TActiveRecordRelation.php
+++ b/framework/Data/ActiveRecord/Relations/TActiveRecordRelation.php
@@ -1,254 +1,254 @@
-<?php
-/**
- * TActiveRecordRelation class file.
- *
- * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
- * @link http://www.pradosoft.com/
- * @copyright Copyright &copy; 2005-2008 PradoSoft
- * @license http://www.pradosoft.com/license/
- * @version $Id$
- * @package System.Data.ActiveRecord.Relations
- */
-
-/**
- * Load active record relationship context.
- */
-Prado::using('System.Data.ActiveRecord.Relations.TActiveRecordRelationContext');
-
-/**
- * Base class for active record relationships.
- *
- * @author Wei Zhuo <weizho[at]gmail[dot]com>
- * @version $Id$
- * @package System.Data.ActiveRecord.Relations
- * @since 3.1
- */
-abstract class TActiveRecordRelation
-{
- private $_context;
- private $_criteria;
-
- public function __construct(TActiveRecordRelationContext $context, $criteria)
- {
- $this->_context = $context;
- $this->_criteria = $criteria;
- }
-
- /**
- * @return TActiveRecordRelationContext
- */
- protected function getContext()
- {
- return $this->_context;
- }
-
- /**
- * @return TActiveRecordCriteria
- */
- protected function getCriteria()
- {
- return $this->_criteria;
- }
-
- /**
- * @return TActiveRecord
- */
- protected function getSourceRecord()
- {
- return $this->getContext()->getSourceRecord();
- }
-
- abstract protected function collectForeignObjects(&$results);
-
- /**
- * Dispatch the method calls to the source record finder object. When
- * an instance of TActiveRecord or an array of TActiveRecord is returned
- * the corresponding foreign objects are also fetched and assigned.
- *
- * Multiple relationship calls can be chain together.
- *
- * @param string method name called
- * @param array method arguments
- * @return mixed TActiveRecord or array of TActiveRecord results depending on the method called.
- */
- public function __call($method,$args)
- {
- static $stack=array();
-
- $results = call_user_func_array(array($this->getSourceRecord(),$method),$args);
- $validArray = is_array($results) && count($results) > 0;
- if($validArray || $results instanceof ArrayAccess || $results instanceof TActiveRecord)
- {
- $this->collectForeignObjects($results);
- while($obj = array_pop($stack))
- $obj->collectForeignObjects($results);
- }
- else if($results instanceof TActiveRecordRelation)
- $stack[] = $this; //call it later
- else if($results === null || !$validArray)
- $stacks=array();
- return $results;
- }
-
- /**
- * Fetch results for current relationship.
- * @return boolean always true.
- */
- public function fetchResultsInto($obj)
- {
- $this->collectForeignObjects($obj);
- return true;
- }
-
- /**
- * Returns foreign keys in $fromRecord with source column names as key
- * and foreign column names in the corresponding $matchesRecord as value.
- * The method returns the first matching foreign key between these 2 records.
- * @param TActiveRecord $fromRecord
- * @param TActiveRecord $matchesRecord
- * @return array foreign keys with source column names as key and foreign column names as value.
- */
- protected function findForeignKeys($from, $matchesRecord, $loose=false)
- {
- $gateway = $matchesRecord->getRecordGateway();
- $recordTableInfo = $gateway->getRecordTableInfo($matchesRecord);
- $matchingTableName = strtolower($recordTableInfo->getTableName());
- $matchingFullTableName = strtolower($recordTableInfo->getTableFullName());
- $tableInfo=$from;
- if($from instanceof TActiveRecord)
- $tableInfo = $gateway->getRecordTableInfo($from);
- //find first non-empty FK
- foreach($tableInfo->getForeignKeys() as $fkeys)
- {
- $fkTable = strtolower($fkeys['table']);
- if($fkTable===$matchingTableName || $fkTable===$matchingFullTableName)
- {
- $hasFkField = !$loose && $this->getContext()->hasFkField();
- $key = $hasFkField ? $this->getFkFields($fkeys['keys']) : $fkeys['keys'];
- if(!empty($key))
- return $key;
- }
- }
-
- //none found
- $matching = $gateway->getRecordTableInfo($matchesRecord)->getTableFullName();
- throw new TActiveRecordException('ar_relations_missing_fk',
- $tableInfo->getTableFullName(), $matching);
- }
-
- /**
- * @return array foreign key field names as key and object properties as value.
- * @since 3.1.2
- */
- abstract public function getRelationForeignKeys();
-
- /**
- * Find matching foreign key fields from the 3rd element of an entry in TActiveRecord::$RELATION.
- * Assume field names consist of [\w-] character sets. Prefix to the field names ending with a dot
- * are ignored.
- */
- private function getFkFields($fkeys)
- {
- $matching = array();
- preg_match_all('/\s*(\S+\.)?([\w-]+)\s*/', $this->getContext()->getFkField(), $matching);
- $fields = array();
- foreach($fkeys as $fkName => $field)
- {
- if(in_array($fkName, $matching[2]))
- $fields[$fkName] = $field;
- }
- return $fields;
- }
-
- /**
- * @param mixed object or array to be hashed
- * @param array name of property for hashing the properties.
- * @return string object hash using crc32 and serialize.
- */
- protected function getObjectHash($obj, $properties)
- {
- $ids=array();
- foreach($properties as $property)
- $ids[] = is_object($obj) ? (string)$obj->getColumnValue($property) : (string)$obj[$property];
- return serialize($ids);
- }
-
- /**
- * Fetches the foreign objects using TActiveRecord::findAllByIndex()
- * @param array field names
- * @param array foreign key index values.
- * @return TActiveRecord[] foreign objects.
- */
- protected function findForeignObjects($fields, $indexValues)
- {
- $finder = $this->getContext()->getForeignRecordFinder();
- return $finder->findAllByIndex($this->_criteria, $fields, $indexValues);
- }
-
- /**
- * Obtain the foreign key index values from the results.
- * @param array property names
- * @param array TActiveRecord results
- * @return array foreign key index values.
- */
- protected function getIndexValues($keys, $results)
- {
- if(!is_array($results) && !$results instanceof ArrayAccess)
- $results = array($results);
- $values=array();
- foreach($results as $result)
- {
- $value = array();
- foreach($keys as $name)
- $value[] = $result->getColumnValue($name);
- $values[] = $value;
- }
- return $values;
- }
-
- /**
- * Populate the results with the foreign objects found.
- * @param array source results
- * @param array source property names
- * @param array foreign objects
- * @param array foreign object field names.
- */
- protected function populateResult(&$results,$properties,&$fkObjects,$fields)
- {
- $collections=array();
- foreach($fkObjects as $fkObject)
- $collections[$this->getObjectHash($fkObject, $fields)][]=$fkObject;
- $this->setResultCollection($results, $collections, $properties);
- }
-
- /**
- * Populates the result array with foreign objects (matched using foreign key hashed property values).
- * @param array $results
- * @param array $collections
- * @param array property names
- */
- protected function setResultCollection(&$results, &$collections, $properties)
- {
- if(is_array($results) || $results instanceof ArrayAccess)
- {
- for($i=0,$k=count($results);$i<$k;$i++)
- $this->setObjectProperty($results[$i], $properties, $collections);
- }
- else
- $this->setObjectProperty($results, $properties, $collections);
- }
-
- /**
- * Sets the foreign objects to the given property on the source object.
- * @param TActiveRecord source object.
- * @param array source properties
- * @param array foreign objects.
- */
- protected function setObjectProperty($source, $properties, &$collections)
- {
- $hash = $this->getObjectHash($source, $properties);
- $prop = $this->getContext()->getProperty();
- $source->$prop=isset($collections[$hash]) ? $collections[$hash] : array();
- }
-}
-
+<?php
+/**
+ * TActiveRecordRelation class file.
+ *
+ * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright &copy; 2005-2008 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Id$
+ * @package System.Data.ActiveRecord.Relations
+ */
+
+/**
+ * Load active record relationship context.
+ */
+Prado::using('System.Data.ActiveRecord.Relations.TActiveRecordRelationContext');
+
+/**
+ * Base class for active record relationships.
+ *
+ * @author Wei Zhuo <weizho[at]gmail[dot]com>
+ * @version $Id$
+ * @package System.Data.ActiveRecord.Relations
+ * @since 3.1
+ */
+abstract class TActiveRecordRelation
+{
+ private $_context;
+ private $_criteria;
+
+ public function __construct(TActiveRecordRelationContext $context, $criteria)
+ {
+ $this->_context = $context;
+ $this->_criteria = $criteria;
+ }
+
+ /**
+ * @return TActiveRecordRelationContext
+ */
+ protected function getContext()
+ {
+ return $this->_context;
+ }
+
+ /**
+ * @return TActiveRecordCriteria
+ */
+ protected function getCriteria()
+ {
+ return $this->_criteria;
+ }
+
+ /**
+ * @return TActiveRecord
+ */
+ protected function getSourceRecord()
+ {
+ return $this->getContext()->getSourceRecord();
+ }
+
+ abstract protected function collectForeignObjects(&$results);
+
+ /**
+ * Dispatch the method calls to the source record finder object. When
+ * an instance of TActiveRecord or an array of TActiveRecord is returned
+ * the corresponding foreign objects are also fetched and assigned.
+ *
+ * Multiple relationship calls can be chain together.
+ *
+ * @param string method name called
+ * @param array method arguments
+ * @return mixed TActiveRecord or array of TActiveRecord results depending on the method called.
+ */
+ public function __call($method,$args)
+ {
+ static $stack=array();
+
+ $results = call_user_func_array(array($this->getSourceRecord(),$method),$args);
+ $validArray = is_array($results) && count($results) > 0;
+ if($validArray || $results instanceof ArrayAccess || $results instanceof TActiveRecord)
+ {
+ $this->collectForeignObjects($results);
+ while($obj = array_pop($stack))
+ $obj->collectForeignObjects($results);
+ }
+ else if($results instanceof TActiveRecordRelation)
+ $stack[] = $this; //call it later
+ else if($results === null || !$validArray)
+ $stack = array();
+ return $results;
+ }
+
+ /**
+ * Fetch results for current relationship.
+ * @return boolean always true.
+ */
+ public function fetchResultsInto($obj)
+ {
+ $this->collectForeignObjects($obj);
+ return true;
+ }
+
+ /**
+ * Returns foreign keys in $fromRecord with source column names as key
+ * and foreign column names in the corresponding $matchesRecord as value.
+ * The method returns the first matching foreign key between these 2 records.
+ * @param TActiveRecord $fromRecord
+ * @param TActiveRecord $matchesRecord
+ * @return array foreign keys with source column names as key and foreign column names as value.
+ */
+ protected function findForeignKeys($from, $matchesRecord, $loose=false)
+ {
+ $gateway = $matchesRecord->getRecordGateway();
+ $recordTableInfo = $gateway->getRecordTableInfo($matchesRecord);
+ $matchingTableName = strtolower($recordTableInfo->getTableName());
+ $matchingFullTableName = strtolower($recordTableInfo->getTableFullName());
+ $tableInfo=$from;
+ if($from instanceof TActiveRecord)
+ $tableInfo = $gateway->getRecordTableInfo($from);
+ //find first non-empty FK
+ foreach($tableInfo->getForeignKeys() as $fkeys)
+ {
+ $fkTable = strtolower($fkeys['table']);
+ if($fkTable===$matchingTableName || $fkTable===$matchingFullTableName)
+ {
+ $hasFkField = !$loose && $this->getContext()->hasFkField();
+ $key = $hasFkField ? $this->getFkFields($fkeys['keys']) : $fkeys['keys'];
+ if(!empty($key))
+ return $key;
+ }
+ }
+
+ //none found
+ $matching = $gateway->getRecordTableInfo($matchesRecord)->getTableFullName();
+ throw new TActiveRecordException('ar_relations_missing_fk',
+ $tableInfo->getTableFullName(), $matching);
+ }
+
+ /**
+ * @return array foreign key field names as key and object properties as value.
+ * @since 3.1.2
+ */
+ abstract public function getRelationForeignKeys();
+
+ /**
+ * Find matching foreign key fields from the 3rd element of an entry in TActiveRecord::$RELATION.
+ * Assume field names consist of [\w-] character sets. Prefix to the field names ending with a dot
+ * are ignored.
+ */
+ private function getFkFields($fkeys)
+ {
+ $matching = array();
+ preg_match_all('/\s*(\S+\.)?([\w-]+)\s*/', $this->getContext()->getFkField(), $matching);
+ $fields = array();
+ foreach($fkeys as $fkName => $field)
+ {
+ if(in_array($fkName, $matching[2]))
+ $fields[$fkName] = $field;
+ }
+ return $fields;
+ }
+
+ /**
+ * @param mixed object or array to be hashed
+ * @param array name of property for hashing the properties.
+ * @return string object hash using crc32 and serialize.
+ */
+ protected function getObjectHash($obj, $properties)
+ {
+ $ids=array();
+ foreach($properties as $property)
+ $ids[] = is_object($obj) ? (string)$obj->getColumnValue($property) : (string)$obj[$property];
+ return serialize($ids);
+ }
+
+ /**
+ * Fetches the foreign objects using TActiveRecord::findAllByIndex()
+ * @param array field names
+ * @param array foreign key index values.
+ * @return TActiveRecord[] foreign objects.
+ */
+ protected function findForeignObjects($fields, $indexValues)
+ {
+ $finder = $this->getContext()->getForeignRecordFinder();
+ return $finder->findAllByIndex($this->_criteria, $fields, $indexValues);
+ }
+
+ /**
+ * Obtain the foreign key index values from the results.
+ * @param array property names
+ * @param array TActiveRecord results
+ * @return array foreign key index values.
+ */
+ protected function getIndexValues($keys, $results)
+ {
+ if(!is_array($results) && !$results instanceof ArrayAccess)
+ $results = array($results);
+ $values=array();
+ foreach($results as $result)
+ {
+ $value = array();
+ foreach($keys as $name)
+ $value[] = $result->getColumnValue($name);
+ $values[] = $value;
+ }
+ return $values;
+ }
+
+ /**
+ * Populate the results with the foreign objects found.
+ * @param array source results
+ * @param array source property names
+ * @param array foreign objects
+ * @param array foreign object field names.
+ */
+ protected function populateResult(&$results,$properties,&$fkObjects,$fields)
+ {
+ $collections=array();
+ foreach($fkObjects as $fkObject)
+ $collections[$this->getObjectHash($fkObject, $fields)][]=$fkObject;
+ $this->setResultCollection($results, $collections, $properties);
+ }
+
+ /**
+ * Populates the result array with foreign objects (matched using foreign key hashed property values).
+ * @param array $results
+ * @param array $collections
+ * @param array property names
+ */
+ protected function setResultCollection(&$results, &$collections, $properties)
+ {
+ if(is_array($results) || $results instanceof ArrayAccess)
+ {
+ for($i=0,$k=count($results);$i<$k;$i++)
+ $this->setObjectProperty($results[$i], $properties, $collections);
+ }
+ else
+ $this->setObjectProperty($results, $properties, $collections);
+ }
+
+ /**
+ * Sets the foreign objects to the given property on the source object.
+ * @param TActiveRecord source object.
+ * @param array source properties
+ * @param array foreign objects.
+ */
+ protected function setObjectProperty($source, $properties, &$collections)
+ {
+ $hash = $this->getObjectHash($source, $properties);
+ $prop = $this->getContext()->getProperty();
+ $source->$prop=isset($collections[$hash]) ? $collections[$hash] : array();
+ }
+}
+
diff --git a/framework/Data/ActiveRecord/Scaffold/TScaffoldBase.php b/framework/Data/ActiveRecord/Scaffold/TScaffoldBase.php
index 9c548308..b41a593e 100644
--- a/framework/Data/ActiveRecord/Scaffold/TScaffoldBase.php
+++ b/framework/Data/ActiveRecord/Scaffold/TScaffoldBase.php
@@ -4,7 +4,7 @@
*
* @author Wei Zhuo <weizhuo[at]gmail[dot]com>
* @link http://www.pradosoft.com/
- * @copyright Copyright &copy; 2005-2008 PradoSoft
+ * @copyright Copyright &copy; 2005-2008 PradoSoft
* @license http://www.pradosoft.com/license/
* @version $Id$
* @package System.Data.ActiveRecord.Scaffold
@@ -65,6 +65,7 @@ abstract class TScaffoldBase extends TTemplateControl
*/
protected function getRecordPkValues($record)
{
+ $data=array();
foreach($this->getTableInfo()->getColumns() as $name=>$column)
{
if($column->getIsPrimaryKey())
diff --git a/framework/Data/ActiveRecord/TActiveRecord.php b/framework/Data/ActiveRecord/TActiveRecord.php
index af171bbd..34de431b 100644
--- a/framework/Data/ActiveRecord/TActiveRecord.php
+++ b/framework/Data/ActiveRecord/TActiveRecord.php
@@ -4,7 +4,7 @@
*
* @author Wei Zhuo <weizhuo[at]gmail[dot]com>
* @link http://www.pradosoft.com/
- * @copyright Copyright &copy; 2005-2008 PradoSoft
+ * @copyright Copyright &copy; 2005-2010 PradoSoft
* @license http://www.pradosoft.com/license/
* @version $Id$
* @package System.Data.ActiveRecord
@@ -225,6 +225,7 @@ abstract class TActiveRecord extends TComponent
*/
public function __construct($data=array(), $connection=null)
{
+ parent::__construct();
if($connection!==null)
$this->setDbConnection($connection);
$this->setupColumnMapping();
diff --git a/framework/Data/ActiveRecord/TActiveRecordConfig.php b/framework/Data/ActiveRecord/TActiveRecordConfig.php
index fb57fd33..51278fc9 100644
--- a/framework/Data/ActiveRecord/TActiveRecordConfig.php
+++ b/framework/Data/ActiveRecord/TActiveRecordConfig.php
@@ -134,4 +134,4 @@ class TActiveRecordConfig extends TDataSourceConfig
{
$this->_invalidFinderResult = TPropertyValue::ensureEnum($value, 'TActiveRecordInvalidFinderResult');
}
-} \ No newline at end of file
+}
diff --git a/framework/Data/ActiveRecord/TActiveRecordGateway.php b/framework/Data/ActiveRecord/TActiveRecordGateway.php
index e588b976..534bd253 100644
--- a/framework/Data/ActiveRecord/TActiveRecordGateway.php
+++ b/framework/Data/ActiveRecord/TActiveRecordGateway.php
@@ -4,7 +4,7 @@
*
* @author Wei Zhuo <weizhuo[at]gmail[dot]com>
* @link http://www.pradosoft.com/
- * @copyright Copyright &copy; 2005-2008 PradoSoft
+ * @copyright Copyright &copy; 2005-2010 PradoSoft
* @license http://www.pradosoft.com/license/
* @version $Id$
* @package System.Data.ActiveRecord
@@ -42,6 +42,7 @@ class TActiveRecordGateway extends TComponent
*/
public function __construct(TActiveRecordManager $manager)
{
+ parent::__construct();
$this->_manager=$manager;
}
@@ -306,7 +307,7 @@ class TActiveRecordGateway extends TComponent
if($column->getIsExcluded())
continue;
$value = $record->getColumnValue($name);
- if(!$column->getAllowNull() && $value===null && !$column->hasSequence() && !$column->getDefaultValue())
+ if(!$column->getAllowNull() && $value===null && !$column->hasSequence() && ($column->getDefaultValue() === TDbTableColumn::UNDEFINED_VALUE))
{
throw new TActiveRecordException(
'ar_value_must_not_be_null', get_class($record),
@@ -342,7 +343,7 @@ class TActiveRecordGateway extends TComponent
if($column->getIsExcluded())
continue;
$value = $record->getColumnValue($name);
- if(!$column->getAllowNull() && $value===null)
+ if(!$column->getAllowNull() && $value===null && ($column->getDefaultValue() === TDbTableColumn::UNDEFINED_VALUE))
{
throw new TActiveRecordException(
'ar_value_must_not_be_null', get_class($record),
diff --git a/framework/Data/Common/Mssql/TMssqlMetaData.php b/framework/Data/Common/Mssql/TMssqlMetaData.php
index 8309e4ec..2751caf3 100644
--- a/framework/Data/Common/Mssql/TMssqlMetaData.php
+++ b/framework/Data/Common/Mssql/TMssqlMetaData.php
@@ -53,9 +53,9 @@ class TMssqlMetaData extends TDbMetaData
AND t.table_name = :table
EOD;
if($schemaName!==null)
- $sql .= ' AND t.schema_name = :schema';
+ $sql .= ' AND t.table_schema = :schema';
if($catalogName!==null)
- $sql .= ' AND t.catalog_name = :catalog';
+ $sql .= ' AND t.table_catalog = :catalog';
$command = $this->getDbConnection()->createCommand($sql);
$command->bindValue(':table', $tableName);
diff --git a/framework/Data/Common/Mysql/TMysqlMetaData.php b/framework/Data/Common/Mysql/TMysqlMetaData.php
index fad33cea..0e17f52c 100644
--- a/framework/Data/Common/Mysql/TMysqlMetaData.php
+++ b/framework/Data/Common/Mysql/TMysqlMetaData.php
@@ -263,7 +263,7 @@ class TMysqlMetaData extends TDbMetaData
*/
protected function getForeignConstraints($schemaName, $tableName)
{
- $andSchema = $schemaName !== null ? 'AND TABLE_SCHEMA = :schema' : '';
+ $andSchema = $schemaName !== null ? 'AND TABLE_SCHEMA LIKE :schema' : '';
$sql = <<<EOD
SELECT
CONSTRAINT_NAME as con,
@@ -275,7 +275,7 @@ class TMysqlMetaData extends TDbMetaData
`INFORMATION_SCHEMA`.`KEY_COLUMN_USAGE`
WHERE
REFERENCED_TABLE_NAME IS NOT NULL
- AND TABLE_NAME = :table
+ AND TABLE_NAME LIKE :table
$andSchema
EOD;
$command = $this->getDbConnection()->createCommand($sql);
diff --git a/framework/Data/Common/Oracle/TOracleMetaData.php b/framework/Data/Common/Oracle/TOracleMetaData.php
index 5fdf1d5c..ac119454 100644
--- a/framework/Data/Common/Oracle/TOracleMetaData.php
+++ b/framework/Data/Common/Oracle/TOracleMetaData.php
@@ -163,7 +163,7 @@ EOD;
$command = $this->getDbConnection()->createCommand($sql);
//$command->bindValue(':schema',$schemaName);
//$command->bindValue(':table', $tableName);
- return intval($command->queryScalar()) === 'VIEW';
+ return intval($command->queryScalar() === 'VIEW');
}
/**
diff --git a/framework/Data/Common/Oracle/TOracleTableInfo.php b/framework/Data/Common/Oracle/TOracleTableInfo.php
index c7d373b2..0a6238e0 100644
--- a/framework/Data/Common/Oracle/TOracleTableInfo.php
+++ b/framework/Data/Common/Oracle/TOracleTableInfo.php
@@ -5,7 +5,7 @@
*
* @author Marcos Nobre <marconobre[at]gmail[dot]com>
* @link http://www.pradosoft.com/
- * @copyright Copyright &copy; 2005-2008 PradoSoft
+ * @copyright Copyright &copy; 2005-2010 PradoSoft
* @license http://www.pradosoft.com/license/
* @version $Id$
* @package System.Data.Common
@@ -36,6 +36,7 @@ class TOracleTableInfo extends TComponent
*/
public function __construct($tableInfo=array(),$primary=array(),$foreign=array())
{
+ parent::__construct();
$this->_info=$tableInfo;
$this->_primaryKeys=$primary;
$this->_foreignKeys=$foreign;
diff --git a/framework/Data/Common/TDbCommandBuilder.php b/framework/Data/Common/TDbCommandBuilder.php
index 0dc13e7e..8619c435 100644
--- a/framework/Data/Common/TDbCommandBuilder.php
+++ b/framework/Data/Common/TDbCommandBuilder.php
@@ -4,7 +4,7 @@
*
* @author Wei Zhuo <weizhuo[at]gmail[dot]com>
* @link http://www.pradosoft.com/
- * @copyright Copyright &copy; 2005-2008 PradoSoft
+ * @copyright Copyright &copy; 2005-2010 PradoSoft
* @license http://www.pradosoft.com/license/
* @version $Id$
* @package System.Data.Common
@@ -30,6 +30,7 @@ class TDbCommandBuilder extends TComponent
*/
public function __construct($connection=null, $tableInfo=null)
{
+ parent::__construct();
$this->setDbConnection($connection);
$this->setTableInfo($tableInfo);
}
diff --git a/framework/Data/Common/TDbMetaData.php b/framework/Data/Common/TDbMetaData.php
index bcdf0e46..1a194056 100644
--- a/framework/Data/Common/TDbMetaData.php
+++ b/framework/Data/Common/TDbMetaData.php
@@ -4,7 +4,7 @@
*
* @author Wei Zhuo <weizhuo[at]gmail[dot]com>
* @link http://www.pradosoft.com/
- * @copyright Copyright &copy; 2005-2008 PradoSoft
+ * @copyright Copyright &copy; 2005-2010 PradoSoft
* @license http://www.pradosoft.com/license/
* @version $Id$
* @package System.Data.Common
@@ -31,6 +31,7 @@ abstract class TDbMetaData extends TComponent
*/
public function __construct($conn)
{
+ parent::__construct();
$this->_connection=$conn;
}
diff --git a/framework/Data/Common/TDbTableColumn.php b/framework/Data/Common/TDbTableColumn.php
index 3bb9454b..84fa6c55 100644
--- a/framework/Data/Common/TDbTableColumn.php
+++ b/framework/Data/Common/TDbTableColumn.php
@@ -4,7 +4,7 @@
*
* @author Wei Zhuo <weizhuo[at]gmail[dot]com>
* @link http://www.pradosoft.com/
- * @copyright Copyright &copy; 2005-2008 PradoSoft
+ * @copyright Copyright &copy; 2005-2010 PradoSoft
* @license http://www.pradosoft.com/license/
* @version $Id$
* @package System.Data.Common
@@ -30,6 +30,7 @@ class TDbTableColumn extends TComponent
*/
public function __construct($columnInfo)
{
+ parent::__construct();
$this->_info=$columnInfo;
}
diff --git a/framework/Data/Common/TDbTableInfo.php b/framework/Data/Common/TDbTableInfo.php
index 455dbc33..6cab9230 100644
--- a/framework/Data/Common/TDbTableInfo.php
+++ b/framework/Data/Common/TDbTableInfo.php
@@ -1,166 +1,167 @@
<?php
-/**
- * TDbTableInfo class file.
- *
- * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
- * @link http://www.pradosoft.com/
- * @copyright Copyright &copy; 2005-2008 PradoSoft
- * @license http://www.pradosoft.com/license/
- * @version $Id$
- * @package System.Data.Common
- */
-
-/**
- * TDbTableInfo class describes the meta data of a database table.
- *
- * @author Wei Zhuo <weizho[at]gmail[dot]com>
- * @version $Id$
- * @package System.Data.Common
- * @since 3.1
- */
-class TDbTableInfo extends TComponent
-{
- private $_info=array();
-
- private $_primaryKeys;
- private $_foreignKeys;
-
- private $_columns;
-
+/**
+ * TDbTableInfo class file.
+ *
+ * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright &copy; 2005-2010 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Id$
+ * @package System.Data.Common
+ */
+
+/**
+ * TDbTableInfo class describes the meta data of a database table.
+ *
+ * @author Wei Zhuo <weizho[at]gmail[dot]com>
+ * @version $Id$
+ * @package System.Data.Common
+ * @since 3.1
+ */
+class TDbTableInfo extends TComponent
+{
+ private $_info=array();
+
+ private $_primaryKeys;
+ private $_foreignKeys;
+
+ private $_columns;
+
private $_lowercase;
/**
* @var null|array
* @since 3.1.7
- */
- private $_names = null;
-
- /**
- * Sets the database table meta data information.
- * @param array table column information.
- */
- public function __construct($tableInfo=array(),$primary=array(),$foreign=array())
- {
- $this->_info=$tableInfo;
- $this->_primaryKeys=$primary;
- $this->_foreignKeys=$foreign;
- $this->_columns=new TMap;
- }
-
- /**
- * @param TDbConnection database connection.
- * @return TDbCommandBuilder new command builder
- */
- public function createCommandBuilder($connection)
- {
- Prado::using('System.Data.Common.TDbCommandBuilder');
- return new TDbCommandBuilder($connection,$this);
- }
-
- /**
- * @param string information array key name
- * @param mixed default value if information array value is null
- * @return mixed information array value.
- */
- protected function getInfo($name,$default=null)
- {
- return isset($this->_info[$name]) ? $this->_info[$name] : $default;
- }
-
- /**
- * @param string information array key name
- * @param mixed new information array value.
- */
- protected function setInfo($name,$value)
- {
- $this->_info[$name]=$value;
- }
-
- /**
- * @return string name of the table this column belongs to.
- */
- public function getTableName()
- {
- return $this->getInfo('TableName');
- }
-
- /**
- * @return string full name of the table, database dependent.
- */
- public function getTableFullName()
- {
- return $this->getTableName();
- }
-
- /**
- * @return boolean whether the table is a view, default is false.
- */
- public function getIsView()
- {
- return $this->getInfo('IsView',false);
- }
-
- /**
- * @return TMap TDbTableColumn column meta data.
- */
- public function getColumns()
- {
- return $this->_columns;
- }
-
- /**
- * @param string column id
- * @return TDbTableColumn column information.
- */
- public function getColumn($name)
- {
- if(($column = $this->_columns->itemAt($name))!==null)
- return $column;
- throw new TDbException('dbtableinfo_invalid_column_name', $name, $this->getTableFullName());
- }
-
- /**
- * @param array list of column Id, empty to get all columns.
- * @return array table column names (identifier quoted)
- */
- public function getColumnNames()
+ */
+ private $_names = null;
+
+ /**
+ * Sets the database table meta data information.
+ * @param array table column information.
+ */
+ public function __construct($tableInfo=array(),$primary=array(),$foreign=array())
+ {
+ parent::__construct();
+ $this->_info=$tableInfo;
+ $this->_primaryKeys=$primary;
+ $this->_foreignKeys=$foreign;
+ $this->_columns=new TMap;
+ }
+
+ /**
+ * @param TDbConnection database connection.
+ * @return TDbCommandBuilder new command builder
+ */
+ public function createCommandBuilder($connection)
+ {
+ Prado::using('System.Data.Common.TDbCommandBuilder');
+ return new TDbCommandBuilder($connection,$this);
+ }
+
+ /**
+ * @param string information array key name
+ * @param mixed default value if information array value is null
+ * @return mixed information array value.
+ */
+ protected function getInfo($name,$default=null)
+ {
+ return isset($this->_info[$name]) ? $this->_info[$name] : $default;
+ }
+
+ /**
+ * @param string information array key name
+ * @param mixed new information array value.
+ */
+ protected function setInfo($name,$value)
+ {
+ $this->_info[$name]=$value;
+ }
+
+ /**
+ * @return string name of the table this column belongs to.
+ */
+ public function getTableName()
+ {
+ return $this->getInfo('TableName');
+ }
+
+ /**
+ * @return string full name of the table, database dependent.
+ */
+ public function getTableFullName()
+ {
+ return $this->getTableName();
+ }
+
+ /**
+ * @return boolean whether the table is a view, default is false.
+ */
+ public function getIsView()
+ {
+ return $this->getInfo('IsView',false);
+ }
+
+ /**
+ * @return TMap TDbTableColumn column meta data.
+ */
+ public function getColumns()
+ {
+ return $this->_columns;
+ }
+
+ /**
+ * @param string column id
+ * @return TDbTableColumn column information.
+ */
+ public function getColumn($name)
+ {
+ if(($column = $this->_columns->itemAt($name))!==null)
+ return $column;
+ throw new TDbException('dbtableinfo_invalid_column_name', $name, $this->getTableFullName());
+ }
+
+ /**
+ * @param array list of column Id, empty to get all columns.
+ * @return array table column names (identifier quoted)
+ */
+ public function getColumnNames()
{
if($this->_names===null)
- {
- $this->_names=array();
- foreach($this->getColumns() as $column)
+ {
+ $this->_names=array();
+ foreach($this->getColumns() as $column)
$this->_names[] = $column->getColumnName();
- }
- return $this->_names;
- }
-
- /**
- * @return string[] names of primary key columns.
- */
- public function getPrimaryKeys()
- {
- return $this->_primaryKeys;
- }
-
- /**
- * @return array tuples of foreign table and column name.
- */
- public function getForeignKeys()
- {
- return $this->_foreignKeys;
- }
-
- /**
- * @return array lowercased column key names mapped to normal column ids.
- */
- public function getLowerCaseColumnNames()
- {
- if($this->_lowercase===null)
- {
- $this->_lowercase=array();
- foreach($this->getColumns()->getKeys() as $key)
- $this->_lowercase[strtolower($key)] = $key;
- }
- return $this->_lowercase;
- }
-} \ No newline at end of file
+ }
+ return $this->_names;
+ }
+
+ /**
+ * @return string[] names of primary key columns.
+ */
+ public function getPrimaryKeys()
+ {
+ return $this->_primaryKeys;
+ }
+
+ /**
+ * @return array tuples of foreign table and column name.
+ */
+ public function getForeignKeys()
+ {
+ return $this->_foreignKeys;
+ }
+
+ /**
+ * @return array lowercased column key names mapped to normal column ids.
+ */
+ public function getLowerCaseColumnNames()
+ {
+ if($this->_lowercase===null)
+ {
+ $this->_lowercase=array();
+ foreach($this->getColumns()->getKeys() as $key)
+ $this->_lowercase[strtolower($key)] = $key;
+ }
+ return $this->_lowercase;
+ }
+}
diff --git a/framework/Data/DataGateway/TDataGatewayCommand.php b/framework/Data/DataGateway/TDataGatewayCommand.php
index e290f457..034ea36e 100644
--- a/framework/Data/DataGateway/TDataGatewayCommand.php
+++ b/framework/Data/DataGateway/TDataGatewayCommand.php
@@ -4,7 +4,7 @@
*
* @author Wei Zhuo <weizhuo[at]gmail[dot]com>
* @link http://www.pradosoft.com/
- * @copyright Copyright &copy; 2005-2008 PradoSoft
+ * @copyright Copyright &copy; 2005-2010 PradoSoft
* @license http://www.pradosoft.com/license/
* @version $Id$
* @package System.Data.DataGateway
@@ -43,6 +43,7 @@ class TDataGatewayCommand extends TComponent
*/
public function __construct($builder)
{
+ parent::__construct();
$this->_builder = $builder;
}
@@ -469,6 +470,7 @@ class TDataGatewayEventParameter extends TEventParameter
public function __construct($command,$criteria)
{
+ parent::__construct();
$this->_command=$command;
$this->_criteria=$criteria;
}
diff --git a/framework/Data/DataGateway/TSqlCriteria.php b/framework/Data/DataGateway/TSqlCriteria.php
index 14e37b35..1b85c7d3 100644
--- a/framework/Data/DataGateway/TSqlCriteria.php
+++ b/framework/Data/DataGateway/TSqlCriteria.php
@@ -4,7 +4,7 @@
*
* @author Wei Zhuo <weizhuo[at]gmail[dot]com>
* @link http://www.pradosoft.com/
- * @copyright Copyright &copy; 2005-2008 PradoSoft
+ * @copyright Copyright &copy; 2005-2010 PradoSoft
* @license http://www.pradosoft.com/license/
* @version $Id: TDbSqlCriteria.php 1835 2007-04-03 01:38:15Z wei $
* @package System.Data.DataGateway
@@ -49,6 +49,7 @@ class TSqlCriteria extends TComponent
*/
public function __construct($condition=null, $parameters=array())
{
+ parent::__construct();
if(!is_array($parameters) && func_num_args() > 1)
$parameters = array_slice(func_get_args(),1);
$this->_parameters=new TAttributeCollection;
diff --git a/framework/Data/SqlMap/Configuration/TParameterMap.php b/framework/Data/SqlMap/Configuration/TParameterMap.php
index 4b5ee144..60b05662 100644
--- a/framework/Data/SqlMap/Configuration/TParameterMap.php
+++ b/framework/Data/SqlMap/Configuration/TParameterMap.php
@@ -4,7 +4,7 @@
*
* @author Wei Zhuo <weizhuo[at]gmail[dot]com>
* @link http://www.pradosoft.com/
- * @copyright Copyright &copy; 2005-2008 PradoSoft
+ * @copyright Copyright &copy; 2005-2010 PradoSoft
* @license http://www.pradosoft.com/license/
* @version $Id$
* @package System.Data.SqlMap.Configuration
@@ -43,6 +43,7 @@ class TParameterMap extends TComponent
*/
public function __construct()
{
+ parent::__construct();
$this->_properties = new TList;
$this->_propertyMap = new TMap;
}
@@ -184,7 +185,10 @@ class TParameterMap extends TComponent
{
throw new TSqlMapException(
'sqlmap_unable_to_get_property_for_parameter',
- $this->getID(), $property->getProperty(), get_class($object));
+ $this->getID(),
+ $property->getProperty(),
+ (is_object($object) ? get_class($object) : gettype($object))
+ );
}
}
diff --git a/framework/Data/SqlMap/Configuration/TResultMap.php b/framework/Data/SqlMap/Configuration/TResultMap.php
index e85dc1aa..b20a81f6 100644
--- a/framework/Data/SqlMap/Configuration/TResultMap.php
+++ b/framework/Data/SqlMap/Configuration/TResultMap.php
@@ -4,7 +4,7 @@
*
* @author Wei Zhuo <weizhuo[at]gmail[dot]com>
* @link http://www.pradosoft.com/
- * @copyright Copyright &copy; 2005-2008 PradoSoft
+ * @copyright Copyright &copy; 2005-2010 PradoSoft
* @license http://www.pradosoft.com/license/
* @version $Id$
* @package System.Data.SqlMap.Configuration
@@ -51,6 +51,7 @@ class TResultMap extends TComponent
*/
public function __construct()
{
+ parent::__construct();
$this->_columns=new TMap;
}
diff --git a/framework/Data/SqlMap/Configuration/TResultProperty.php b/framework/Data/SqlMap/Configuration/TResultProperty.php
index 7316ef0b..24401812 100644
--- a/framework/Data/SqlMap/Configuration/TResultProperty.php
+++ b/framework/Data/SqlMap/Configuration/TResultProperty.php
@@ -4,7 +4,7 @@
*
* @author Wei Zhuo <weizhuo[at]gmail[dot]com>
* @link http://www.pradosoft.com/
- * @copyright Copyright &copy; 2005-2008 PradoSoft
+ * @copyright Copyright &copy; 2005-2010 PradoSoft
* @license http://www.pradosoft.com/license/
* @version $Id$
* @package System.Data.SqlMap.Configuration
@@ -57,6 +57,7 @@ class TResultProperty extends TComponent
*/
public function __construct($resultMap=null)
{
+ parent::__construct();
if($resultMap instanceof TResultMap)
$this->_hostResultMapID = $resultMap->getID();
}
diff --git a/framework/Data/SqlMap/Configuration/TSqlMapXmlConfiguration.php b/framework/Data/SqlMap/Configuration/TSqlMapXmlConfiguration.php
index c49a4219..2448659a 100644
--- a/framework/Data/SqlMap/Configuration/TSqlMapXmlConfiguration.php
+++ b/framework/Data/SqlMap/Configuration/TSqlMapXmlConfiguration.php
@@ -4,7 +4,7 @@
*
* @author Wei Zhuo <weizhuo[at]gmail[dot]com>
* @link http://www.pradosoft.com/
- * @copyright Copyright &copy; 2005-2008 PradoSoft
+ * @copyright Copyright &copy; 2005-2010 PradoSoft
* @license http://www.pradosoft.com/license/
* @version $Id$
* @package System.Data.SqlMap.Configuration
diff --git a/framework/Data/SqlMap/Statements/TMappedStatement.php b/framework/Data/SqlMap/Statements/TMappedStatement.php
index c4bb53dd..7aab3510 100644
--- a/framework/Data/SqlMap/Statements/TMappedStatement.php
+++ b/framework/Data/SqlMap/Statements/TMappedStatement.php
@@ -4,7 +4,7 @@
*
* @author Wei Zhuo <weizhuo[at]gmail[dot]com>
* @link http://www.pradosoft.com/
- * @copyright Copyright &copy; 2005-2008 PradoSoft
+ * @copyright Copyright &copy; 2005-2010 PradoSoft
* @license http://www.pradosoft.com/license/
* @version $Id$
* @package System.Data.SqlMap.Statements
@@ -116,6 +116,7 @@ class TMappedStatement extends TComponent implements IMappedStatement
*/
public function __construct(TSqlMapManager $sqlMap, TSqlMapStatement $statement)
{
+ parent::__construct();
$this->_manager = $sqlMap;
$this->_statement = $statement;
$this->_command = new TPreparedCommand();
diff --git a/framework/Data/SqlMap/Statements/TPreparedStatement.php b/framework/Data/SqlMap/Statements/TPreparedStatement.php
index 7d862378..c9faf4ee 100644
--- a/framework/Data/SqlMap/Statements/TPreparedStatement.php
+++ b/framework/Data/SqlMap/Statements/TPreparedStatement.php
@@ -4,7 +4,7 @@
*
* @author Wei Zhuo <weizhuo[at]gmail[dot]com>
* @link http://www.pradosoft.com/
- * @copyright Copyright &copy; 2005-2008 PradoSoft
+ * @copyright Copyright &copy; 2005-2010 PradoSoft
* @license http://www.pradosoft.com/license/
* @version $Id$
* @package System.Data.SqlMap.Statements
@@ -26,6 +26,7 @@ class TPreparedStatement extends TComponent
public function __construct()
{
+ parent::__construct();
$this->_parameterNames=new TList;
$this->_parameterValues=new TMap;
}
diff --git a/framework/Data/SqlMap/Statements/TSimpleDynamicSql.php b/framework/Data/SqlMap/Statements/TSimpleDynamicSql.php
index 5d85ded9..5335c41c 100644
--- a/framework/Data/SqlMap/Statements/TSimpleDynamicSql.php
+++ b/framework/Data/SqlMap/Statements/TSimpleDynamicSql.php
@@ -4,7 +4,7 @@
*
* @author Wei Zhuo <weizhuo[at]gmail[dot]com>
* @link http://www.pradosoft.com/
- * @copyright Copyright &copy; 2005-2008 PradoSoft
+ * @copyright Copyright &copy; 2005-2010 PradoSoft
* @license http://www.pradosoft.com/license/
* @version $Id$
* @package System.Data.SqlMap.Statements
@@ -24,6 +24,7 @@ class TSimpleDynamicSql extends TStaticSql
public function __construct($mappings)
{
+ parent::__construct();
$this->_mappings = $mappings;
}
diff --git a/framework/Data/SqlMap/TSqlMapGateway.php b/framework/Data/SqlMap/TSqlMapGateway.php
index 97b31b50..3a19d155 100644
--- a/framework/Data/SqlMap/TSqlMapGateway.php
+++ b/framework/Data/SqlMap/TSqlMapGateway.php
@@ -4,7 +4,7 @@
*
* @author Wei Zhuo <weizhuo[at]gmail[dot]com>
* @link http://www.pradosoft.com/
- * @copyright Copyright &copy; 2005-2008 PradoSoft
+ * @copyright Copyright &copy; 2005-2010 PradoSoft
* @license http://www.pradosoft.com/license/
* @version $Id$
* @package System.Data.SqlMap
@@ -36,6 +36,7 @@ class TSqlMapGateway extends TComponent
public function __construct($manager)
{
+ parent::__construct();
$this->_manager=$manager;
}
@@ -122,7 +123,7 @@ class TSqlMapGateway extends TComponent
* @param string The name of the sql statement to execute.
* @param mixed The object used to set the parameters in the SQL.
* @param integer The maximum number of objects to store in each page.
- * @param integer The number of the page to initially load into the list.
+ * @param integer The number of the page to initially load into the list.
* @return TPagedList A PaginatedList of beans containing the rows.
*/
public function queryForPagedList($statementName, $parameter=null, $pageSize=10, $page=0)
@@ -143,7 +144,7 @@ class TSqlMapGateway extends TComponent
* @param callback Row delegate handler, a valid callback required.
* @param mixed The object used to set the parameters in the SQL.
* @param integer The maximum number of objects to store in each page.
- * @param integer The number of the page to initially load into the list.
+ * @param integer The number of the page to initially load into the list.
* @return TPagedList A PaginatedList of beans containing the rows.
*/
public function queryForPagedListWithRowDelegate($statementName,$delegate, $parameter=null, $pageSize=10, $page=0)
diff --git a/framework/Data/SqlMap/TSqlMapManager.php b/framework/Data/SqlMap/TSqlMapManager.php
index 432c1c5e..0af90a3d 100644
--- a/framework/Data/SqlMap/TSqlMapManager.php
+++ b/framework/Data/SqlMap/TSqlMapManager.php
@@ -4,7 +4,7 @@
*
* @author Wei Zhuo <weizhuo[at]gmail[dot]com>
* @link http://www.pradosoft.com/
- * @copyright Copyright &copy; 2005-2008 PradoSoft
+ * @copyright Copyright &copy; 2005-2010 PradoSoft
* @license http://www.pradosoft.com/license/
* @version $Id$
* @package System.Data.SqlMap
@@ -60,6 +60,7 @@ class TSqlMapManager extends TComponent
*/
public function __construct($connection=null)
{
+ parent::__construct();
$this->_connection=$connection;
$this->_mappedStatements=new TMap;
diff --git a/framework/Data/TDataSourceConfig.php b/framework/Data/TDataSourceConfig.php
index 53a5ef22..bea15ec4 100644
--- a/framework/Data/TDataSourceConfig.php
+++ b/framework/Data/TDataSourceConfig.php
@@ -58,13 +58,13 @@ class TDataSourceConfig extends TModule
*/
public function init($xml)
{
- if($prop=$xml->getElementByTagName('database'))
- {
- $db=$this->getDbConnection();
- foreach($prop->getAttributes() as $name=>$value)
- $db->setSubproperty($name,$value);
+ if($prop=$xml->getElementByTagName('database'))
+ {
+ $db=$this->getDbConnection();
+ foreach($prop->getAttributes() as $name=>$value)
+ $db->setSubproperty($name,$value);
+ }
}
- }
/**
* The module ID of another TDataSourceConfig. The {@link getDbConnection DbConnection}
@@ -153,4 +153,3 @@ class TDataSourceConfig extends TModule
throw new TConfigurationException('datasource_dbconnection_invalid',$id);
}
}
-
diff --git a/framework/Data/TDbCommand.php b/framework/Data/TDbCommand.php
index d09c53f4..749d3ec3 100644
--- a/framework/Data/TDbCommand.php
+++ b/framework/Data/TDbCommand.php
@@ -4,7 +4,7 @@
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.pradosoft.com/
- * @copyright Copyright &copy; 2005-2008 PradoSoft
+ * @copyright Copyright &copy; 2005-2010 PradoSoft
* @license http://www.pradosoft.com/license/
* @version $Id$
* @package System.Data
@@ -49,6 +49,7 @@ class TDbCommand extends TComponent
*/
public function __construct(TDbConnection $connection,$text)
{
+ parent::__construct();
$this->_connection=$connection;
$this->setText($text);
}
diff --git a/framework/Data/TDbConnection.php b/framework/Data/TDbConnection.php
index 4726083c..1eba022b 100644
--- a/framework/Data/TDbConnection.php
+++ b/framework/Data/TDbConnection.php
@@ -1,634 +1,640 @@
-<?php
-/**
- * TDbConnection class file
- *
- * @author Qiang Xue <qiang.xue@gmail.com>
- * @link http://www.pradosoft.com/
- * @copyright Copyright &copy; 2005-2008 PradoSoft
- * @license http://www.pradosoft.com/license/
- * @version $Id$
- * @package System.Data
- */
-
-Prado::using('System.Data.TDbTransaction');
-Prado::using('System.Data.TDbCommand');
-
-/**
- * TDbConnection class
- *
- * TDbConnection represents a connection to a database.
- *
- * TDbConnection works together with {@link TDbCommand}, {@link TDbDataReader}
- * and {@link TDbTransaction} to provide data access to various DBMS
- * in a common set of APIs. They are a thin wrapper of the {@link http://www.php.net/manual/en/ref.pdo.php PDO}
- * PHP extension.
- *
- * To establish a connection, set {@link setActive Active} to true after
- * 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)
- * 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, ...
- *
- * The following example shows how to create a TDbConnection instance and establish
- * the actual connection:
- * <code>
- * $connection=new TDbConnection($dsn,$username,$password);
- * $connection->Active=true;
- * </code>
- *
- * After the DB connection is established, one can execute an SQL statement like the following:
- * <code>
- * $command=$connection->createCommand($sqlStatement);
- * $command->execute(); // a non-query SQL statement execution
- * // or execute an SQL query and fetch the result set
- * $reader=$command->query();
- *
- * // each $row is an array representing a row of data
- * foreach($reader as $row) ...
- * </code>
- *
- * One can do prepared SQL execution and bind parameters to the prepared SQL:
- * <code>
- * $command=$connection->createCommand($sqlStatement);
- * $command->bindParameter($name1,$value1);
- * $command->bindParameter($name2,$value2);
- * $command->execute();
- * </code>
- *
- * To use transaction, do like the following:
- * <code>
- * $transaction=$connection->beginTransaction();
- * try
- * {
- * $connection->createCommand($sql1)->execute();
- * $connection->createCommand($sql2)->execute();
- * //.... other SQL executions
- * $transaction->commit();
- * }
- * catch(Exception $e)
- * {
- * $transaction->rollBack();
- * }
- * </code>
- *
- * TDbConnection provides a set of methods to support setting and querying
- * of certain DBMS attributes, such as {@link getNullConversion NullConversion}.
- *
- * @author Qiang Xue <qiang.xue@gmail.com>
- * @version $Id$
- * @package System.Data
- * @since 3.0
- */
-class TDbConnection extends TComponent
-{
- /**
- *
- * @since 3.1.7
- */
- const DEFAULT_TRANSACTION_CLASS = 'System.Data.TDbTransaction';
-
- private $_dsn='';
- private $_username='';
- private $_password='';
- private $_charset='';
- private $_attributes=array();
- private $_active=false;
- 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.
- * @param string Charset used for DB Connection (MySql & pgsql only). If not set, will use the default charset of your database server
- * @see http://www.php.net/manual/en/function.PDO-construct.php
- */
- public function __construct($dsn='',$username='',$password='', $charset='')
- {
- $this->_dsn=$dsn;
- $this->_username=$username;
- $this->_password=$password;
- $this->_charset=$charset;
- }
-
- /**
- * Close the connection when serializing.
- */
- public function __sleep()
- {
- $this->close();
- return array_keys(get_object_vars($this));
- }
-
- /**
- * @return array list of available PDO drivers
- * @see http://www.php.net/manual/en/function.PDO-getAvailableDrivers.php
- */
- public static function getAvailableDrivers()
- {
- return PDO::getAvailableDrivers();
- }
-
- /**
- * @return boolean whether the DB connection is established
- */
- public function getActive()
- {
- return $this->_active;
- }
-
- /**
- * Open or close the DB connection.
- * @param boolean whether to open or close DB connection
- * @throws TDbException if connection fails
- */
- public function setActive($value)
- {
- $value=TPropertyValue::ensureBoolean($value);
- if($value!==$this->_active)
- {
- if($value)
- $this->open();
- else
- $this->close();
- }
- }
-
- /**
- * Opens DB connection if it is currently not
- * @throws TDbException if connection fails
- */
- protected function open()
- {
- if($this->_pdo===null)
- {
- try
- {
- $this->_pdo=new PDO($this->getConnectionString(),$this->getUsername(),
+<?php
+/**
+ * TDbConnection class file
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright &copy; 2005-2010 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Id$
+ * @package System.Data
+ */
+
+Prado::using('System.Data.TDbTransaction');
+Prado::using('System.Data.TDbCommand');
+
+/**
+ * TDbConnection class
+ *
+ * TDbConnection represents a connection to a database.
+ *
+ * TDbConnection works together with {@link TDbCommand}, {@link TDbDataReader}
+ * and {@link TDbTransaction} to provide data access to various DBMS
+ * in a common set of APIs. They are a thin wrapper of the {@link http://www.php.net/manual/en/ref.pdo.php PDO}
+ * PHP extension.
+ *
+ * To establish a connection, set {@link setActive Active} to true after
+ * 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)
+ * 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, ...
+ *
+ * The following example shows how to create a TDbConnection instance and establish
+ * the actual connection:
+ * <code>
+ * $connection=new TDbConnection($dsn,$username,$password);
+ * $connection->Active=true;
+ * </code>
+ *
+ * After the DB connection is established, one can execute an SQL statement like the following:
+ * <code>
+ * $command=$connection->createCommand($sqlStatement);
+ * $command->execute(); // a non-query SQL statement execution
+ * // or execute an SQL query and fetch the result set
+ * $reader=$command->query();
+ *
+ * // each $row is an array representing a row of data
+ * foreach($reader as $row) ...
+ * </code>
+ *
+ * One can do prepared SQL execution and bind parameters to the prepared SQL:
+ * <code>
+ * $command=$connection->createCommand($sqlStatement);
+ * $command->bindParameter($name1,$value1);
+ * $command->bindParameter($name2,$value2);
+ * $command->execute();
+ * </code>
+ *
+ * To use transaction, do like the following:
+ * <code>
+ * $transaction=$connection->beginTransaction();
+ * try
+ * {
+ * $connection->createCommand($sql1)->execute();
+ * $connection->createCommand($sql2)->execute();
+ * //.... other SQL executions
+ * $transaction->commit();
+ * }
+ * catch(Exception $e)
+ * {
+ * $transaction->rollBack();
+ * }
+ * </code>
+ *
+ * TDbConnection provides a set of methods to support setting and querying
+ * of certain DBMS attributes, such as {@link getNullConversion NullConversion}.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Id$
+ * @package System.Data
+ * @since 3.0
+ */
+class TDbConnection extends TComponent
+{
+ /**
+ *
+ * @since 3.1.7
+ */
+ const DEFAULT_TRANSACTION_CLASS = 'System.Data.TDbTransaction';
+
+ private $_dsn='';
+ private $_username='';
+ private $_password='';
+ private $_charset='';
+ private $_attributes=array();
+ private $_active=false;
+ 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.
+ * @param string Charset used for DB Connection (MySql & pgsql only). If not set, will use the default charset of your database server
+ * @see http://www.php.net/manual/en/function.PDO-construct.php
+ */
+ public function __construct($dsn='',$username='',$password='', $charset='')
+ {
+ parent::__construct();
+ $this->_dsn=$dsn;
+ $this->_username=$username;
+ $this->_password=$password;
+ $this->_charset=$charset;
+ }
+
+ /**
+ * Close the connection when serializing.
+ */
+ public function __sleep()
+ {
+ $this->close();
+ return array_keys(get_object_vars($this));
+ }
+
+ /**
+ * @return array list of available PDO drivers
+ * @see http://www.php.net/manual/en/function.PDO-getAvailableDrivers.php
+ */
+ public static function getAvailableDrivers()
+ {
+ return PDO::getAvailableDrivers();
+ }
+
+ /**
+ * @return boolean whether the DB connection is established
+ */
+ public function getActive()
+ {
+ return $this->_active;
+ }
+
+ /**
+ * Open or close the DB connection.
+ * @param boolean whether to open or close DB connection
+ * @throws TDbException if connection fails
+ */
+ public function setActive($value)
+ {
+ $value=TPropertyValue::ensureBoolean($value);
+ if($value!==$this->_active)
+ {
+ if($value)
+ $this->open();
+ else
+ $this->close();
+ }
+ }
+
+ /**
+ * Opens DB connection if it is currently not
+ * @throws TDbException if connection fails
+ */
+ protected function open()
+ {
+ if($this->_pdo===null)
+ {
+ try
+ {
+ $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);
- $this->_active=true;
- $this->setConnectionCharset();
- }
- catch(PDOException $e)
- {
- throw new TDbException('dbconnection_open_failed',$e->getMessage());
- }
- }
- }
-
- /**
- * Closes the currently active DB connection.
- * It does nothing if the connection is already closed.
- */
- protected function close()
- {
- $this->_pdo=null;
- $this->_active=false;
- }
-
- /*
- * Set the database connection charset.
- * Only MySql databases are supported for now.
- * @since 3.1.2
- */
- protected function setConnectionCharset()
- {
- if ($this->_charset === '' || $this->_active === false)
- return;
- switch ($this->_pdo->getAttribute(PDO::ATTR_DRIVER_NAME))
- {
- case 'mysql':
- $stmt = $this->_pdo->prepare('SET NAMES ?');
- break;
- case 'pgsql':
- $stmt = $this->_pdo->prepare('SET client_encoding TO ?');
- break;
- }
- $stmt->execute(array($this->_charset));
- }
-
- /**
- * @return string The Data Source Name, or DSN, contains the information required to connect to the database.
- */
- public function getConnectionString()
- {
- return $this->_dsn;
- }
-
- /**
- * @param string The Data Source Name, or DSN, contains the information required to connect to the database.
- * @see http://www.php.net/manual/en/function.PDO-construct.php
- */
- public function setConnectionString($value)
- {
- $this->_dsn=$value;
- }
-
- /**
- * @return string the username for establishing DB connection. Defaults to empty string.
- */
- public function getUsername()
- {
- return $this->_username;
- }
-
- /**
- * @param string the username for establishing DB connection
- */
- public function setUsername($value)
- {
- $this->_username=$value;
- }
-
- /**
- * @return string the password for establishing DB connection. Defaults to empty string.
- */
- public function getPassword()
- {
- return $this->_password;
- }
-
- /**
- * @param string the password for establishing DB connection
- */
- public function setPassword($value)
- {
- $this->_password=$value;
- }
-
- /**
- * @return string the charset used for database connection. Defaults to emtpy string.
- */
- public function getCharset ()
- {
- return $this->_charset;
- }
-
- /**
- * @param string the charset used for database connection
- */
- public function setCharset ($value)
- {
- $this->_charset=$value;
- $this->setConnectionCharset();
- }
-
- /**
- * @return PDO the PDO instance, null if the connection is not established yet
- */
- public function getPdoInstance()
- {
- return $this->_pdo;
- }
-
- /**
- * Creates a command for execution.
- * @param string SQL statement associated with the new command.
- * @return TDbCommand the DB command
- * @throws TDbException if the connection is not active
- */
- public function createCommand($sql)
- {
- if($this->getActive())
- return new TDbCommand($this,$sql);
- else
- throw new TDbException('dbconnection_connection_inactive');
- }
-
- /**
- * @return TDbTransaction the currently active transaction. Null if no active transaction.
- */
- public function getCurrentTransaction()
- {
- if($this->_transaction!==null)
- {
- if($this->_transaction->getActive())
- return $this->_transaction;
- }
- return null;
- }
-
- /**
- * Starts a transaction.
- * @return TDbTransaction the transaction initiated
- * @throws TDbException if the connection is not active
- */
- public function beginTransaction()
- {
- if($this->getActive())
- {
- $this->_pdo->beginTransaction();
- 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)
- * @return string the row ID of the last row inserted, or the last value retrieved from the sequence object
- * @see http://www.php.net/manual/en/function.PDO-lastInsertId.php
- */
- public function getLastInsertID($sequenceName='')
- {
- if($this->getActive())
- return $this->_pdo->lastInsertId($sequenceName);
- else
- throw new TDbException('dbconnection_connection_inactive');
- }
-
- /**
- * Quotes a string for use in a query.
- * @param string string to be quoted
- * @return string the properly quoted string
- * @see http://www.php.net/manual/en/function.PDO-quote.php
- */
- public function quoteString($str)
- {
- if($this->getActive())
- return $this->_pdo->quote($str);
- else
- throw new TDbException('dbconnection_connection_inactive');
- }
-
- /**
- * @return TDbColumnCaseMode the case of the column names
- */
- public function getColumnCase()
- {
- switch($this->getAttribute(PDO::ATTR_CASE))
- {
- case PDO::CASE_NATURAL:
- return TDbColumnCaseMode::Preserved;
- case PDO::CASE_LOWER:
- return TDbColumnCaseMode::LowerCase;
- case PDO::CASE_UPPER:
- return TDbColumnCaseMode::UpperCase;
- }
- }
-
- /**
- * @param TDbColumnCaseMode the case of the column names
- */
- public function setColumnCase($value)
- {
- switch(TPropertyValue::ensureEnum($value,'TDbColumnCaseMode'))
- {
- case TDbColumnCaseMode::Preserved:
- $value=PDO::CASE_NATURAL;
- break;
- case TDbColumnCaseMode::LowerCase:
- $value=PDO::CASE_LOWER;
- break;
- case TDbColumnCaseMode::UpperCase:
- $value=PDO::CASE_UPPER;
- break;
- }
- $this->setAttribute(PDO::ATTR_CASE,$value);
- }
-
- /**
- * @return TDbNullConversionMode how the null and empty strings are converted
- */
- public function getNullConversion()
- {
- switch($this->getAttribute(PDO::ATTR_ORACLE_NULLS))
- {
- case PDO::NULL_NATURAL:
- return TDbNullConversionMode::Preserved;
- case PDO::NULL_EMPTY_STRING:
- return TDbNullConversionMode::EmptyStringToNull;
- case PDO::NULL_TO_STRING:
- return TDbNullConversionMode::NullToEmptyString;
- }
- }
-
- /**
- * @param TDbNullConversionMode how the null and empty strings are converted
- */
- public function setNullConversion($value)
- {
- switch(TPropertyValue::ensureEnum($value,'TDbNullConversionMode'))
- {
- case TDbNullConversionMode::Preserved:
- $value=PDO::NULL_NATURAL;
- break;
- case TDbNullConversionMode::EmptyStringToNull:
- $value=PDO::NULL_EMPTY_STRING;
- break;
- case TDbNullConversionMode::NullToEmptyString:
- $value=PDO::NULL_TO_STRING;
- break;
- }
- $this->setAttribute(PDO::ATTR_ORACLE_NULLS,$value);
- }
-
- /**
- * @return boolean whether creating or updating a DB record will be automatically committed.
- * Some DBMS (such as sqlite) may not support this feature.
- */
- public function getAutoCommit()
- {
- return $this->getAttribute(PDO::ATTR_AUTOCOMMIT);
- }
-
- /**
- * @param boolean whether creating or updating a DB record will be automatically committed.
- * Some DBMS (such as sqlite) may not support this feature.
- */
- public function setAutoCommit($value)
- {
- $this->setAttribute(PDO::ATTR_AUTOCOMMIT,TPropertyValue::ensureBoolean($value));
- }
-
- /**
- * @return boolean whether the connection is persistent or not
- * Some DBMS (such as sqlite) may not support this feature.
- */
- public function getPersistent()
- {
- return $this->getAttribute(PDO::ATTR_PERSISTENT);
- }
-
- /**
- * @param boolean whether the connection is persistent or not
- * Some DBMS (such as sqlite) may not support this feature.
- */
- public function setPersistent($value)
- {
- return $this->setAttribute(PDO::ATTR_PERSISTENT,TPropertyValue::ensureBoolean($value));
- }
-
- /**
- * @return string name of the DB driver
- */
- public function getDriverName()
- {
- return $this->getAttribute(PDO::ATTR_DRIVER_NAME);
- }
-
- /**
- * @return string the version information of the DB driver
- */
- public function getClientVersion()
- {
- return $this->getAttribute(PDO::ATTR_CLIENT_VERSION);
- }
-
- /**
- * @return string the status of the connection
- * Some DBMS (such as sqlite) may not support this feature.
- */
- public function getConnectionStatus()
- {
- return $this->getAttribute(PDO::ATTR_CONNECTION_STATUS);
- }
-
- /**
- * @return boolean whether the connection performs data prefetching
- */
- public function getPrefetch()
- {
- return $this->getAttribute(PDO::ATTR_PREFETCH);
- }
-
- /**
- * @return string the information of DBMS server
- */
- public function getServerInfo()
- {
- return $this->getAttribute(PDO::ATTR_SERVER_INFO);
- }
-
- /**
- * @return string the version information of DBMS server
- */
- public function getServerVersion()
- {
- return $this->getAttribute(PDO::ATTR_SERVER_VERSION);
- }
-
- /**
- * @return int timeout settings for the connection
- */
- public function getTimeout()
- {
- return $this->getAttribute(PDO::ATTR_TIMEOUT);
- }
-
- /**
- * Obtains a specific DB connection attribute information.
- * @param int the attribute to be queried
- * @return mixed the corresponding attribute information
- * @see http://www.php.net/manual/en/function.PDO-getAttribute.php
- */
- public function getAttribute($name)
- {
- if($this->getActive())
- return $this->_pdo->getAttribute($name);
- else
- throw new TDbException('dbconnection_connection_inactive');
- }
-
- /**
- * Sets an attribute on the database connection.
- * @param int the attribute to be set
- * @param mixed the attribute value
- * @see http://www.php.net/manual/en/function.PDO-setAttribute.php
- */
- public function setAttribute($name,$value)
- {
- if($this->_pdo instanceof PDO)
- $this->_pdo->setAttribute($name,$value);
- else
- $this->_attributes[$name]=$value;
- }
-}
-
-/**
- * TDbColumnCaseMode
- *
- * @author Qiang Xue <qiang.xue@gmail.com>
- * @version $Id$
- * @package System.Data
- * @since 3.0
- */
-class TDbColumnCaseMode extends TEnumerable
-{
- /**
- * Column name cases are kept as is from the database
- */
- const Preserved='Preserved';
- /**
- * Column names are converted to lower case
- */
- const LowerCase='LowerCase';
- /**
- * Column names are converted to upper case
- */
- const UpperCase='UpperCase';
-}
-
-/**
- * TDbNullConversionMode
- *
- * @author Qiang Xue <qiang.xue@gmail.com>
- * @version $Id$
- * @package System.Data
- * @since 3.0
- */
-class TDbNullConversionMode extends TEnumerable
-{
- /**
- * No conversion is performed for null and empty values.
- */
- const Preserved='Preserved';
- /**
- * NULL is converted to empty string
- */
- const NullToEmptyString='NullToEmptyString';
- /**
- * Empty string is converted to NULL
- */
- const EmptyStringToNull='EmptyStringToNull';
-}
-
-?>
+ @$this->_pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
+ $this->_pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+ $this->_active=true;
+ $this->setConnectionCharset();
+ }
+ catch(PDOException $e)
+ {
+ throw new TDbException('dbconnection_open_failed',$e->getMessage());
+ }
+ }
+ }
+
+ /**
+ * Closes the currently active DB connection.
+ * It does nothing if the connection is already closed.
+ */
+ protected function close()
+ {
+ $this->_pdo=null;
+ $this->_active=false;
+ }
+
+ /*
+ * Set the database connection charset.
+ * Only MySql databases are supported for now.
+ * @since 3.1.2
+ */
+ protected function setConnectionCharset()
+ {
+ if ($this->_charset === '' || $this->_active === false)
+ return;
+ switch ($this->_pdo->getAttribute(PDO::ATTR_DRIVER_NAME))
+ {
+ case 'mysql':
+ $stmt = $this->_pdo->prepare('SET NAMES ?');
+ break;
+ case 'pgsql':
+ $stmt = $this->_pdo->prepare('SET client_encoding TO ?');
+ break;
+ case 'sqlite':
+ $stmt = $pdo->prepare ('SET NAMES ?');
+ break;
+ default:
+ throw new TDbException('dbconnection_unsupported_driver_charset', $driver);
+ }
+ $stmt->execute(array($this->_charset));
+ }
+
+ /**
+ * @return string The Data Source Name, or DSN, contains the information required to connect to the database.
+ */
+ public function getConnectionString()
+ {
+ return $this->_dsn;
+ }
+
+ /**
+ * @param string The Data Source Name, or DSN, contains the information required to connect to the database.
+ * @see http://www.php.net/manual/en/function.PDO-construct.php
+ */
+ public function setConnectionString($value)
+ {
+ $this->_dsn=$value;
+ }
+
+ /**
+ * @return string the username for establishing DB connection. Defaults to empty string.
+ */
+ public function getUsername()
+ {
+ return $this->_username;
+ }
+
+ /**
+ * @param string the username for establishing DB connection
+ */
+ public function setUsername($value)
+ {
+ $this->_username=$value;
+ }
+
+ /**
+ * @return string the password for establishing DB connection. Defaults to empty string.
+ */
+ public function getPassword()
+ {
+ return $this->_password;
+ }
+
+ /**
+ * @param string the password for establishing DB connection
+ */
+ public function setPassword($value)
+ {
+ $this->_password=$value;
+ }
+
+ /**
+ * @return string the charset used for database connection. Defaults to emtpy string.
+ */
+ public function getCharset ()
+ {
+ return $this->_charset;
+ }
+
+ /**
+ * @param string the charset used for database connection
+ */
+ public function setCharset ($value)
+ {
+ $this->_charset=$value;
+ $this->setConnectionCharset();
+ }
+
+ /**
+ * @return PDO the PDO instance, null if the connection is not established yet
+ */
+ public function getPdoInstance()
+ {
+ return $this->_pdo;
+ }
+
+ /**
+ * Creates a command for execution.
+ * @param string SQL statement associated with the new command.
+ * @return TDbCommand the DB command
+ * @throws TDbException if the connection is not active
+ */
+ public function createCommand($sql)
+ {
+ if($this->getActive())
+ return new TDbCommand($this,$sql);
+ else
+ throw new TDbException('dbconnection_connection_inactive');
+ }
+
+ /**
+ * @return TDbTransaction the currently active transaction. Null if no active transaction.
+ */
+ public function getCurrentTransaction()
+ {
+ if($this->_transaction!==null)
+ {
+ if($this->_transaction->getActive())
+ return $this->_transaction;
+ }
+ return null;
+ }
+
+ /**
+ * Starts a transaction.
+ * @return TDbTransaction the transaction initiated
+ * @throws TDbException if the connection is not active
+ */
+ public function beginTransaction()
+ {
+ if($this->getActive())
+ {
+ $this->_pdo->beginTransaction();
+ 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)
+ * @return string the row ID of the last row inserted, or the last value retrieved from the sequence object
+ * @see http://www.php.net/manual/en/function.PDO-lastInsertId.php
+ */
+ public function getLastInsertID($sequenceName='')
+ {
+ if($this->getActive())
+ return $this->_pdo->lastInsertId($sequenceName);
+ else
+ throw new TDbException('dbconnection_connection_inactive');
+ }
+
+ /**
+ * Quotes a string for use in a query.
+ * @param string string to be quoted
+ * @return string the properly quoted string
+ * @see http://www.php.net/manual/en/function.PDO-quote.php
+ */
+ public function quoteString($str)
+ {
+ if($this->getActive())
+ return $this->_pdo->quote($str);
+ else
+ throw new TDbException('dbconnection_connection_inactive');
+ }
+
+ /**
+ * @return TDbColumnCaseMode the case of the column names
+ */
+ public function getColumnCase()
+ {
+ switch($this->getAttribute(PDO::ATTR_CASE))
+ {
+ case PDO::CASE_NATURAL:
+ return TDbColumnCaseMode::Preserved;
+ case PDO::CASE_LOWER:
+ return TDbColumnCaseMode::LowerCase;
+ case PDO::CASE_UPPER:
+ return TDbColumnCaseMode::UpperCase;
+ }
+ }
+
+ /**
+ * @param TDbColumnCaseMode the case of the column names
+ */
+ public function setColumnCase($value)
+ {
+ switch(TPropertyValue::ensureEnum($value,'TDbColumnCaseMode'))
+ {
+ case TDbColumnCaseMode::Preserved:
+ $value=PDO::CASE_NATURAL;
+ break;
+ case TDbColumnCaseMode::LowerCase:
+ $value=PDO::CASE_LOWER;
+ break;
+ case TDbColumnCaseMode::UpperCase:
+ $value=PDO::CASE_UPPER;
+ break;
+ }
+ $this->setAttribute(PDO::ATTR_CASE,$value);
+ }
+
+ /**
+ * @return TDbNullConversionMode how the null and empty strings are converted
+ */
+ public function getNullConversion()
+ {
+ switch($this->getAttribute(PDO::ATTR_ORACLE_NULLS))
+ {
+ case PDO::NULL_NATURAL:
+ return TDbNullConversionMode::Preserved;
+ case PDO::NULL_EMPTY_STRING:
+ return TDbNullConversionMode::EmptyStringToNull;
+ case PDO::NULL_TO_STRING:
+ return TDbNullConversionMode::NullToEmptyString;
+ }
+ }
+
+ /**
+ * @param TDbNullConversionMode how the null and empty strings are converted
+ */
+ public function setNullConversion($value)
+ {
+ switch(TPropertyValue::ensureEnum($value,'TDbNullConversionMode'))
+ {
+ case TDbNullConversionMode::Preserved:
+ $value=PDO::NULL_NATURAL;
+ break;
+ case TDbNullConversionMode::EmptyStringToNull:
+ $value=PDO::NULL_EMPTY_STRING;
+ break;
+ case TDbNullConversionMode::NullToEmptyString:
+ $value=PDO::NULL_TO_STRING;
+ break;
+ }
+ $this->setAttribute(PDO::ATTR_ORACLE_NULLS,$value);
+ }
+
+ /**
+ * @return boolean whether creating or updating a DB record will be automatically committed.
+ * Some DBMS (such as sqlite) may not support this feature.
+ */
+ public function getAutoCommit()
+ {
+ return $this->getAttribute(PDO::ATTR_AUTOCOMMIT);
+ }
+
+ /**
+ * @param boolean whether creating or updating a DB record will be automatically committed.
+ * Some DBMS (such as sqlite) may not support this feature.
+ */
+ public function setAutoCommit($value)
+ {
+ $this->setAttribute(PDO::ATTR_AUTOCOMMIT,TPropertyValue::ensureBoolean($value));
+ }
+
+ /**
+ * @return boolean whether the connection is persistent or not
+ * Some DBMS (such as sqlite) may not support this feature.
+ */
+ public function getPersistent()
+ {
+ return $this->getAttribute(PDO::ATTR_PERSISTENT);
+ }
+
+ /**
+ * @param boolean whether the connection is persistent or not
+ * Some DBMS (such as sqlite) may not support this feature.
+ */
+ public function setPersistent($value)
+ {
+ return $this->setAttribute(PDO::ATTR_PERSISTENT,TPropertyValue::ensureBoolean($value));
+ }
+
+ /**
+ * @return string name of the DB driver
+ */
+ public function getDriverName()
+ {
+ return $this->getAttribute(PDO::ATTR_DRIVER_NAME);
+ }
+
+ /**
+ * @return string the version information of the DB driver
+ */
+ public function getClientVersion()
+ {
+ return $this->getAttribute(PDO::ATTR_CLIENT_VERSION);
+ }
+
+ /**
+ * @return string the status of the connection
+ * Some DBMS (such as sqlite) may not support this feature.
+ */
+ public function getConnectionStatus()
+ {
+ return $this->getAttribute(PDO::ATTR_CONNECTION_STATUS);
+ }
+
+ /**
+ * @return boolean whether the connection performs data prefetching
+ */
+ public function getPrefetch()
+ {
+ return $this->getAttribute(PDO::ATTR_PREFETCH);
+ }
+
+ /**
+ * @return string the information of DBMS server
+ */
+ public function getServerInfo()
+ {
+ return $this->getAttribute(PDO::ATTR_SERVER_INFO);
+ }
+
+ /**
+ * @return string the version information of DBMS server
+ */
+ public function getServerVersion()
+ {
+ return $this->getAttribute(PDO::ATTR_SERVER_VERSION);
+ }
+
+ /**
+ * @return int timeout settings for the connection
+ */
+ public function getTimeout()
+ {
+ return $this->getAttribute(PDO::ATTR_TIMEOUT);
+ }
+
+ /**
+ * Obtains a specific DB connection attribute information.
+ * @param int the attribute to be queried
+ * @return mixed the corresponding attribute information
+ * @see http://www.php.net/manual/en/function.PDO-getAttribute.php
+ */
+ public function getAttribute($name)
+ {
+ if($this->getActive())
+ return $this->_pdo->getAttribute($name);
+ else
+ throw new TDbException('dbconnection_connection_inactive');
+ }
+
+ /**
+ * Sets an attribute on the database connection.
+ * @param int the attribute to be set
+ * @param mixed the attribute value
+ * @see http://www.php.net/manual/en/function.PDO-setAttribute.php
+ */
+ public function setAttribute($name,$value)
+ {
+ if($this->_pdo instanceof PDO)
+ $this->_pdo->setAttribute($name,$value);
+ else
+ $this->_attributes[$name]=$value;
+ }
+}
+
+/**
+ * TDbColumnCaseMode
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Id$
+ * @package System.Data
+ * @since 3.0
+ */
+class TDbColumnCaseMode extends TEnumerable
+{
+ /**
+ * Column name cases are kept as is from the database
+ */
+ const Preserved='Preserved';
+ /**
+ * Column names are converted to lower case
+ */
+ const LowerCase='LowerCase';
+ /**
+ * Column names are converted to upper case
+ */
+ const UpperCase='UpperCase';
+}
+
+/**
+ * TDbNullConversionMode
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Id$
+ * @package System.Data
+ * @since 3.0
+ */
+class TDbNullConversionMode extends TEnumerable
+{
+ /**
+ * No conversion is performed for null and empty values.
+ */
+ const Preserved='Preserved';
+ /**
+ * NULL is converted to empty string
+ */
+ const NullToEmptyString='NullToEmptyString';
+ /**
+ * Empty string is converted to NULL
+ */
+ const EmptyStringToNull='EmptyStringToNull';
+}
+
+?>
diff --git a/framework/Data/TDbDataReader.php b/framework/Data/TDbDataReader.php
index 7b54414e..4a323024 100644
--- a/framework/Data/TDbDataReader.php
+++ b/framework/Data/TDbDataReader.php
@@ -4,7 +4,7 @@
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.pradosoft.com/
- * @copyright Copyright &copy; 2005-2008 PradoSoft
+ * @copyright Copyright &copy; 2005-2010 PradoSoft
* @license http://www.pradosoft.com/license/
* @version $Id$
* @package System.Data
@@ -47,6 +47,7 @@ class TDbDataReader extends TComponent implements Iterator
*/
public function __construct(TDbCommand $command)
{
+ parent::__construct();
$this->_statement=$command->getPdoStatement();
$this->_statement->setFetchMode(PDO::FETCH_ASSOC);
}
diff --git a/framework/Data/TDbTransaction.php b/framework/Data/TDbTransaction.php
index 60b14a55..7c646833 100644
--- a/framework/Data/TDbTransaction.php
+++ b/framework/Data/TDbTransaction.php
@@ -4,7 +4,7 @@
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.pradosoft.com/
- * @copyright Copyright &copy; 2005-2008 PradoSoft
+ * @copyright Copyright &copy; 2005-2010 PradoSoft
* @license http://www.pradosoft.com/license/
* @version $Id$
* @package System.Data
@@ -51,6 +51,7 @@ class TDbTransaction extends TComponent
*/
public function __construct(TDbConnection $connection)
{
+ parent::__construct();
$this->_connection=$connection;
$this->setActive(true);
}
diff --git a/framework/Exceptions/TErrorHandler.php b/framework/Exceptions/TErrorHandler.php
index 4ac312d0..f4db5050 100644
--- a/framework/Exceptions/TErrorHandler.php
+++ b/framework/Exceptions/TErrorHandler.php
@@ -1,404 +1,404 @@
-<?php
-/**
- * TErrorHandler class file
- *
- * @author Qiang Xue <qiang.xue@gmail.com>
- * @link http://www.pradosoft.com/
+<?php
+/**
+ * TErrorHandler class file
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.pradosoft.com/
* @copyright Copyright &copy; 2005-2008 PradoSoft
- * @license http://www.pradosoft.com/license/
- * @version $Id$
- * @package System.Exceptions
- */
-
-/**
- * TErrorHandler class
- *
- * TErrorHandler handles all PHP user errors and exceptions generated during
- * servicing user requests. It displays these errors using different templates
- * and if possible, using languages preferred by the client user.
- * Note, PHP parsing errors cannot be caught and handled by TErrorHandler.
- *
- * The templates used to format the error output are stored under System.Exceptions.
- * You may choose to use your own templates, should you not like the templates
- * provided by Prado. Simply set {@link setErrorTemplatePath ErrorTemplatePath}
- * to the path (in namespace format) storing your own templates.
- *
- * There are two sets of templates, one for errors to be displayed to client users
- * (called external errors), one for errors to be displayed to system developers
- * (called internal errors). The template file name for the former is
- * <b>error[StatusCode][-LanguageCode].html</b>, and for the latter it is
- * <b>exception[-LanguageCode].html</b>, where StatusCode refers to response status
- * code (e.g. 404, 500) specified when {@link THttpException} is thrown,
- * and LanguageCode is the client user preferred language code (e.g. en, zh, de).
- * The templates <b>error.html</b> and <b>exception.html</b> are default ones
- * that are used if no other appropriate templates are available.
- * Note, these templates are not Prado control templates. They are simply
- * html files with keywords (e.g. %%ErrorMessage%%, %%Version%%)
- * to be replaced with the corresponding information.
- *
- * By default, TErrorHandler is registered with {@link TApplication} as the
- * error handler module. It can be accessed via {@link TApplication::getErrorHandler()}.
- * You seldom need to deal with the error handler directly. It is mainly used
- * by the application object to handle errors.
- *
- * TErrorHandler may be configured in application configuration file as follows
- * <module id="error" class="TErrorHandler" ErrorTemplatePath="System.Exceptions" />
- *
- * @author Qiang Xue <qiang.xue@gmail.com>
- * @version $Id$
- * @package System.Exceptions
- * @since 3.0
- */
-class TErrorHandler extends TModule
-{
- /**
- * error template file basename
- */
- const ERROR_FILE_NAME='error';
- /**
- * exception template file basename
- */
- const EXCEPTION_FILE_NAME='exception';
- /**
- * number of lines before and after the error line to be displayed in case of an exception
- */
- const SOURCE_LINES=12;
-
- /**
- * @var string error template directory
- */
- private $_templatePath=null;
-
- /**
- * Initializes the module.
- * This method is required by IModule and is invoked by application.
- * @param TXmlElement module configuration
- */
- public function init($config)
- {
- $this->getApplication()->setErrorHandler($this);
- }
-
- /**
- * @return string the directory containing error template files.
- */
- public function getErrorTemplatePath()
+ * @license http://www.pradosoft.com/license/
+ * @version $Id$
+ * @package System.Exceptions
+ */
+
+/**
+ * TErrorHandler class
+ *
+ * TErrorHandler handles all PHP user errors and exceptions generated during
+ * servicing user requests. It displays these errors using different templates
+ * and if possible, using languages preferred by the client user.
+ * Note, PHP parsing errors cannot be caught and handled by TErrorHandler.
+ *
+ * The templates used to format the error output are stored under System.Exceptions.
+ * You may choose to use your own templates, should you not like the templates
+ * provided by Prado. Simply set {@link setErrorTemplatePath ErrorTemplatePath}
+ * to the path (in namespace format) storing your own templates.
+ *
+ * There are two sets of templates, one for errors to be displayed to client users
+ * (called external errors), one for errors to be displayed to system developers
+ * (called internal errors). The template file name for the former is
+ * <b>error[StatusCode][-LanguageCode].html</b>, and for the latter it is
+ * <b>exception[-LanguageCode].html</b>, where StatusCode refers to response status
+ * code (e.g. 404, 500) specified when {@link THttpException} is thrown,
+ * and LanguageCode is the client user preferred language code (e.g. en, zh, de).
+ * The templates <b>error.html</b> and <b>exception.html</b> are default ones
+ * that are used if no other appropriate templates are available.
+ * Note, these templates are not Prado control templates. They are simply
+ * html files with keywords (e.g. %%ErrorMessage%%, %%Version%%)
+ * to be replaced with the corresponding information.
+ *
+ * By default, TErrorHandler is registered with {@link TApplication} as the
+ * error handler module. It can be accessed via {@link TApplication::getErrorHandler()}.
+ * You seldom need to deal with the error handler directly. It is mainly used
+ * by the application object to handle errors.
+ *
+ * TErrorHandler may be configured in application configuration file as follows
+ * <module id="error" class="TErrorHandler" ErrorTemplatePath="System.Exceptions" />
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Id$
+ * @package System.Exceptions
+ * @since 3.0
+ */
+class TErrorHandler extends TModule
+{
+ /**
+ * error template file basename
+ */
+ const ERROR_FILE_NAME='error';
+ /**
+ * exception template file basename
+ */
+ const EXCEPTION_FILE_NAME='exception';
+ /**
+ * number of lines before and after the error line to be displayed in case of an exception
+ */
+ const SOURCE_LINES=12;
+
+ /**
+ * @var string error template directory
+ */
+ private $_templatePath=null;
+
+ /**
+ * Initializes the module.
+ * This method is required by IModule and is invoked by application.
+ * @param TXmlElement module configuration
+ */
+ public function init($config)
+ {
+ $this->getApplication()->setErrorHandler($this);
+ }
+
+ /**
+ * @return string the directory containing error template files.
+ */
+ public function getErrorTemplatePath()
{
if($this->_templatePath===null)
- $this->_templatePath=Prado::getFrameworkPath().'/Exceptions/templates';
- return $this->_templatePath;
- }
-
- /**
- * Sets the path storing all error and exception template files.
- * The path must be in namespace format, such as System.Exceptions (which is the default).
- * @param string template path in namespace format
- * @throws TConfigurationException if the template path is invalid
- */
- public function setErrorTemplatePath($value)
- {
- if(($templatePath=Prado::getPathOfNamespace($value))!==null && is_dir($templatePath))
- $this->_templatePath=$templatePath;
- else
- throw new TConfigurationException('errorhandler_errortemplatepath_invalid',$value);
- }
-
- /**
- * Handles PHP user errors and exceptions.
- * This is the event handler responding to the <b>Error</b> event
- * raised in {@link TApplication}.
- * The method mainly uses appropriate template to display the error/exception.
- * It terminates the application immediately after the error is displayed.
- * @param mixed sender of the event
- * @param mixed event parameter (if the event is raised by TApplication, it refers to the exception instance)
- */
- public function handleError($sender,$param)
- {
- static $handling=false;
- // We need to restore error and exception handlers,
- // because within error and exception handlers, new errors and exceptions
- // cannot be handled properly by PHP
- restore_error_handler();
- restore_exception_handler();
- // ensure that we do not enter infinite loop of error handling
- if($handling)
- $this->handleRecursiveError($param);
- else
- {
- $handling=true;
- if(($response=$this->getResponse())!==null)
- $response->clear();
- if(!headers_sent())
- header('Content-Type: text/html; charset=UTF-8');
- if($param instanceof THttpException)
- $this->handleExternalError($param->getStatusCode(),$param);
- else if($this->getApplication()->getMode()===TApplicationMode::Debug)
- $this->displayException($param);
- else
- $this->handleExternalError(500,$param);
- }
- }
-
-
- /**
- * @param string $value
- * @param Exception|null$exception
- * @return string
- * @since 3.1.6
- */
- protected static function hideSecurityRelated($value, $exception=null)
- {
- $aRpl = array();
- if($exception !== null && $exception instanceof Exception)
- {
- $aTrace = $exception->getTrace();
- foreach($aTrace as $item)
- {
- $file = $item['file'];
- $aRpl[dirname($file) . DIRECTORY_SEPARATOR] = '<hidden>' . DIRECTORY_SEPARATOR;
- }
- }
- $aRpl[$_SERVER['DOCUMENT_ROOT']] = '${DocumentRoot}';
- $aRpl[str_replace('/', DIRECTORY_SEPARATOR, $_SERVER['DOCUMENT_ROOT'])] = '${DocumentRoot}';
- $aRpl[PRADO_DIR . DIRECTORY_SEPARATOR] = '${PradoFramework}' . DIRECTORY_SEPARATOR;
- if(isset($aRpl[DIRECTORY_SEPARATOR])) unset($aRpl[DIRECTORY_SEPARATOR]);
- $aRpl = array_reverse($aRpl, true);
-
- return str_replace(array_keys($aRpl), $aRpl, $value);
- }
-
- /**
- * Displays error to the client user.
- * THttpException and errors happened when the application is in <b>Debug</b>
- * mode will be displayed to the client user.
- * @param integer response status code
- * @param Exception exception instance
- */
- protected function handleExternalError($statusCode,$exception)
- {
- if(!($exception instanceof THttpException))
- error_log($exception->__toString());
-
- $content=$this->getErrorTemplate($statusCode,$exception);
-
- $serverAdmin=isset($_SERVER['SERVER_ADMIN'])?$_SERVER['SERVER_ADMIN']:'';
-
- $isDebug = $this->getApplication()->getMode()===TApplicationMode::Debug;
-
- $errorMessage = $exception->getMessage();
- if($isDebug)
- $version=$_SERVER['SERVER_SOFTWARE'].' <a href="http://www.pradosoft.com/">PRADO</a>/'.Prado::getVersion();
- else
- {
- $version='';
- $errorMessage = self::hideSecurityRelated($errorMessage, $exception);
- }
- $tokens=array(
- '%%StatusCode%%' => "$statusCode",
- '%%ErrorMessage%%' => htmlspecialchars($errorMessage),
- '%%ServerAdmin%%' => $serverAdmin,
- '%%Version%%' => $version,
- '%%Time%%' => @strftime('%Y-%m-%d %H:%M',time())
- );
-
- if($isDebug)
- header("HTTP/1.0 $statusCode ".$exception->getMessage(), true, $statusCode);
- else
- header("HTTP/1.0 $statusCode", true, $statusCode);
-
- echo strtr($content,$tokens);
- }
-
- /**
- * Handles error occurs during error handling (called recursive error).
- * THttpException and errors happened when the application is in <b>Debug</b>
- * mode will be displayed to the client user.
- * Error is displayed without using existing template to prevent further errors.
- * @param Exception exception instance
- */
- protected function handleRecursiveError($exception)
- {
- if($this->getApplication()->getMode()===TApplicationMode::Debug)
- {
- echo "<html><head><title>Recursive Error</title></head>\n";
- echo "<body><h1>Recursive Error</h1>\n";
- echo "<pre>".$exception->__toString()."</pre>\n";
- echo "</body></html>";
- }
- else
- {
- error_log("Error happened while processing an existing error:\n".$exception->__toString());
- header('HTTP/1.0 500 Internal Error');
- }
- }
-
- /**
- * Displays exception information.
- * Exceptions are displayed with rich context information, including
- * the call stack and the context source code.
- * This method is only invoked when application is in <b>Debug</b> mode.
- * @param Exception exception instance
- */
- protected function displayException($exception)
- {
- if(php_sapi_name()==='cli')
- {
- echo $exception->getMessage()."\n";
- echo $exception->getTraceAsString();
- return;
- }
-
- if($exception instanceof TTemplateException)
- {
- $fileName=$exception->getTemplateFile();
- $lines=empty($fileName)?explode("\n",$exception->getTemplateSource()):@file($fileName);
- $source=$this->getSourceCode($lines,$exception->getLineNumber());
- if($fileName==='')
- $fileName='---embedded template---';
- $errorLine=$exception->getLineNumber();
- }
- else
- {
- if(($trace=$this->getExactTrace($exception))!==null)
- {
- $fileName=$trace['file'];
- $errorLine=$trace['line'];
- }
- else
- {
- $fileName=$exception->getFile();
- $errorLine=$exception->getLine();
- }
- $source=$this->getSourceCode(@file($fileName),$errorLine);
- }
-
- if($this->getApplication()->getMode()===TApplicationMode::Debug)
- $version=$_SERVER['SERVER_SOFTWARE'].' <a href="http://www.pradosoft.com/">PRADO</a>/'.Prado::getVersion();
- else
- $version='';
-
- $tokens=array(
- '%%ErrorType%%' => get_class($exception),
- '%%ErrorMessage%%' => $this->addLink(htmlspecialchars($exception->getMessage())),
- '%%SourceFile%%' => htmlspecialchars($fileName).' ('.$errorLine.')',
- '%%SourceCode%%' => $source,
- '%%StackTrace%%' => htmlspecialchars($exception->getTraceAsString()),
- '%%Version%%' => $version,
- '%%Time%%' => @strftime('%Y-%m-%d %H:%M',time())
- );
-
- $content=$this->getExceptionTemplate($exception);
-
- echo strtr($content,$tokens);
- }
-
- /**
- * Retrieves the template used for displaying internal exceptions.
- * Internal exceptions will be displayed with source code causing the exception.
- * This occurs when the application is in debug mode.
- * @param Exception the exception to be displayed
- * @return string the template content
- */
- protected function getExceptionTemplate($exception)
- {
- $lang=Prado::getPreferredLanguage();
- $exceptionFile=Prado::getFrameworkPath().'/Exceptions/templates/'.self::EXCEPTION_FILE_NAME.'-'.$lang.'.html';
- if(!is_file($exceptionFile))
- $exceptionFile=Prado::getFrameworkPath().'/Exceptions/templates/'.self::EXCEPTION_FILE_NAME.'.html';
- if(($content=@file_get_contents($exceptionFile))===false)
- die("Unable to open exception template file '$exceptionFile'.");
- return $content;
- }
-
- /**
- * Retrieves the template used for displaying external exceptions.
- * External exceptions are those displayed to end-users. They do not contain
- * error source code. Therefore, you might want to override this method
- * to provide your own error template for displaying certain external exceptions.
- * The following tokens in the template will be replaced with corresponding content:
- * %%StatusCode%% : the status code of the exception
- * %%ErrorMessage%% : the error message (HTML encoded).
- * %%ServerAdmin%% : the server admin information (retrieved from Web server configuration)
- * %%Version%% : the version information of the Web server.
- * %%Time%% : the time the exception occurs at
- *
- * @param integer status code (such as 404, 500, etc.)
- * @param Exception the exception to be displayed
- * @return string the template content
- */
- protected function getErrorTemplate($statusCode,$exception)
- {
- $base=$this->getErrorTemplatePath().DIRECTORY_SEPARATOR.self::ERROR_FILE_NAME;
- $lang=Prado::getPreferredLanguage();
- if(is_file("$base$statusCode-$lang.html"))
- $errorFile="$base$statusCode-$lang.html";
- else if(is_file("$base$statusCode.html"))
- $errorFile="$base$statusCode.html";
- else if(is_file("$base-$lang.html"))
- $errorFile="$base-$lang.html";
- else
- $errorFile="$base.html";
- if(($content=@file_get_contents($errorFile))===false)
- die("Unable to open error template file '$errorFile'.");
- return $content;
- }
-
- private function getExactTrace($exception)
- {
- $trace=$exception->getTrace();
- $result=null;
- // if PHP exception, we want to show the 2nd stack level context
- // because the 1st stack level is of little use (it's in error handler)
- if($exception instanceof TPhpErrorException)
- $result=isset($trace[0]['file'])?$trace[0]:$trace[1];
- else if($exception instanceof TInvalidOperationException)
- {
- // in case of getter or setter error, find out the exact file and row
- if(($result=$this->getPropertyAccessTrace($trace,'__get'))===null)
- $result=$this->getPropertyAccessTrace($trace,'__set');
- }
- if($result!==null && strpos($result['file'],': eval()\'d code')!==false)
- return null;
-
- return $result;
- }
-
- private function getPropertyAccessTrace($trace,$pattern)
- {
- $result=null;
- foreach($trace as $t)
- {
- if(isset($t['function']) && $t['function']===$pattern)
- $result=$t;
- else
- break;
- }
- return $result;
- }
-
- private function getSourceCode($lines,$errorLine)
- {
- $beginLine=$errorLine-self::SOURCE_LINES>=0?$errorLine-self::SOURCE_LINES:0;
- $endLine=$errorLine+self::SOURCE_LINES<=count($lines)?$errorLine+self::SOURCE_LINES:count($lines);
-
- $source='';
- for($i=$beginLine;$i<$endLine;++$i)
- {
- if($i===$errorLine-1)
- {
- $line=htmlspecialchars(sprintf("%04d: %s",$i+1,str_replace("\t",' ',$lines[$i])));
- $source.="<div class=\"error\">".$line."</div>";
- }
- else
- $source.=htmlspecialchars(sprintf("%04d: %s",$i+1,str_replace("\t",' ',$lines[$i])));
- }
- return $source;
- }
-
- private function addLink($message)
- {
- $baseUrl='http://www.pradosoft.com/docs/classdoc';
- return preg_replace('/\b(T[A-Z]\w+)\b/',"<a href=\"$baseUrl/\${1}\" target=\"_blank\">\${1}</a>",$message);
- }
-}
-
+ $this->_templatePath=Prado::getFrameworkPath().'/Exceptions/templates';
+ return $this->_templatePath;
+ }
+
+ /**
+ * Sets the path storing all error and exception template files.
+ * The path must be in namespace format, such as System.Exceptions (which is the default).
+ * @param string template path in namespace format
+ * @throws TConfigurationException if the template path is invalid
+ */
+ public function setErrorTemplatePath($value)
+ {
+ if(($templatePath=Prado::getPathOfNamespace($value))!==null && is_dir($templatePath))
+ $this->_templatePath=$templatePath;
+ else
+ throw new TConfigurationException('errorhandler_errortemplatepath_invalid',$value);
+ }
+
+ /**
+ * Handles PHP user errors and exceptions.
+ * This is the event handler responding to the <b>Error</b> event
+ * raised in {@link TApplication}.
+ * The method mainly uses appropriate template to display the error/exception.
+ * It terminates the application immediately after the error is displayed.
+ * @param mixed sender of the event
+ * @param mixed event parameter (if the event is raised by TApplication, it refers to the exception instance)
+ */
+ public function handleError($sender,$param)
+ {
+ static $handling=false;
+ // We need to restore error and exception handlers,
+ // because within error and exception handlers, new errors and exceptions
+ // cannot be handled properly by PHP
+ restore_error_handler();
+ restore_exception_handler();
+ // ensure that we do not enter infinite loop of error handling
+ if($handling)
+ $this->handleRecursiveError($param);
+ else
+ {
+ $handling=true;
+ if(($response=$this->getResponse())!==null)
+ $response->clear();
+ if(!headers_sent())
+ header('Content-Type: text/html; charset=UTF-8');
+ if($param instanceof THttpException)
+ $this->handleExternalError($param->getStatusCode(),$param);
+ else if($this->getApplication()->getMode()===TApplicationMode::Debug)
+ $this->displayException($param);
+ else
+ $this->handleExternalError(500,$param);
+ }
+ }
+
+
+ /**
+ * @param string $value
+ * @param Exception|null$exception
+ * @return string
+ * @since 3.1.6
+ */
+ protected static function hideSecurityRelated($value, $exception=null)
+ {
+ $aRpl = array();
+ if($exception !== null && $exception instanceof Exception)
+ {
+ $aTrace = $exception->getTrace();
+ foreach($aTrace as $item)
+ {
+ $file = $item['file'];
+ $aRpl[dirname($file) . DIRECTORY_SEPARATOR] = '<hidden>' . DIRECTORY_SEPARATOR;
+ }
+ }
+ $aRpl[$_SERVER['DOCUMENT_ROOT']] = '${DocumentRoot}';
+ $aRpl[str_replace('/', DIRECTORY_SEPARATOR, $_SERVER['DOCUMENT_ROOT'])] = '${DocumentRoot}';
+ $aRpl[PRADO_DIR . DIRECTORY_SEPARATOR] = '${PradoFramework}' . DIRECTORY_SEPARATOR;
+ if(isset($aRpl[DIRECTORY_SEPARATOR])) unset($aRpl[DIRECTORY_SEPARATOR]);
+ $aRpl = array_reverse($aRpl, true);
+
+ return str_replace(array_keys($aRpl), $aRpl, $value);
+ }
+
+ /**
+ * Displays error to the client user.
+ * THttpException and errors happened when the application is in <b>Debug</b>
+ * mode will be displayed to the client user.
+ * @param integer response status code
+ * @param Exception exception instance
+ */
+ protected function handleExternalError($statusCode,$exception)
+ {
+ if(!($exception instanceof THttpException))
+ error_log($exception->__toString());
+
+ $content=$this->getErrorTemplate($statusCode,$exception);
+
+ $serverAdmin=isset($_SERVER['SERVER_ADMIN'])?$_SERVER['SERVER_ADMIN']:'';
+
+ $isDebug = $this->getApplication()->getMode()===TApplicationMode::Debug;
+
+ $errorMessage = $exception->getMessage();
+ if($isDebug)
+ $version=$_SERVER['SERVER_SOFTWARE'].' <a href="http://www.pradosoft.com/">PRADO</a>/'.Prado::getVersion();
+ else
+ {
+ $version='';
+ $errorMessage = self::hideSecurityRelated($errorMessage, $exception);
+ }
+ $tokens=array(
+ '%%StatusCode%%' => "$statusCode",
+ '%%ErrorMessage%%' => htmlspecialchars($errorMessage),
+ '%%ServerAdmin%%' => $serverAdmin,
+ '%%Version%%' => $version,
+ '%%Time%%' => @strftime('%Y-%m-%d %H:%M',time())
+ );
+
+ if($isDebug)
+ header("HTTP/1.0 $statusCode ".$exception->getMessage(), true, TPropertyValue::ensureInteger($statusCode));
+ else
+ header("HTTP/1.0 $statusCode", true, TPropertyValue::ensureInteger($statusCode));
+
+ echo strtr($content,$tokens);
+ }
+
+ /**
+ * Handles error occurs during error handling (called recursive error).
+ * THttpException and errors happened when the application is in <b>Debug</b>
+ * mode will be displayed to the client user.
+ * Error is displayed without using existing template to prevent further errors.
+ * @param Exception exception instance
+ */
+ protected function handleRecursiveError($exception)
+ {
+ if($this->getApplication()->getMode()===TApplicationMode::Debug)
+ {
+ echo "<html><head><title>Recursive Error</title></head>\n";
+ echo "<body><h1>Recursive Error</h1>\n";
+ echo "<pre>".$exception->__toString()."</pre>\n";
+ echo "</body></html>";
+ }
+ else
+ {
+ error_log("Error happened while processing an existing error:\n".$exception->__toString());
+ header('HTTP/1.0 500 Internal Error');
+ }
+ }
+
+ /**
+ * Displays exception information.
+ * Exceptions are displayed with rich context information, including
+ * the call stack and the context source code.
+ * This method is only invoked when application is in <b>Debug</b> mode.
+ * @param Exception exception instance
+ */
+ protected function displayException($exception)
+ {
+ if(php_sapi_name()==='cli')
+ {
+ echo $exception->getMessage()."\n";
+ echo $exception->getTraceAsString();
+ return;
+ }
+
+ if($exception instanceof TTemplateException)
+ {
+ $fileName=$exception->getTemplateFile();
+ $lines=empty($fileName)?explode("\n",$exception->getTemplateSource()):@file($fileName);
+ $source=$this->getSourceCode($lines,$exception->getLineNumber());
+ if($fileName==='')
+ $fileName='---embedded template---';
+ $errorLine=$exception->getLineNumber();
+ }
+ else
+ {
+ if(($trace=$this->getExactTrace($exception))!==null)
+ {
+ $fileName=$trace['file'];
+ $errorLine=$trace['line'];
+ }
+ else
+ {
+ $fileName=$exception->getFile();
+ $errorLine=$exception->getLine();
+ }
+ $source=$this->getSourceCode(@file($fileName),$errorLine);
+ }
+
+ if($this->getApplication()->getMode()===TApplicationMode::Debug)
+ $version=$_SERVER['SERVER_SOFTWARE'].' <a href="http://www.pradosoft.com/">PRADO</a>/'.Prado::getVersion();
+ else
+ $version='';
+
+ $tokens=array(
+ '%%ErrorType%%' => get_class($exception),
+ '%%ErrorMessage%%' => $this->addLink(htmlspecialchars($exception->getMessage())),
+ '%%SourceFile%%' => htmlspecialchars($fileName).' ('.$errorLine.')',
+ '%%SourceCode%%' => $source,
+ '%%StackTrace%%' => htmlspecialchars($exception->getTraceAsString()),
+ '%%Version%%' => $version,
+ '%%Time%%' => @strftime('%Y-%m-%d %H:%M',time())
+ );
+
+ $content=$this->getExceptionTemplate($exception);
+
+ echo strtr($content,$tokens);
+ }
+
+ /**
+ * Retrieves the template used for displaying internal exceptions.
+ * Internal exceptions will be displayed with source code causing the exception.
+ * This occurs when the application is in debug mode.
+ * @param Exception the exception to be displayed
+ * @return string the template content
+ */
+ protected function getExceptionTemplate($exception)
+ {
+ $lang=Prado::getPreferredLanguage();
+ $exceptionFile=Prado::getFrameworkPath().'/Exceptions/templates/'.self::EXCEPTION_FILE_NAME.'-'.$lang.'.html';
+ if(!is_file($exceptionFile))
+ $exceptionFile=Prado::getFrameworkPath().'/Exceptions/templates/'.self::EXCEPTION_FILE_NAME.'.html';
+ if(($content=@file_get_contents($exceptionFile))===false)
+ die("Unable to open exception template file '$exceptionFile'.");
+ return $content;
+ }
+
+ /**
+ * Retrieves the template used for displaying external exceptions.
+ * External exceptions are those displayed to end-users. They do not contain
+ * error source code. Therefore, you might want to override this method
+ * to provide your own error template for displaying certain external exceptions.
+ * The following tokens in the template will be replaced with corresponding content:
+ * %%StatusCode%% : the status code of the exception
+ * %%ErrorMessage%% : the error message (HTML encoded).
+ * %%ServerAdmin%% : the server admin information (retrieved from Web server configuration)
+ * %%Version%% : the version information of the Web server.
+ * %%Time%% : the time the exception occurs at
+ *
+ * @param integer status code (such as 404, 500, etc.)
+ * @param Exception the exception to be displayed
+ * @return string the template content
+ */
+ protected function getErrorTemplate($statusCode,$exception)
+ {
+ $base=$this->getErrorTemplatePath().DIRECTORY_SEPARATOR.self::ERROR_FILE_NAME;
+ $lang=Prado::getPreferredLanguage();
+ if(is_file("$base$statusCode-$lang.html"))
+ $errorFile="$base$statusCode-$lang.html";
+ else if(is_file("$base$statusCode.html"))
+ $errorFile="$base$statusCode.html";
+ else if(is_file("$base-$lang.html"))
+ $errorFile="$base-$lang.html";
+ else
+ $errorFile="$base.html";
+ if(($content=@file_get_contents($errorFile))===false)
+ die("Unable to open error template file '$errorFile'.");
+ return $content;
+ }
+
+ private function getExactTrace($exception)
+ {
+ $trace=$exception->getTrace();
+ $result=null;
+ // if PHP exception, we want to show the 2nd stack level context
+ // because the 1st stack level is of little use (it's in error handler)
+ if($exception instanceof TPhpErrorException)
+ $result=isset($trace[0]['file'])?$trace[0]:$trace[1];
+ else if($exception instanceof TInvalidOperationException)
+ {
+ // in case of getter or setter error, find out the exact file and row
+ if(($result=$this->getPropertyAccessTrace($trace,'__get'))===null)
+ $result=$this->getPropertyAccessTrace($trace,'__set');
+ }
+ if($result!==null && strpos($result['file'],': eval()\'d code')!==false)
+ return null;
+
+ return $result;
+ }
+
+ private function getPropertyAccessTrace($trace,$pattern)
+ {
+ $result=null;
+ foreach($trace as $t)
+ {
+ if(isset($t['function']) && $t['function']===$pattern)
+ $result=$t;
+ else
+ break;
+ }
+ return $result;
+ }
+
+ private function getSourceCode($lines,$errorLine)
+ {
+ $beginLine=$errorLine-self::SOURCE_LINES>=0?$errorLine-self::SOURCE_LINES:0;
+ $endLine=$errorLine+self::SOURCE_LINES<=count($lines)?$errorLine+self::SOURCE_LINES:count($lines);
+
+ $source='';
+ for($i=$beginLine;$i<$endLine;++$i)
+ {
+ if($i===$errorLine-1)
+ {
+ $line=htmlspecialchars(sprintf("%04d: %s",$i+1,str_replace("\t",' ',$lines[$i])));
+ $source.="<div class=\"error\">".$line."</div>";
+ }
+ else
+ $source.=htmlspecialchars(sprintf("%04d: %s",$i+1,str_replace("\t",' ',$lines[$i])));
+ }
+ return $source;
+ }
+
+ private function addLink($message)
+ {
+ $baseUrl='http://www.pradosoft.com/docs/classdoc';
+ return preg_replace('/\b(T[A-Z]\w+)\b/',"<a href=\"$baseUrl/\${1}\" target=\"_blank\">\${1}</a>",$message);
+ }
+}
+
diff --git a/framework/Exceptions/messages/messages-fr.txt b/framework/Exceptions/messages/messages-fr.txt
index 5dce3812..4e6a396b 100644
--- a/framework/Exceptions/messages/messages-fr.txt
+++ b/framework/Exceptions/messages/messages-fr.txt
@@ -366,6 +366,7 @@ tactivecustomvalidator_clientfunction_unsupported = {0} does not support client
dbconnection_open_failed = TDbConnection failed to establish DB connection: {0}
dbconnection_connection_inactive = TDbConnection is inactive.
+dbconnection_unsupported_driver_charset = Le pilote de base de données '{0}' ne supporte pas la modification du jeu de caractères.
dbcommand_prepare_failed = TDbCommand failed to prepare the SQL statement "{1}": {0}
dbcommand_execute_failed = TDbCommand failed to execute the SQL statement "{1}": {0}
@@ -409,3 +410,9 @@ feedservice_id_required = TFeedService requires 'id' attribute in its feed e
feedservice_feedtype_invalid = The class feed '{0}' must implement IFeedContentProvider interface.
feedservice_class_required = TFeedService requires 'class' attribute in its feed elements.
feedservice_feed_unknown = Unknown feed '{0}' requested.
+
+tactivetablecell_control_outoftable = {0} '{1}' must be enclosed within a TTableRow control.
+tactivetablecell_control_notincollection = {0} '{1}' no member of the TTableCellCollection of the parent TTableRow control.
+
+tactivetablerow_control_outoftable = {0} '{1}' must be enclosed within a TTable control.
+tactivetablerow_control_notincollection = {0} '{1}' no member of the TTableRowCollection of the parent TTable control. \ No newline at end of file
diff --git a/framework/Exceptions/messages/messages-id.txt b/framework/Exceptions/messages/messages-id.txt
index 61699ddd..687d4f30 100644
--- a/framework/Exceptions/messages/messages-id.txt
+++ b/framework/Exceptions/messages/messages-id.txt
@@ -367,6 +367,7 @@ tactivecustomvalidator_clientfunction_unsupported = {0} tidak mendukung fungsi v
dbconnection_open_failed = TDbConnection gagal untuk menyelesaikan koneksi DB: {0}
dbconnection_connection_inactive = TDbConnection tidak aktif.
+dbconnection_unsupported_driver_charset = Database driver '{0}' doesn't support setting charset.
dbcommand_prepare_failed = TDbCommand gagal untuk menyiapkan pernyataan SQL "{1}": {0}
dbcommand_execute_failed = TDbCommand gagal untuk menjalankan pernyataan SQL "{1}": {0}
diff --git a/framework/Exceptions/messages/messages-zh.txt b/framework/Exceptions/messages/messages-zh.txt
index 1859aa92..9dc14a8b 100644
--- a/framework/Exceptions/messages/messages-zh.txt
+++ b/framework/Exceptions/messages/messages-zh.txt
@@ -372,6 +372,7 @@ tactivecustomvalidator_clientfunction_unsupported = {0} does not support client
dbconnection_open_failed = TDbConnection failed to establish DB connection: {0}
dbconnection_connection_inactive = TDbConnection is inactive.
+dbconnection_unsupported_driver_charset = Database driver '{0}' doesn't support setting charset.
dbcommand_prepare_failed = TDbCommand failed to prepare the SQL statement "{1}": {0}
dbcommand_execute_failed = TDbCommand failed to execute the SQL statement "{1}": {0}
diff --git a/framework/Exceptions/messages/messages.txt b/framework/Exceptions/messages/messages.txt
index 0750c38d..fd85920c 100644
--- a/framework/Exceptions/messages/messages.txt
+++ b/framework/Exceptions/messages/messages.txt
@@ -24,7 +24,7 @@ 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.
-application_includefile_invalid = Unable to find application configuration {0}. Make sure it is in namespace format and the file ends with ".xml".
+application_includefile_invalid = Unable to find application configuration {0}. Make sure it is in namespace format and the file ends with ".xml" or ".php".
application_basepath_invalid = Application base path '{0}' does not exist or is not a directory.
application_runtimepath_invalid = Application runtime path '{0}' does not exist or is not writable by Web server process.
application_service_invalid = Service '{0}' must implement IService interface.
@@ -115,7 +115,7 @@ pageservice_page_required = Page Name Required
pageservice_defaultpage_unchangeable = TPageService.DefaultPage cannot be modified after the service is initialized.
pageservice_basepath_unchangeable = TPageService.BasePath cannot be modified after the service is initialized.
pageservice_pageclass_invalid = Page class {0} is invalid. It should be TPage or extend from TPage.
-pageservice_includefile_invalid = Unable to find page service configuration {0}. Make sure it is in namespace format and the file ends with ".xml".
+pageservice_includefile_invalid = Unable to find page service configuration {0}. Make sure it is in namespace format and the file ends with ".xml" or ".php".
pageserviceconf_file_invalid = Unable to open page directory configuration file '{0}'.
pageserviceconf_aliaspath_invalid = <alias id="{0}"> uses an invalid file path "{1}" in page directory configuration file '{2}'.
@@ -317,7 +317,7 @@ htmlarea_textmode_readonly = THtmlArea.TextMode is read-only.
htmlarea_tarfile_invalid = THtmlArea is unable to locate the TinyMCE tar file.
parametermodule_parameterfile_unchangeable = TParameterModule.ParameterFile is not changeable because the module is already initialized.
-parametermodule_parameterfile_invalid = TParameterModule.ParameterFile '{0}' is invalid. Make sure it is in namespace format and the file extension is '.xml'.
+parametermodule_parameterfile_invalid = TParameterModule.ParameterFile '{0}' is invalid. Make sure it is in namespace format and the file extension is '.xml' or '.php'.
parametermodule_parameterid_required = Parameter element must have 'id' attribute.
datagridcolumn_id_invalid = {0}.ID '{1}' is invalid. Only alphanumeric and underline characters are allowed. The first character must be an alphabetic or underline character.
@@ -376,6 +376,7 @@ tactivecustomvalidator_clientfunction_unsupported = {0} does not support client
dbconnection_open_failed = TDbConnection failed to establish DB connection: {0}
dbconnection_connection_inactive = TDbConnection is inactive.
+dbconnection_unsupported_driver_charset = Database driver '{0}' doesn't support setting charset.
dbcommand_prepare_failed = TDbCommand failed to prepare the SQL statement "{1}": {0}
dbcommand_execute_failed = TDbCommand failed to execute the SQL statement "{1}": {0}
@@ -403,7 +404,7 @@ dbtablegateway_invalid_table_info = Table must be a string or an instance of TD
directorycachedependency_directory_invalid = TDirectoryCacheDependency.Directory {0} does not refer to a valid directory.
cachedependencylist_cachedependency_required = Only objects implementing ICacheDependency can be added into TCacheDependencyList.
-soapservice_configfile_invalid = TSoapService.ConfigFile '{0}' does not exist. Note, it has to be specified in a namespace format and the file extension must be '.xml'.
+soapservice_configfile_invalid = TSoapService.ConfigFile '{0}' does not exist. Note, it has to be specified in a namespace format and the file extension must be '.xml' or '.php'.
soapservice_request_invalid = SOAP server '{0}' not found.
soapservice_serverid_required = <soap> element must have 'id' attribute.
soapservice_serverid_duplicated = SOAP server ID '{0}' is duplicated.
@@ -470,8 +471,18 @@ ar_save_invalid = The {0} instance cannot be saved because it is either de
ar_delete_invalid = The {0} instance cannot be deleted because it is either a new record or a record already deleted.
datasource_dbconnection_invalid = TDataSourceConfig.DbConnection '{0}' is invalid. Please make sure it points to a valid application module.
+distributeddatasource_child_required = {0} requires one '{1}' child element at minimum.
+masterslavedbconnection_connection_exists = {0}.{1} connection already exists.
+masterslavedbconnection_interface_required = {0}.{1} requires an instance implementing {2} interface.
+slavedbconnection_requires_master = {0} requires a {1}.
response_status_reason_missing = HTTP 1.1 need reason for extended status-codes
response_status_reason_badchars = For HTTP 1.1 header, the token status-reason must not contain token CR or LF
activefileupload_temppath_invalid = TActiveFileUpload TempPath path '{0}' does not exist or is not writable by Web server process.
+
+tactivetablecell_control_outoftable = {0} '{1}' must be enclosed within a TTableRow control.
+tactivetablecell_control_notincollection = {0} '{1}' no member of the TTableCellCollection of the parent TTableRow control.
+
+tactivetablerow_control_outoftable = {0} '{1}' must be enclosed within a TTable control.
+tactivetablerow_control_notincollection = {0} '{1}' no member of the TTableRowCollection of the parent TTable control. \ No newline at end of file