SQLAnywhereConnection.php 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. <?php
  2. namespace Doctrine\DBAL\Driver\SQLAnywhere;
  3. use Doctrine\DBAL\Driver\Connection;
  4. use Doctrine\DBAL\Driver\Result;
  5. use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
  6. use Doctrine\DBAL\ParameterType;
  7. use Doctrine\Deprecations\Deprecation;
  8. use function assert;
  9. use function func_get_args;
  10. use function is_float;
  11. use function is_int;
  12. use function is_resource;
  13. use function is_string;
  14. use function sasql_affected_rows;
  15. use function sasql_commit;
  16. use function sasql_connect;
  17. use function sasql_error;
  18. use function sasql_errorcode;
  19. use function sasql_escape_string;
  20. use function sasql_insert_id;
  21. use function sasql_pconnect;
  22. use function sasql_real_query;
  23. use function sasql_rollback;
  24. use function sasql_set_option;
  25. /**
  26. * SAP Sybase SQL Anywhere implementation of the Connection interface.
  27. */
  28. class SQLAnywhereConnection implements Connection, ServerInfoAwareConnection
  29. {
  30. /** @var resource The SQL Anywhere connection resource. */
  31. private $connection;
  32. /**
  33. * Connects to database with given connection string.
  34. *
  35. * @internal The connection can be only instantiated by its driver.
  36. *
  37. * @param string $dsn The connection string.
  38. * @param bool $persistent Whether or not to establish a persistent connection.
  39. *
  40. * @throws SQLAnywhereException
  41. */
  42. public function __construct($dsn, $persistent = false)
  43. {
  44. $this->connection = $persistent ? @sasql_pconnect($dsn) : @sasql_connect($dsn);
  45. if (! is_resource($this->connection)) {
  46. throw SQLAnywhereException::fromSQLAnywhereError();
  47. }
  48. // Disable PHP warnings on error.
  49. if (! sasql_set_option($this->connection, 'verbose_errors', false)) {
  50. throw SQLAnywhereException::fromSQLAnywhereError($this->connection);
  51. }
  52. // Enable auto committing by default.
  53. if (! sasql_set_option($this->connection, 'auto_commit', 'on')) {
  54. throw SQLAnywhereException::fromSQLAnywhereError($this->connection);
  55. }
  56. }
  57. /**
  58. * {@inheritdoc}
  59. *
  60. * @throws SQLAnywhereException
  61. */
  62. public function beginTransaction()
  63. {
  64. if (! sasql_set_option($this->connection, 'auto_commit', 'off')) {
  65. throw SQLAnywhereException::fromSQLAnywhereError($this->connection);
  66. }
  67. return true;
  68. }
  69. /**
  70. * {@inheritdoc}
  71. *
  72. * @throws SQLAnywhereException
  73. */
  74. public function commit()
  75. {
  76. if (! sasql_commit($this->connection)) {
  77. throw SQLAnywhereException::fromSQLAnywhereError($this->connection);
  78. }
  79. $this->endTransaction();
  80. return true;
  81. }
  82. /**
  83. * {@inheritdoc}
  84. *
  85. * @deprecated The error information is available via exceptions.
  86. */
  87. public function errorCode()
  88. {
  89. return sasql_errorcode($this->connection);
  90. }
  91. /**
  92. * {@inheritdoc}
  93. *
  94. * @deprecated The error information is available via exceptions.
  95. */
  96. public function errorInfo()
  97. {
  98. return sasql_error($this->connection);
  99. }
  100. /**
  101. * {@inheritdoc}
  102. */
  103. public function exec($sql)
  104. {
  105. if (sasql_real_query($this->connection, $sql) === false) {
  106. throw SQLAnywhereException::fromSQLAnywhereError($this->connection);
  107. }
  108. return sasql_affected_rows($this->connection);
  109. }
  110. /**
  111. * {@inheritdoc}
  112. */
  113. public function getServerVersion()
  114. {
  115. $stmt = $this->query("SELECT PROPERTY('ProductVersion')");
  116. if ($stmt instanceof Result) {
  117. $version = $stmt->fetchOne();
  118. } else {
  119. $version = $stmt->fetchColumn();
  120. }
  121. assert(is_string($version));
  122. return $version;
  123. }
  124. /**
  125. * {@inheritdoc}
  126. */
  127. public function lastInsertId($name = null)
  128. {
  129. if ($name === null) {
  130. return sasql_insert_id($this->connection);
  131. }
  132. $stmt = $this->query('SELECT ' . $name . '.CURRVAL');
  133. if ($stmt instanceof Result) {
  134. return $stmt->fetchOne();
  135. }
  136. return $stmt->fetchColumn();
  137. }
  138. /**
  139. * {@inheritdoc}
  140. */
  141. public function prepare($sql)
  142. {
  143. return new SQLAnywhereStatement($this->connection, $sql);
  144. }
  145. /**
  146. * {@inheritdoc}
  147. */
  148. public function query()
  149. {
  150. $args = func_get_args();
  151. $stmt = $this->prepare($args[0]);
  152. $stmt->execute();
  153. return $stmt;
  154. }
  155. /**
  156. * {@inheritdoc}
  157. */
  158. public function quote($value, $type = ParameterType::STRING)
  159. {
  160. if (is_int($value) || is_float($value)) {
  161. return $value;
  162. }
  163. return "'" . sasql_escape_string($this->connection, $value) . "'";
  164. }
  165. /**
  166. * {@inheritdoc}
  167. */
  168. public function requiresQueryForServerVersion()
  169. {
  170. Deprecation::triggerIfCalledFromOutside(
  171. 'doctrine/dbal',
  172. 'https://github.com/doctrine/dbal/pull/4114',
  173. 'ServerInfoAwareConnection::requiresQueryForServerVersion() is deprecated and removed in DBAL 3.'
  174. );
  175. return true;
  176. }
  177. /**
  178. * {@inheritdoc}
  179. *
  180. * @throws SQLAnywhereException
  181. */
  182. public function rollBack()
  183. {
  184. if (! sasql_rollback($this->connection)) {
  185. throw SQLAnywhereException::fromSQLAnywhereError($this->connection);
  186. }
  187. $this->endTransaction();
  188. return true;
  189. }
  190. /**
  191. * Ends transactional mode and enables auto commit again.
  192. *
  193. * @return bool Whether or not ending transactional mode succeeded.
  194. *
  195. * @throws SQLAnywhereException
  196. */
  197. private function endTransaction()
  198. {
  199. if (! sasql_set_option($this->connection, 'auto_commit', 'on')) {
  200. throw SQLAnywhereException::fromSQLAnywhereError($this->connection);
  201. }
  202. return true;
  203. }
  204. }