Work in progress on fetching table defs from existing tables in new format -- unfinished
This commit is contained in:
parent
6df4ed697c
commit
a680e1798c
@ -81,7 +81,8 @@ class MysqlSchema extends Schema
|
|||||||
public function getTableDef($name)
|
public function getTableDef($name)
|
||||||
{
|
{
|
||||||
$query = "SELECT * FROM INFORMATION_SCHEMA.COLUMNS " .
|
$query = "SELECT * FROM INFORMATION_SCHEMA.COLUMNS " .
|
||||||
"WHERE TABLE_SCHEMA='%s' AND TABLE_NAME='%s'";
|
"WHERE TABLE_SCHEMA='%s' AND TABLE_NAME='%s' " .
|
||||||
|
"ORDER BY ORDINAL_POSITION";
|
||||||
$schema = $this->conn->dsn['database'];
|
$schema = $this->conn->dsn['database'];
|
||||||
$sql = sprintf($query, $schema, $name);
|
$sql = sprintf($query, $schema, $name);
|
||||||
$res = $this->conn->query($sql);
|
$res = $this->conn->query($sql);
|
||||||
@ -98,45 +99,124 @@ class MysqlSchema extends Schema
|
|||||||
|
|
||||||
$td->name = $name;
|
$td->name = $name;
|
||||||
$td->columns = array();
|
$td->columns = array();
|
||||||
|
$def = array();
|
||||||
|
|
||||||
$row = array();
|
$row = array();
|
||||||
|
|
||||||
while ($res->fetchInto($row, DB_FETCHMODE_ASSOC)) {
|
while ($res->fetchInto($row, DB_FETCHMODE_ASSOC)) {
|
||||||
|
|
||||||
$cd = new ColumnDef();
|
$name = $row['COLUMN_NAME'];
|
||||||
|
$field = array();
|
||||||
|
|
||||||
$cd->name = $row['COLUMN_NAME'];
|
if ($row['DATA_TYPE'] !== null) {
|
||||||
|
$field['type'] = $row['DATA_TYPE'];
|
||||||
$packed = $row['COLUMN_TYPE'];
|
}
|
||||||
|
if ($row['CHARACTER_MAXIMUM_LENGTH'] !== null) {
|
||||||
if (preg_match('/^(\w+)\((\d+)\)$/', $packed, $match)) {
|
$field['length'] = intval($row['CHARACTER_MAXIMUM_LENGTH']);
|
||||||
$cd->type = $match[1];
|
}
|
||||||
$cd->size = $match[2];
|
if ($row['NUMERIC_PRECISION'] !== null) {
|
||||||
} else {
|
$field['precision'] = intval($row['NUMERIC_PRECISION']);
|
||||||
$cd->type = $packed;
|
}
|
||||||
|
if ($row['NUMERIC_SCALE'] !== null) {
|
||||||
|
$field['scale'] = intval($row['NUMERIC_SCALE']);
|
||||||
|
}
|
||||||
|
if ($row['IS_NULLABLE'] == 'NO') {
|
||||||
|
$field['not null'] = true;
|
||||||
|
}
|
||||||
|
if ($row['COLUMN_DEFAULT'] !== null) {
|
||||||
|
$field['default'] = $row['COLUMN_DEFAULT'];
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
if ($row['COLUMN_KEY'] == 'PRI') {
|
||||||
|
if (isset($def['primary keys'])) {
|
||||||
|
$def['primary keys'][] = $name;
|
||||||
|
} else {
|
||||||
|
$def['primary keys'][] = array($name);
|
||||||
|
}
|
||||||
|
} else if ($row['COLUMN_KEY'] == 'MUL') {
|
||||||
|
// @fixme
|
||||||
|
} else if ($row['COLUMN_KEY'] == 'UNI') {
|
||||||
|
// @fixme
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
if ($row['COLUMN_COMMENT'] !== null) {
|
||||||
|
$field['description'] = $row['COLUMN_COMMENT'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$cd->nullable = ($row['IS_NULLABLE'] == 'YES') ? true : false;
|
// $row['EXTRA'] may contain 'autoincrement'
|
||||||
$cd->key = $row['COLUMN_KEY'];
|
// ^ type=serial?
|
||||||
$cd->default = $row['COLUMN_DEFAULT'];
|
// $row['EXTRA'] may contain 'on update CURRENT_TIMESTAMP'
|
||||||
$cd->extra = $row['EXTRA'];
|
// ^ ...... how to specify?
|
||||||
|
// these seem to be the only values in curent use
|
||||||
// Autoincrement is stuck into the extra column.
|
|
||||||
// Pull it out so we don't accidentally mod it every time...
|
if ($row['CHARACTER_SET_NAME'] !== null) {
|
||||||
$extra = preg_replace('/(^|\s)auto_increment(\s|$)/i', '$1$2', $cd->extra);
|
// @fixme check against defaults?
|
||||||
if ($extra != $cd->extra) {
|
//$def['charset'] = $row['CHARACTER_SET_NAME'];
|
||||||
$cd->extra = trim($extra);
|
//$def['collate'] = $row['COLLATION_NAME'];
|
||||||
$cd->auto_increment = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// mysql extensions -- not (yet) used by base class
|
$def['fields'][$name] = $field;
|
||||||
$cd->charset = $row['CHARACTER_SET_NAME'];
|
|
||||||
$cd->collate = $row['COLLATION_NAME'];
|
|
||||||
|
|
||||||
$td->columns[] = $cd;
|
|
||||||
}
|
}
|
||||||
$res->free();
|
$res->free();
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
BLURRRRRRF
|
||||||
|
we need to first pull the list/types of keys
|
||||||
|
|
||||||
|
we could get those and the columns like this:
|
||||||
|
// this works but is insanely slow!
|
||||||
|
SELECT CONSTRAINT_NAME AS keyName,
|
||||||
|
(SELECT GROUP_CONCAT(COLUMN_NAME)
|
||||||
|
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS keyColumns
|
||||||
|
WHERE keyColumns.TABLE_SCHEMA=keyDefs.TABLE_SCHEMA
|
||||||
|
AND keyColumns.TABLE_NAME=keyDefs.TABLE_NAME
|
||||||
|
AND keyColumns.CONSTRAINT_NAME=keyDefs.CONSTRAINT_NAME
|
||||||
|
ORDER BY ORDINAL_POSITION)
|
||||||
|
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS keyDefs
|
||||||
|
WHERE TABLE_SCHEMA='mublog'
|
||||||
|
AND TABLE_NAME='subscription'
|
||||||
|
ORDER BY TABLE_NAME, CONSTRAINT_NAME;
|
||||||
|
|
||||||
|
However MySQL's query optimizer is crap here and it does something
|
||||||
|
insane. ;) Using constants is faster, but won't let us do bulk
|
||||||
|
fetches. So... maybe go ahead and fetch each table separately.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Now fetch the key info...
|
||||||
|
$query = "SELECT * FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE " .
|
||||||
|
"WHERE TABLE_SCHEMA='%s' AND TABLE_NAME='%s' " .
|
||||||
|
"ORDER BY CONSTRAINT_NAME,ORDINAL_POSITION";
|
||||||
|
$schema = $this->conn->dsn['database'];
|
||||||
|
$sql = sprintf($query, $schema, $name);
|
||||||
|
$res = $this->conn->query($sql);
|
||||||
|
|
||||||
|
if (PEAR::isError($res)) {
|
||||||
|
throw new Exception($res->getMessage());
|
||||||
|
}
|
||||||
|
if ($res->numRows() == 0) {
|
||||||
|
$res->free();
|
||||||
|
throw new SchemaTableMissingException("No such table: $name");
|
||||||
|
}
|
||||||
|
$row = array();
|
||||||
|
|
||||||
|
while ($res->fetchInto($row, DB_FETCHMODE_ASSOC)) {
|
||||||
|
$keyName = $row['CONSTRAINT_NAME'];
|
||||||
|
$colName = $row['COLUMN_NAME'];
|
||||||
|
// @fixme what about prefixes?
|
||||||
|
if ($keyName == 'PRIMARY') {
|
||||||
|
if (!isset($def['primary key'])) {
|
||||||
|
$def['primary key'] = array();
|
||||||
|
}
|
||||||
|
$def['primary key'][] = $colName;
|
||||||
|
} else {
|
||||||
|
if (!isset($def['indexes'][$keyName])) {
|
||||||
|
$def['indexes'][$keyName] = array();
|
||||||
|
}
|
||||||
|
$def['indexes'][$keyName][] = $colName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$res->free();
|
||||||
return $td;
|
return $td;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user