diff --git a/dibi/drivers/mssql.php b/dibi/drivers/mssql.php index 6b528a23..f4811e53 100644 --- a/dibi/drivers/mssql.php +++ b/dibi/drivers/mssql.php @@ -339,15 +339,18 @@ class DibiMsSqlDriver extends DibiObject implements IDibiDriver public function getColumnsMeta() { $count = mssql_num_fields($this->resultSet); - $meta = array(); + $res = array(); for ($i = 0; $i < $count; $i++) { - // items 'name' and 'table' are required - $info = (array) mssql_fetch_field($this->resultSet, $i); - $info['table'] = $info['column_source']; - $info['nativetype'] = $info['type']; - $meta[] = $info; + $row = (array) mssql_fetch_field($this->resultSet, $i); + $res[] = array( + '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 $meta; + return $res; } diff --git a/dibi/drivers/mysql.php b/dibi/drivers/mysql.php index 1751af84..e94b5b7f 100644 --- a/dibi/drivers/mysql.php +++ b/dibi/drivers/mysql.php @@ -405,13 +405,18 @@ class DibiMySqlDriver extends DibiObject implements IDibiDriver public function getColumnsMeta() { $count = mysql_num_fields($this->resultSet); - $meta = array(); + $res = array(); for ($i = 0; $i < $count; $i++) { - $info = (array) mysql_fetch_field($this->resultSet, $i); - $info['nativetype'] = $info['type']; - $meta[] = $info; + $row = (array) mysql_fetch_field($this->resultSet, $i); + $res[] = array( + 'fullname' => $row['table'] ? $row['table'] . '.' . $row['name'] : $row['name'], + 'type' => NULL, + 'nativetype' => strtoupper($row['type']), + 'nullable' => !($row['not_null']), + 'default' => $row['def'], + ) + $row; } - return $meta; + return $res; } @@ -438,10 +443,13 @@ class DibiMySqlDriver extends DibiObject implements IDibiDriver */ public function getTables() { - $this->query("SHOW TABLES"); + $this->query("SHOW FULL TABLES"); $res = array(); - while ($row = mysql_fetch_array($this->resultSet, MYSQL_NUM)) { - $res[] = array('name' => $row[0]); + while ($row = $this->fetch(FALSE)) { + $res[] = array( + 'name' => $row[0], + 'view' => isset($row[1]) && $row[1] === 'VIEW', + ); } $this->free(); return $res; @@ -456,7 +464,22 @@ class DibiMySqlDriver extends DibiObject implements IDibiDriver */ public function getColumns($table) { - throw new NotImplementedException; + $this->query("SHOW COLUMNS FROM `$table`"); + $res = array(); + while ($row = $this->fetch(TRUE)) { + $type = explode('(', $row['Type']); + $res[] = array( + 'name' => $row['Field'], + 'table' => $table, + 'nativetype' => strtoupper($type[0]), + 'size' => isset($type[1]) ? (int) $type[1] : NULL, + 'nullable' => $row['Null'] === 'YES', + 'default' => $row['Default'], + 'autoincrement' => $row['Extra'] === 'auto_increment', + ); + } + $this->free(); + return $res; } @@ -468,7 +491,16 @@ class DibiMySqlDriver extends DibiObject implements IDibiDriver */ public function getIndexes($table) { - throw new NotImplementedException; + $this->query("SHOW INDEX FROM `$table`"); + $res = array(); + while ($row = $this->fetch(TRUE)) { + $res[$row['Key_name']]['name'] = $row['Key_name']; + $res[$row['Key_name']]['unique'] = !$row['Non_unique']; + $res[$row['Key_name']]['primary'] = $row['Key_name'] === 'PRIMARY'; + $res[$row['Key_name']]['columns'][$row['Seq_in_index'] - 1] = $row['Column_name']; + } + $this->free(); + return array_values($res); } diff --git a/dibi/drivers/mysqli.php b/dibi/drivers/mysqli.php index 4755fb89..7f563ad8 100644 --- a/dibi/drivers/mysqli.php +++ b/dibi/drivers/mysqli.php @@ -387,14 +387,22 @@ class DibiMySqliDriver extends DibiObject implements IDibiDriver public function getColumnsMeta() { $count = mysqli_num_fields($this->resultSet); - $meta = array(); + $res = array(); for ($i = 0; $i < $count; $i++) { - // items 'name' and 'table' are required - $info = (array) mysqli_fetch_field_direct($this->resultSet, $i); - $info['nativetype'] = $info['type']; - $meta[] = $info; + $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; } - return $meta; + return $res; } @@ -421,10 +429,18 @@ class DibiMySqliDriver extends DibiObject implements IDibiDriver */ public function getTables() { - $this->query("SHOW TABLES"); + /*$this->query(" + SELECT TABLE_NAME as name, TABLE_TYPE = 'VIEW' as view + FROM INFORMATION_SCHEMA.TABLES + WHERE TABLE_SCHEMA = DATABASE() + ");*/ + $this->query("SHOW FULL TABLES"); $res = array(); - while ($row = mysqli_fetch_array($this->resultSet, MYSQLI_NUM)) { - $res[] = array('name' => $row[0]); + while ($row = $this->fetch(FALSE)) { + $res[] = array( + 'name' => $row[0], + 'view' => isset($row[1]) && $row[1] === 'VIEW', + ); } $this->free(); return $res; @@ -439,7 +455,28 @@ class DibiMySqliDriver extends DibiObject implements IDibiDriver */ public function getColumns($table) { - throw new NotImplementedException; + /*$table = $this->escape($table, dibi::FIELD_TEXT); + $this->query(" + SELECT * + FROM INFORMATION_SCHEMA.COLUMNS + WHERE TABLE_NAME = $table AND TABLE_SCHEMA = DATABASE() + ");*/ + $this->query("SHOW COLUMNS FROM `$table`"); + $res = array(); + while ($row = $this->fetch(TRUE)) { + $type = explode('(', $row['Type']); + $res[] = array( + 'name' => $row['Field'], + 'table' => $table, + 'nativetype' => strtoupper($type[0]), + 'size' => isset($type[1]) ? (int) $type[1] : NULL, + 'nullable' => $row['Null'] === 'YES', + 'default' => $row['Default'], + 'autoincrement' => $row['Extra'] === 'auto_increment', + ); + } + $this->free(); + return $res; } @@ -451,7 +488,23 @@ class DibiMySqliDriver extends DibiObject implements IDibiDriver */ public function getIndexes($table) { - throw new NotImplementedException; + /*$table = $this->escape($table, dibi::FIELD_TEXT); + $this->query(" + SELECT * + FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE + WHERE TABLE_NAME = $table AND TABLE_SCHEMA = DATABASE() + AND REFERENCED_COLUMN_NAME IS NULL + ");*/ + $this->query("SHOW INDEX FROM `$table`"); + $res = array(); + while ($row = $this->fetch(TRUE)) { + $res[$row['Key_name']]['name'] = $row['Key_name']; + $res[$row['Key_name']]['unique'] = !$row['Non_unique']; + $res[$row['Key_name']]['primary'] = $row['Key_name'] === 'PRIMARY'; + $res[$row['Key_name']]['columns'][$row['Seq_in_index'] - 1] = $row['Column_name']; + } + $this->free(); + return array_values($res); } diff --git a/dibi/drivers/odbc.php b/dibi/drivers/odbc.php index b4f7f08c..5b9843b5 100644 --- a/dibi/drivers/odbc.php +++ b/dibi/drivers/odbc.php @@ -361,19 +361,16 @@ class DibiOdbcDriver extends DibiObject implements IDibiDriver public function getColumnsMeta() { $count = odbc_num_fields($this->resultSet); - $meta = array(); + $res = array(); for ($i = 1; $i <= $count; $i++) { - // items 'name' and 'table' are required - $meta[] = array( + $res[] = array( 'name' => odbc_field_name($this->resultSet, $i), 'table' => NULL, + 'fullname' => odbc_field_name($this->resultSet, $i), 'nativetype'=> odbc_field_type($this->resultSet, $i), - 'length' => odbc_field_len($this->resultSet, $i), - 'scale' => odbc_field_scale($this->resultSet, $i), - 'precision' => odbc_field_precision($this->resultSet, $i), ); } - return $meta; + return $res; } @@ -402,9 +399,15 @@ class DibiOdbcDriver extends DibiObject implements IDibiDriver { $result = odbc_tables($this->connection); $res = array(); - while (odbc_fetch_row($result)) { - $res[] = array('name' => odbc_result($result, 'TABLE_NAME')); + while ($row = odbc_fetch_array($result)) { + if ($row['TABLE_TYPE'] === 'TABLE' || $row['TABLE_TYPE'] === 'VIEW') { + $res[] = array( + 'name' => $row['TABLE_NAME'], + 'view' => $row['TABLE_TYPE'] === 'VIEW', + ); + } } + odbc_free_result($result); return $res; } @@ -417,7 +420,22 @@ class DibiOdbcDriver extends DibiObject implements IDibiDriver */ public function getColumns($table) { - throw new NotImplementedException; + $result = odbc_columns($this->connection); + $res = array(); + while ($row = odbc_fetch_array($result)) { + if ($row['TABLE_NAME'] === $table) { + $res[] = array( + 'name' => $row['COLUMN_NAME'], + 'table' => $table, + 'nativetype' => $row['TYPE_NAME'], + 'size' => $row['COLUMN_SIZE'], + 'nullable' => (bool) $row['NULLABLE'], + 'default' => $row['COLUMN_DEF'], + ); + } + } + odbc_free_result($result); + return $res; } diff --git a/dibi/drivers/oracle.php b/dibi/drivers/oracle.php index 6b1d6588..d1c7ecd7 100644 --- a/dibi/drivers/oracle.php +++ b/dibi/drivers/oracle.php @@ -347,19 +347,16 @@ class DibiOracleDriver extends DibiObject implements IDibiDriver public function getColumnsMeta() { $count = oci_num_fields($this->resultSet); - $meta = array(); + $res = array(); for ($i = 1; $i <= $count; $i++) { - // items 'name' and 'table' are required - $meta[] = array( + $res[] = array( 'name' => oci_field_name($this->resultSet, $i), 'table' => NULL, + 'fullname' => oci_field_name($this->resultSet, $i), 'nativetype'=> oci_field_type($this->resultSet, $i), - 'size' => oci_field_size($this->resultSet, $i), - 'scale' => oci_field_scale($this->resultSet, $i), - 'precision' => oci_field_precision($this->resultSet, $i), ); } - return $meta; + return $res; } diff --git a/dibi/drivers/pdo.php b/dibi/drivers/pdo.php index d4bfeef7..ed055aa7 100644 --- a/dibi/drivers/pdo.php +++ b/dibi/drivers/pdo.php @@ -393,17 +393,19 @@ class DibiPdoDriver extends DibiObject implements IDibiDriver public function getColumnsMeta() { $count = $this->resultSet->columnCount(); - $meta = array(); + $res = array(); for ($i = 0; $i < $count; $i++) { - // items 'name' and 'table' are required - $info = @$this->resultSet->getColumnsMeta($i); // intentionally @ - if ($info === FALSE) { + $row = @$this->resultSet->getColumnMeta($i); // intentionally @ + if ($row === FALSE) { throw new DibiDriverException('Driver does not support meta data.'); } - $info['nativetype'] = $info['native_type']; - $meta[] = $info; + $res[] = array( + 'type' => NULL, + 'nativetype' => $row['native_type'], + 'fullname' => $row['table'] ? $row['table'] . '.' . $row['name'] : $row['name'], + ) + $row; } - return $meta; + return $res; } diff --git a/dibi/drivers/postgre.php b/dibi/drivers/postgre.php index 88663437..20b96f07 100644 --- a/dibi/drivers/postgre.php +++ b/dibi/drivers/postgre.php @@ -396,18 +396,17 @@ class DibiPostgreDriver extends DibiObject implements IDibiDriver { $hasTable = version_compare(PHP_VERSION , '5.2.0', '>='); $count = pg_num_fields($this->resultSet); - $meta = array(); + $res = array(); for ($i = 0; $i < $count; $i++) { - // items 'name' and 'table' are required - $meta[] = array( + $row = array( 'name' => pg_field_name($this->resultSet, $i), 'table' => $hasTable ? pg_field_table($this->resultSet, $i) : NULL, 'nativetype'=> pg_field_type($this->resultSet, $i), - 'size' => pg_field_size($this->resultSet, $i), - 'prtlen' => pg_field_prtlen($this->resultSet, $i), ); + $row['fullname'] = $row['table'] ? $row['table'] . '.' . $row['name'] : $row['name']; + $res[] = $row; } - return $meta; + return $res; } @@ -434,7 +433,14 @@ class DibiPostgreDriver extends DibiObject implements IDibiDriver */ public function getTables() { - throw new NotImplementedException; + $this->query(" + SELECT table_name as name, CAST(table_type = 'VIEW' AS INTEGER) as view + FROM information_schema.tables + WHERE table_schema = current_schema() + "); + $res = pg_fetch_all($this->resultSet); + $this->free(); + return $res; } diff --git a/dibi/drivers/sqlite.php b/dibi/drivers/sqlite.php index 29f9e72e..b4c5714f 100644 --- a/dibi/drivers/sqlite.php +++ b/dibi/drivers/sqlite.php @@ -361,18 +361,17 @@ class DibiSqliteDriver extends DibiObject implements IDibiDriver public function getColumnsMeta() { $count = sqlite_num_fields($this->resultSet); - $meta = array(); + $res = array(); for ($i = 0; $i < $count; $i++) { - $pair = explode('.', str_replace(array('[', ']'), '', sqlite_field_name($this->resultSet, $i))); - if (!isset($pair[1])) { - array_unshift($pair, NULL); - } - $meta[] = array( - 'name' => $pair[1], - 'table' => $pair[0], + $name = str_replace(array('[', ']'), '', sqlite_field_name($this->resultSet, $i)); + $pair = explode('.', $name); + $res[] = array( + 'name' => isset($pair[1]) ? $pair[1] : $pair[0], + 'table' => isset($pair[1]) ? $pair[0] : NULL, + 'fullname' => $name, ); } - return $meta; + return $res; } @@ -400,10 +399,14 @@ class DibiSqliteDriver extends DibiObject implements IDibiDriver public function getTables() { $this->query(" - SELECT name FROM sqlite_master WHERE type='table' - UNION ALL SELECT name FROM sqlite_temp_master WHERE type='table' ORDER BY name + SELECT name, type = 'view' as view FROM sqlite_master WHERE type IN ('table', 'view') + UNION ALL + SELECT name, type = 'view' as view FROM sqlite_temp_master WHERE type IN ('table', 'view') + ORDER BY name "); - return sqlite_fetch_all($this->resultSet, SQLITE_ASSOC); + $res = sqlite_fetch_all($this->resultSet, SQLITE_ASSOC); + $this->free(); + return $res; } diff --git a/dibi/libs/DibiDataSource.php b/dibi/libs/DibiDataSource.php index 636da9ce..58cf79bb 100644 --- a/dibi/libs/DibiDataSource.php +++ b/dibi/libs/DibiDataSource.php @@ -65,7 +65,7 @@ class DibiDataSource extends DibiObject implements IDataSource * @param array columns * @return ArrayIterator */ - public function getIterator($offset = NULL, $limit = NULL, $cols = NULL) + public function getIterator($offset = NULL, $limit = NULL) { return $this->connection->query(' SELECT * diff --git a/dibi/libs/DibiDatabaseInfo.php b/dibi/libs/DibiDatabaseInfo.php index 65d2a3d0..ebb497a4 100644 --- a/dibi/libs/DibiDatabaseInfo.php +++ b/dibi/libs/DibiDatabaseInfo.php @@ -111,16 +111,6 @@ class DibiDatabaseInfo extends DibiObject - /** - * @return array - */ - public function getSequences() - { - throw new NotImplementedException; - } - - - /** * @return void */ @@ -289,7 +279,7 @@ class DibiTableInfo extends DibiObject { if ($this->columns === NULL) { $this->columns = array(); - foreach ($this->driver->getColumns($this->name) as $info) { + foreach ($this->driver->getColumns($this->info['name']) as $info) { $this->columns[strtolower($info['name'])] = new DibiColumnInfo($this->driver, $info); } } @@ -305,15 +295,13 @@ class DibiTableInfo extends DibiObject if ($this->indexes === NULL) { $this->initColumns(); $this->indexes = array(); - foreach ($this->driver->getIndexes($this->name) as $info) { - $cols = array(); - foreach ($info['columns'] as $name) { - $cols[] = $this->columns[strtolower($name)]; + foreach ($this->driver->getIndexes($this->info['name']) as $info) { + foreach ($info['columns'] as $key => $name) { + $info['columns'][$key] = $this->columns[strtolower($name)]; } - $name = $info['name']; - $this->indexes[strtolower($name)] = new DibiIndexInfo($this, $name, $cols, $info['unique']); + $this->indexes[strtolower($info['name'])] = new DibiIndexInfo($info); if (!empty($info['primary'])) { - $this->primaryKey = $this->indexes[strtolower($name)]; + $this->primaryKey = $this->indexes[strtolower($info['name'])]; } } } @@ -343,7 +331,7 @@ class DibiColumnInfo extends DibiObject /** @var IDibiDriver */ private $driver; - /** @var array (name, table, type, nativetype, size, precision, scale, nullable, default, autoincrement) */ + /** @var array (name, table, fullname, type, nativetype, size, nullable, default, autoincrement) */ private $info; @@ -366,6 +354,16 @@ class DibiColumnInfo extends DibiObject + /** + * @return bool + */ + public function hasTable() + { + return !empty($this->info['table']); + } + + + /** * @return DibiTableInfo */ @@ -409,26 +407,6 @@ class DibiColumnInfo extends DibiObject - /** - * @return int - */ - public function getPrecision() - { - return isset($this->info['precision']) ? (int) $this->info['precision'] : NULL; - } - - - - /** - * @return int - */ - public function getScale() - { - return isset($this->info['scale']) ? (int) $this->info['scale'] : NULL; - } - - - /** * @return bool */ @@ -452,11 +430,22 @@ class DibiColumnInfo extends DibiObject /** * @return mixed */ - public function getDefaultValue() + public function getDefault() { return isset($this->info['default']) ? $this->info['default'] : NULL; } + + + /** + * @param string + * @return mixed + */ + public function getInfo($key) + { + return isset($this->info[$key]) ? $this->info[$key] : NULL; + } + } @@ -513,22 +502,13 @@ class DibiForeignKeyInfo extends DibiObject */ class DibiIndexInfo extends DibiObject { - /** @var string */ - private $name; - - /** @var array of DibiColumnInfo */ - private $columns; - - /** @var bool */ - private $unique; + /** @var array (name, columns, unique, primary) */ + private $info; - - public function __construct($name, array $columns, $unique) + public function __construct(array $info) { - $this->name = $name; - $this->columns = $columns; - $this->unique = (bool) $unique; + $this->info = $info; } @@ -538,7 +518,7 @@ class DibiIndexInfo extends DibiObject */ public function getName() { - return $this->name; + return $this->info['name']; } @@ -548,7 +528,7 @@ class DibiIndexInfo extends DibiObject */ public function getColumns() { - return $this->columns; + return $this->info['columns']; } @@ -558,7 +538,18 @@ class DibiIndexInfo extends DibiObject */ public function isUnique() { - return $this->unique; + return !empty($this->info['unique']); + } + + + + + /** + * @return bool + */ + public function isPrimary() + { + return !empty($this->info['primary']); } } diff --git a/dibi/libs/DibiFluent.php b/dibi/libs/DibiFluent.php index fedc1abd..13596985 100644 --- a/dibi/libs/DibiFluent.php +++ b/dibi/libs/DibiFluent.php @@ -216,7 +216,7 @@ class DibiFluent extends DibiObject * @param string flag name * @return bool */ - final public function getFlag($flag, $value = TRUE) + final public function getFlag($flag) { return isset($this->flags[strtoupper($flag)]); } diff --git a/dibi/libs/DibiObject.php b/dibi/libs/DibiObject.php index 37e174bd..142efdb4 100644 --- a/dibi/libs/DibiObject.php +++ b/dibi/libs/DibiObject.php @@ -124,7 +124,7 @@ abstract class DibiObject } } } - return; + return NULL; } } @@ -173,7 +173,7 @@ abstract class DibiObject self::$extMethods[$pair[1]][''] = NULL; } } - if ($name === NULL) return; + if ($name === NULL) return NULL; } $name = strtolower($name); @@ -189,7 +189,7 @@ abstract class DibiObject if ($callback !== NULL) { // works as setter $l[$class] = $callback; $l[''] = NULL; - return; + return NULL; } // works as getter diff --git a/dibi/libs/DibiResult.php b/dibi/libs/DibiResult.php index 0f57ac31..4bc7c4aa 100644 --- a/dibi/libs/DibiResult.php +++ b/dibi/libs/DibiResult.php @@ -169,9 +169,8 @@ class DibiResult extends DibiObject implements IDataSource } $cols = array(); - foreach ($this->metaCache as $col) { - // intentional == - $name = $col['table'] == '' ? $col['name'] : ($col['table'] . '.' . $col['name']); + foreach ($this->metaCache as $info) { + $name = $info['fullname']; if (isset($cols[$name])) { $fix = 1; while (isset($cols[$name . '#' . $fix])) $fix++; @@ -539,7 +538,7 @@ class DibiResult extends DibiObject implements IDataSource } $cols = array(); foreach ($this->metaCache as $info) { - $cols[] = (!$withTables || $info['table'] === NULL) ? $info['name'] : ($info['table'] . '.' . $info['name']); + $cols[] = $info[$withTables ? 'fullname' : 'name']; } return $cols; } diff --git a/dibi/libs/DibiTable.php b/dibi/libs/DibiTable.php index 34f3e0b3..d624c914 100644 --- a/dibi/libs/DibiTable.php +++ b/dibi/libs/DibiTable.php @@ -147,9 +147,7 @@ abstract class DibiTable extends DibiObject 'INSERT INTO %n', $this->name, '%v', $this->prepare($data) ); - if ($this->primaryAutoIncrement) { - return $this->connection->insertId(); - } + return $this->primaryAutoIncrement ? $this->connection->insertId() : NULL; } diff --git a/dibi/libs/DibiTranslator.php b/dibi/libs/DibiTranslator.php index c47311d4..f2c39f4a 100644 --- a/dibi/libs/DibiTranslator.php +++ b/dibi/libs/DibiTranslator.php @@ -250,7 +250,7 @@ final class DibiTranslator extends DibiObject case 'by': // key ASC, key DESC foreach ($value as $k => $v) { if (is_string($k)) { - $v = (is_string($v) && strcasecmp($v, 'desc')) || $v > 0 ? 'ASC' : 'DESC'; + $v = (is_string($v) && strncasecmp($v, 'd', 1)) || $v > 0 ? 'ASC' : 'DESC'; $vx[] = $this->delimite($k) . ' ' . $v; } else { $vx[] = $this->delimite($v);