1
0
mirror of https://github.com/dg/dibi.git synced 2025-08-06 14:16:39 +02:00

- added dibi-field-type autodetection

- added DibiColumnInfo::getVendorInfo()
This commit is contained in:
David Grudl
2008-10-28 14:37:40 +00:00
parent 318b3093a5
commit 7565ffb1d4
9 changed files with 119 additions and 50 deletions

View File

@@ -101,6 +101,7 @@ class dibi
FIELD_FLOAT = 'f',
FIELD_DATE = 'd',
FIELD_DATETIME = 't',
FIELD_TIME = 't',
// special
IDENTIFIER = 'n';

View File

@@ -346,9 +346,8 @@ class DibiMsSqlDriver extends DibiObject implements IDibiDriver
'name' => $row['name'],
'fullname' => $row['column_source'] ? $row['column_source'] . '.' . $row['name'] : $row['name'],
'table' => $row['column_source'],
'type' => NULL,
'nativetype' => $row['type'],
) + $row;
);
}
return $res;
}

View File

@@ -409,12 +409,12 @@ class DibiMySqlDriver extends DibiObject implements IDibiDriver
for ($i = 0; $i < $count; $i++) {
$row = (array) mysql_fetch_field($this->resultSet, $i);
$res[] = array(
'name' => $row['name'],
'table' => $row['table'],
'fullname' => $row['table'] ? $row['table'] . '.' . $row['name'] : $row['name'],
'type' => NULL,
'nativetype' => strtoupper($row['type']),
'nullable' => !($row['not_null']),
'default' => $row['def'],
) + $row;
'vendor' => $row,
);
}
return $res;
}

View File

@@ -386,21 +386,27 @@ class DibiMySqliDriver extends DibiObject implements IDibiDriver
*/
public function getColumnsMeta()
{
static $types;
if (empty($types)) {
$consts = get_defined_constants(TRUE);
foreach ($consts['mysqli'] as $key => $value) {
if (strncmp($key, 'MYSQLI_TYPE_', 12) === 0) {
$types[$value] = substr($key, 12);
}
}
}
$count = mysqli_num_fields($this->resultSet);
$res = array();
for ($i = 0; $i < $count; $i++) {
$row = (array) mysqli_fetch_field_direct($this->resultSet, $i);
$res[] = array(
'name' => $row['name'],
'column' => $row['orgname'],
'alias' => $row['table'],
'table' => $row['orgtable'],
'fullname' => $row['table'] ? $row['table'] . '.' . $row['name'] : $row['name'],
'type' => NULL,
'nativetype' => $row['type'],
'nullable' => !($row['flags'] & MYSQLI_NOT_NULL_FLAG),
'default' => $row['def'],
) + $row;
'nativetype' => $types[$row['type']],
'vendor' => $row,
);
}
return $res;
}

View File

@@ -400,10 +400,12 @@ class DibiPdoDriver extends DibiObject implements IDibiDriver
throw new DibiDriverException('Driver does not support meta data.');
}
$res[] = array(
'type' => NULL,
'name' => $row['name'],
'table' => $row['table'],
'nativetype' => $row['native_type'],
'fullname' => $row['table'] ? $row['table'] . '.' . $row['name'] : $row['name'],
) + $row;
'vendor' => $row,
);
}
return $res;
}

View File

@@ -456,14 +456,14 @@ class DibiPostgreDriver extends DibiObject implements IDibiDriver
$this->query("
SELECT indkey
FROM pg_index, pg_class
WHERE pg_class.relname = '$_table' AND pg_class.oid = pg_index.indrelid AND pg_index.indisprimary
WHERE pg_class.relname = $_table AND pg_class.oid = pg_index.indrelid AND pg_index.indisprimary
");
$primary = (int) pg_fetch_object($this->resultSet)->indkey;
$this->query("
SELECT *
FROM information_schema.columns
WHERE table_name = '$_table' AND table_schema = current_schema()
WHERE table_name = $_table AND table_schema = current_schema()
ORDER BY ordinal_position
");
$res = array();
@@ -472,13 +472,13 @@ class DibiPostgreDriver extends DibiObject implements IDibiDriver
$res[] = array(
'name' => $row['column_name'],
'table' => $table,
'type' => NULL,
'nativetype' => strtoupper($row['udt_name']),
'size' => $size ? $size : NULL,
'nullable' => $row['is_nullable'] === 'YES',
'default' => $row['column_default'],
'autoincrement' => (int) $row['ordinal_position'] === $primary && substr($row['column_default'], 0, 7) === 'nextval',
) + $row;
'vendor' => $row,
);
}
$this->free();
return $res;

View File

@@ -369,6 +369,7 @@ class DibiSqliteDriver extends DibiObject implements IDibiDriver
'name' => isset($pair[1]) ? $pair[1] : $pair[0],
'table' => isset($pair[1]) ? $pair[0] : NULL,
'fullname' => $name,
'nativetype' => NULL,
);
}
return $res;

View File

@@ -138,8 +138,11 @@ class DibiTableInfo extends DibiObject
/** @var IDibiDriver */
private $driver;
/** @var array */
private $info;
/** @var string */
private $name;
/** @var bool */
private $view;
/** @var array */
private $columns;
@@ -158,7 +161,8 @@ class DibiTableInfo extends DibiObject
public function __construct(IDibiDriver $driver, array $info)
{
$this->driver = $driver;
$this->info = $info;
$this->name = $info['name'];
$this->view = !empty($info['view']);
}
@@ -168,7 +172,7 @@ class DibiTableInfo extends DibiObject
*/
public function getName()
{
return $this->info['name'];
return $this->name;
}
@@ -178,7 +182,7 @@ class DibiTableInfo extends DibiObject
*/
public function isView()
{
return !empty($this->info['view']);
return $this->view;
}
@@ -279,7 +283,7 @@ class DibiTableInfo extends DibiObject
{
if ($this->columns === NULL) {
$this->columns = array();
foreach ($this->driver->getColumns($this->info['name']) as $info) {
foreach ($this->driver->getColumns($this->name) as $info) {
$this->columns[strtolower($info['name'])] = new DibiColumnInfo($this->driver, $info);
}
}
@@ -295,7 +299,7 @@ class DibiTableInfo extends DibiObject
if ($this->indexes === NULL) {
$this->initColumns();
$this->indexes = array();
foreach ($this->driver->getIndexes($this->info['name']) as $info) {
foreach ($this->driver->getIndexes($this->name) as $info) {
foreach ($info['columns'] as $key => $name) {
$info['columns'][$key] = $this->columns[strtolower($name)];
}
@@ -328,18 +332,25 @@ class DibiTableInfo extends DibiObject
*/
class DibiColumnInfo extends DibiObject
{
/** @var array */
private static $types;
/** @var IDibiDriver */
private $driver;
/** @var array (name, table, fullname, type, nativetype, size, nullable, default, autoincrement) */
/** @var array (name, nativetype, [table], [fullname], [size], [nullable], [default], [autoincrement], [vendor]) */
private $info;
/** @var string */
private $type;
public function __construct(IDibiDriver $driver, array $info)
{
$this->driver = $driver;
$this->info = $info;
$this->type = self::detectType($this->info['nativetype']);
}
@@ -382,7 +393,7 @@ class DibiColumnInfo extends DibiObject
*/
public function getType()
{
return isset($this->info['type']) ? $this->info['type'] : NULL;
return $this->type;
}
@@ -392,7 +403,7 @@ class DibiColumnInfo extends DibiObject
*/
public function getNativeType()
{
return isset($this->info['nativetype']) ? $this->info['nativetype'] : NULL;
return $this->info['nativetype'];
}
@@ -412,7 +423,7 @@ class DibiColumnInfo extends DibiObject
*/
public function isNullable()
{
return !empty($this->info['nullable']);
return isset($this->info['nullable']) ? (bool) $this->info['nullable'] : NULL;
}
@@ -422,7 +433,7 @@ class DibiColumnInfo extends DibiObject
*/
public function isAutoIncrement()
{
return !empty($this->info['autoincrement']);
return isset($this->info['autoincrement']) ? (bool) $this->info['autoincrement'] : NULL;
}
@@ -441,9 +452,39 @@ class DibiColumnInfo extends DibiObject
* @param string
* @return mixed
*/
public function getInfo($key)
public function getVendorInfo($key)
{
return isset($this->info[$key]) ? $this->info[$key] : NULL;
return isset($this->info['vendor'][$key]) ? $this->info['vendor'][$key] : NULL;
}
/**
* Heuristic type detection.
* @param string
* @return string
*/
public static function detectType($type)
{
static $patterns = array(
'BYTE|COUNTER|SERIAL|INT|LONG' => dibi::FIELD_INTEGER,
'CURRENCY|REAL|MONEY|FLOAT|DOUBLE|DECIMAL|NUMERIC' => dibi::FIELD_FLOAT,
'^TIME$' => dibi::FIELD_TIME,
'TIME' => dibi::FIELD_DATETIME, // DATETIME, TIMESTAMP
'YEAR|DATE' => dibi::FIELD_DATE,
'BYTEA|BLOB|BIN' => dibi::FIELD_BINARY,
'BOOL|BIT' => dibi::FIELD_BOOL,
);
if (!isset(self::$types[$type])) {
self::$types[$type] = dibi::FIELD_TEXT;
foreach ($patterns as $s => $val) {
if (preg_match("#$s#i", $type)) {
return self::$types[$type] = $val;
}
}
}
return self::$types[$type];
}
}
@@ -454,6 +495,7 @@ class DibiColumnInfo extends DibiObject
/**
* Reflection metadata class for a foreign key.
* @package dibi
* @todo
*/
class DibiForeignKeyInfo extends DibiObject
{
@@ -502,7 +544,7 @@ class DibiForeignKeyInfo extends DibiObject
*/
class DibiIndexInfo extends DibiObject
{
/** @var array (name, columns, unique, primary) */
/** @var array (name, columns, [unique], [primary]) */
private $info;

View File

@@ -58,7 +58,7 @@ class DibiResult extends DibiObject implements IDataSource
* Cache for $driver->getColumnsMeta().
* @var array
*/
private $metaCache;
private $meta;
/**
* Already fetched? Used for allowance for first seek(0).
@@ -164,12 +164,8 @@ class DibiResult extends DibiObject implements IDataSource
final public function setWithTables($val)
{
if ($val) {
if ($this->metaCache === NULL) {
$this->metaCache = $this->getDriver()->getColumnsMeta();
}
$cols = array();
foreach ($this->metaCache as $info) {
foreach ($this->getMeta() as $info) {
$name = $info['fullname'];
if (isset($cols[$name])) {
$fix = 1;
@@ -446,6 +442,19 @@ class DibiResult extends DibiObject implements IDataSource
/**
* Autodetect column types.
* @return void
*/
final public function detectTypes()
{
foreach ($this->getMeta() as $info) {
$this->xlat[$info['name']] = array('type' => $info['type'], 'format' => NULL);
}
}
/**
* Define multiple columns types (for internal usage).
* @param array
@@ -508,18 +517,14 @@ class DibiResult extends DibiObject implements IDataSource
/**
* Gets an array of meta informations about column.
* Gets an array of meta informations about columns.
*
* @return array of DibiColumnInfo
*/
final public function getColumns()
{
if ($this->metaCache === NULL) {
$this->metaCache = $this->getDriver()->getColumnsMeta();
}
$cols = array();
foreach ($this->metaCache as $info) {
foreach ($this->getMeta() as $info) {
$cols[] = new DibiColumnInfo($this->driver, $info);
}
return $cols;
@@ -533,11 +538,8 @@ class DibiResult extends DibiObject implements IDataSource
*/
public function getColumnNames($withTables = FALSE)
{
if ($this->metaCache === NULL) {
$this->metaCache = $this->getDriver()->getColumnsMeta();
}
$cols = array();
foreach ($this->metaCache as $info) {
foreach ($this->getMeta() as $info) {
$cols[] = $info[$withTables ? 'fullname' : 'name'];
}
return $cols;
@@ -623,6 +625,22 @@ class DibiResult extends DibiObject implements IDataSource
}
/**
* Meta lazy initialization.
* @return array
*/
private function getMeta()
{
if ($this->meta === NULL) {
$this->meta = $this->getDriver()->getColumnsMeta();
foreach ($this->meta as & $row) {
$row['type'] = DibiColumnInfo::detectType($row['nativetype']);
}
}
return $this->meta;
}
}