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:
extension.
**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
**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.
- ``sqlanywhere``: A SAP Sybase SQL Anywhere driver that uses the sqlanywhere PHP extension.
......@@ -192,8 +194,8 @@ pdo\_oci / oci8
- ``charset`` (string): The charset used when connecting to the
database.
pdo\_sqlsrv
^^^^^^^^^^^
pdo\_sqlsrv / sqlsrv
^^^^^^^^^^^^^^^^^^^^
- ``user`` (string): Username to use when connecting to the
......
......@@ -48,7 +48,7 @@ that detects the format automatically:
::
use Doctrine\DBAL\Types\Type;
Type::overrideType('datetime', 'Doctrine\DBAL\Types\VarDateTimeType');
Type::overrideType('datetimetz', 'Doctrine\DBAL\Types\VarDateTimeType');
Type::overrideType('time', 'Doctrine\DBAL\Types\VarDateTimeType');
......@@ -180,7 +180,18 @@ that detects the format automatically:
::
use Doctrine\DBAL\Types\Type;
Type::overrideType('datetime', 'Doctrine\DBAL\Types\VarDateTime');
Type::overrideType('datetimetz', '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
/**
* {@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);
}
......
......@@ -70,6 +70,20 @@ class SQLSrvStatement implements IteratorAggregate, Statement
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.
*
......@@ -200,7 +214,9 @@ class SQLSrvStatement implements IteratorAggregate, Statement
*/
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;
}
......@@ -225,8 +241,8 @@ class SQLSrvStatement implements IteratorAggregate, Statement
if (isset(self::$fetchMap[$fetchMode])) {
return sqlsrv_fetch_array($this->stmt, self::$fetchMap[$fetchMode]);
} elseif ($fetchMode == PDO::FETCH_OBJ || $fetchMode == PDO::FETCH_CLASS) {
$className = null;
$ctorArgs = null;
$className = $this->defaultFetchClass;
$ctorArgs = $this->defaultFetchClassCtorArgs;
if (count($args) >= 2) {
$className = $args[1];
$ctorArgs = (isset($args[2])) ? $args[2] : array();
......@@ -242,17 +258,23 @@ class SQLSrvStatement implements IteratorAggregate, Statement
*/
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();
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;
......@@ -265,7 +287,11 @@ class SQLSrvStatement implements IteratorAggregate, Statement
{
$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
$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();
/**
......
......@@ -17,6 +17,10 @@ class BlobTest extends \Doctrine\Tests\DbalFunctionalTestCase
{
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 {
/* @var $sm \Doctrine\DBAL\Schema\AbstractSchemaManager */
$table = new \Doctrine\DBAL\Schema\Table("blob_table");
......
......@@ -212,8 +212,9 @@ class DataAccessTest extends \Doctrine\Tests\DbalFunctionalTestCase
*/
public function testFetchAllWithMissingTypes()
{
if ($this->_conn->getDriver() instanceof \Doctrine\DBAL\Driver\Mysqli\Driver) {
$this->markTestSkipped('mysqli actually supports this');
if ($this->_conn->getDriver() instanceof \Doctrine\DBAL\Driver\Mysqli\Driver ||
$this->_conn->getDriver() instanceof \Doctrine\DBAL\Driver\SQLSrv\Driver) {
$this->markTestSkipped('mysqli and sqlsrv actually supports this');
}
$datetimeString = '2010-01-01 10:10:10';
......
......@@ -559,7 +559,10 @@ class SchemaManagerFunctionalTestCase extends \Doctrine\Tests\DbalFunctionalTest
'id', new \Doctrine\DBAL\Schema\Column(
'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);
......
<?php
namespace Doctrine\Tests\DBAL\Sharding\SQLAzure;
use Doctrine\DBAL\Sharding\SQLAzure\SQLAzureSchemaSynchronizer;
use Doctrine\DBAL\Sharding\SQLAzure\SQLAzureFederationsSynchronizer;
class FunctionalTest extends AbstractTestCase
{
......@@ -9,7 +9,7 @@ class FunctionalTest extends AbstractTestCase
{
$schema = $this->createShopSchema();
$synchronizer = new SQLAzureSchemaSynchronizer($this->conn, $this->sm);
$synchronizer = new SQLAzureFederationsSynchronizer($this->conn, $this->sm);
$synchronizer->dropAllSchema();
$synchronizer->createSchema($schema);
......
<?php
namespace Doctrine\Tests\DBAL\Sharding\SQLAzure;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Sharding\SQLAzure\SQLAzureFederationsSynchronizer;
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