1: <?php
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: class DibiOracleDriver extends DibiObject implements IDibiDriver, IDibiResultDriver, IDibiReflector
31: {
32:
33: private $connection;
34:
35:
36: private $resultSet;
37:
38:
39: private $autocommit = TRUE;
40:
41:
42: private $fmtDate, $fmtDateTime;
43:
44:
45:
46: 47: 48:
49: public function __construct()
50: {
51: if (!extension_loaded('oci8')) {
52: throw new DibiDriverException("PHP extension 'oci8' is not loaded.");
53: }
54: }
55:
56:
57:
58: 59: 60: 61: 62:
63: public function connect(array &$config)
64: {
65: $foo = & $config['charset'];
66: $this->fmtDate = isset($config['formatDate']) ? $config['formatDate'] : 'U';
67: $this->fmtDateTime = isset($config['formatDateTime']) ? $config['formatDateTime'] : 'U';
68:
69: if (isset($config['resource'])) {
70: $this->connection = $config['resource'];
71: } else {
72: $this->connection = @oci_new_connect($config['username'], $config['password'], $config['database'], $config['charset']); 73: }
74:
75: if (!$this->connection) {
76: $err = oci_error();
77: throw new DibiDriverException($err['message'], $err['code']);
78: }
79: }
80:
81:
82:
83: 84: 85: 86:
87: public function disconnect()
88: {
89: oci_close($this->connection);
90: }
91:
92:
93:
94: 95: 96: 97: 98: 99:
100: public function query($sql)
101: {
102: $this->resultSet = oci_parse($this->connection, $sql);
103: if ($this->resultSet) {
104: oci_execute($this->resultSet, $this->autocommit ? OCI_COMMIT_ON_SUCCESS : OCI_DEFAULT);
105: $err = oci_error($this->resultSet);
106: if ($err) {
107: throw new DibiDriverException($err['message'], $err['code'], $sql);
108: }
109: } else {
110: $err = oci_error($this->connection);
111: throw new DibiDriverException($err['message'], $err['code'], $sql);
112: }
113:
114: return is_resource($this->resultSet) ? clone $this : NULL;
115: }
116:
117:
118:
119: 120: 121: 122:
123: public function getAffectedRows()
124: {
125: throw new NotImplementedException;
126: }
127:
128:
129:
130: 131: 132: 133:
134: public function getInsertId($sequence)
135: {
136: $row = $this->query("SELECT $sequence.CURRVAL AS ID FROM DUAL")->fetch(TRUE);
137: return isset($row['ID']) ? (int) $row['ID'] : FALSE;
138: }
139:
140:
141:
142: 143: 144: 145: 146:
147: public function begin($savepoint = NULL)
148: {
149: $this->autocommit = FALSE;
150: }
151:
152:
153:
154: 155: 156: 157: 158: 159:
160: public function commit($savepoint = NULL)
161: {
162: if (!oci_commit($this->connection)) {
163: $err = oci_error($this->connection);
164: throw new DibiDriverException($err['message'], $err['code']);
165: }
166: $this->autocommit = TRUE;
167: }
168:
169:
170:
171: 172: 173: 174: 175: 176:
177: public function rollback($savepoint = NULL)
178: {
179: if (!oci_rollback($this->connection)) {
180: $err = oci_error($this->connection);
181: throw new DibiDriverException($err['message'], $err['code']);
182: }
183: $this->autocommit = TRUE;
184: }
185:
186:
187:
188: 189: 190: 191:
192: public function getResource()
193: {
194: return $this->connection;
195: }
196:
197:
198:
199: 200: 201: 202:
203: public function getReflector()
204: {
205: return $this;
206: }
207:
208:
209:
210:
211:
212:
213:
214: 215: 216: 217: 218: 219: 220:
221: public function escape($value, $type)
222: {
223: switch ($type) {
224: case dibi::TEXT:
225: case dibi::BINARY:
226: return "'" . str_replace("'", "''", $value) . "'"; 227:
228: case dibi::IDENTIFIER:
229: 230: return '"' . str_replace('"', '""', $value) . '"';
231:
232: case dibi::BOOL:
233: return $value ? 1 : 0;
234:
235: case dibi::DATE:
236: return $value instanceof DateTime ? $value->format($this->fmtDate) : date($this->fmtDate, $value);
237:
238: case dibi::DATETIME:
239: return $value instanceof DateTime ? $value->format($this->fmtDateTime) : date($this->fmtDateTime, $value);
240:
241: default:
242: throw new InvalidArgumentException('Unsupported type.');
243: }
244: }
245:
246:
247:
248: 249: 250: 251: 252: 253:
254: public function escapeLike($value, $pos)
255: {
256: throw new NotImplementedException;
257: }
258:
259:
260:
261: 262: 263: 264: 265: 266: 267:
268: public function unescape($value, $type)
269: {
270: if ($type === dibi::BINARY) {
271: return $value;
272: }
273: throw new InvalidArgumentException('Unsupported type.');
274: }
275:
276:
277:
278: 279: 280: 281: 282: 283: 284:
285: public function applyLimit(&$sql, $limit, $offset)
286: {
287: if ($offset > 0) {
288: 289: $sql = 'SELECT * FROM (SELECT t.*, ROWNUM AS "__rnum" FROM (' . $sql . ') t ' . ($limit >= 0 ? 'WHERE ROWNUM <= ' . ((int) $offset + (int) $limit) : '') . ') WHERE "__rnum" > '. (int) $offset;
290:
291: } elseif ($limit >= 0) {
292: $sql = 'SELECT * FROM (' . $sql . ') WHERE ROWNUM <= ' . (int) $limit;
293: }
294: }
295:
296:
297:
298:
299:
300:
301:
302: 303: 304: 305:
306: public function getRowCount()
307: {
308: throw new NotSupportedException('Row count is not available for unbuffered queries.');
309: }
310:
311:
312:
313: 314: 315: 316: 317:
318: public function fetch($assoc)
319: {
320: return oci_fetch_array($this->resultSet, ($assoc ? OCI_ASSOC : OCI_NUM) | OCI_RETURN_NULLS);
321: }
322:
323:
324:
325: 326: 327: 328: 329:
330: public function seek($row)
331: {
332: throw new NotImplementedException;
333: }
334:
335:
336:
337: 338: 339: 340:
341: public function free()
342: {
343: oci_free_statement($this->resultSet);
344: $this->resultSet = NULL;
345: }
346:
347:
348:
349: 350: 351: 352:
353: public function getResultColumns()
354: {
355: $count = oci_num_fields($this->resultSet);
356: $columns = array();
357: for ($i = 1; $i <= $count; $i++) {
358: $columns[] = array(
359: 'name' => oci_field_name($this->resultSet, $i),
360: 'table' => NULL,
361: 'fullname' => oci_field_name($this->resultSet, $i),
362: 'nativetype'=> oci_field_type($this->resultSet, $i),
363: );
364: }
365: return $columns;
366: }
367:
368:
369:
370: 371: 372: 373:
374: public function getResultResource()
375: {
376: return $this->resultSet;
377: }
378:
379:
380:
381:
382:
383:
384:
385: 386: 387: 388:
389: public function getTables()
390: {
391: $res = $this->query('SELECT * FROM cat');
392: $tables = array();
393: while ($row = $res->fetch(FALSE)) {
394: if ($row[1] === 'TABLE' || $row[1] === 'VIEW') {
395: $tables[] = array(
396: 'name' => $row[0],
397: 'view' => $row[1] === 'VIEW',
398: );
399: }
400: }
401: $res->free();
402: return $tables;
403: }
404:
405:
406:
407: 408: 409: 410: 411:
412: public function getColumns($table)
413: {
414: throw new NotImplementedException;
415: }
416:
417:
418:
419: 420: 421: 422: 423:
424: public function getIndexes($table)
425: {
426: throw new NotImplementedException;
427: }
428:
429:
430:
431: 432: 433: 434: 435:
436: public function getForeignKeys($table)
437: {
438: throw new NotImplementedException;
439: }
440:
441: }
442: