Sqlserver.php 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. <?php
  2. /**
  3. * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
  4. * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  5. *
  6. * Licensed under The MIT License
  7. * For full copyright and license information, please see the LICENSE.txt
  8. * Redistributions of files must retain the above copyright notice.
  9. *
  10. * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  11. * @link https://cakephp.org CakePHP(tm) Project
  12. * @since 3.0.0
  13. * @license https://opensource.org/licenses/mit-license.php MIT License
  14. */
  15. namespace Cake\Database\Driver;
  16. use Cake\Database\Dialect\SqlserverDialectTrait;
  17. use Cake\Database\Driver;
  18. use Cake\Database\Query;
  19. use Cake\Database\Statement\SqlserverStatement;
  20. use PDO;
  21. /**
  22. * SQLServer driver.
  23. */
  24. class Sqlserver extends Driver
  25. {
  26. use SqlserverDialectTrait;
  27. /**
  28. * Base configuration settings for Sqlserver driver
  29. *
  30. * @var array
  31. */
  32. protected $_baseConfig = [
  33. 'host' => 'localhost\SQLEXPRESS',
  34. 'username' => '',
  35. 'password' => '',
  36. 'database' => 'cake',
  37. 'port' => '',
  38. // PDO::SQLSRV_ENCODING_UTF8
  39. 'encoding' => 65001,
  40. 'flags' => [],
  41. 'init' => [],
  42. 'settings' => [],
  43. 'attributes' => [],
  44. 'app' => null,
  45. 'connectionPooling' => null,
  46. 'failoverPartner' => null,
  47. 'loginTimeout' => null,
  48. 'multiSubnetFailover' => null,
  49. ];
  50. /**
  51. * Establishes a connection to the database server.
  52. *
  53. * Please note that the PDO::ATTR_PERSISTENT attribute is not supported by
  54. * the SQL Server PHP PDO drivers. As a result you cannot use the
  55. * persistent config option when connecting to a SQL Server (for more
  56. * information see: https://github.com/Microsoft/msphpsql/issues/65).
  57. *
  58. * @throws \InvalidArgumentException if an unsupported setting is in the driver config
  59. * @return bool true on success
  60. */
  61. public function connect()
  62. {
  63. if ($this->_connection) {
  64. return true;
  65. }
  66. $config = $this->_config;
  67. if (isset($config['persistent']) && $config['persistent']) {
  68. throw new \InvalidArgumentException('Config setting "persistent" cannot be set to true, as the Sqlserver PDO driver does not support PDO::ATTR_PERSISTENT');
  69. }
  70. $config['flags'] += [
  71. PDO::ATTR_EMULATE_PREPARES => false,
  72. PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
  73. ];
  74. if (!empty($config['encoding'])) {
  75. $config['flags'][PDO::SQLSRV_ATTR_ENCODING] = $config['encoding'];
  76. }
  77. $port = '';
  78. if (strlen($config['port'])) {
  79. $port = ',' . $config['port'];
  80. }
  81. $dsn = "sqlsrv:Server={$config['host']}{$port};Database={$config['database']};MultipleActiveResultSets=false";
  82. if ($config['app'] !== null) {
  83. $dsn .= ";APP={$config['app']}";
  84. }
  85. if ($config['connectionPooling'] !== null) {
  86. $dsn .= ";ConnectionPooling={$config['connectionPooling']}";
  87. }
  88. if ($config['failoverPartner'] !== null) {
  89. $dsn .= ";Failover_Partner={$config['failoverPartner']}";
  90. }
  91. if ($config['loginTimeout'] !== null) {
  92. $dsn .= ";LoginTimeout={$config['loginTimeout']}";
  93. }
  94. if ($config['multiSubnetFailover'] !== null) {
  95. $dsn .= ";MultiSubnetFailover={$config['multiSubnetFailover']}";
  96. }
  97. $this->_connect($dsn, $config);
  98. $connection = $this->getConnection();
  99. if (!empty($config['init'])) {
  100. foreach ((array)$config['init'] as $command) {
  101. $connection->exec($command);
  102. }
  103. }
  104. if (!empty($config['settings']) && is_array($config['settings'])) {
  105. foreach ($config['settings'] as $key => $value) {
  106. $connection->exec("SET {$key} {$value}");
  107. }
  108. }
  109. if (!empty($config['attributes']) && is_array($config['attributes'])) {
  110. foreach ($config['attributes'] as $key => $value) {
  111. $connection->setAttribute($key, $value);
  112. }
  113. }
  114. return true;
  115. }
  116. /**
  117. * Returns whether PHP is able to use this driver for connecting to database
  118. *
  119. * @return bool true if it is valid to use this driver
  120. */
  121. public function enabled()
  122. {
  123. return in_array('sqlsrv', PDO::getAvailableDrivers());
  124. }
  125. /**
  126. * Prepares a sql statement to be executed
  127. *
  128. * @param string|\Cake\Database\Query $query The query to prepare.
  129. * @return \Cake\Database\StatementInterface
  130. */
  131. public function prepare($query)
  132. {
  133. $this->connect();
  134. $options = [PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL];
  135. $isObject = $query instanceof Query;
  136. if ($isObject && $query->isBufferedResultsEnabled() === false) {
  137. $options = [];
  138. }
  139. $statement = $this->_connection->prepare($isObject ? $query->sql() : $query, $options);
  140. return new SqlserverStatement($statement, $this);
  141. }
  142. /**
  143. * {@inheritDoc}
  144. */
  145. public function supportsDynamicConstraints()
  146. {
  147. return true;
  148. }
  149. }