Packages

  • dibi
    • drivers
    • nette
    • reflection
  • None
  • PHP

Classes

  • DibiColumnInfo
  • DibiDatabaseInfo
  • DibiForeignKeyInfo
  • DibiIndexInfo
  • DibiResultInfo
  • DibiTableInfo
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: 
  3: /**
  4:  * This file is part of the "dibi" - smart database abstraction layer.
  5:  *
  6:  * Copyright (c) 2005 David Grudl (http://davidgrudl.com)
  7:  *
  8:  * For the full copyright and license information, please view
  9:  * the file license.txt that was distributed with this source code.
 10:  */
 11: 
 12: 
 13: 
 14: /**
 15:  * Reflection metadata class for a database.
 16:  *
 17:  * @author     David Grudl
 18:  * @package    dibi\reflection
 19:  *
 20:  * @property-read string $name
 21:  * @property-read array $tables
 22:  * @property-read array $tableNames
 23:  */
 24: class DibiDatabaseInfo extends DibiObject
 25: {
 26:     /** @var IDibiReflector */
 27:     private $reflector;
 28: 
 29:     /** @var string */
 30:     private $name;
 31: 
 32:     /** @var array */
 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:      * @return string
 47:      */
 48:     public function getName()
 49:     {
 50:         return $this->name;
 51:     }
 52: 
 53: 
 54: 
 55:     /**
 56:      * @return array of DibiTableInfo
 57:      */
 58:     public function getTables()
 59:     {
 60:         $this->init();
 61:         return array_values($this->tables);
 62:     }
 63: 
 64: 
 65: 
 66:     /**
 67:      * @return array of string
 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:      * @param  string
 83:      * @return DibiTableInfo
 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:      * @param  string
101:      * @return bool
102:      */
103:     public function hasTable($name)
104:     {
105:         $this->init();
106:         return isset($this->tables[strtolower($name)]);
107:     }
108: 
109: 
110: 
111:     /**
112:      * @return void
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:  * Reflection metadata class for a database table.
131:  *
132:  * @author     David Grudl
133:  * @package    dibi\reflection
134:  *
135:  * @property-read string $name
136:  * @property-read bool $view
137:  * @property-read array $columns
138:  * @property-read array $columnNames
139:  * @property-read array $foreignKeys
140:  * @property-read array $indexes
141:  * @property-read DibiIndexInfo $primaryKey
142:  */
143: class DibiTableInfo extends DibiObject
144: {
145:     /** @var IDibiReflector */
146:     private $reflector;
147: 
148:     /** @var string */
149:     private $name;
150: 
151:     /** @var bool */
152:     private $view;
153: 
154:     /** @var array */
155:     private $columns;
156: 
157:     /** @var array */
158:     private $foreignKeys;
159: 
160:     /** @var array */
161:     private $indexes;
162: 
163:     /** @var DibiIndexInfo */
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:      * @return string
179:      */
180:     public function getName()
181:     {
182:         return $this->name;
183:     }
184: 
185: 
186: 
187:     /**
188:      * @return bool
189:      */
190:     public function isView()
191:     {
192:         return $this->view;
193:     }
194: 
195: 
196: 
197:     /**
198:      * @return array of DibiColumnInfo
199:      */
200:     public function getColumns()
201:     {
202:         $this->initColumns();
203:         return array_values($this->columns);
204:     }
205: 
206: 
207: 
208:     /**
209:      * @return array of string
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:      * @param  string
225:      * @return DibiColumnInfo
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:      * @param  string
243:      * @return bool
244:      */
245:     public function hasColumn($name)
246:     {
247:         $this->initColumns();
248:         return isset($this->columns[strtolower($name)]);
249:     }
250: 
251: 
252: 
253:     /**
254:      * @return array of DibiForeignKeyInfo
255:      */
256:     public function getForeignKeys()
257:     {
258:         $this->initForeignKeys();
259:         return $this->foreignKeys;
260:     }
261: 
262: 
263: 
264:     /**
265:      * @return array of DibiIndexInfo
266:      */
267:     public function getIndexes()
268:     {
269:         $this->initIndexes();
270:         return $this->indexes;
271:     }
272: 
273: 
274: 
275:     /**
276:      * @return DibiIndexInfo
277:      */
278:     public function getPrimaryKey()
279:     {
280:         $this->initIndexes();
281:         return $this->primaryKey;
282:     }
283: 
284: 
285: 
286:     /**
287:      * @return void
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:      * @return void
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:      * @return void
325:      */
326:     protected function initForeignKeys()
327:     {
328:         throw new DibiNotImplementedException;
329:     }
330: 
331: }
332: 
333: 
334: 
335: 
336: /**
337:  * Reflection metadata class for a result set.
338:  *
339:  * @author     David Grudl
340:  * @package    dibi\reflection
341:  *
342:  * @property-read array $columns
343:  * @property-read array $columnNames
344:  */
345: class DibiResultInfo extends DibiObject
346: {
347:     /** @var IDibiResultDriver */
348:     private $driver;
349: 
350:     /** @var array */
351:     private $columns;
352: 
353:     /** @var array */
354:     private $names;
355: 
356: 
357: 
358:     public function __construct(IDibiResultDriver $driver)
359:     {
360:         $this->driver = $driver;
361:     }
362: 
363: 
364: 
365:     /**
366:      * @return array of DibiColumnInfo
367:      */
368:     public function getColumns()
369:     {
370:         $this->initColumns();
371:         return array_values($this->columns);
372:     }
373: 
374: 
375: 
376:     /**
377:      * @param  bool
378:      * @return array of string
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:      * @param  string
394:      * @return DibiColumnInfo
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:      * @param  string
412:      * @return bool
413:      */
414:     public function hasColumn($name)
415:     {
416:         $this->initColumns();
417:         return isset($this->names[strtolower($name)]);
418:     }
419: 
420: 
421: 
422:     /**
423:      * @return void
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:  * Reflection metadata class for a table or result set column.
443:  *
444:  * @author     David Grudl
445:  * @package    dibi\reflection
446:  *
447:  * @property-read string $name
448:  * @property-read string $fullName
449:  * @property-read DibiTableInfo $table
450:  * @property-read string $type
451:  * @property-read mixed $nativeType
452:  * @property-read int $size
453:  * @property-read bool $unsigned
454:  * @property-read bool $nullable
455:  * @property-read bool $autoIncrement
456:  * @property-read mixed $default
457:  */
458: class DibiColumnInfo extends DibiObject
459: {
460:     /** @var array */
461:     private static $types;
462: 
463:     /** @var IDibiReflector|NULL when created by DibiResultInfo */
464:     private $reflector;
465: 
466:     /** @var array (name, nativetype, [table], [fullname], [size], [nullable], [default], [autoincrement], [vendor]) */
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:      * @return string
481:      */
482:     public function getName()
483:     {
484:         return $this->info['name'];
485:     }
486: 
487: 
488: 
489:     /**
490:      * @return string
491:      */
492:     public function getFullName()
493:     {
494:         return isset($this->info['fullname']) ? $this->info['fullname'] : NULL;
495:     }
496: 
497: 
498: 
499:     /**
500:      * @return bool
501:      */
502:     public function hasTable()
503:     {
504:         return !empty($this->info['table']);
505:     }
506: 
507: 
508: 
509:     /**
510:      * @return DibiTableInfo
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:      * @return string
524:      */
525:     public function getTableName()
526:     {
527:         return isset($this->info['table']) ? $this->info['table'] : NULL;
528:     }
529: 
530: 
531: 
532:     /**
533:      * @return string
534:      */
535:     public function getType()
536:     {
537:         return self::getTypeCache()->{$this->info['nativetype']};
538:     }
539: 
540: 
541: 
542:     /**
543:      * @return mixed
544:      */
545:     public function getNativeType()
546:     {
547:         return $this->info['nativetype'];
548:     }
549: 
550: 
551: 
552:     /**
553:      * @return int
554:      */
555:     public function getSize()
556:     {
557:         return isset($this->info['size']) ? (int) $this->info['size'] : NULL;
558:     }
559: 
560: 
561: 
562:     /**
563:      * @return bool
564:      */
565:     public function isUnsigned()
566:     {
567:         return isset($this->info['unsigned']) ? (bool) $this->info['unsigned'] : NULL;
568:     }
569: 
570: 
571: 
572:     /**
573:      * @return bool
574:      */
575:     public function isNullable()
576:     {
577:         return isset($this->info['nullable']) ? (bool) $this->info['nullable'] : NULL;
578:     }
579: 
580: 
581: 
582:     /**
583:      * @return bool
584:      */
585:     public function isAutoIncrement()
586:     {
587:         return isset($this->info['autoincrement']) ? (bool) $this->info['autoincrement'] : NULL;
588:     }
589: 
590: 
591: 
592:     /**
593:      * @return mixed
594:      */
595:     public function getDefault()
596:     {
597:         return isset($this->info['default']) ? $this->info['default'] : NULL;
598:     }
599: 
600: 
601: 
602:     /**
603:      * @param  string
604:      * @return mixed
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:      * Heuristic type detection.
615:      * @param  string
616:      * @return string
617:      * @internal
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, // DATETIME, TIMESTAMP
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:      * @internal
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:  * Reflection metadata class for a foreign key.
660:  *
661:  * @author     David Grudl
662:  * @package    dibi\reflection
663:  * @todo
664:  *
665:  * @property-read string $name
666:  * @property-read array $references
667:  */
668: class DibiForeignKeyInfo extends DibiObject
669: {
670:     /** @var string */
671:     private $name;
672: 
673:     /** @var array of array(local, foreign, onDelete, onUpdate) */
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:      * @return string
688:      */
689:     public function getName()
690:     {
691:         return $this->name;
692:     }
693: 
694: 
695: 
696:     /**
697:      * @return array
698:      */
699:     public function getReferences()
700:     {
701:         return $this->references;
702:     }
703: 
704: }
705: 
706: 
707: 
708: 
709: /**
710:  * Reflection metadata class for a index or primary key.
711:  *
712:  * @author     David Grudl
713:  * @package    dibi\reflection
714:  *
715:  * @property-read string $name
716:  * @property-read array $columns
717:  * @property-read bool $unique
718:  * @property-read bool $primary
719:  */
720: class DibiIndexInfo extends DibiObject
721: {
722:     /** @var array (name, columns, [unique], [primary]) */
723:     private $info;
724: 
725: 
726:     public function __construct(array $info)
727:     {
728:         $this->info = $info;
729:     }
730: 
731: 
732: 
733:     /**
734:      * @return string
735:      */
736:     public function getName()
737:     {
738:         return $this->info['name'];
739:     }
740: 
741: 
742: 
743:     /**
744:      * @return array
745:      */
746:     public function getColumns()
747:     {
748:         return $this->info['columns'];
749:     }
750: 
751: 
752: 
753:     /**
754:      * @return bool
755:      */
756:     public function isUnique()
757:     {
758:         return !empty($this->info['unique']);
759:     }
760: 
761: 
762: 
763:     /**
764:      * @return bool
765:      */
766:     public function isPrimary()
767:     {
768:         return !empty($this->info['primary']);
769:     }
770: 
771: }
772: 
dibi API documentation API documentation generated by ApiGen 2.3.0