forked from sfedosimov/yii2-oci8pdo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Oci8PDO.php
360 lines (318 loc) · 10.1 KB
/
Oci8PDO.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
<?php
/**
* PDO Userspace Driver for Oracle (oci8)
*
* @category Database
* @package Pdo
* @subpackage Oci8
* @author Ben Ramsey <ramsey@php.net>
* @copyright Copyright (c) 2015 Ben Ramsey (http://benramsey.com/)
* @license http://open.benramsey.com/license/mit MIT License
*/
namespace sfedosimov\oci8pdo;
use PDO;
use PDOException;
/**
* Oci8 class to mimic the interface of the PDO class
*
* This class extends PDO but overrides all of its methods. It does this so
* that instanceof checks and type-hinting of existing code will work
* seamlessly.
*/
class Oci8PDO extends PDO
{
/**
* Analog constant OCI_B_CLOB
*
* @const int
*/
const PARAM_CLOB = 112;
/**
* Analog constant OCI_B_BLOB
*
* @const int
*/
const PARAM_BLOB = 113;
/**
* Database handler
*
* @var resource
*/
protected $_dbh;
/**
* Driver options
*
* @var array
*/
protected $_options = array();
/**
* Whether currently in a transaction
*
* @var bool
*/
protected $_isTransaction = false;
/**
* Constructor
*
* @param string $dsn
* @param string $username
* @param null $password
* @param array $options
*
* @internal param string $passwd
* @return Oci8PDO
*/
public function __construct(
$dsn,
$username = null,
$password = null,
$options = array()
) {
$parsedDsn = Oci8PDO_Util::parseDsn($dsn, array('dbname', 'charset'));
if (isset($options[PDO::ATTR_PERSISTENT])
&& $options[PDO::ATTR_PERSISTENT]
) {
$this->_dbh = @oci_pconnect(
$username,
$password,
$parsedDsn['dbname'],
$parsedDsn['charset']);
} else {
$this->_dbh = @oci_connect(
$username,
$password,
$parsedDsn['dbname'],
$parsedDsn['charset']);
}
if (!$this->_dbh) {
$e = oci_error();
throw new PDOException($e['message']);
}
$this->_options = $options;
}
/**
* Return the resource connection
*
* @return mixed
*/
public function getDbh() {
return $this->_dbh;
}
/**
* Prepares a statement for execution and returns a statement object
*
* @param string $statement
* @param array $options
*
* @return Oci8PDO_Statement
*/
public function prepare($statement, $options = null)
{
$sth = @oci_parse($this->_dbh, $statement);
if (!$sth) {
$e = oci_error($this->_dbh);
throw new PDOException($e['message']);
}
if (!is_array($options)) {
$options = array();
}
return new Oci8PDO_Statement($sth, $this, $options);
}
/**
* Begins a transaction (turns off autocommit mode)
*
* @return void
*/
public function beginTransaction()
{
if ($this->isTransaction()) {
throw new PDOException('There is already an active transaction');
}
$this->_isTransaction = true;
return true;
}
/**
* Returns true if the current process is in a transaction
*
* @return bool
*/
public function isTransaction()
{
return $this->_isTransaction;
}
/**
* Commits all statements issued during a transaction and ends the transaction
*
* @return bool
*/
public function commit()
{
if (!$this->isTransaction()) {
throw new PDOException('There is no active transaction');
}
if (oci_commit($this->_dbh)) {
$this->_isTransaction = false;
return true;
}
return false;
}
/**
* Rolls back a transaction
*
* @return bool
*/
public function rollBack()
{
if (!$this->isTransaction()) {
throw new PDOException('There is no active transaction');
}
if (oci_rollback($this->_dbh)) {
$this->_isTransaction = false;
return true;
}
return false;
}
/**
* Sets an attribute on the database handle
*
* @param int $attribute
* @param mixed $value
*
* @return bool
*/
public function setAttribute($attribute, $value)
{
//433: $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
//435: $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES,$this->emulatePrepare);
//612: $this->setAttribute(PDO::ATTR_CASE,$value);
//632: $this->setAttribute(PDO::ATTR_ORACLE_NULLS,$value);
//652: $this->setAttribute(PDO::ATTR_AUTOCOMMIT,$value);
//672: return $this->setAttribute(PDO::ATTR_PERSISTENT,$value);
$this->_options[$attribute] = $value;
return true;
}
/**
* Executes an SQL statement and returns the number of affected rows
*
* @param string $query
*
* @return int The number of rows affected
*/
public function exec($query)
{
$stmt = $this->prepare($query);
$stmt->execute();
return $stmt->rowCount();
}
/**
* Executes an SQL statement, returning the results as a Oci8PDO_Statement
*
* @param string $query
* @param int|null $fetchType
* @param mixed|null $typeArg
* @param array|null $ctorArgs
*
* @return Oci8PDO_Statement
* @todo Implement support for $fetchType, $typeArg, and $ctorArgs.
*/
public function query(
$query,
$fetchType = null,
$typeArg = null,
array $ctorArgs = array()
) {
$stmt = $this->prepare($query);
$stmt->execute();
return $stmt;
}
/**
* Issues a PHP warning, just as with the PDO_OCI driver
*
* Oracle does not support the last inserted ID functionality like MySQL.
* You must implement this yourself by returning the sequence ID from a
* stored procedure, for example.
*
* @param string $name Sequence name; no use in this context
*
* @return void
*/
public function lastInsertId($name = null)
{
trigger_error(
'SQLSTATE[IM001]: Driver does not support this function: driver does not support lastInsertId()',
E_USER_WARNING);
}
/**
* Returns the error code associated with the last operation
*
* While this returns an error code, it merely emulates the action. If
* there are no errors, it returns the success SQLSTATE code (00000).
* If there are errors, it returns HY000. See errorInfo() to retrieve
* the actual Oracle error code and message.
*
* @return string
*/
public function errorCode()
{
$error = $this->errorInfo();
return $error[0];
}
/**
* Returns extended error information for the last operation on the database
*
* @return array
*/
public function errorInfo()
{
$e = oci_error($this->_dbh);
if (is_array($e)) {
return array(
'HY000',
$e['code'],
$e['message']
);
}
return array('00000', null, null);
}
/**
* Retrieve a database connection attribute
*
* @param int $attribute
*
* @return mixed|null
*/
public function getAttribute($attribute)
{
//438: $driver=strtolower($pdo->getAttribute(PDO::ATTR_DRIVER_NAME));
//602: return $this->getAttribute(PDO::ATTR_CASE);
//622: return $this->getAttribute(PDO::ATTR_ORACLE_NULLS);
//642: return $this->getAttribute(PDO::ATTR_AUTOCOMMIT);
//662: return $this->getAttribute(PDO::ATTR_PERSISTENT);
//692: return $this->getAttribute(PDO::ATTR_CLIENT_VERSION);
//702: return $this->getAttribute(PDO::ATTR_CONNECTION_STATUS);
//711: return $this->getAttribute(PDO::ATTR_PREFETCH);
//720: return $this->getAttribute(PDO::ATTR_SERVER_INFO);
//729: return $this->getAttribute(PDO::ATTR_SERVER_VERSION);
//738: return $this->getAttribute(PDO::ATTR_TIMEOUT);
if (isset($this->_options[$attribute])) {
return $this->_options[$attribute];
}
return null;
}
/**
* Quotes a string for use in a query
*
* @param string $string
* @param int $parameter_type
*
* @return string
* @todo Implement support for $parameter_type.
*/
public function quote($string, $parameter_type = PDO::PARAM_STR)
{
if ($parameter_type !== PDO::PARAM_STR) {
throw new PDOException('Only PDO::PARAM_STR is currently implemented for the $parameter_type of Oci8PDO::quote()');
}
return "'" . str_replace("'", "''", $string) . "'";
}
}