OCI8Connection.php 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. <?php
  2. namespace Doctrine\DBAL\Driver\OCI8;
  3. use Doctrine\DBAL\Driver\Connection as ConnectionInterface;
  4. use Doctrine\DBAL\Driver\OCI8\Exception\SequenceDoesNotExist;
  5. use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
  6. use Doctrine\DBAL\ParameterType;
  7. use Doctrine\Deprecations\Deprecation;
  8. use UnexpectedValueException;
  9. use function addcslashes;
  10. use function func_get_args;
  11. use function is_float;
  12. use function is_int;
  13. use function oci_commit;
  14. use function oci_connect;
  15. use function oci_error;
  16. use function oci_pconnect;
  17. use function oci_rollback;
  18. use function oci_server_version;
  19. use function preg_match;
  20. use function sprintf;
  21. use function str_replace;
  22. use const OCI_COMMIT_ON_SUCCESS;
  23. use const OCI_NO_AUTO_COMMIT;
  24. /**
  25. * OCI8 implementation of the Connection interface.
  26. *
  27. * @deprecated Use {@link Connection} instead
  28. */
  29. class OCI8Connection implements ConnectionInterface, ServerInfoAwareConnection
  30. {
  31. /** @var resource */
  32. protected $dbh;
  33. /** @var int */
  34. protected $executeMode = OCI_COMMIT_ON_SUCCESS;
  35. /**
  36. * Creates a Connection to an Oracle Database using oci8 extension.
  37. *
  38. * @internal The connection can be only instantiated by its driver.
  39. *
  40. * @param string $username
  41. * @param string $password
  42. * @param string $db
  43. * @param string $charset
  44. * @param int $sessionMode
  45. * @param bool $persistent
  46. *
  47. * @throws OCI8Exception
  48. */
  49. public function __construct(
  50. $username,
  51. $password,
  52. $db,
  53. $charset = '',
  54. $sessionMode = OCI_NO_AUTO_COMMIT,
  55. $persistent = false
  56. ) {
  57. $dbh = $persistent
  58. ? @oci_pconnect($username, $password, $db, $charset, $sessionMode)
  59. : @oci_connect($username, $password, $db, $charset, $sessionMode);
  60. if ($dbh === false) {
  61. throw OCI8Exception::fromErrorInfo(oci_error());
  62. }
  63. $this->dbh = $dbh;
  64. }
  65. /**
  66. * {@inheritdoc}
  67. *
  68. * @throws UnexpectedValueException If the version string returned by the database server
  69. * does not contain a parsable version number.
  70. */
  71. public function getServerVersion()
  72. {
  73. $version = oci_server_version($this->dbh);
  74. if ($version === false) {
  75. throw OCI8Exception::fromErrorInfo(oci_error($this->dbh));
  76. }
  77. if (! preg_match('/\s+(\d+\.\d+\.\d+\.\d+\.\d+)\s+/', $version, $matches)) {
  78. throw new UnexpectedValueException(
  79. sprintf(
  80. 'Unexpected database version string "%s". Cannot parse an appropriate version number from it. ' .
  81. 'Please report this database version string to the Doctrine team.',
  82. $version
  83. )
  84. );
  85. }
  86. return $matches[1];
  87. }
  88. /**
  89. * {@inheritdoc}
  90. */
  91. public function requiresQueryForServerVersion()
  92. {
  93. Deprecation::triggerIfCalledFromOutside(
  94. 'doctrine/dbal',
  95. 'https://github.com/doctrine/dbal/pull/4114',
  96. 'ServerInfoAwareConnection::requiresQueryForServerVersion() is deprecated and removed in DBAL 3.'
  97. );
  98. return false;
  99. }
  100. /**
  101. * {@inheritdoc}
  102. */
  103. public function prepare($sql)
  104. {
  105. return new Statement($this->dbh, $sql, $this);
  106. }
  107. /**
  108. * {@inheritdoc}
  109. */
  110. public function query()
  111. {
  112. $args = func_get_args();
  113. $sql = $args[0];
  114. //$fetchMode = $args[1];
  115. $stmt = $this->prepare($sql);
  116. $stmt->execute();
  117. return $stmt;
  118. }
  119. /**
  120. * {@inheritdoc}
  121. */
  122. public function quote($value, $type = ParameterType::STRING)
  123. {
  124. if (is_int($value) || is_float($value)) {
  125. return $value;
  126. }
  127. $value = str_replace("'", "''", $value);
  128. return "'" . addcslashes($value, "\000\n\r\\\032") . "'";
  129. }
  130. /**
  131. * {@inheritdoc}
  132. */
  133. public function exec($sql)
  134. {
  135. $stmt = $this->prepare($sql);
  136. $stmt->execute();
  137. return $stmt->rowCount();
  138. }
  139. /**
  140. * {@inheritdoc}
  141. *
  142. * @param string|null $name
  143. *
  144. * @return int|false
  145. */
  146. public function lastInsertId($name = null)
  147. {
  148. if ($name === null) {
  149. return false;
  150. }
  151. $sql = 'SELECT ' . $name . '.CURRVAL FROM DUAL';
  152. $stmt = $this->query($sql);
  153. $result = $stmt->fetchColumn();
  154. if ($result === false) {
  155. throw SequenceDoesNotExist::new();
  156. }
  157. return (int) $result;
  158. }
  159. /**
  160. * Returns the current execution mode.
  161. *
  162. * @internal
  163. *
  164. * @return int
  165. */
  166. public function getExecuteMode()
  167. {
  168. return $this->executeMode;
  169. }
  170. /**
  171. * {@inheritdoc}
  172. */
  173. public function beginTransaction()
  174. {
  175. $this->executeMode = OCI_NO_AUTO_COMMIT;
  176. return true;
  177. }
  178. /**
  179. * {@inheritdoc}
  180. */
  181. public function commit()
  182. {
  183. if (! oci_commit($this->dbh)) {
  184. throw OCI8Exception::fromErrorInfo($this->errorInfo());
  185. }
  186. $this->executeMode = OCI_COMMIT_ON_SUCCESS;
  187. return true;
  188. }
  189. /**
  190. * {@inheritdoc}
  191. */
  192. public function rollBack()
  193. {
  194. if (! oci_rollback($this->dbh)) {
  195. throw OCI8Exception::fromErrorInfo($this->errorInfo());
  196. }
  197. $this->executeMode = OCI_COMMIT_ON_SUCCESS;
  198. return true;
  199. }
  200. /**
  201. * {@inheritdoc}
  202. *
  203. * @deprecated The error information is available via exceptions.
  204. */
  205. public function errorCode()
  206. {
  207. $error = oci_error($this->dbh);
  208. if ($error !== false) {
  209. return $error['code'];
  210. }
  211. return null;
  212. }
  213. /**
  214. * {@inheritdoc}
  215. *
  216. * @deprecated The error information is available via exceptions.
  217. */
  218. public function errorInfo()
  219. {
  220. $error = oci_error($this->dbh);
  221. if ($error === false) {
  222. return [];
  223. }
  224. return $error;
  225. }
  226. }