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