1
0
mirror of https://github.com/dg/dibi.git synced 2025-02-24 19:02:36 +01:00
php-dibi/dibi/libs/DibiDatabaseInfo.php

773 lines
12 KiB
PHP
Raw Normal View History

<?php
/**
2010-09-14 18:40:41 +02:00
* This file is part of the "dibi" - smart database abstraction layer.
*
2012-01-02 20:24:16 +01:00
* Copyright (c) 2005 David Grudl (http://davidgrudl.com)
2010-09-14 18:40:41 +02:00
*
* For the full copyright and license information, please view
* the file license.txt that was distributed with this source code.
*/
/**
* Reflection metadata class for a database.
2008-10-28 15:24:47 +00:00
*
2010-09-14 18:40:41 +02:00
* @author David Grudl
2012-01-03 04:50:11 +01:00
* @package dibi\reflection
2010-04-22 12:12:11 +02:00
*
* @property-read string $name
* @property-read array $tables
* @property-read array $tableNames
*/
class DibiDatabaseInfo extends DibiObject
{
/** @var IDibiReflector */
private $reflector;
/** @var string */
private $name;
/** @var array */
private $tables;
public function __construct(IDibiReflector $reflector, $name)
{
$this->reflector = $reflector;
$this->name = $name;
}
/**
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* @return array of DibiTableInfo
*/
public function getTables()
{
$this->init();
return array_values($this->tables);
}
/**
* @return array of string
*/
public function getTableNames()
{
$this->init();
$res = array();
foreach ($this->tables as $table) {
$res[] = $table->getName();
}
return $res;
}
/**
2009-02-05 23:13:29 +00:00
* @param string
* @return DibiTableInfo
*/
public function getTable($name)
{
$this->init();
$l = strtolower($name);
if (isset($this->tables[$l])) {
return $this->tables[$l];
} else {
throw new DibiException("Database '$this->name' has no table '$name'.");
}
}
/**
2009-02-05 23:13:29 +00:00
* @param string
* @return bool
*/
public function hasTable($name)
{
$this->init();
return isset($this->tables[strtolower($name)]);
}
/**
* @return void
*/
protected function init()
{
if ($this->tables === NULL) {
$this->tables = array();
foreach ($this->reflector->getTables() as $info) {
$this->tables[strtolower($info['name'])] = new DibiTableInfo($this->reflector, $info);
}
}
}
}
/**
* Reflection metadata class for a database table.
2008-10-28 15:24:47 +00:00
*
2010-09-14 18:40:41 +02:00
* @author David Grudl
2012-01-03 04:50:11 +01:00
* @package dibi\reflection
2010-04-22 12:12:11 +02:00
*
* @property-read string $name
* @property-read bool $view
* @property-read array $columns
* @property-read array $columnNames
* @property-read array $foreignKeys
* @property-read array $indexes
* @property-read DibiIndexInfo $primaryKey
*/
class DibiTableInfo extends DibiObject
{
/** @var IDibiReflector */
private $reflector;
/** @var string */
private $name;
/** @var bool */
private $view;
/** @var array */
private $columns;
/** @var array */
private $foreignKeys;
/** @var array */
private $indexes;
/** @var DibiIndexInfo */
private $primaryKey;
public function __construct(IDibiReflector $reflector, array $info)
{
$this->reflector = $reflector;
$this->name = $info['name'];
$this->view = !empty($info['view']);
}
/**
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* @return bool
*/
public function isView()
{
return $this->view;
}
/**
* @return array of DibiColumnInfo
*/
public function getColumns()
{
$this->initColumns();
return array_values($this->columns);
}
/**
* @return array of string
*/
public function getColumnNames()
{
$this->initColumns();
$res = array();
foreach ($this->columns as $column) {
$res[] = $column->getName();
}
return $res;
}
/**
2009-02-05 23:13:29 +00:00
* @param string
* @return DibiColumnInfo
*/
public function getColumn($name)
{
$this->initColumns();
$l = strtolower($name);
if (isset($this->columns[$l])) {
return $this->columns[$l];
} else {
throw new DibiException("Table '$this->name' has no column '$name'.");
}
}
/**
2009-02-05 23:13:29 +00:00
* @param string
* @return bool
*/
public function hasColumn($name)
{
$this->initColumns();
return isset($this->columns[strtolower($name)]);
}
/**
* @return array of DibiForeignKeyInfo
*/
public function getForeignKeys()
{
$this->initForeignKeys();
return $this->foreignKeys;
}
/**
* @return array of DibiIndexInfo
*/
public function getIndexes()
{
$this->initIndexes();
return $this->indexes;
}
/**
* @return DibiIndexInfo
*/
public function getPrimaryKey()
{
$this->initIndexes();
return $this->primaryKey;
}
/**
* @return void
*/
protected function initColumns()
{
if ($this->columns === NULL) {
$this->columns = array();
foreach ($this->reflector->getColumns($this->name) as $info) {
$this->columns[strtolower($info['name'])] = new DibiColumnInfo($this->reflector, $info);
}
}
}
/**
* @return void
*/
protected function initIndexes()
{
if ($this->indexes === NULL) {
$this->initColumns();
$this->indexes = array();
foreach ($this->reflector->getIndexes($this->name) as $info) {
2008-10-28 01:03:50 +00:00
foreach ($info['columns'] as $key => $name) {
$info['columns'][$key] = $this->columns[strtolower($name)];
}
2008-10-28 01:03:50 +00:00
$this->indexes[strtolower($info['name'])] = new DibiIndexInfo($info);
if (!empty($info['primary'])) {
2008-10-28 01:03:50 +00:00
$this->primaryKey = $this->indexes[strtolower($info['name'])];
}
}
}
}
/**
* @return void
*/
protected function initForeignKeys()
{
2011-07-01 07:58:27 +02:00
throw new DibiNotImplementedException;
}
}
/**
* Reflection metadata class for a result set.
*
2010-09-14 18:40:41 +02:00
* @author David Grudl
2012-01-03 04:50:11 +01:00
* @package dibi\reflection
2010-04-22 12:12:11 +02:00
*
* @property-read array $columns
* @property-read array $columnNames
*/
class DibiResultInfo extends DibiObject
{
/** @var IDibiResultDriver */
private $driver;
/** @var array */
private $columns;
/** @var array */
private $names;
public function __construct(IDibiResultDriver $driver)
{
$this->driver = $driver;
}
/**
* @return array of DibiColumnInfo
*/
public function getColumns()
{
$this->initColumns();
return array_values($this->columns);
}
/**
* @param bool
* @return array of string
*/
public function getColumnNames($fullNames = FALSE)
{
$this->initColumns();
$res = array();
foreach ($this->columns as $column) {
$res[] = $fullNames ? $column->getFullName() : $column->getName();
}
return $res;
}
/**
* @param string
* @return DibiColumnInfo
*/
public function getColumn($name)
{
$this->initColumns();
$l = strtolower($name);
if (isset($this->names[$l])) {
return $this->names[$l];
} else {
throw new DibiException("Result set has no column '$name'.");
}
}
/**
* @param string
* @return bool
*/
public function hasColumn($name)
{
$this->initColumns();
return isset($this->names[strtolower($name)]);
}
/**
* @return void
*/
protected function initColumns()
{
if ($this->columns === NULL) {
$this->columns = array();
$reflector = $this->driver instanceof IDibiReflector ? $this->driver : NULL;
foreach ($this->driver->getResultColumns() as $info) {
$this->columns[] = $this->names[$info['name']] = new DibiColumnInfo($reflector, $info);
}
}
}
}
/**
* Reflection metadata class for a table or result set column.
2008-10-28 15:24:47 +00:00
*
2010-09-14 18:40:41 +02:00
* @author David Grudl
2012-01-03 04:50:11 +01:00
* @package dibi\reflection
2010-04-22 12:12:11 +02:00
*
* @property-read string $name
* @property-read string $fullName
* @property-read DibiTableInfo $table
* @property-read string $type
* @property-read mixed $nativeType
* @property-read int $size
* @property-read bool $unsigned
* @property-read bool $nullable
* @property-read bool $autoIncrement
* @property-read mixed $default
*/
class DibiColumnInfo extends DibiObject
{
/** @var array */
private static $types;
/** @var IDibiReflector|NULL when created by DibiResultInfo */
private $reflector;
/** @var array (name, nativetype, [table], [fullname], [size], [nullable], [default], [autoincrement], [vendor]) */
private $info;
public function __construct(IDibiReflector $reflector = NULL, array $info)
{
$this->reflector = $reflector;
$this->info = $info;
}
/**
* @return string
*/
public function getName()
{
return $this->info['name'];
}
/**
* @return string
*/
public function getFullName()
{
2010-08-03 22:48:44 +02:00
return isset($this->info['fullname']) ? $this->info['fullname'] : NULL;
}
2008-10-28 01:03:50 +00:00
/**
* @return bool
*/
public function hasTable()
{
return !empty($this->info['table']);
}
/**
* @return DibiTableInfo
*/
public function getTable()
{
if (empty($this->info['table']) || !$this->reflector) {
throw new DibiException("Table is unknown or not available.");
}
return new DibiTableInfo($this->reflector, array('name' => $this->info['table']));
}
/**
* @return string
*/
public function getTableName()
{
return isset($this->info['table']) ? $this->info['table'] : NULL;
}
/**
* @return string
*/
public function getType()
{
return self::getTypeCache()->{$this->info['nativetype']};
}
/**
* @return mixed
*/
public function getNativeType()
{
return $this->info['nativetype'];
}
/**
* @return int
*/
public function getSize()
{
return isset($this->info['size']) ? (int) $this->info['size'] : NULL;
}
/**
2008-10-28 01:03:50 +00:00
* @return bool
*/
public function isUnsigned()
{
return isset($this->info['unsigned']) ? (bool) $this->info['unsigned'] : NULL;
}
2010-04-22 12:12:11 +02:00
/**
* @return bool
*/
2008-10-28 01:03:50 +00:00
public function isNullable()
{
return isset($this->info['nullable']) ? (bool) $this->info['nullable'] : NULL;
}
/**
* @return bool
*/
2008-10-28 01:03:50 +00:00
public function isAutoIncrement()
{
return isset($this->info['autoincrement']) ? (bool) $this->info['autoincrement'] : NULL;
}
/**
2008-10-28 01:03:50 +00:00
* @return mixed
*/
2008-10-28 01:03:50 +00:00
public function getDefault()
{
2008-10-28 01:03:50 +00:00
return isset($this->info['default']) ? $this->info['default'] : NULL;
}
/**
2008-10-28 01:03:50 +00:00
* @param string
* @return mixed
*/
public function getVendorInfo($key)
{
return isset($this->info['vendor'][$key]) ? $this->info['vendor'][$key] : NULL;
}
/**
* Heuristic type detection.
* @param string
* @return string
2010-08-03 22:48:44 +02:00
* @internal
*/
public static function detectType($type)
{
static $patterns = array(
2012-01-19 10:51:33 +01:00
'^_' => dibi::TEXT, // PostgreSQL arrays
2009-03-17 07:26:09 +00:00
'BYTEA|BLOB|BIN' => dibi::BINARY,
'TEXT|CHAR' => dibi::TEXT,
'YEAR|BYTE|COUNTER|SERIAL|INT|LONG' => dibi::INTEGER,
'CURRENCY|REAL|MONEY|FLOAT|DOUBLE|DECIMAL|NUMERIC|NUMBER' => dibi::FLOAT,
'^TIME$' => dibi::TIME,
'TIME' => dibi::DATETIME, // DATETIME, TIMESTAMP
'DATE' => dibi::DATE,
'BOOL|BIT' => dibi::BOOL,
);
foreach ($patterns as $s => $val) {
if (preg_match("#$s#i", $type)) {
return $val;
}
}
return dibi::TEXT;
}
/**
* @internal
*/
public static function getTypeCache()
{
if (self::$types === NULL) {
self::$types = new DibiHashMap(array(__CLASS__, 'detectType'));
}
return self::$types;
}
}
/**
* Reflection metadata class for a foreign key.
2008-10-28 15:24:47 +00:00
*
2010-09-14 18:40:41 +02:00
* @author David Grudl
2012-01-03 04:50:11 +01:00
* @package dibi\reflection
* @todo
2010-04-22 12:12:11 +02:00
*
* @property-read string $name
* @property-read array $references
*/
class DibiForeignKeyInfo extends DibiObject
{
/** @var string */
private $name;
/** @var array of array(local, foreign, onDelete, onUpdate) */
private $references;
public function __construct($name, array $references)
{
$this->name = $name;
$this->references = $references;
}
/**
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* @return array
*/
public function getReferences()
{
return $this->references;
}
}
/**
2009-02-05 23:13:29 +00:00
* Reflection metadata class for a index or primary key.
2008-10-28 15:24:47 +00:00
*
2010-09-14 18:40:41 +02:00
* @author David Grudl
2012-01-03 04:50:11 +01:00
* @package dibi\reflection
2010-04-22 12:12:11 +02:00
*
* @property-read string $name
* @property-read array $columns
* @property-read bool $unique
* @property-read bool $primary
*/
class DibiIndexInfo extends DibiObject
{
/** @var array (name, columns, [unique], [primary]) */
2008-10-28 01:03:50 +00:00
private $info;
2008-10-28 01:03:50 +00:00
public function __construct(array $info)
{
2008-10-28 01:03:50 +00:00
$this->info = $info;
}
/**
* @return string
*/
public function getName()
{
2008-10-28 01:03:50 +00:00
return $this->info['name'];
}
/**
* @return array
*/
public function getColumns()
{
2008-10-28 01:03:50 +00:00
return $this->info['columns'];
}
/**
* @return bool
*/
public function isUnique()
{
2008-10-28 01:03:50 +00:00
return !empty($this->info['unique']);
}
/**
* @return bool
*/
public function isPrimary()
{
return !empty($this->info['primary']);
}
}