OCI8Connection.php 5.2 KB

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