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