$orderedFields[$row['ordinal_position']] = $name;
$field = array();
-
- // ??
- list($type, $size) = $this->reverseMapType($row['udt_name']);
- $field['type'] = $type;
- if ($size !== null) {
- $field['size'] = $size;
- }
+ $field['type'] = $row['udt_name'];
if ($type == 'char' || $type == 'varchar') {
if ($row['character_maximum_length'] !== null) {
return $out;
}
- /**
- *
- * Creates a table with the given names and columns.
- *
- * @param string $name Name of the table
- * @param array $columns Array of ColumnDef objects
- * for new table.
- *
- * @return boolean success flag
- */
-
- public function createTable($name, $columns)
- {
- $uniques = array();
- $primary = array();
- $indices = array();
- $onupdate = array();
-
- $sql = "CREATE TABLE $name (\n";
-
- for ($i = 0; $i < count($columns); $i++) {
-
- $cd =& $columns[$i];
-
- if ($i > 0) {
- $sql .= ",\n";
- }
-
- $sql .= $this->_columnSql($cd);
- switch ($cd->key) {
- case 'UNI':
- $uniques[] = $cd->name;
- break;
- case 'PRI':
- $primary[] = $cd->name;
- break;
- case 'MUL':
- $indices[] = $cd->name;
- break;
- }
- }
-
- if (count($primary) > 0) { // it really should be...
- $sql .= ",\n PRIMARY KEY (" . implode(',', $primary) . ")";
- }
-
- $sql .= "); ";
-
-
- foreach ($uniques as $u) {
- $sql .= "\n CREATE index {$name}_{$u}_idx ON {$name} ($u); ";
- }
-
- foreach ($indices as $i) {
- $sql .= "CREATE index {$name}_{$i}_idx ON {$name} ($i)";
- }
- $res = $this->conn->query($sql);
-
- if (PEAR::isError($res)) {
- throw new Exception($res->getMessage(). ' SQL was '. $sql);
- }
-
- return true;
- }
-
/**
* Translate the (mostly) mysql-ish column types into somethings more standard
* @param string column type
return $type;
}
- /**
- * Modifies a column in the schema.
- *
- * The name must match an existing column and table.
- *
- * @param string $table name of the table
- * @param ColumnDef $columndef new definition of the column.
- *
- * @return boolean success flag
- */
-
- public function modifyColumn($table, $columndef)
- {
- $sql = "ALTER TABLE $table ALTER COLUMN TYPE " .
- $this->_columnSql($columndef);
-
- $res = $this->conn->query($sql);
-
- if (PEAR::isError($res)) {
- throw new Exception($res->getMessage());
- }
-
- return true;
- }
-
/**
* Return the proper SQL for creating or
* altering a column.
* Appropriate for use in CREATE TABLE or
* ALTER TABLE statements.
*
- * @param string $tableName
- * @param array $tableDef
- * @param string $columnName
* @param array $cd column to create
*
* @return string correct SQL for that column
*/
- function columnSql($name, array $cd)
+ function columnSql(array $cd)
{
$line = array();
- $line[] = parent::_columnSql($cd);
+ $line[] = parent::columnSql($cd);
+ /*
if ($table['foreign keys'][$name]) {
foreach ($table['foreign keys'][$name] as $foreignTable => $foreignColumn) {
$line[] = 'references';
- $line[] = $this->quoteId($foreignTable);
- $line[] = '(' . $this->quoteId($foreignColumn) . ')';
+ $line[] = $this->quoteIdentifier($foreignTable);
+ $line[] = '(' . $this->quoteIdentifier($foreignColumn) . ')';
}
}
+ */
return implode(' ', $line);
}
}
}
+ /**
+ * Append an SQL statement to drop an index from a table.
+ * Note that in PostgreSQL, index names are DB-unique.
+ *
+ * @param array $statements
+ * @param string $table
+ * @param string $name
+ * @param array $def
+ */
+ function appendDropIndex(array &$statements, $table, $name)
+ {
+ $statements[] = "DROP INDEX $name";
+ }
+
/**
* Quote a db/table/column identifier if necessary.
*
*/
function quoteIdentifier($name)
{
- return '"' . $name . '"';
+ return $this->conn->quoteIdentifier($name);
}
function mapType($column)
$type = $map[$type];
}
- if (!empty($column['size'])) {
- $size = $column['size'];
- if ($type == 'integer' &&
- in_array($size, array('small', 'big'))) {
- $type = $size . 'int';
+ if ($type == 'int') {
+ if (!empty($column['size'])) {
+ $size = $column['size'];
+ if ($size == 'small') {
+ return 'int2';
+ } else if ($size == 'big') {
+ return 'int8';
+ }
}
+ return 'int4';
}
return $type;
}
/**
- * Map a native type back to an independent type + size
+ * Filter the given table definition array to match features available
+ * in this database.
*
- * @param string $type
- * @return array ($type, $size) -- $size may be null
+ * This lets us strip out unsupported things like comments, foreign keys,
+ * or type variants that we wouldn't get back from getTableDef().
+ *
+ * @param array $tableDef
*/
- protected function reverseMapType($type)
+ function filterDef(array $tableDef)
{
- $type = strtolower($type);
- $map = array(
- 'int4' => array('int', null),
- 'int8' => array('int', 'big'),
- 'bytea' => array('blob', null),
- );
- if (isset($map[$type])) {
- return $map[$type];
- } else {
- return array($type, null);
+ foreach ($tableDef['fields'] as $name => &$col) {
+ // No convenient support for field descriptions
+ unset($col['description']);
+
+ /*
+ if (isset($col['size'])) {
+ // Don't distinguish between tinyint and int.
+ if ($col['size'] == 'tiny' && $col['type'] == 'int') {
+ unset($col['size']);
+ }
+ }
+ */
+ $col['type'] = $this->mapType($col);
+ unset($col['size']);
+ }
+ if (!empty($tableDef['primary key'])) {
+ $tableDef['primary key'] = $this->filterKeyDef($tableDef['primary key']);
+ }
+ if (!empty($tableDef['unique keys'])) {
+ foreach ($tableDef['unique keys'] as $i => $def) {
+ $tableDef['unique keys'][$i] = $this->filterKeyDef($def);
+ }
}
+ return $tableDef;
}
+ /**
+ * Filter the given key/index definition to match features available
+ * in this database.
+ *
+ * @param array $def
+ * @return array
+ */
+ function filterKeyDef(array $def)
+ {
+ // PostgreSQL doesn't like prefix lengths specified on keys...?
+ foreach ($def as $i => $item)
+ {
+ if (is_array($item)) {
+ $def[$i] = $item[0];
+ }
+ }
+ return $def;
+ }
}