1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10:
11:
12:
13: 14: 15:
16: if (version_compare(PHP_VERSION, '5.2.0', '<')) {
17: throw new Exception('dibi needs PHP 5.2.0 or newer.');
18: }
19:
20: @set_magic_quotes_runtime(FALSE);
21:
22:
23:
24: require_once dirname(__FILE__) . '/libs/interfaces.php';
25: require_once dirname(__FILE__) . '/libs/DibiDateTime.php';
26: require_once dirname(__FILE__) . '/libs/DibiObject.php';
27: require_once dirname(__FILE__) . '/libs/DibiLiteral.php';
28: require_once dirname(__FILE__) . '/libs/DibiHashMap.php';
29: require_once dirname(__FILE__) . '/libs/DibiException.php';
30: require_once dirname(__FILE__) . '/libs/DibiConnection.php';
31: require_once dirname(__FILE__) . '/libs/DibiResult.php';
32: require_once dirname(__FILE__) . '/libs/DibiResultIterator.php';
33: require_once dirname(__FILE__) . '/libs/DibiRow.php';
34: require_once dirname(__FILE__) . '/libs/DibiTranslator.php';
35: require_once dirname(__FILE__) . '/libs/DibiDataSource.php';
36: require_once dirname(__FILE__) . '/libs/DibiFluent.php';
37: require_once dirname(__FILE__) . '/libs/DibiDatabaseInfo.php';
38: require_once dirname(__FILE__) . '/libs/DibiEvent.php';
39: require_once dirname(__FILE__) . '/libs/DibiFileLogger.php';
40: require_once dirname(__FILE__) . '/libs/DibiFirePhpLogger.php';
41: if (interface_exists('Nette\Diagnostics\IBarPanel') || interface_exists('IBarPanel')) {
42: require_once dirname(__FILE__) . '/Nette/DibiNettePanel.php';
43: }
44:
45:
46:
47:
48:
49: 50: 51: 52: 53: 54: 55: 56: 57:
58: class dibi
59: {
60:
61: const TEXT = 's',
62: BINARY = 'bin',
63: BOOL = 'b',
64: INTEGER = 'i',
65: FLOAT = 'f',
66: DATE = 'd',
67: DATETIME = 't',
68: TIME = 't';
69:
70: const IDENTIFIER = 'n';
71:
72:
73: const FIELD_TEXT = dibi::TEXT,
74: FIELD_BINARY = dibi::BINARY,
75: FIELD_BOOL = dibi::BOOL,
76: FIELD_INTEGER = dibi::INTEGER,
77: FIELD_FLOAT = dibi::FLOAT,
78: FIELD_DATE = dibi::DATE,
79: FIELD_DATETIME = dibi::DATETIME,
80: FIELD_TIME = dibi::TIME;
81:
82:
83: const VERSION = '1.5-rc2',
84: REVISION = 'b964887 released on 2012-01-12';
85:
86:
87: const ASC = 'ASC',
88: DESC = 'DESC';
89:
90:
91: private static $registry = array();
92:
93:
94: private static $connection;
95:
96:
97: private static $handlers = array();
98:
99:
100: public static $sql;
101:
102:
103: public static $elapsedTime;
104:
105:
106: public static $totalTime;
107:
108:
109: public static $numOfQueries = 0;
110:
111:
112: public static $defaultDriver = 'mysql';
113:
114:
115:
116: 117: 118:
119: final public function __construct()
120: {
121: throw new LogicException("Cannot instantiate static class " . get_class($this));
122: }
123:
124:
125:
126:
127:
128:
129:
130: 131: 132: 133: 134: 135: 136:
137: public static function connect($config = array(), $name = 0)
138: {
139: return self::$connection = self::$registry[$name] = new DibiConnection($config, $name);
140: }
141:
142:
143:
144: 145: 146: 147:
148: public static function disconnect()
149: {
150: self::getConnection()->disconnect();
151: }
152:
153:
154:
155: 156: 157: 158:
159: public static function isConnected()
160: {
161: return (self::$connection !== NULL) && self::$connection->isConnected();
162: }
163:
164:
165:
166: 167: 168: 169: 170: 171:
172: public static function getConnection($name = NULL)
173: {
174: if ($name === NULL) {
175: if (self::$connection === NULL) {
176: throw new DibiException('Dibi is not connected to database.');
177: }
178:
179: return self::$connection;
180: }
181:
182: if (!isset(self::$registry[$name])) {
183: throw new DibiException("There is no connection named '$name'.");
184: }
185:
186: return self::$registry[$name];
187: }
188:
189:
190:
191: 192: 193: 194: 195:
196: public static function setConnection(DibiConnection $connection)
197: {
198: return self::$connection = $connection;
199: }
200:
201:
202:
203: 204: 205: 206: 207: 208:
209: public static function activate($name)
210: {
211: self::$connection = self::getConnection($name);
212: }
213:
214:
215:
216:
217:
218:
219:
220: 221: 222: 223: 224: 225:
226: public static function query($args)
227: {
228: $args = func_get_args();
229: return self::getConnection()->query($args);
230: }
231:
232:
233:
234: 235: 236: 237: 238:
239: public static function nativeQuery($sql)
240: {
241: return self::getConnection()->nativeQuery($sql);
242: }
243:
244:
245:
246: 247: 248: 249: 250:
251: public static function test($args)
252: {
253: $args = func_get_args();
254: return self::getConnection()->test($args);
255: }
256:
257:
258:
259: 260: 261: 262: 263:
264: public static function dataSource($args)
265: {
266: $args = func_get_args();
267: return self::getConnection()->dataSource($args);
268: }
269:
270:
271:
272: 273: 274: 275: 276: 277:
278: public static function fetch($args)
279: {
280: $args = func_get_args();
281: return self::getConnection()->query($args)->fetch();
282: }
283:
284:
285:
286: 287: 288: 289: 290: 291:
292: public static function fetchAll($args)
293: {
294: $args = func_get_args();
295: return self::getConnection()->query($args)->fetchAll();
296: }
297:
298:
299:
300: 301: 302: 303: 304: 305:
306: public static function fetchSingle($args)
307: {
308: $args = func_get_args();
309: return self::getConnection()->query($args)->fetchSingle();
310: }
311:
312:
313:
314: 315: 316: 317: 318: 319:
320: public static function fetchPairs($args)
321: {
322: $args = func_get_args();
323: return self::getConnection()->query($args)->fetchPairs();
324: }
325:
326:
327:
328: 329: 330: 331: 332: 333:
334: public static function getAffectedRows()
335: {
336: return self::getConnection()->getAffectedRows();
337: }
338:
339:
340:
341: 342: 343: 344: 345:
346: public static function affectedRows()
347: {
348: return self::getConnection()->getAffectedRows();
349: }
350:
351:
352:
353: 354: 355: 356: 357: 358: 359:
360: public static function getInsertId($sequence=NULL)
361: {
362: return self::getConnection()->getInsertId($sequence);
363: }
364:
365:
366:
367: 368: 369: 370: 371: 372:
373: public static function insertId($sequence=NULL)
374: {
375: return self::getConnection()->getInsertId($sequence);
376: }
377:
378:
379:
380: 381: 382: 383: 384: 385:
386: public static function begin($savepoint = NULL)
387: {
388: self::getConnection()->begin($savepoint);
389: }
390:
391:
392:
393: 394: 395: 396: 397: 398:
399: public static function commit($savepoint = NULL)
400: {
401: self::getConnection()->commit($savepoint);
402: }
403:
404:
405:
406: 407: 408: 409: 410: 411:
412: public static function rollback($savepoint = NULL)
413: {
414: self::getConnection()->rollback($savepoint);
415: }
416:
417:
418:
419: 420: 421: 422:
423: public static function getDatabaseInfo()
424: {
425: return self::getConnection()->getDatabaseInfo();
426: }
427:
428:
429:
430: 431: 432: 433: 434:
435: public static function loadFile($file)
436: {
437: return self::getConnection()->loadFile($file);
438: }
439:
440:
441:
442: 443: 444:
445: public static function __callStatic($name, $args)
446: {
447:
448:
449:
450: return call_user_func_array(array(self::getConnection(), $name), $args);
451: }
452:
453:
454:
455:
456:
457:
458:
459: 460: 461:
462: public static function command()
463: {
464: return self::getConnection()->command();
465: }
466:
467:
468:
469: 470: 471: 472:
473: public static function select($args)
474: {
475: $args = func_get_args();
476: return call_user_func_array(array(self::getConnection(), 'select'), $args);
477: }
478:
479:
480:
481: 482: 483: 484: 485:
486: public static function update($table, $args)
487: {
488: return self::getConnection()->update($table, $args);
489: }
490:
491:
492:
493: 494: 495: 496: 497:
498: public static function insert($table, $args)
499: {
500: return self::getConnection()->insert($table, $args);
501: }
502:
503:
504:
505: 506: 507: 508:
509: public static function delete($table)
510: {
511: return self::getConnection()->delete($table);
512: }
513:
514:
515:
516:
517:
518:
519:
520: 521: 522:
523: public static function datetime($time = NULL)
524: {
525: trigger_error(__METHOD__ . '() is deprecated; create DibiDateTime object instead.', E_USER_WARNING);
526: return new DibiDateTime($time);
527: }
528:
529:
530:
531: 532: 533:
534: public static function date($date = NULL)
535: {
536: trigger_error(__METHOD__ . '() is deprecated; create DibiDateTime object instead.', E_USER_WARNING);
537: return new DibiDateTime($date);
538: }
539:
540:
541:
542:
543:
544:
545:
546: 547: 548: 549:
550: public static function getSubstitutes()
551: {
552: return self::getConnection()->getSubstitutes();
553: }
554:
555:
556:
557:
558: public static function addSubst($expr, $subst)
559: {
560: trigger_error(__METHOD__ . '() is deprecated; use dibi::getSubstitutes()->expr = val; instead.', E_USER_WARNING);
561: self::getSubstitutes()->$expr = $subst;
562: }
563:
564:
565:
566:
567: public static function removeSubst($expr)
568: {
569: trigger_error(__METHOD__ . '() is deprecated; use unset(dibi::getSubstitutes()->expr) instead.', E_USER_WARNING);
570: $substitutes = self::getSubstitutes();
571: if ($expr === TRUE) {
572: foreach ($substitutes as $expr => $foo) {
573: unset($substitutes->$expr);
574: }
575: } else {
576: unset($substitutes->$expr);
577: }
578: }
579:
580:
581:
582:
583: public static function setSubstFallback($callback)
584: {
585: trigger_error(__METHOD__ . '() is deprecated; use dibi::getSubstitutes()->setCallback() instead.', E_USER_WARNING);
586: self::getSubstitutes()->setCallback($callback);
587: }
588:
589:
590:
591:
592:
593:
594:
595: 596: 597: 598: 599: 600:
601: public static function dump($sql = NULL, $return = FALSE)
602: {
603: ob_start();
604: if ($sql instanceof DibiResult) {
605: $sql->dump();
606:
607: } else {
608: if ($sql === NULL) $sql = self::$sql;
609:
610: static $keywords1 = 'SELECT|(?:ON\s+DUPLICATE\s+KEY)?UPDATE|INSERT(?:\s+INTO)?|REPLACE(?:\s+INTO)?|DELETE|CALL|UNION|FROM|WHERE|HAVING|GROUP\s+BY|ORDER\s+BY|LIMIT|OFFSET|SET|VALUES|LEFT\s+JOIN|INNER\s+JOIN|TRUNCATE';
611: static $keywords2 = 'ALL|DISTINCT|DISTINCTROW|IGNORE|AS|USING|ON|AND|OR|IN|IS|NOT|NULL|LIKE|RLIKE|REGEXP|TRUE|FALSE';
612:
613:
614: $sql = " $sql ";
615: $sql = preg_replace("#(?<=[\\s,(])($keywords1)(?=[\\s,)])#i", "\n\$1", $sql);
616:
617:
618: $sql = preg_replace('#[ \t]{2,}#', " ", $sql);
619:
620: $sql = wordwrap($sql, 100);
621: $sql = preg_replace("#([ \t]*\r?\n){2,}#", "\n", $sql);
622:
623: if (PHP_SAPI === 'cli') {
624: echo trim($sql) . "\n\n";
625: } else {
626:
627: $sql = htmlSpecialChars($sql);
628: $sql = preg_replace_callback("#(/\\*.+?\\*/)|(\\*\\*.+?\\*\\*)|(?<=[\\s,(])($keywords1)(?=[\\s,)])|(?<=[\\s,(=])($keywords2)(?=[\\s,)=])#is", array('dibi', 'highlightCallback'), $sql);
629: echo '<pre class="dump">', trim($sql), "</pre>\n";
630: }
631: }
632:
633: if ($return) {
634: return ob_get_clean();
635: } else {
636: ob_end_flush();
637: }
638: }
639:
640:
641:
642: private static function highlightCallback($matches)
643: {
644: if (!empty($matches[1]))
645: return '<em style="color:gray">' . $matches[1] . '</em>';
646:
647: if (!empty($matches[2]))
648: return '<strong style="color:red">' . $matches[2] . '</strong>';
649:
650: if (!empty($matches[3]))
651: return '<strong style="color:blue">' . $matches[3] . '</strong>';
652:
653: if (!empty($matches[4]))
654: return '<strong style="color:green">' . $matches[4] . '</strong>';
655: }
656:
657: }
658: