Commit f7678be4 authored by Benjamin Eberlei's avatar Benjamin Eberlei

Merge remote-tracking branch 'origin/2.3' into 2.3

parents 1ed30bda 6470e208
# Upgrade to 2.3
## Doctrine\DBAL\Connection and Doctrine\DBAL\Statement
The query related methods including but not limited to executeQuery, exec, query, and executeUpdate
now wrap the driver exceptions such as PDOException with DBALException to add more debugging
information such as the executed SQL statement, and any bound parameters.
If you want to retrieve the driver specific exception, you can retrieve it by calling the
``getPrevious()`` method on DBALException.
Before:
catch(\PDOException $ex) {
// ...
}
After:
catch(\Doctrine\DBAL\DBALException $ex) {
$pdoException = $ex->getPrevious();
// ...
}
## Doctrine\DBAL\Connection#setCharsetSQL() removed
This method only worked on MySQL and it is considered unsafe on MySQL to use SET NAMES UTF-8 instead
......
......@@ -594,7 +594,12 @@ class Connection implements DriverConnection
{
$this->connect();
try {
$stmt = new Statement($statement, $this);
} catch (\Exception $ex) {
throw DBALException::driverExceptionDuringQuery($ex, $statement);
}
$stmt->setFetchMode($this->_defaultFetchMode);
return $stmt;
......@@ -626,6 +631,7 @@ class Connection implements DriverConnection
$logger->startQuery($query, $params, $types);
}
try {
if ($params) {
list($query, $params, $types) = SQLParserUtils::expandListParameters($query, $params, $types);
......@@ -639,6 +645,9 @@ class Connection implements DriverConnection
} else {
$stmt = $this->_conn->query($query);
}
} catch (\Exception $ex) {
throw DBALException::driverExceptionDuringQuery($ex, $query, $this->resolveParams($params, $types));
}
$stmt->setFetchMode($this->_defaultFetchMode);
......@@ -729,7 +738,12 @@ class Connection implements DriverConnection
$logger->startQuery($args[0]);
}
try {
$statement = call_user_func_array(array($this->_conn, 'query'), $args);
} catch (\Exception $ex) {
throw DBALException::driverExceptionDuringQuery($ex, func_get_arg(0));
}
$statement->setFetchMode($this->_defaultFetchMode);
if ($logger) {
......@@ -760,6 +774,7 @@ class Connection implements DriverConnection
$logger->startQuery($query, $params, $types);
}
try {
if ($params) {
list($query, $params, $types) = SQLParserUtils::expandListParameters($query, $params, $types);
......@@ -774,6 +789,9 @@ class Connection implements DriverConnection
} else {
$result = $this->_conn->exec($query);
}
} catch (\Exception $ex) {
throw DBALException::driverExceptionDuringQuery($ex, $query, $this->resolveParams($params, $types));
}
if ($logger) {
$logger->stopQuery();
......@@ -797,7 +815,11 @@ class Connection implements DriverConnection
$logger->startQuery($statement);
}
try {
$result = $this->_conn->exec($statement);
} catch (\Exception $ex) {
throw DBALException::driverExceptionDuringQuery($ex, $statement);
}
if ($logger) {
$logger->stopQuery();
......@@ -1227,6 +1249,53 @@ class Connection implements DriverConnection
return array($value, $bindingType);
}
/**
* Resolves the parameters to a format which can be displayed.
*
* @internal This is a purely internal method. If you rely on this method, you are advised to
* copy/paste the code as this method may change, or be removed without prior notice.
*
* @param array $params
* @param array $types
*
* @return array
*/
public function resolveParams(array $params, array $types)
{
$resolvedParams = array();
// Check whether parameters are positional or named. Mixing is not allowed, just like in PDO.
if (is_int(key($params))) {
// Positional parameters
$typeOffset = array_key_exists(0, $types) ? -1 : 0;
$bindIndex = 1;
foreach ($params as $value) {
$typeIndex = $bindIndex + $typeOffset;
if (isset($types[$typeIndex])) {
$type = $types[$typeIndex];
list($value,) = $this->getBindingInfo($value, $type);
$resolvedParams[$bindIndex] = $value;
} else {
$resolvedParams[$bindIndex] = $value;
}
++$bindIndex;
}
} else {
// Named parameters
foreach ($params as $name => $value) {
if (isset($types[$name])) {
$type = $types[$name];
list($value,) = $this->getBindingInfo($value, $type);
$resolvedParams[$name] = $value;
} else {
$resolvedParams[$name] = $value;
}
}
}
return $resolvedParams;
}
/**
* Create a new instance of a SQL query builder.
*
......
......@@ -36,6 +36,17 @@ class DBALException extends \Exception
"Doctrine currently supports only the following drivers: ".implode(", ", $knownDrivers));
}
public static function driverExceptionDuringQuery(\Exception $driverEx, $sql, array $params = array())
{
$msg = "An exception occurred while executing '".$sql."'";
if ($params) {
$msg .= " with params ".json_encode($params);
}
$msg .= ":\n\n".$driverEx->getMessage();
return new self($msg, 0, $driverEx);
}
public static function invalidWrapperClass($wrapperClass)
{
return new self("The given 'wrapperClass' ".$wrapperClass." has to be a ".
......
......@@ -56,7 +56,7 @@ class DB2Statement implements \IteratorAggregate, Statement
/**
* {@inheritdoc}
*/
public function bindParam($column, &$variable, $type = null)
public function bindParam($column, &$variable, $type = null, $length = null)
{
$this->_bindParam[$column] =& $variable;
......
......@@ -86,7 +86,7 @@ class MysqliStatement implements \IteratorAggregate, Statement
/**
* {@inheritdoc}
*/
public function bindParam($column, &$variable, $type = null)
public function bindParam($column, &$variable, $type = null, $length = null)
{
if (null === $type) {
$type = 's';
......
......@@ -106,13 +106,13 @@ class OCI8Statement implements \IteratorAggregate, Statement
*/
public function bindValue($param, $value, $type = null)
{
return $this->bindParam($param, $value, $type);
return $this->bindParam($param, $value, $type, null);
}
/**
* {@inheritdoc}
*/
public function bindParam($column, &$variable, $type = null)
public function bindParam($column, &$variable, $type = null,$length = null)
{
$column = isset($this->_paramMap[$column]) ? $this->_paramMap[$column] : $column;
......
......@@ -102,13 +102,13 @@ class SQLSrvStatement implements IteratorAggregate, Statement
public function bindValue($param, $value, $type = null)
{
return $this->bindParam($param, $value, $type);
return $this->bindParam($param, $value, $type,null);
}
/**
* {@inheritdoc}
*/
public function bindParam($column, &$variable, $type = null)
public function bindParam($column, &$variable, $type = null, $length = null)
{
if (!is_numeric($column)) {
throw new SQLSrvException("sqlsrv does not support named parameters to queries, use question mark (?) placeholders instead.");
......
......@@ -70,9 +70,10 @@ interface Statement extends ResultStatement
* @param integer $type Explicit data type for the parameter using the PDO::PARAM_* constants. To return
* an INOUT parameter from a stored procedure, use the bitwise OR operator to set the
* PDO::PARAM_INPUT_OUTPUT bits for the data_type parameter.
* @param integer $length You must specify maxlength when using an OUT bind so that PHP allocates enough memory to hold the returned value.
* @return boolean Returns TRUE on success or FALSE on failure.
*/
function bindParam($column, &$variable, $type = null);
function bindParam($column, &$variable, $type = null, $length = null);
/**
* errorCode
......
This diff is collapsed.
......@@ -32,7 +32,7 @@ use Doctrine\DBAL\DBALException,
class DrizzlePlatform extends AbstractPlatform
{
/**
* {@inheritdoc}
* {@inheritDoc}
*/
public function getName()
{
......@@ -40,59 +40,82 @@ class DrizzlePlatform extends AbstractPlatform
}
/**
* {@inheritdoc}
* {@inheritDoc}
*/
public function getIdentifierQuoteCharacter()
{
return '`';
}
public function getConcatExpression()
/**
* {@inheritDoc}
*/ public function getConcatExpression()
{
$args = func_get_args();
return 'CONCAT(' . join(', ', (array) $args) . ')';
}
/**
* {@inheritDoc}
*/
public function getDateDiffExpression($date1, $date2)
{
return 'DATEDIFF(' . $date1 . ', ' . $date2 . ')';
}
/**
* {@inheritDoc}
*/
public function getDateAddDaysExpression($date, $days)
{
return 'DATE_ADD(' . $date . ', INTERVAL ' . $days . ' DAY)';
}
/**
* {@inheritDoc}
*/
public function getDateSubDaysExpression($date, $days)
{
return 'DATE_SUB(' . $date . ', INTERVAL ' . $days . ' DAY)';
}
/**
* {@inheritDoc}
*/
public function getDateAddMonthExpression($date, $months)
{
return 'DATE_ADD(' . $date . ', INTERVAL ' . $months . ' MONTH)';
}
/**
* {@inheritDoc}
*/
public function getDateSubMonthExpression($date, $months)
{
return 'DATE_SUB(' . $date . ', INTERVAL ' . $months . ' MONTH)';
}
/**
* @override
* {@inheritDoc}
*/
public function getBooleanTypeDeclarationSQL(array $field)
{
return 'BOOLEAN';
}
/**
* {@inheritDoc}
*/
public function getIntegerTypeDeclarationSQL(array $field)
{
return 'INT' . $this->_getCommonIntegerTypeDeclarationSQL($field);
}
/**
* {@inheritDoc}
*/
protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef)
{
$autoinc = '';
......@@ -102,22 +125,33 @@ class DrizzlePlatform extends AbstractPlatform
return $autoinc;
}
/**
* {@inheritDoc}
*/
public function getBigIntTypeDeclarationSQL(array $field)
{
return 'BIGINT' . $this->_getCommonIntegerTypeDeclarationSQL($field);
}
/**
* {@inheritDoc}
*/
public function getSmallIntTypeDeclarationSQL(array $field)
{
return 'INT' . $this->_getCommonIntegerTypeDeclarationSQL($field);
}
/**
* {@inheritDoc}
*/
protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed)
{
return $length ? 'VARCHAR(' . $length . ')' : 'VARCHAR(255)';
}
/**
* {@inheritDoc}
*/
protected function initializeDoctrineTypeMappings()
{
$this->doctrineTypeMapping = array(
......@@ -136,24 +170,33 @@ class DrizzlePlatform extends AbstractPlatform
);
}
/**
* {@inheritDoc}
*/
public function getClobTypeDeclarationSQL(array $field)
{
return 'TEXT';
}
/**
* Gets the SQL Snippet used to declare a BLOB column type.
* {@inheritDoc}
*/
public function getBlobTypeDeclarationSQL(array $field)
{
return 'BLOB';
}
/**
* {@inheritDoc}
*/
public function getCreateDatabaseSQL($name)
{
return 'CREATE DATABASE ' . $name;
}
/**
* {@inheritDoc}
*/
public function getDropDatabaseSQL($name)
{
return 'DROP DATABASE ' . $name;
......@@ -164,6 +207,9 @@ class DrizzlePlatform extends AbstractPlatform
return "SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE CATALOG_NAME='LOCAL'";
}
/**
* {@inheritDoc}
*/
protected function getReservedKeywordsClass()
{
return 'Doctrine\DBAL\Platforms\Keywords\DrizzleKeywords';
......@@ -201,6 +247,9 @@ class DrizzlePlatform extends AbstractPlatform
" WHERE CONSTRAINT_SCHEMA=" . $database . " AND CONSTRAINT_TABLE='" . $table . "'";
}
/**
* {@inheritDoc}
*/
public function getListTableIndexesSQL($table, $database = null)
{
if ($database) {
......@@ -214,37 +263,52 @@ class DrizzlePlatform extends AbstractPlatform
" WHERE TABLE_SCHEMA=" . $database . " AND TABLE_NAME='" . $table . "'";
}
/**
* {@inheritDoc}
*/
public function prefersIdentityColumns()
{
return true;
}
/**
* {@inheritDoc}
*/
public function supportsIdentityColumns()
{
return true;
}
/**
* {@inheritDoc}
*/
public function supportsInlineColumnComments()
{
return true;
}
/**
* {@inheritDoc}
*/
public function supportsViews()
{
return false;
}
/**
* {@inheritDoc}
*/
public function getDropIndexSQL($index, $table=null)
{
if($index instanceof Index) {
if ($index instanceof Index) {
$indexName = $index->getQuotedName($this);
} else if(is_string($index)) {
} else if (is_string($index)) {
$indexName = $index;
} else {
throw new \InvalidArgumentException('DrizzlePlatform::getDropIndexSQL() expects $index parameter to be string or \Doctrine\DBAL\Schema\Index.');
}
if($table instanceof Table) {
if ($table instanceof Table) {
$table = $table->getQuotedName($this);
} else if(!is_string($table)) {
throw new \InvalidArgumentException('DrizzlePlatform::getDropIndexSQL() expects $table parameter to be string or \Doctrine\DBAL\Schema\Table.');
......@@ -262,36 +326,44 @@ class DrizzlePlatform extends AbstractPlatform
/**
* @param Index $index
* @param Table $table
*
* @return string
*/
protected function getDropPrimaryKeySQL($table)
{
return 'ALTER TABLE ' . $table . ' DROP PRIMARY KEY';
}
/**
* {@inheritDoc}
*/
public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration)
{
if (isset($fieldDeclaration['version']) && $fieldDeclaration['version'] == true) {
return 'TIMESTAMP';
} else {
return 'DATETIME';
}
return 'DATETIME';
}
/**
* {@inheritDoc}
*/
public function getTimeTypeDeclarationSQL(array $fieldDeclaration)
{
return 'TIME';
}
/**
* {@inheritDoc}
*/
public function getDateTypeDeclarationSQL(array $fieldDeclaration)
{
return 'DATE';
}
/**
* C/P from mysql platform
*
* @param TableDiff $diff
* @return string
* {@inheritDoc}
*/
public function getAlterTableSQL(TableDiff $diff)
{
......@@ -302,7 +374,7 @@ class DrizzlePlatform extends AbstractPlatform
$queryParts[] = 'RENAME TO ' . $diff->newName;
}
foreach ($diff->addedColumns as $fieldName => $column) {
foreach ($diff->addedColumns as $column) {
if ($this->onSchemaAlterTableAddColumn($column, $diff, $columnSql)) {
continue;
}
......@@ -361,9 +433,12 @@ class DrizzlePlatform extends AbstractPlatform
return array_merge($sql, $tableSql, $columnSql);
}
/**
* {@inheritDoc}
*/
public function getDropTemporaryTableSQL($table)
{
if ($table instanceof \Doctrine\DBAL\Schema\Table) {
if ($table instanceof Table) {
$table = $table->getQuotedName($this);
} else if(!is_string($table)) {
throw new \InvalidArgumentException('getDropTableSQL() expects $table parameter to be string or \Doctrine\DBAL\Schema\Table.');
......@@ -372,6 +447,9 @@ class DrizzlePlatform extends AbstractPlatform
return 'DROP TEMPORARY TABLE ' . $table;
}
/**
* {@inheritDoc}
*/
public function convertBooleans($item)
{
if (is_array($item)) {
......@@ -380,28 +458,36 @@ class DrizzlePlatform extends AbstractPlatform
$item[$key] = ($value) ? 'true' : 'false';
}
}
} else {
if (is_bool($item) || is_numeric($item)) {
} else if (is_bool($item) || is_numeric($item)) {
$item = ($item) ? 'true' : 'false';
}
}
return $item;
}
/**
* {@inheritDoc}
*/
public function getLocateExpression($str, $substr, $startPos = false)
{
if ($startPos == false) {
return 'LOCATE(' . $substr . ', ' . $str . ')';
} else {
return 'LOCATE(' . $substr . ', ' . $str . ', '.$startPos.')';
}
return 'LOCATE(' . $substr . ', ' . $str . ', '.$startPos.')';
}
/**
* {@inheritDoc}
*/
public function getGuidExpression()
{
return 'UUID()';
}
/**
* {@inheritDoc}
*/
public function getRegexpExpression()
{
return 'RLIKE';
......
......@@ -30,6 +30,9 @@ use Doctrine\DBAL\Schema\Table;
*/
class SQLAzurePlatform extends SQLServer2008Platform
{
/**
* {@inheritDoc}
*/
public function getCreateTableSQL(Table $table, $createFlags=self::CREATE_INDEXES)
{
$sql = parent::getCreateTableSQL($table, $createFlags);
......@@ -41,6 +44,7 @@ class SQLAzurePlatform extends SQLServer2008Platform
$sql[0] = $sql[0] . $stmt;
}
return $sql;
}
}
......
......@@ -36,14 +36,16 @@ namespace Doctrine\DBAL\Platforms;
class SQLServer2005Platform extends SQLServerPlatform
{
/**
* @override
* {@inheritDoc}
*/
public function supportsLimitOffset()
{
return true;
}
/** @override */
/**
* {@inheritDoc}
*/
public function getClobTypeDeclarationSQL(array $field)
{
return 'VARCHAR(MAX)';
......
......@@ -28,7 +28,7 @@ namespace Doctrine\DBAL\Platforms;
class SQLServer2008Platform extends SQLServer2005Platform
{
/**
* @override
* {@inheritDoc}
*/
public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration)
{
......@@ -38,7 +38,7 @@ class SQLServer2008Platform extends SQLServer2005Platform
}
/**
* @override
* {@inheritDoc}
*/
public function getDateTypeDeclarationSQL(array $fieldDeclaration)
{
......@@ -46,7 +46,7 @@ class SQLServer2008Platform extends SQLServer2005Platform
}
/**
* @override
* {@inheritDoc}
*/
public function getTimeTypeDeclarationSQL(array $fieldDeclaration)
{
......@@ -54,7 +54,7 @@ class SQLServer2008Platform extends SQLServer2005Platform
}
/**
* @override
* {@inheritDoc}
*/
public function getDateTimeFormatString()
{
......@@ -62,7 +62,7 @@ class SQLServer2008Platform extends SQLServer2005Platform
}
/**
* @override
* {@inheritDoc}
*/
public function getDateTimeTzFormatString()
{
......@@ -70,7 +70,7 @@ class SQLServer2008Platform extends SQLServer2005Platform
}
/**
* @override
* {@inheritDoc}
*/
public function getDateFormatString()
{
......@@ -78,7 +78,7 @@ class SQLServer2008Platform extends SQLServer2005Platform
}
/**
* @override
* {@inheritDoc}
*/
public function getTimeFormatString()
{
......@@ -86,6 +86,8 @@ class SQLServer2008Platform extends SQLServer2005Platform
}
/**
* {@inheritDoc}
*
* Adding Datetime2 Type
*/
protected function initializeDoctrineTypeMappings()
......
......@@ -66,7 +66,7 @@ class Statement implements \IteratorAggregate, \Doctrine\DBAL\Driver\Statement
$this->case = $conn->getFetchCase();
}
public function bindParam($column, &$variable, $type = null)
public function bindParam($column, &$variable, $type = null,$length = null)
{
return $this->stmt->bindParam($column, $variable, $type);
}
......
......@@ -21,6 +21,8 @@
namespace Doctrine\DBAL\Schema;
use Doctrine\DBAL\Platforms\AbstractPlatform;
/**
* Marker interface for contraints
*
......@@ -34,5 +36,7 @@ interface Constraint
{
public function getName();
public function getQuotedName(AbstractPlatform $platform);
public function getColumns();
}
......@@ -22,6 +22,7 @@
namespace Doctrine\DBAL\Schema;
use Doctrine\DBAL\Schema\Visitor\Visitor;
use Doctrine\DBAL\Platforms\AbstractPlatform;
class ForeignKeyConstraint extends AbstractAsset implements Constraint
{
......@@ -109,6 +110,24 @@ class ForeignKeyConstraint extends AbstractAsset implements Constraint
return $this->_foreignTableName;
}
/**
* Get the quoted representation of this asset but only if it was defined with one. Otherwise
* return the plain unquoted value as inserted.
*
* @param AbstractPlatform $platform
* @return string
*/
public function getQuotedForeignTableName(AbstractPlatform $platform)
{
$keywords = $platform->getReservedKeywordsList();
$parts = explode(".", $this->getForeignTableName());
foreach ($parts AS $k => $v) {
$parts[$k] = ($this->_quoted || $keywords->isKeyword($v)) ? $platform->quoteIdentifier($v) : $v;
}
return implode(".", $parts);
}
/**
* @return array
*/
......
This diff is collapsed.
This diff is collapsed.
Subproject commit 15b04ec520ccded3dc0eba65b12a69ff1931360f
Subproject commit 9b67267f19eee00cbf0ffb489b36977d4e205e36
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment