Commit 637ef6a1 authored by Benjamin Eberlei's avatar Benjamin Eberlei

Merge pull request #491 from deeky666/fix-sqlsrv-drivers-test-suite

Fix SQL Server drivers and functional test suites
parents 0e932715 03cc3d5c
...@@ -51,6 +51,8 @@ interfaces to use. It can be configured in one of three ways: ...@@ -51,6 +51,8 @@ interfaces to use. It can be configured in one of three ways:
extension. extension.
**Note that this driver caused problems in our tests. Prefer the oci8 driver if possible.** **Note that this driver caused problems in our tests. Prefer the oci8 driver if possible.**
- ``pdo_sqlsrv``: A Microsoft SQL Server driver that uses pdo\_sqlsrv PDO - ``pdo_sqlsrv``: A Microsoft SQL Server driver that uses pdo\_sqlsrv PDO
**Note that this driver caused problems in our tests. Prefer the sqlsrv driver if possible.**
- ``sqlsrv``: A Microsoft SQL Server driver that uses the sqlsrv PHP extension.
- ``oci8``: An Oracle driver that uses the oci8 PHP extension. - ``oci8``: An Oracle driver that uses the oci8 PHP extension.
- ``sqlanywhere``: A SAP Sybase SQL Anywhere driver that uses the sqlanywhere PHP extension. - ``sqlanywhere``: A SAP Sybase SQL Anywhere driver that uses the sqlanywhere PHP extension.
...@@ -192,8 +194,8 @@ pdo\_oci / oci8 ...@@ -192,8 +194,8 @@ pdo\_oci / oci8
- ``charset`` (string): The charset used when connecting to the - ``charset`` (string): The charset used when connecting to the
database. database.
pdo\_sqlsrv pdo\_sqlsrv / sqlsrv
^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^
- ``user`` (string): Username to use when connecting to the - ``user`` (string): Username to use when connecting to the
......
...@@ -48,7 +48,7 @@ that detects the format automatically: ...@@ -48,7 +48,7 @@ that detects the format automatically:
:: ::
use Doctrine\DBAL\Types\Type; use Doctrine\DBAL\Types\Type;
Type::overrideType('datetime', 'Doctrine\DBAL\Types\VarDateTimeType'); Type::overrideType('datetime', 'Doctrine\DBAL\Types\VarDateTimeType');
Type::overrideType('datetimetz', 'Doctrine\DBAL\Types\VarDateTimeType'); Type::overrideType('datetimetz', 'Doctrine\DBAL\Types\VarDateTimeType');
Type::overrideType('time', 'Doctrine\DBAL\Types\VarDateTimeType'); Type::overrideType('time', 'Doctrine\DBAL\Types\VarDateTimeType');
...@@ -180,7 +180,18 @@ that detects the format automatically: ...@@ -180,7 +180,18 @@ that detects the format automatically:
:: ::
use Doctrine\DBAL\Types\Type; use Doctrine\DBAL\Types\Type;
Type::overrideType('datetime', 'Doctrine\DBAL\Types\VarDateTime'); Type::overrideType('datetime', 'Doctrine\DBAL\Types\VarDateTime');
Type::overrideType('datetimetz', 'Doctrine\DBAL\Types\VarDateTime'); Type::overrideType('datetimetz', 'Doctrine\DBAL\Types\VarDateTime');
Type::overrideType('time', 'Doctrine\DBAL\Types\VarDateTime'); Type::overrideType('time', 'Doctrine\DBAL\Types\VarDateTime');
PDO_SQLSRV: VARBINARY/BLOB columns
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The ``PDO_SQLSRV`` driver currently has a bug when binding values to
VARBINARY/BLOB columns with ``bindValue`` in prepared statements.
This raises an implicit conversion from data type error as it tries
to convert a character type value to a binary type value even if
you explicitly define the value as ``\PDO::PARAM_LOB`` type.
Therefore it is highly encouraged to use the native ``sqlsrv``
driver instead which does not have this limitation.
...@@ -65,7 +65,7 @@ class PDOStatement extends \PDOStatement implements Statement ...@@ -65,7 +65,7 @@ class PDOStatement extends \PDOStatement implements Statement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function bindParam($column, &$variable, $type = \PDO::PARAM_STR, $length = null, $driverOptions = array()) public function bindParam($column, &$variable, $type = \PDO::PARAM_STR, $length = null, $driverOptions = null)
{ {
return parent::bindParam($column, $variable, $type, $length, $driverOptions); return parent::bindParam($column, $variable, $type, $length, $driverOptions);
} }
......
...@@ -70,6 +70,20 @@ class SQLSrvStatement implements IteratorAggregate, Statement ...@@ -70,6 +70,20 @@ class SQLSrvStatement implements IteratorAggregate, Statement
PDO::FETCH_NUM => SQLSRV_FETCH_NUMERIC, PDO::FETCH_NUM => SQLSRV_FETCH_NUMERIC,
); );
/**
* The name of the default class to instantiate when fetch mode is \PDO::FETCH_CLASS.
*
* @var string
*/
private $defaultFetchClass = '\stdClass';
/**
* The constructor arguments for the default class to instantiate when fetch mode is \PDO::FETCH_CLASS.
*
* @var string
*/
private $defaultFetchClassCtorArgs = array();
/** /**
* The fetch style. * The fetch style.
* *
...@@ -200,7 +214,9 @@ class SQLSrvStatement implements IteratorAggregate, Statement ...@@ -200,7 +214,9 @@ class SQLSrvStatement implements IteratorAggregate, Statement
*/ */
public function setFetchMode($fetchMode, $arg2 = null, $arg3 = null) public function setFetchMode($fetchMode, $arg2 = null, $arg3 = null)
{ {
$this->defaultFetchMode = $fetchMode; $this->defaultFetchMode = $fetchMode;
$this->defaultFetchClass = $arg2 ?: $this->defaultFetchClass;
$this->defaultFetchClassCtorArgs = $arg3 ? (array) $arg3 : $this->defaultFetchClassCtorArgs;
return true; return true;
} }
...@@ -225,8 +241,8 @@ class SQLSrvStatement implements IteratorAggregate, Statement ...@@ -225,8 +241,8 @@ class SQLSrvStatement implements IteratorAggregate, Statement
if (isset(self::$fetchMap[$fetchMode])) { if (isset(self::$fetchMap[$fetchMode])) {
return sqlsrv_fetch_array($this->stmt, self::$fetchMap[$fetchMode]); return sqlsrv_fetch_array($this->stmt, self::$fetchMap[$fetchMode]);
} elseif ($fetchMode == PDO::FETCH_OBJ || $fetchMode == PDO::FETCH_CLASS) { } elseif ($fetchMode == PDO::FETCH_OBJ || $fetchMode == PDO::FETCH_CLASS) {
$className = null; $className = $this->defaultFetchClass;
$ctorArgs = null; $ctorArgs = $this->defaultFetchClassCtorArgs;
if (count($args) >= 2) { if (count($args) >= 2) {
$className = $args[1]; $className = $args[1];
$ctorArgs = (isset($args[2])) ? $args[2] : array(); $ctorArgs = (isset($args[2])) ? $args[2] : array();
...@@ -242,17 +258,23 @@ class SQLSrvStatement implements IteratorAggregate, Statement ...@@ -242,17 +258,23 @@ class SQLSrvStatement implements IteratorAggregate, Statement
*/ */
public function fetchAll($fetchMode = null) public function fetchAll($fetchMode = null)
{ {
$className = null;
$ctorArgs = null;
if (func_num_args() >= 2) {
$args = func_get_args();
$className = $args[1];
$ctorArgs = (isset($args[2])) ? $args[2] : array();
}
$rows = array(); $rows = array();
while ($row = $this->fetch($fetchMode, $className, $ctorArgs)) {
$rows[] = $row; switch ($fetchMode) {
case PDO::FETCH_CLASS:
while ($row = call_user_func_array(array($this, 'fetch'), func_get_args())) {
$rows[] = $row;
}
break;
case PDO::FETCH_COLUMN:
while ($row = $this->fetchColumn()) {
$rows[] = $row;
}
break;
default:
while ($row = $this->fetch($fetchMode)) {
$rows[] = $row;
}
} }
return $rows; return $rows;
...@@ -265,7 +287,11 @@ class SQLSrvStatement implements IteratorAggregate, Statement ...@@ -265,7 +287,11 @@ class SQLSrvStatement implements IteratorAggregate, Statement
{ {
$row = $this->fetch(PDO::FETCH_NUM); $row = $this->fetch(PDO::FETCH_NUM);
return $row[$columnIndex]; if ($row && isset($row[$columnIndex])) {
return $row[$columnIndex];
}
return false;
} }
/** /**
......
...@@ -537,8 +537,6 @@ class SQLServerPlatform extends AbstractPlatform ...@@ -537,8 +537,6 @@ class SQLServerPlatform extends AbstractPlatform
$sql[] = "sp_RENAME '". $diff->name. ".". $oldColumnName . "', '".$column->getQuotedName($this)."', 'COLUMN'"; $sql[] = "sp_RENAME '". $diff->name. ".". $oldColumnName . "', '".$column->getQuotedName($this)."', 'COLUMN'";
// todo: Find a way how to implement column comment alteration statements for renamed columns.
$columnDef = $column->toArray(); $columnDef = $column->toArray();
/** /**
......
...@@ -17,6 +17,10 @@ class BlobTest extends \Doctrine\Tests\DbalFunctionalTestCase ...@@ -17,6 +17,10 @@ class BlobTest extends \Doctrine\Tests\DbalFunctionalTestCase
{ {
parent::setUp(); parent::setUp();
if ($this->_conn->getDriver() instanceof \Doctrine\DBAL\Driver\PDOSqlsrv\Driver) {
$this->markTestSkipped('This test does not work on pdo_sqlsrv driver due to a bug. See: http://social.msdn.microsoft.com/Forums/sqlserver/en-US/5a755bdd-41e9-45cb-9166-c9da4475bb94/how-to-set-null-for-varbinarymax-using-bindvalue-using-pdosqlsrv?forum=sqldriverforphp');
}
try { try {
/* @var $sm \Doctrine\DBAL\Schema\AbstractSchemaManager */ /* @var $sm \Doctrine\DBAL\Schema\AbstractSchemaManager */
$table = new \Doctrine\DBAL\Schema\Table("blob_table"); $table = new \Doctrine\DBAL\Schema\Table("blob_table");
......
...@@ -212,8 +212,9 @@ class DataAccessTest extends \Doctrine\Tests\DbalFunctionalTestCase ...@@ -212,8 +212,9 @@ class DataAccessTest extends \Doctrine\Tests\DbalFunctionalTestCase
*/ */
public function testFetchAllWithMissingTypes() public function testFetchAllWithMissingTypes()
{ {
if ($this->_conn->getDriver() instanceof \Doctrine\DBAL\Driver\Mysqli\Driver) { if ($this->_conn->getDriver() instanceof \Doctrine\DBAL\Driver\Mysqli\Driver ||
$this->markTestSkipped('mysqli actually supports this'); $this->_conn->getDriver() instanceof \Doctrine\DBAL\Driver\SQLSrv\Driver) {
$this->markTestSkipped('mysqli and sqlsrv actually supports this');
} }
$datetimeString = '2010-01-01 10:10:10'; $datetimeString = '2010-01-01 10:10:10';
......
...@@ -559,7 +559,10 @@ class SchemaManagerFunctionalTestCase extends \Doctrine\Tests\DbalFunctionalTest ...@@ -559,7 +559,10 @@ class SchemaManagerFunctionalTestCase extends \Doctrine\Tests\DbalFunctionalTest
'id', new \Doctrine\DBAL\Schema\Column( 'id', new \Doctrine\DBAL\Schema\Column(
'id', \Doctrine\DBAL\Types\Type::getType('integer'), array('primary' => true) 'id', \Doctrine\DBAL\Types\Type::getType('integer'), array('primary' => true)
), ),
array('comment') array('comment'),
new \Doctrine\DBAL\Schema\Column(
'id', \Doctrine\DBAL\Types\Type::getType('integer'), array('comment' => 'This is a comment')
)
); );
$this->_sm->alterTable($tableDiff); $this->_sm->alterTable($tableDiff);
......
<?php <?php
namespace Doctrine\Tests\DBAL\Sharding\SQLAzure; namespace Doctrine\Tests\DBAL\Sharding\SQLAzure;
use Doctrine\DBAL\Sharding\SQLAzure\SQLAzureSchemaSynchronizer; use Doctrine\DBAL\Sharding\SQLAzure\SQLAzureFederationsSynchronizer;
class FunctionalTest extends AbstractTestCase class FunctionalTest extends AbstractTestCase
{ {
...@@ -9,7 +9,7 @@ class FunctionalTest extends AbstractTestCase ...@@ -9,7 +9,7 @@ class FunctionalTest extends AbstractTestCase
{ {
$schema = $this->createShopSchema(); $schema = $this->createShopSchema();
$synchronizer = new SQLAzureSchemaSynchronizer($this->conn, $this->sm); $synchronizer = new SQLAzureFederationsSynchronizer($this->conn, $this->sm);
$synchronizer->dropAllSchema(); $synchronizer->dropAllSchema();
$synchronizer->createSchema($schema); $synchronizer->createSchema($schema);
......
<?php <?php
namespace Doctrine\Tests\DBAL\Sharding\SQLAzure; namespace Doctrine\Tests\DBAL\Sharding\SQLAzure;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Sharding\SQLAzure\SQLAzureFederationsSynchronizer; use Doctrine\DBAL\Sharding\SQLAzure\SQLAzureFederationsSynchronizer;
class SQLAzureFederationsSynchronizerTest extends AbstractTestCase class SQLAzureFederationsSynchronizerTest extends AbstractTestCase
......
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