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:
@@ -101,6 +101,7 @@ class dibi
|
||||
FIELD_FLOAT = 'f',
|
||||
FIELD_DATE = 'd',
|
||||
FIELD_DATETIME = 't',
|
||||
FIELD_TIME = 't',
|
||||
|
||||
// special
|
||||
IDENTIFIER = 'n';
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user