Skip to content
Permalink
Browse files

Remove the 'persistent' config option for Sqlserver connections

- The PDO::ATTR_PERSISTENT connection configuration option is not allowed
  by the SQL Server PHP driver.  In newer versions of the driver an
  exception is thrown if that option is set.  In older versions of the
  driver it triggered a heap corruption bug which usually caused
  intermittent crashes.
  • Loading branch information...
MCF committed Aug 11, 2017
1 parent 2b73b0a commit 43959d9926e1f4a55246f7001b6882de172aace3
Showing with 80 additions and 5 deletions.
  1. +12 −3 src/Database/Driver/Sqlserver.php
  2. +68 −2 tests/TestCase/Database/Driver/SqlserverTest.php
@@ -35,7 +35,6 @@ class Sqlserver extends Driver
* @var array
*/
protected $_baseConfig = [
'persistent' => false,
'host' => 'localhost\SQLEXPRESS',
'username' => '',
'password' => '',
@@ -54,8 +53,14 @@ class Sqlserver extends Driver
];
/**
* Establishes a connection to the database server
* Establishes a connection to the database server.
*
* Please note that the PDO::ATTR_PERSISTENT attribute is not supported by
* the SQL Server PHP PDO drivers. As a result you cannot use the
* persistent config option when connecting to a SQL Server (for more
* information see: https://github.com/Microsoft/msphpsql/issues/65).
*
* @throws \InvalidArgumentException if an unsupported setting is in the driver config
* @return bool true on success
*/
public function connect()
@@ -64,8 +69,12 @@ public function connect()
return true;
}
$config = $this->_config;
if (isset($config['persistent']) && $config['persistent']) {
throw new \InvalidArgumentException('Config setting "persistent" cannot be set to true, as the Sqlserver PDO driver does not support PDO::ATTR_PERSISTENT');
}
$config['flags'] += [
PDO::ATTR_PERSISTENT => $config['persistent'],
PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
];
@@ -103,7 +103,6 @@ public function testConnectionConfigCustom()
{
$this->skipIf($this->missingExtension, 'pdo_sqlsrv is not installed.');
$config = [
'persistent' => false,
'host' => 'foo',
'username' => 'Administrator',
'password' => 'blablabla',
@@ -121,7 +120,6 @@ public function testConnectionConfigCustom()
$expected = $config;
$expected['flags'] += [
PDO::ATTR_PERSISTENT => false,
PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::SQLSRV_ATTR_ENCODING => 'a-language'
@@ -159,6 +157,74 @@ public function testConnectionConfigCustom()
$driver->connect();
}
/**
* Test connecting to Sqlserver with persistent set to false
*
* @return void
*/
public function testConnectionPersistentFalse()
{
$this->skipIf($this->missingExtension, 'pdo_sqlsrv is not installed.');
$config = [
'persistent' => false,
'host' => 'foo',
'username' => 'Administrator',
'password' => 'blablabla',
'database' => 'bar',
'encoding' => 'a-language',
];
$driver = $this->getMockBuilder('Cake\Database\Driver\Sqlserver')
->setMethods(['_connect', 'connection'])
->setConstructorArgs([$config])
->getMock();
$dsn = 'sqlsrv:Server=foo;Database=bar;MultipleActiveResultSets=false';
$expected = $config;
$expected['flags'] = [
PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::SQLSRV_ATTR_ENCODING => 'a-language'
];
$expected['attributes'] = [];
$expected['settings'] = [];
$expected['init'] = [];
$expected['app'] = null;
$expected['connectionPooling'] = null;
$expected['failoverPartner'] = null;
$expected['loginTimeout'] = null;
$expected['multiSubnetFailover'] = null;
$driver->expects($this->once())->method('_connect')
->with($dsn, $expected);
$driver->connect();
}
/**
* Test if attempting to connect with the driver throws an exception when
* using an invalid config setting.
*
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage Config setting "persistent" cannot be set to true, as the Sqlserver PDO driver does not support PDO::ATTR_PERSISTENT
* @return void
*/
public function testConnectionPersistentTrueException()
{
$this->skipIf($this->missingExtension, 'pdo_sqlsrv is not installed.');
$config = [
'persistent' => true,
'host' => 'foo',
'username' => 'Administrator',
'password' => 'blablabla',
'database' => 'bar',
];
$driver = $this->getMockBuilder('Cake\Database\Driver\Sqlserver')
->setMethods(['_connect', 'connection'])
->setConstructorArgs([$config])
->getMock();
$driver->connect();
}
/**
* Test select with limit only and SQLServer2012+
*

0 comments on commit 43959d9

Please sign in to comment.
You can’t perform that action at this time.