1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Jpina\PdoOci8; |
4
|
|
|
|
5
|
|
|
use Jpina\Oci8\Oci8Connection; |
6
|
|
|
use Jpina\Oci8\Oci8ConnectionInterface; |
7
|
|
|
use Jpina\Oci8\Oci8Exception; |
8
|
|
|
use Jpina\Oci8\Oci8PersistentConnection; |
9
|
|
|
use Jpina\Oci8\Oci8StatementInterface; |
10
|
|
|
|
11
|
|
|
/** |
12
|
|
|
* Custom PDO_OCI implementation via OCI8 driver |
13
|
|
|
* |
14
|
|
|
* @see http://php.net/manual/en/class.pdo.php |
15
|
|
|
*/ |
16
|
|
|
class PdoOci8 extends \PDO |
17
|
|
|
{ |
18
|
|
|
const OCI_ATTR_SESSION_MODE = 8000; |
19
|
|
|
|
20
|
|
|
const OCI_ATTR_RETURN_LOBS = 8001; |
21
|
|
|
|
22
|
|
|
/** |
23
|
|
|
* @var Oci8ConnectionInterface |
24
|
|
|
*/ |
25
|
|
|
protected $connection; |
26
|
|
|
|
27
|
|
|
/** |
28
|
|
|
* @var bool |
29
|
|
|
*/ |
30
|
|
|
private $autoCommitMode = false; |
31
|
|
|
|
32
|
|
|
/** @var bool */ |
33
|
|
|
private $isTransactionStarted = false; |
34
|
|
|
|
35
|
|
|
/** |
36
|
|
|
* @var array |
37
|
|
|
*/ |
38
|
|
|
protected $options = array(); |
39
|
|
|
|
40
|
|
|
// TODO Receive Oci8ConnectionInterface? |
41
|
14 |
|
public function __construct($dsn, $username = '', $password = '', $options = array()) |
42
|
|
|
{ |
43
|
14 |
|
$this->options = array( |
44
|
14 |
|
\PDO::ATTR_AUTOCOMMIT => true, |
45
|
14 |
|
\PDO::ATTR_CASE => \PDO::CASE_NATURAL, |
46
|
14 |
|
\PDO::ATTR_CLIENT_VERSION => '', |
47
|
14 |
|
\PDO::ATTR_CONNECTION_STATUS => '', |
48
|
14 |
|
\PDO::ATTR_DRIVER_NAME => 'oci', |
49
|
14 |
|
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_SILENT, |
50
|
14 |
|
\PDO::ATTR_ORACLE_NULLS => \PDO::NULL_NATURAL, |
51
|
14 |
|
\PDO::ATTR_PERSISTENT => false, |
52
|
14 |
|
\PDO::ATTR_PREFETCH => 100, |
53
|
14 |
|
\PDO::ATTR_SERVER_INFO => '', |
54
|
14 |
|
\PDO::ATTR_SERVER_VERSION => '', |
55
|
14 |
|
\PDO::ATTR_TIMEOUT => 600, |
56
|
14 |
|
\PDO::ATTR_STRINGIFY_FETCHES => false, |
57
|
14 |
|
\PDO::ATTR_STATEMENT_CLASS => null, |
58
|
14 |
|
\PDO::ATTR_EMULATE_PREPARES => false, |
59
|
14 |
|
\PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_BOTH, |
60
|
14 |
|
static::OCI_ATTR_SESSION_MODE => OCI_DEFAULT, |
61
|
14 |
|
static::OCI_ATTR_RETURN_LOBS => false, |
62
|
|
|
); |
63
|
|
|
|
64
|
14 |
View Code Duplication |
foreach ($options as $option => $value) { |
|
|
|
|
65
|
4 |
|
if (array_key_exists($option, $this->options)) { |
66
|
4 |
|
$this->options[$option] = $value; |
67
|
4 |
|
} |
68
|
14 |
|
} |
69
|
|
|
|
70
|
14 |
|
foreach ($options as $attribute => $value) { |
71
|
4 |
|
$this->setAttribute($attribute, $value); |
72
|
14 |
|
} |
73
|
|
|
|
74
|
14 |
|
$connection = $this->getOracleConnection($dsn, $username, $password); |
75
|
12 |
|
$this->setAttribute(\PDO::ATTR_CLIENT_VERSION, $connection->getClientVersion()); |
76
|
12 |
|
$this->setAttribute(\PDO::ATTR_SERVER_VERSION, $connection->getServerVersion()); |
77
|
|
|
|
78
|
12 |
|
$autocommitMode = $this->getAttribute(\PDO::ATTR_AUTOCOMMIT); |
79
|
12 |
|
$this->setAutocommitMode($autocommitMode); |
80
|
12 |
|
if ($this->getAttribute(\PDO::ATTR_AUTOCOMMIT) === false) { |
81
|
1 |
|
$this->beginTransaction(); |
82
|
1 |
|
} |
83
|
|
|
|
84
|
12 |
|
$this->connection = $connection; |
85
|
12 |
|
} |
86
|
|
|
|
87
|
|
|
/** |
88
|
|
|
* @return bool |
89
|
|
|
*/ |
90
|
3 |
|
protected function getAutocommitMode() |
91
|
|
|
{ |
92
|
3 |
|
return $this->autoCommitMode; |
93
|
|
|
} |
94
|
|
|
|
95
|
|
|
/** |
96
|
|
|
* @param string $dsn |
97
|
|
|
* @return string |
98
|
|
|
*/ |
99
|
13 |
|
protected function getCharset($dsn) |
100
|
|
|
{ |
101
|
13 |
|
$connectionStringItems = $this->getConnectionStringItems($dsn); |
102
|
|
|
|
103
|
13 |
|
return $connectionStringItems['charset']; |
104
|
|
|
} |
105
|
|
|
|
106
|
|
|
/** |
107
|
|
|
* @return Oci8ConnectionInterface |
108
|
|
|
*/ |
109
|
43 |
|
protected function getConnection() |
110
|
|
|
{ |
111
|
43 |
|
return $this->connection; |
112
|
|
|
} |
113
|
|
|
|
114
|
|
|
/** |
115
|
|
|
* @param string $dsn |
116
|
|
|
* @param string $username |
117
|
|
|
* @param string $password |
118
|
|
|
* @return Oci8ConnectionInterface |
119
|
|
|
*/ |
120
|
14 |
|
protected function getOracleConnection($dsn, $username = null, $password = null) |
121
|
|
|
{ |
122
|
14 |
|
$connectionString = $this->getConnectionString($dsn); |
123
|
13 |
|
$charset = $this->getCharset($dsn); |
124
|
13 |
|
$sessionMode = $this->getAttribute(static::OCI_ATTR_SESSION_MODE); |
125
|
|
|
|
126
|
13 |
|
$connection = null; |
127
|
|
|
try { |
128
|
13 |
|
if ($this->getAttribute(\PDO::ATTR_PERSISTENT)) { |
129
|
1 |
|
$connection = new Oci8PersistentConnection( |
130
|
1 |
|
$username, |
131
|
1 |
|
$password, |
132
|
1 |
|
$connectionString, |
133
|
1 |
|
$charset, |
134
|
|
|
$sessionMode |
135
|
1 |
|
); |
136
|
1 |
|
} else { |
137
|
12 |
|
$connection = new Oci8Connection( |
138
|
12 |
|
$username, |
139
|
12 |
|
$password, |
140
|
12 |
|
$connectionString, |
141
|
12 |
|
$charset, |
142
|
|
|
$sessionMode |
143
|
12 |
|
); |
144
|
|
|
} |
145
|
13 |
|
} catch (Oci8Exception $ex) { |
146
|
1 |
|
throw new PdoOci8Exception($ex->getMessage(), $ex->getCode(), $ex); |
147
|
|
|
} |
148
|
|
|
|
149
|
12 |
|
return $connection; |
150
|
|
|
} |
151
|
|
|
|
152
|
|
|
/** |
153
|
|
|
* @param string $dsn |
154
|
|
|
* @return string |
155
|
|
|
*/ |
156
|
14 |
|
protected function getConnectionString($dsn) |
157
|
|
|
{ |
158
|
14 |
|
$connectionStringItems = $this->getConnectionStringItems($dsn); |
159
|
13 |
|
$hostname = $connectionStringItems['hostname']; |
160
|
13 |
|
$port = $connectionStringItems['port']; |
161
|
13 |
|
$database = $connectionStringItems['database']; |
162
|
13 |
|
$connectionString = "//{$hostname}:{$port}/{$database}"; |
163
|
|
|
|
164
|
13 |
|
return $connectionString; |
165
|
|
|
} |
166
|
|
|
|
167
|
|
|
/** |
168
|
|
|
* @param string $dsn |
169
|
|
|
* @return array |
170
|
|
|
*/ |
171
|
14 |
|
protected function getConnectionStringItems($dsn) |
172
|
|
|
{ |
173
|
14 |
|
$dsnRegex = $this->getDsnRegex(); |
174
|
14 |
|
$matches = array(); |
175
|
14 |
|
if (preg_match("/^{$dsnRegex}$/i", $dsn, $matches) !== 1) { |
176
|
1 |
|
throw new PdoOci8Exception('Invalid DSN'); |
177
|
|
|
} |
178
|
|
|
|
179
|
|
|
// TODO Remove the variables below |
180
|
13 |
|
$hostname = 'localhost'; |
181
|
13 |
|
$port = 1521; |
182
|
13 |
|
$database = null; |
|
|
|
|
183
|
13 |
|
$charset = 'AL32UTF8'; |
184
|
|
|
|
185
|
13 |
|
switch (count($matches)) { |
186
|
13 |
|
case 16: |
187
|
11 |
|
$charset = empty($matches[15]) ? $charset : $matches[15]; |
188
|
|
|
// fall through next case to get the rest of the variables |
189
|
13 |
|
case 14: |
190
|
13 |
|
$port = empty($matches[12]) ? $port : (int)$matches[12]; |
191
|
13 |
|
$hostname = $matches[4]; |
192
|
13 |
|
$database = $matches[13]; |
193
|
13 |
|
break; |
194
|
|
|
default: |
195
|
|
|
$database = $matches[1]; |
196
|
13 |
|
} |
197
|
|
|
|
198
|
|
|
return array( |
199
|
13 |
|
'hostname' => $hostname, |
200
|
13 |
|
'port' => $port, |
201
|
13 |
|
'database' => $database, |
202
|
13 |
|
'charset' => $charset, |
203
|
13 |
|
); |
204
|
|
|
} |
205
|
|
|
|
206
|
|
|
/** |
207
|
|
|
* @return string |
208
|
|
|
*/ |
209
|
14 |
|
protected function getDsnRegex() |
210
|
|
|
{ |
211
|
14 |
|
$hostnameRegrex = "(([a-z]|[a-z][a-z0-9\-_]*[a-z0-9])\.)*([a-z]|[a-z][a-z0-9\-_]*[a-z0-9])"; |
212
|
|
|
$validIpAddressRegex = "(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}" . |
213
|
14 |
|
"([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])"; |
214
|
14 |
|
$hostnameOrIpAddressRegrex = "\/\/({$hostnameRegrex}|{$validIpAddressRegex})"; |
215
|
14 |
|
$databaseRegex = "([a-z_][a-z\-_\d]*)|({$hostnameOrIpAddressRegrex}(:(\d+))?\/([a-z_][a-z\-_\d]*))"; |
216
|
14 |
|
$charsetRegex = "(charset=([a-z\d\-_]+))?"; |
217
|
14 |
|
$dsnRegex = "oci\:database=({$databaseRegex});?{$charsetRegex}"; |
218
|
|
|
|
219
|
14 |
|
return $dsnRegex; |
220
|
|
|
} |
221
|
|
|
|
222
|
|
|
/** |
223
|
|
|
* @param array $overrideOptions |
224
|
|
|
* @return array |
225
|
|
|
*/ |
226
|
38 |
|
protected function getOptions($overrideOptions = array()) |
227
|
|
|
{ |
228
|
38 |
|
$options = array_merge($this->options, $overrideOptions); |
229
|
|
|
|
230
|
38 |
|
return $options; |
231
|
|
|
} |
232
|
|
|
|
233
|
|
|
/** |
234
|
|
|
* @link http://php.net/manual/en/pdo.begintransaction.php |
235
|
|
|
* @return bool |
236
|
|
|
*/ |
237
|
5 |
|
public function beginTransaction() |
238
|
|
|
{ |
239
|
5 |
|
if ($this->inTransaction()) { |
240
|
2 |
|
return false; |
241
|
|
|
} |
242
|
|
|
|
243
|
5 |
|
$this->setAttribute(\PDO::ATTR_AUTOCOMMIT, false); |
244
|
5 |
|
$this->isTransactionStarted = true; |
245
|
|
|
|
246
|
5 |
|
return true; |
247
|
|
|
} |
248
|
|
|
|
249
|
|
|
/** |
250
|
|
|
* @link http://php.net/manual/en/pdo.commit.php |
251
|
|
|
* @return bool |
252
|
|
|
*/ |
253
|
1 |
|
public function commit() |
254
|
|
|
{ |
255
|
|
|
try { |
256
|
1 |
|
$isSuccess = $this->getConnection()->commit(); |
257
|
1 |
|
} catch (Oci8Exception $ex) { |
258
|
|
|
$isSuccess = false; |
259
|
|
|
} |
260
|
|
|
|
261
|
1 |
|
$this->restoreAutocommitMode(); |
262
|
|
|
|
263
|
1 |
|
return $isSuccess; |
264
|
|
|
} |
265
|
|
|
|
266
|
|
|
/** |
267
|
|
|
* @link http://php.net/manual/en/pdo.errorcode.php |
268
|
|
|
* @return null|string |
269
|
|
|
*/ |
270
|
1 |
View Code Duplication |
public function errorCode() |
|
|
|
|
271
|
|
|
{ |
272
|
1 |
|
$connection = $this->getConnection(); |
273
|
1 |
|
$driverError = $connection->getError(); |
274
|
1 |
|
if (!$driverError) { |
275
|
1 |
|
return null; |
276
|
|
|
} |
277
|
|
|
|
278
|
|
|
$error = $this->errorInfo(); |
279
|
|
|
$sqlStateErrorCode = $error[0]; |
280
|
|
|
|
281
|
|
|
return $sqlStateErrorCode; |
282
|
|
|
} |
283
|
|
|
|
284
|
|
|
/** |
285
|
|
|
* @link http://php.net/manual/en/pdo.errorinfo.php |
286
|
|
|
* @return array |
287
|
|
|
*/ |
288
|
1 |
|
public function errorInfo() |
289
|
|
|
{ |
290
|
1 |
|
$error = $this->getConnection()->getError(); |
291
|
1 |
|
if (is_array($error)) { |
292
|
|
|
$errorInfo = array( |
293
|
|
|
OracleSqlStateCode::getSqlStateErrorCode((int)$error['code']), |
294
|
|
|
$error['message'], |
295
|
|
|
$error['code'] |
296
|
|
|
); |
297
|
|
|
} else { |
298
|
|
|
$errorInfo = array( |
299
|
1 |
|
'00000', |
300
|
1 |
|
null, |
301
|
|
|
null |
302
|
1 |
|
); |
303
|
|
|
} |
304
|
|
|
|
305
|
1 |
|
return $errorInfo; |
306
|
|
|
} |
307
|
|
|
|
308
|
|
|
/** |
309
|
|
|
* @param string $statement |
310
|
|
|
* |
311
|
|
|
* @link http://php.net/manual/en/pdo.exec.php |
312
|
|
|
* @return bool|int |
313
|
|
|
*/ |
314
|
4 |
|
public function exec($statement) |
315
|
|
|
{ |
316
|
4 |
|
$statement = $this->prepare($statement); |
317
|
4 |
|
$type = $this->getStatementType($statement); |
|
|
|
|
318
|
4 |
|
if ($type === 'SELECT') { |
319
|
1 |
|
return false; |
|
|
|
|
320
|
|
|
} |
321
|
3 |
|
$statement->execute(); |
322
|
|
|
|
323
|
3 |
|
return $statement->rowCount(); |
324
|
|
|
} |
325
|
|
|
|
326
|
|
|
/** |
327
|
|
|
* @param PdoOci8Statement $statement |
328
|
|
|
* @return string |
329
|
|
|
*/ |
330
|
4 |
|
protected function getStatementType($statement) |
331
|
|
|
{ |
332
|
4 |
|
$class = new \ReflectionClass($statement); |
333
|
4 |
|
$property = $class->getProperty('statement'); |
334
|
4 |
|
$property->setAccessible(true); |
335
|
|
|
/** @var Oci8StatementInterface $rawStatement */ |
336
|
4 |
|
$oci8Statement = $property->getValue($statement); |
337
|
4 |
|
$type = $oci8Statement->getType(); |
338
|
|
|
|
339
|
4 |
|
return $type; |
340
|
|
|
} |
341
|
|
|
|
342
|
|
|
/** |
343
|
|
|
* @param int $attribute |
344
|
|
|
* |
345
|
|
|
* @link http://php.net/manual/en/pdo.getattribute.php |
346
|
|
|
* @return mixed |
347
|
|
|
*/ |
348
|
13 |
|
public function getAttribute($attribute) |
349
|
|
|
{ |
350
|
13 |
|
if (array_key_exists($attribute, $this->options)) { |
351
|
13 |
|
return $this->options[$attribute]; |
352
|
|
|
} |
353
|
|
|
|
354
|
|
|
return null; |
355
|
|
|
} |
356
|
|
|
|
357
|
|
|
/** |
358
|
|
|
* @link http://php.net/manual/en/pdo.getavailabledrivers.php |
359
|
|
|
* @return array |
360
|
|
|
*/ |
361
|
1 |
|
public static function getAvailableDrivers() |
362
|
|
|
{ |
363
|
1 |
|
return array('oci'); |
364
|
|
|
} |
365
|
|
|
|
366
|
|
|
/** |
367
|
|
|
* @link http://php.net/manual/en/pdo.intransaction.php |
368
|
|
|
* @return bool |
369
|
|
|
*/ |
370
|
6 |
|
public function inTransaction() |
371
|
|
|
{ |
372
|
6 |
|
return $this->isTransactionStarted; |
373
|
|
|
} |
374
|
|
|
|
375
|
|
|
/** |
376
|
|
|
* @param string $name |
377
|
|
|
* |
378
|
|
|
* @link http://php.net/manual/en/pdo.lastinsertid.php |
379
|
|
|
* @return string |
380
|
|
|
*/ |
381
|
|
|
public function lastInsertId($name = null) |
382
|
|
|
{ |
383
|
|
|
$statement = $this->query("select {$name}.currval from dual"); |
384
|
|
|
$lastInsertedId = $statement->fetch(); |
385
|
|
|
|
386
|
|
|
return $lastInsertedId; |
387
|
|
|
} |
388
|
|
|
|
389
|
|
|
/** |
390
|
|
|
* @param string $statement |
391
|
|
|
* @param array $driver_options |
392
|
|
|
* |
393
|
|
|
* @link http://php.net/manual/en/pdo.prepare.php |
394
|
|
|
* @return bool|PdoOci8Statement |
395
|
|
|
*/ |
396
|
38 |
|
public function prepare($statement, $driver_options = array()) |
397
|
|
|
{ |
398
|
|
|
// TODO Use $driver_options, eg. configure a cursor |
399
|
38 |
|
$exception = null; |
|
|
|
|
400
|
|
|
try { |
401
|
38 |
|
$options = $this->getOptions($driver_options); |
402
|
38 |
|
return new PdoOci8Statement($this->getConnection(), $statement, $options); |
|
|
|
|
403
|
|
|
} catch (\Exception $ex) { |
404
|
|
|
$exception = new PdoOci8Exception($ex->getMessage(), $ex->getCode(), $ex); |
405
|
|
|
} |
406
|
|
|
|
407
|
|
|
// TODO Create error handler |
408
|
|
|
$errorMode = $this->getAttribute(\PDO::ATTR_ERRMODE); |
409
|
|
|
switch ($errorMode) { |
410
|
|
|
case \PDO::ERRMODE_EXCEPTION: |
411
|
|
|
throw $exception; |
412
|
|
|
case \PDO::ERRMODE_WARNING: |
413
|
|
|
trigger_error($exception->getMessage(), E_WARNING); |
414
|
|
|
break; |
415
|
|
|
case \PDO::ERRMODE_SILENT: |
416
|
|
|
default: |
417
|
|
|
} |
418
|
|
|
|
419
|
|
|
return false; |
|
|
|
|
420
|
|
|
} |
421
|
|
|
|
422
|
|
|
/** |
423
|
|
|
* @param string $statement |
424
|
|
|
* @param int $mode |
425
|
|
|
* @param int|string|object $arg3 |
426
|
|
|
* @param array $ctorargs |
427
|
|
|
* |
428
|
|
|
* @link http://php.net/manual/en/pdo.query.php |
429
|
|
|
* @return bool|PdoOci8Statement |
430
|
|
|
*/ |
431
|
3 |
|
public function query($statement, $mode = \PDO::ATTR_DEFAULT_FETCH_MODE, $arg3 = null, $ctorargs = array()) |
432
|
|
|
{ |
433
|
3 |
|
$result = false; |
434
|
|
|
try { |
435
|
3 |
|
$statement = $this->prepare($statement); |
436
|
|
|
switch ($mode) { |
437
|
3 |
|
case \PDO::FETCH_CLASS: |
438
|
|
|
$statement->setFetchMode($mode, $arg3, $ctorargs); |
439
|
|
|
break; |
440
|
3 |
|
case \PDO::FETCH_INTO: |
441
|
|
|
$statement->setFetchMode($mode, $arg3); |
442
|
|
|
break; |
443
|
3 |
|
case \PDO::FETCH_COLUMN: |
444
|
3 |
|
default: |
445
|
3 |
|
$statement->setFetchMode($mode); |
446
|
3 |
|
} |
447
|
3 |
|
$statement->execute(); |
448
|
3 |
|
$result = $statement; |
449
|
3 |
|
} catch (\PDOException $ex) { |
450
|
|
|
//TODO Handle Exception |
451
|
|
|
} |
452
|
|
|
|
453
|
3 |
|
return $result; |
|
|
|
|
454
|
|
|
} |
455
|
|
|
|
456
|
|
|
/** |
457
|
|
|
* @param string $string |
458
|
|
|
* @param int $parameter_type |
459
|
|
|
* |
460
|
|
|
* @link http://php.net/manual/en/pdo.quote.php |
461
|
|
|
* @return bool|string |
462
|
|
|
*/ |
463
|
5 |
|
public function quote($string, $parameter_type = \PDO::PARAM_STR) |
464
|
|
|
{ |
465
|
5 |
|
if (!is_scalar($string)) { |
466
|
1 |
|
return false; |
|
|
|
|
467
|
|
|
} |
468
|
|
|
|
469
|
|
|
try { |
470
|
4 |
|
if ($parameter_type !== \PDO::PARAM_STR) { |
471
|
1 |
|
$quotedString = (string)$string; |
472
|
1 |
|
$quotedString = "'" . $quotedString . "'"; |
473
|
1 |
|
return $quotedString; |
474
|
|
|
} |
475
|
4 |
|
} catch (\Exception $ex) { |
|
|
|
|
476
|
|
|
return false; |
477
|
|
|
} |
478
|
|
|
|
479
|
4 |
|
$quotedString = str_replace("\'", "'", $string); |
480
|
4 |
|
$quotedString = str_replace("'", "''", $quotedString); |
481
|
4 |
|
$quotedString = "'" . $quotedString . "'"; |
482
|
|
|
|
483
|
4 |
|
return $quotedString; |
484
|
|
|
} |
485
|
|
|
|
486
|
3 |
|
protected function restoreAutocommitMode() |
487
|
|
|
{ |
488
|
3 |
|
$autocommitMode = $this->getAutocommitMode(); |
489
|
3 |
|
$this->setAttribute(\PDO::ATTR_AUTOCOMMIT, $autocommitMode); |
490
|
3 |
|
} |
491
|
|
|
|
492
|
|
|
/** |
493
|
|
|
* @link http://php.net/manual/en/pdo.rollback.php |
494
|
|
|
* @return bool |
495
|
|
|
*/ |
496
|
3 |
|
public function rollback() |
497
|
|
|
{ |
498
|
3 |
|
if (!$this->inTransaction()) { |
499
|
1 |
|
throw new PdoOci8Exception('There is no active transaction'); |
500
|
|
|
} |
501
|
|
|
|
502
|
|
|
try { |
503
|
2 |
|
$isSuccess = $this->getConnection()->rollback(); |
504
|
2 |
|
} catch (Oci8Exception $ex) { |
505
|
|
|
$isSuccess = false; |
506
|
|
|
} |
507
|
|
|
|
508
|
2 |
|
$this->restoreAutocommitMode(); |
509
|
|
|
|
510
|
2 |
|
return $isSuccess; |
511
|
|
|
} |
512
|
|
|
|
513
|
|
|
/** |
514
|
|
|
* @param bool $onOff |
515
|
|
|
*/ |
516
|
12 |
|
protected function setAutocommitMode($onOff) |
517
|
|
|
{ |
518
|
12 |
|
$this->autoCommitMode = $onOff; |
519
|
12 |
|
} |
520
|
|
|
|
521
|
|
|
/** |
522
|
|
|
* @param int $attribute |
523
|
|
|
* @param mixed $value |
524
|
|
|
* |
525
|
|
|
* @link http://php.net/manual/en/pdo.setattribute.php |
526
|
|
|
* @return bool |
527
|
|
|
*/ |
528
|
12 |
|
public function setAttribute($attribute, $value) |
529
|
|
|
{ |
530
|
|
|
$readOnlyAttributes = array( |
531
|
12 |
|
\PDO::ATTR_CLIENT_VERSION, |
532
|
12 |
|
\PDO::ATTR_CONNECTION_STATUS, |
533
|
12 |
|
\PDO::ATTR_DRIVER_NAME, |
534
|
12 |
|
\PDO::ATTR_PERSISTENT, |
535
|
12 |
|
\PDO::ATTR_SERVER_INFO, |
536
|
12 |
|
\PDO::ATTR_SERVER_VERSION, |
537
|
12 |
|
); |
538
|
|
|
|
539
|
12 |
View Code Duplication |
if (array_search($attribute, $readOnlyAttributes) !== false || |
|
|
|
|
540
|
12 |
|
!array_key_exists($attribute, $this->options)) { |
541
|
12 |
|
return false; |
542
|
|
|
} |
543
|
|
|
|
544
|
6 |
|
$this->options[$attribute] = $value; |
545
|
|
|
|
546
|
6 |
|
return true; |
547
|
|
|
} |
548
|
|
|
} |
549
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.