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: class DibiDatabaseInfo extends DibiObject
25: {
26:
27: private $reflector;
28:
29:
30: private $name;
31:
32:
33: private $tables;
34:
35:
36:
37: public function __construct(IDibiReflector $reflector, $name)
38: {
39: $this->reflector = $reflector;
40: $this->name = $name;
41: }
42:
43:
44:
45: 46: 47:
48: public function getName()
49: {
50: return $this->name;
51: }
52:
53:
54:
55: 56: 57:
58: public function getTables()
59: {
60: $this->init();
61: return array_values($this->tables);
62: }
63:
64:
65:
66: 67: 68:
69: public function getTableNames()
70: {
71: $this->init();
72: $res = array();
73: foreach ($this->tables as $table) {
74: $res[] = $table->getName();
75: }
76: return $res;
77: }
78:
79:
80:
81: 82: 83: 84:
85: public function getTable($name)
86: {
87: $this->init();
88: $l = strtolower($name);
89: if (isset($this->tables[$l])) {
90: return $this->tables[$l];
91:
92: } else {
93: throw new DibiException("Database '$this->name' has no table '$name'.");
94: }
95: }
96:
97:
98:
99: 100: 101: 102:
103: public function hasTable($name)
104: {
105: $this->init();
106: return isset($this->tables[strtolower($name)]);
107: }
108:
109:
110:
111: 112: 113:
114: protected function init()
115: {
116: if ($this->tables === NULL) {
117: $this->tables = array();
118: foreach ($this->reflector->getTables() as $info) {
119: $this->tables[strtolower($info['name'])] = new DibiTableInfo($this->reflector, $info);
120: }
121: }
122: }
123:
124: }
125:
126:
127:
128:
129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142:
143: class DibiTableInfo extends DibiObject
144: {
145:
146: private $reflector;
147:
148:
149: private $name;
150:
151:
152: private $view;
153:
154:
155: private $columns;
156:
157:
158: private $foreignKeys;
159:
160:
161: private $indexes;
162:
163:
164: private $primaryKey;
165:
166:
167:
168: public function __construct(IDibiReflector $reflector, array $info)
169: {
170: $this->reflector = $reflector;
171: $this->name = $info['name'];
172: $this->view = !empty($info['view']);
173: }
174:
175:
176:
177: 178: 179:
180: public function getName()
181: {
182: return $this->name;
183: }
184:
185:
186:
187: 188: 189:
190: public function isView()
191: {
192: return $this->view;
193: }
194:
195:
196:
197: 198: 199:
200: public function getColumns()
201: {
202: $this->initColumns();
203: return array_values($this->columns);
204: }
205:
206:
207:
208: 209: 210:
211: public function getColumnNames()
212: {
213: $this->initColumns();
214: $res = array();
215: foreach ($this->columns as $column) {
216: $res[] = $column->getName();
217: }
218: return $res;
219: }
220:
221:
222:
223: 224: 225: 226:
227: public function getColumn($name)
228: {
229: $this->initColumns();
230: $l = strtolower($name);
231: if (isset($this->columns[$l])) {
232: return $this->columns[$l];
233:
234: } else {
235: throw new DibiException("Table '$this->name' has no column '$name'.");
236: }
237: }
238:
239:
240:
241: 242: 243: 244:
245: public function hasColumn($name)
246: {
247: $this->initColumns();
248: return isset($this->columns[strtolower($name)]);
249: }
250:
251:
252:
253: 254: 255:
256: public function getForeignKeys()
257: {
258: $this->initForeignKeys();
259: return $this->foreignKeys;
260: }
261:
262:
263:
264: 265: 266:
267: public function getIndexes()
268: {
269: $this->initIndexes();
270: return $this->indexes;
271: }
272:
273:
274:
275: 276: 277:
278: public function getPrimaryKey()
279: {
280: $this->initIndexes();
281: return $this->primaryKey;
282: }
283:
284:
285:
286: 287: 288:
289: protected function initColumns()
290: {
291: if ($this->columns === NULL) {
292: $this->columns = array();
293: foreach ($this->reflector->getColumns($this->name) as $info) {
294: $this->columns[strtolower($info['name'])] = new DibiColumnInfo($this->reflector, $info);
295: }
296: }
297: }
298:
299:
300:
301: 302: 303:
304: protected function initIndexes()
305: {
306: if ($this->indexes === NULL) {
307: $this->initColumns();
308: $this->indexes = array();
309: foreach ($this->reflector->getIndexes($this->name) as $info) {
310: foreach ($info['columns'] as $key => $name) {
311: $info['columns'][$key] = $this->columns[strtolower($name)];
312: }
313: $this->indexes[strtolower($info['name'])] = new DibiIndexInfo($info);
314: if (!empty($info['primary'])) {
315: $this->primaryKey = $this->indexes[strtolower($info['name'])];
316: }
317: }
318: }
319: }
320:
321:
322:
323: 324: 325:
326: protected function initForeignKeys()
327: {
328: throw new DibiNotImplementedException;
329: }
330:
331: }
332:
333:
334:
335:
336: 337: 338: 339: 340: 341: 342: 343: 344:
345: class DibiResultInfo extends DibiObject
346: {
347:
348: private $driver;
349:
350:
351: private $columns;
352:
353:
354: private $names;
355:
356:
357:
358: public function __construct(IDibiResultDriver $driver)
359: {
360: $this->driver = $driver;
361: }
362:
363:
364:
365: 366: 367:
368: public function getColumns()
369: {
370: $this->initColumns();
371: return array_values($this->columns);
372: }
373:
374:
375:
376: 377: 378: 379:
380: public function getColumnNames($fullNames = FALSE)
381: {
382: $this->initColumns();
383: $res = array();
384: foreach ($this->columns as $column) {
385: $res[] = $fullNames ? $column->getFullName() : $column->getName();
386: }
387: return $res;
388: }
389:
390:
391:
392: 393: 394: 395:
396: public function getColumn($name)
397: {
398: $this->initColumns();
399: $l = strtolower($name);
400: if (isset($this->names[$l])) {
401: return $this->names[$l];
402:
403: } else {
404: throw new DibiException("Result set has no column '$name'.");
405: }
406: }
407:
408:
409:
410: 411: 412: 413:
414: public function hasColumn($name)
415: {
416: $this->initColumns();
417: return isset($this->names[strtolower($name)]);
418: }
419:
420:
421:
422: 423: 424:
425: protected function initColumns()
426: {
427: if ($this->columns === NULL) {
428: $this->columns = array();
429: $reflector = $this->driver instanceof IDibiReflector ? $this->driver : NULL;
430: foreach ($this->driver->getResultColumns() as $info) {
431: $this->columns[] = $this->names[$info['name']] = new DibiColumnInfo($reflector, $info);
432: }
433: }
434: }
435:
436: }
437:
438:
439:
440:
441: 442: 443: 444: 445: 446: 447: 448: 449: 450: 451: 452: 453: 454: 455: 456: 457:
458: class DibiColumnInfo extends DibiObject
459: {
460:
461: private static $types;
462:
463:
464: private $reflector;
465:
466:
467: private $info;
468:
469:
470:
471: public function __construct(IDibiReflector $reflector = NULL, array $info)
472: {
473: $this->reflector = $reflector;
474: $this->info = $info;
475: }
476:
477:
478:
479: 480: 481:
482: public function getName()
483: {
484: return $this->info['name'];
485: }
486:
487:
488:
489: 490: 491:
492: public function getFullName()
493: {
494: return isset($this->info['fullname']) ? $this->info['fullname'] : NULL;
495: }
496:
497:
498:
499: 500: 501:
502: public function hasTable()
503: {
504: return !empty($this->info['table']);
505: }
506:
507:
508:
509: 510: 511:
512: public function getTable()
513: {
514: if (empty($this->info['table']) || !$this->reflector) {
515: throw new DibiException("Table is unknown or not available.");
516: }
517: return new DibiTableInfo($this->reflector, array('name' => $this->info['table']));
518: }
519:
520:
521:
522: 523: 524:
525: public function getTableName()
526: {
527: return isset($this->info['table']) ? $this->info['table'] : NULL;
528: }
529:
530:
531:
532: 533: 534:
535: public function getType()
536: {
537: return self::getTypeCache()->{$this->info['nativetype']};
538: }
539:
540:
541:
542: 543: 544:
545: public function getNativeType()
546: {
547: return $this->info['nativetype'];
548: }
549:
550:
551:
552: 553: 554:
555: public function getSize()
556: {
557: return isset($this->info['size']) ? (int) $this->info['size'] : NULL;
558: }
559:
560:
561:
562: 563: 564:
565: public function isUnsigned()
566: {
567: return isset($this->info['unsigned']) ? (bool) $this->info['unsigned'] : NULL;
568: }
569:
570:
571:
572: 573: 574:
575: public function isNullable()
576: {
577: return isset($this->info['nullable']) ? (bool) $this->info['nullable'] : NULL;
578: }
579:
580:
581:
582: 583: 584:
585: public function isAutoIncrement()
586: {
587: return isset($this->info['autoincrement']) ? (bool) $this->info['autoincrement'] : NULL;
588: }
589:
590:
591:
592: 593: 594:
595: public function getDefault()
596: {
597: return isset($this->info['default']) ? $this->info['default'] : NULL;
598: }
599:
600:
601:
602: 603: 604: 605:
606: public function getVendorInfo($key)
607: {
608: return isset($this->info['vendor'][$key]) ? $this->info['vendor'][$key] : NULL;
609: }
610:
611:
612:
613: 614: 615: 616: 617: 618:
619: public static function detectType($type)
620: {
621: static $patterns = array(
622: 'BYTEA|BLOB|BIN' => dibi::BINARY,
623: 'TEXT|CHAR' => dibi::TEXT,
624: 'YEAR|BYTE|COUNTER|SERIAL|INT|LONG' => dibi::INTEGER,
625: 'CURRENCY|REAL|MONEY|FLOAT|DOUBLE|DECIMAL|NUMERIC|NUMBER' => dibi::FLOAT,
626: '^TIME$' => dibi::TIME,
627: 'TIME' => dibi::DATETIME,
628: 'DATE' => dibi::DATE,
629: 'BOOL|BIT' => dibi::BOOL,
630: );
631:
632: foreach ($patterns as $s => $val) {
633: if (preg_match("#$s#i", $type)) {
634: return $val;
635: }
636: }
637: return dibi::TEXT;
638: }
639:
640:
641:
642: 643: 644:
645: public static function getTypeCache()
646: {
647: if (self::$types === NULL) {
648: self::$types = new DibiHashMap(array(__CLASS__, 'detectType'));
649: }
650: return self::$types;
651: }
652:
653: }
654:
655:
656:
657:
658: 659: 660: 661: 662: 663: 664: 665: 666: 667:
668: class DibiForeignKeyInfo extends DibiObject
669: {
670:
671: private $name;
672:
673:
674: private $references;
675:
676:
677:
678: public function __construct($name, array $references)
679: {
680: $this->name = $name;
681: $this->references = $references;
682: }
683:
684:
685:
686: 687: 688:
689: public function getName()
690: {
691: return $this->name;
692: }
693:
694:
695:
696: 697: 698:
699: public function getReferences()
700: {
701: return $this->references;
702: }
703:
704: }
705:
706:
707:
708:
709: 710: 711: 712: 713: 714: 715: 716: 717: 718: 719:
720: class DibiIndexInfo extends DibiObject
721: {
722:
723: private $info;
724:
725:
726: public function __construct(array $info)
727: {
728: $this->info = $info;
729: }
730:
731:
732:
733: 734: 735:
736: public function getName()
737: {
738: return $this->info['name'];
739: }
740:
741:
742:
743: 744: 745:
746: public function getColumns()
747: {
748: return $this->info['columns'];
749: }
750:
751:
752:
753: 754: 755:
756: public function isUnique()
757: {
758: return !empty($this->info['unique']);
759: }
760:
761:
762:
763: 764: 765:
766: public function isPrimary()
767: {
768: return !empty($this->info['primary']);
769: }
770:
771: }
772: