From 4f833531dd5aa05e56ab00dd95eda4ce8419564d Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 20 Jul 2009 19:04:48 -0400 Subject: start a module for schema management --- lib/schema.php | 124 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 lib/schema.php (limited to 'lib/schema.php') diff --git a/lib/schema.php b/lib/schema.php new file mode 100644 index 000000000..db2f49a78 --- /dev/null +++ b/lib/schema.php @@ -0,0 +1,124 @@ +. + * + * @category Database + * @package Laconica + * @author Evan Prodromou + * @copyright 2009 Control Yourself, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ + */ + +if (!defined('LACONICA')) { + exit(1); +} + +/** + * Class representing the database schema + * + * A class representing the database schema. Can be used to + * manipulate the schema -- especially for plugins and upgrade + * utilities. + * + * @category Database + * @package Laconica + * @author Evan Prodromou + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ + */ + +class Schema +{ + protected $db = null; + + static function get() + { + + } + + public function getTableDef($name) + { + } + + public function getColumnDef($table, $column) + { + } + + public function getIndexDef($table, $index) + { + } + + public function createTable($name, $columns, $indices=null) + { + } + + public function dropTable($name) + { + } + + public function createIndex($name, $table, $columns) + { + } + + public function dropIndex($name, $table) + { + } + + public function addColumn($table, $columndef) + { + } + + public function modifyColumn($table, $column, $columndef) + { + } + + public function dropColumn($table, $column) + { + } + + public function ensureTable($name, $columns, $indices) + { + $def = $this->tableDef($name); + if (empty($def)) { + return $this->createTable($name, $columns, $indices); + } + } +} + +class TableDef +{ + public $name; + public $columns; +} + +class ColumnDef +{ + public $name; + public $type; + public $size; +} + +class IndexDef +{ + public $name; + public $table; + public $columns; +} -- cgit v1.2.3-54-g00ecf From f31653ca5bc06db4d1a2a2dc8a1943f2d99f735a Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 24 Aug 2009 11:22:40 -0400 Subject: make table def method of schema code work --- lib/schema.php | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 2 deletions(-) (limited to 'lib/schema.php') diff --git a/lib/schema.php b/lib/schema.php index db2f49a78..624765eb2 100644 --- a/lib/schema.php +++ b/lib/schema.php @@ -47,15 +47,65 @@ if (!defined('LACONICA')) { class Schema { - protected $db = null; + static $_single = null; + protected $conn = null; - static function get() + protected function __construct() { + // XXX: there should be an easier way to do this. + $user = new User(); + $this->conn = $user->getDatabaseConnection(); + $user->free(); + unset($user); + } + static function get() + { + if (empty(self::$_single)) { + self::$_single = new Schema(); + } + return self::$_single; } public function getTableDef($name) { + $res =& $this->conn->query('DESCRIBE ' . $name); + + if (PEAR::isError($res)) { + throw new Exception($res->getMessage()); + } + + $td = new TableDef(); + + $td->name = $name; + $td->columns = array(); + + $row = array(); + + while ($res->fetchInto($row, DB_FETCHMODE_ASSOC)) { + + $cd = new ColumnDef(); + + $cd->name = $row['Field']; + + $packed = $row['Type']; + + if (preg_match('/^(\w+)\((\d+)\)$/', $packed, $match)) { + $cd->type = $match[1]; + $cd->size = $match[2]; + } else { + $cd->type = $packed; + } + + $cd->nullable = ($row['Null'] == 'YES') ? true : false; + $cd->key = $row['Key']; + $cd->default = $row['Default']; + $cd->extra = $row['Extra']; + + $td->columns[] = $cd; + } + + return $td; } public function getColumnDef($table, $column) @@ -114,6 +164,10 @@ class ColumnDef public $name; public $type; public $size; + public $nullable; + public $key; + public $default; + public $extra; } class IndexDef -- cgit v1.2.3-54-g00ecf From e206324f245145a0e8c9ec0535cba1d62344ebf7 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Wed, 23 Sep 2009 09:20:04 -0400 Subject: statusize schema-related modules --- lib/schema.php | 18 +++++++++--------- scripts/showtable.php | 4 ++-- 2 files changed, 11 insertions(+), 11 deletions(-) (limited to 'lib/schema.php') diff --git a/lib/schema.php b/lib/schema.php index 624765eb2..d3b30aeeb 100644 --- a/lib/schema.php +++ b/lib/schema.php @@ -1,6 +1,6 @@ . * * @category Database - * @package Laconica - * @author Evan Prodromou - * @copyright 2009 Control Yourself, Inc. + * @package StatusNet + * @author Evan Prodromou + * @copyright 2009 StatusNet, Inc. * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 - * @link http://laconi.ca/ + * @link http://status.net/ */ -if (!defined('LACONICA')) { +if (!defined('STATUSNET')) { exit(1); } @@ -39,10 +39,10 @@ if (!defined('LACONICA')) { * utilities. * * @category Database - * @package Laconica - * @author Evan Prodromou + * @package StatusNet + * @author Evan Prodromou * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 - * @link http://laconi.ca/ + * @link http://status.net/ */ class Schema diff --git a/scripts/showtable.php b/scripts/showtable.php index 30f0bb5a9..eb18a98e2 100644 --- a/scripts/showtable.php +++ b/scripts/showtable.php @@ -1,8 +1,8 @@ #!/usr/bin/env php Date: Wed, 23 Sep 2009 22:24:35 -0400 Subject: use schema tool to create a table --- lib/schema.php | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) (limited to 'lib/schema.php') diff --git a/lib/schema.php b/lib/schema.php index d3b30aeeb..f49075690 100644 --- a/lib/schema.php +++ b/lib/schema.php @@ -110,18 +110,87 @@ class Schema public function getColumnDef($table, $column) { + $td = $this->getTableDef($table); + + foreach ($td->columns as $cd) { + if ($cd->name == $column) { + return $cd; + } + } + + return null; } public function getIndexDef($table, $index) { + return null; } public function createTable($name, $columns, $indices=null) { + $uniques = array(); + $primary = array(); + $indices = 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 .= ",\nconstraint primary key (" . implode(',', $primary) . ")"; + } + + foreach ($uniques as $u) { + $sql .= ",\nunique index {$name}_{$u}_idx ($u)"; + } + + foreach ($indices as $i) { + $sql .= ",\nindex {$name}_{$i}_idx ($i)"; + } + + $sql .= "); "; + + common_debug($sql); + + $res =& $this->conn->query($sql); + + if (PEAR::isError($res)) { + throw new Exception($res->getMessage()); + } + + return true; } public function dropTable($name) { + $res =& $this->conn->query("DROP TABLE $name"); + + if (PEAR::isError($res)) { + throw new Exception($res->getMessage()); + } + + return true; } public function createIndex($name, $table, $columns) @@ -151,6 +220,25 @@ class Schema return $this->createTable($name, $columns, $indices); } } + + function _columnSql($cd) + { + $sql = "{$cd->name} "; + + if (!empty($cd->size)) { + $sql .= "{$cd->type}({$cd->size}) "; + } else { + $sql .= "{$cd->type} "; + } + + if (!empty($cd->default)) { + $sql .= "default {$cd->default} "; + } else { + $sql .= ($cd->nullable) ? "null " : "not null "; + } + + return $sql; + } } class TableDef @@ -168,6 +256,17 @@ class ColumnDef public $key; public $default; public $extra; + + function __construct($name, $type, $size=null, $nullable=null, + $key=null, $default=null, $extra=null) { + $this->name = $name; + $this->type = $type; + $this->size = $size; + $this->nullable = $nullable; + $this->key = $key; + $this->default = $default; + $this->extra = $extra; + } } class IndexDef -- cgit v1.2.3-54-g00ecf From b980f5e45b613d60e968e84b304ef9db260f24c2 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Thu, 1 Oct 2009 15:00:54 -0400 Subject: add some more methods to Schema --- lib/schema.php | 189 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 177 insertions(+), 12 deletions(-) (limited to 'lib/schema.php') diff --git a/lib/schema.php b/lib/schema.php index f49075690..056c2093d 100644 --- a/lib/schema.php +++ b/lib/schema.php @@ -193,32 +193,161 @@ class Schema return true; } - public function createIndex($name, $table, $columns) + public function createIndex($table, $columnNames, $name = null) { + if (!is_array($columnNames)) { + $columnNames = array($columnNames); + } + + if (empty($name)) { + $name = "$table_".implode("_", $columnNames)."_idx"; + } + + $res =& $this->conn->query("ALTER TABLE $table ADD INDEX $name (".implode(",", $columnNames).")"); + + if (PEAR::isError($res)) { + throw new Exception($res->getMessage()); + } + + return true; } - public function dropIndex($name, $table) + public function dropIndex($table, $name) { + $res =& $this->conn->query("ALTER TABLE $table DROP INDEX $name"); + + if (PEAR::isError($res)) { + throw new Exception($res->getMessage()); + } + + return true; } public function addColumn($table, $columndef) { + $sql = "ALTER TABLE $table ADD COLUMN " . $this->_columnSql($columndef); + + $res =& $this->conn->query($sql); + + if (PEAR::isError($res)) { + throw new Exception($res->getMessage()); + } + + return true; + } + + public function modifyColumn($table, $columndef) + { + $sql = "ALTER TABLE $table MODIFY COLUMN " . $this->_columnSql($columndef); + + $res =& $this->conn->query($sql); + + if (PEAR::isError($res)) { + throw new Exception($res->getMessage()); + } + + return true; + } + + public function dropColumn($table, $columnName) + { + $sql = "ALTER TABLE $table DROP COLUMN $columnName"; + + $res =& $this->conn->query($sql); + + if (PEAR::isError($res)) { + throw new Exception($res->getMessage()); + } + + return true; } - public function modifyColumn($table, $column, $columndef) + public function ensureTable($tableName, $columns, $indices=null) { + // XXX: DB engine portability -> toilet + + try { + $td = $this->getTableDef($tableName); + } catch (Exception $e) { + if (preg_match('/no such table/', $e->getMessage())) { + return $this->createTable($tableName, $columns, $indices); + } else { + throw $e; + } + } + + $cur = $this->_names($td->columns); + $new = $this->_names($columns); + + $toadd = array_diff($new, $cur); + $todrop = array_diff($cur, $new); + + $same = array_intersect($new, $cur); + + foreach ($same as $m) { + $curCol = $this->_byName($td->columns, $m); + $newCol = $this->_byName($columns, $m); + + if (!$newCol->equals($curCol)) { + $tomod[] = $newCol->name; + } + } + + if (count($toadd) + count($todrop) + count($tomod) == 0) { + // nothing to do + return true; + } + + // For efficiency, we want this all in one + // query, instead of using our methods. + + $phrase = array(); + + foreach ($toadd as $columnName) { + $cd = $this->_byName($columns, $columnName); + $phrase[] = 'ADD COLUMN ' . $this->_columnSql($cd); + } + + foreach ($todrop as $columnName) { + $phrase[] = 'DROP COLUMN ' . $columnName; + } + + foreach ($tomod as $columnName) { + $cd = $this->_byName($columns, $columnName); + $phrase[] = 'MODIFY COLUMN ' . $this->_columnSql($cd); + } + + $sql = 'ALTER TABLE ' . $tableName . ' ' . implode(', ', $phrase); + + $res =& $this->conn->query($sql); + + if (PEAR::isError($res)) { + throw new Exception($res->getMessage()); + } + + return true; } - public function dropColumn($table, $column) + function _names($cds) { + $names = array(); + + foreach ($cds as $cd) { + $names[] = $cd->name; + } + + return $names; } - public function ensureTable($name, $columns, $indices) + function _byName($cds, $name) { - $def = $this->tableDef($name); - if (empty($def)) { - return $this->createTable($name, $columns, $indices); + foreach ($cds as $cd) { + if ($cd->name == $name) { + return $cd; + } } + + return null; } function _columnSql($cd) @@ -257,16 +386,52 @@ class ColumnDef public $default; public $extra; - function __construct($name, $type, $size=null, $nullable=null, + function __construct($name, $type, $size=null, $nullable=true, $key=null, $default=null, $extra=null) { - $this->name = $name; - $this->type = $type; - $this->size = $size; + $this->name = strtolower($name); + $this->type = strtolower($type); + $this->size = $size+0; $this->nullable = $nullable; $this->key = $key; $this->default = $default; $this->extra = $extra; } + + function equals($other) + { + return ($this->name == $other->name && + $this->_typeMatch($other) && + $this->_defaultMatch($other) && + $this->_nullMatch($other) && + $this->key == $other->key); + } + + function _typeMatch($other) + { + switch ($this->type) { + case 'integer': + case 'int': + return ($other->type == 'integer' || + $other->type == 'int'); + break; + default: + return ($this->type == $other->type && + $this->size == $other->size); + } + } + + function _defaultMatch($other) + { + return ((is_null($this->default) && is_null($other->default)) || + ($this->default == $other->default)); + } + + function _nullMatch($other) + { + return ((!is_null($this->default) && !is_null($other->default) && + $this->default == $other->default) || + ($this->nullable == $other->nullable)); + } } class IndexDef -- cgit v1.2.3-54-g00ecf From 544c58d263e61e2eda3b2c54a4f0a1a6bbfa4910 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Thu, 1 Oct 2009 15:43:08 -0400 Subject: Some bug fixes The $tomod variable wasn't set, and the ColumnDef constructor didn't work without any args. These are fixed. --- lib/schema.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'lib/schema.php') diff --git a/lib/schema.php b/lib/schema.php index 056c2093d..8c8f5e9ff 100644 --- a/lib/schema.php +++ b/lib/schema.php @@ -284,6 +284,8 @@ class Schema $same = array_intersect($new, $cur); + $tomod = array(); + foreach ($same as $m) { $curCol = $this->_byName($td->columns, $m); $newCol = $this->_byName($columns, $m); @@ -386,8 +388,9 @@ class ColumnDef public $default; public $extra; - function __construct($name, $type, $size=null, $nullable=true, - $key=null, $default=null, $extra=null) { + function __construct($name=null, $type=null, $size=null, + $nullable=true, $key=null, $default=null, + $extra=null) { $this->name = strtolower($name); $this->type = strtolower($type); $this->size = $size+0; -- cgit v1.2.3-54-g00ecf From 87858a11f4435e20b0bd2f43da2961976a9c9a2d Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Fri, 2 Oct 2009 15:02:33 -0400 Subject: make lib/schema.php phpcs-clean --- lib/schema.php | 309 ++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 272 insertions(+), 37 deletions(-) (limited to 'lib/schema.php') diff --git a/lib/schema.php b/lib/schema.php index 8c8f5e9ff..1e0c1f3e9 100644 --- a/lib/schema.php +++ b/lib/schema.php @@ -50,15 +50,29 @@ class Schema static $_single = null; protected $conn = null; + /** + * Constructor. Only run once for singleton object. + */ + protected function __construct() { // XXX: there should be an easier way to do this. $user = new User(); + $this->conn = $user->getDatabaseConnection(); + $user->free(); + unset($user); } + /** + * Main public entry point. Use this to get + * the singleton object. + * + * @return Schema the (single) Schema object + */ + static function get() { if (empty(self::$_single)) { @@ -67,6 +81,17 @@ class Schema return self::$_single; } + /** + * Returns a TableDef object for the table + * in the schema with the given name. + * + * Throws an exception if the table is not found. + * + * @param string $name Name of the table to get + * + * @return TableDef tabledef for that table. + */ + public function getTableDef($name) { $res =& $this->conn->query('DESCRIBE ' . $name); @@ -108,6 +133,18 @@ class Schema return $td; } + /** + * Gets a ColumnDef object for a single column. + * + * Throws an exception if the table is not found. + * + * @param string $table name of the table + * @param string $column name of the column + * + * @return ColumnDef definition of the column or null + * if not found. + */ + public function getColumnDef($table, $column) { $td = $this->getTableDef($table); @@ -121,12 +158,17 @@ class Schema return null; } - public function getIndexDef($table, $index) - { - return null; - } - - public function createTable($name, $columns, $indices=null) + /** + * 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(); @@ -145,13 +187,13 @@ class Schema $sql .= $this->_columnSql($cd); switch ($cd->key) { - case 'UNI': + case 'UNI': $uniques[] = $cd->name; break; - case 'PRI': + case 'PRI': $primary[] = $cd->name; break; - case 'MUL': + case 'MUL': $indices[] = $cd->name; break; } @@ -171,8 +213,6 @@ class Schema $sql .= "); "; - common_debug($sql); - $res =& $this->conn->query($sql); if (PEAR::isError($res)) { @@ -182,6 +222,16 @@ class Schema return true; } + /** + * Drops a table from the schema + * + * Throws an exception if the table is not found. + * + * @param string $name Name of the table to drop + * + * @return boolean success flag + */ + public function dropTable($name) { $res =& $this->conn->query("DROP TABLE $name"); @@ -193,7 +243,23 @@ class Schema return true; } - public function createIndex($table, $columnNames, $name = null) + /** + * Adds an index to a table. + * + * If no name is provided, a name will be made up based + * on the table name and column names. + * + * Throws an exception on database error, esp. if the table + * does not exist. + * + * @param string $table Name of the table + * @param array $columnNames Name of columns to index + * @param string $name (Optional) name of the index + * + * @return boolean success flag + */ + + public function createIndex($table, $columnNames, $name=null) { if (!is_array($columnNames)) { $columnNames = array($columnNames); @@ -203,7 +269,9 @@ class Schema $name = "$table_".implode("_", $columnNames)."_idx"; } - $res =& $this->conn->query("ALTER TABLE $table ADD INDEX $name (".implode(",", $columnNames).")"); + $res =& $this->conn->query("ALTER TABLE $table ". + "ADD INDEX $name (". + implode(",", $columnNames).")"); if (PEAR::isError($res)) { throw new Exception($res->getMessage()); @@ -212,6 +280,15 @@ class Schema return true; } + /** + * Drops a named index from a table. + * + * @param string $table name of the table the index is on. + * @param string $name name of the index + * + * @return boolean success flag + */ + public function dropIndex($table, $name) { $res =& $this->conn->query("ALTER TABLE $table DROP INDEX $name"); @@ -223,6 +300,16 @@ class Schema return true; } + /** + * Adds a column to a table + * + * @param string $table name of the table + * @param ColumnDef $columndef Definition of the new + * column. + * + * @return boolean success flag + */ + public function addColumn($table, $columndef) { $sql = "ALTER TABLE $table ADD COLUMN " . $this->_columnSql($columndef); @@ -236,9 +323,21 @@ class Schema return true; } + /** + * 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 MODIFY COLUMN " . $this->_columnSql($columndef); + $sql = "ALTER TABLE $table MODIFY COLUMN " . + $this->_columnSql($columndef); $res =& $this->conn->query($sql); @@ -249,6 +348,17 @@ class Schema return true; } + /** + * Drops a column from a table + * + * The name must match an existing column. + * + * @param string $table name of the table + * @param string $columnName name of the column to drop + * + * @return boolean success flag + */ + public function dropColumn($table, $columnName) { $sql = "ALTER TABLE $table DROP COLUMN $columnName"; @@ -262,7 +372,22 @@ class Schema return true; } - public function ensureTable($tableName, $columns, $indices=null) + /** + * Ensures that a table exists with the given + * name and the given column definitions. + * + * If the table does not yet exist, it will + * create the table. If it does exist, it will + * alter the table to match the column definitions. + * + * @param string $tableName name of the table + * @param array $columns array of ColumnDef + * objects for the table + * + * @return boolean success flag + */ + + public function ensureTable($tableName, $columns) { // XXX: DB engine portability -> toilet @@ -270,7 +395,7 @@ class Schema $td = $this->getTableDef($tableName); } catch (Exception $e) { if (preg_match('/no such table/', $e->getMessage())) { - return $this->createTable($tableName, $columns, $indices); + return $this->createTable($tableName, $columns); } else { throw $e; } @@ -281,10 +406,8 @@ class Schema $toadd = array_diff($new, $cur); $todrop = array_diff($cur, $new); - - $same = array_intersect($new, $cur); - - $tomod = array(); + $same = array_intersect($new, $cur); + $tomod = array(); foreach ($same as $m) { $curCol = $this->_byName($td->columns, $m); @@ -307,6 +430,7 @@ class Schema foreach ($toadd as $columnName) { $cd = $this->_byName($columns, $columnName); + $phrase[] = 'ADD COLUMN ' . $this->_columnSql($cd); } @@ -316,6 +440,7 @@ class Schema foreach ($tomod as $columnName) { $cd = $this->_byName($columns, $columnName); + $phrase[] = 'MODIFY COLUMN ' . $this->_columnSql($cd); } @@ -330,7 +455,16 @@ class Schema return true; } - function _names($cds) + /** + * Returns the array of names from an array of + * ColumnDef objects. + * + * @param array $cds array of ColumnDef objects + * + * @return array strings for name values + */ + + private function _names($cds) { $names = array(); @@ -341,7 +475,17 @@ class Schema return $names; } - function _byName($cds, $name) + /** + * Get a ColumnDef from an array matching + * name. + * + * @param array $cds Array of ColumnDef objects + * @param string $name Name of the column + * + * @return ColumnDef matching item or null if no match. + */ + + private function _byName($cds, $name) { foreach ($cds as $cd) { if ($cd->name == $name) { @@ -352,7 +496,19 @@ class Schema return null; } - function _columnSql($cd) + /** + * Return the proper SQL for creating or + * altering a column. + * + * Appropriate for use in CREATE TABLE or + * ALTER TABLE statements. + * + * @param ColumnDef $cd column to create + * + * @return string correct SQL for that column + */ + + private function _columnSql($cd) { $sql = "{$cd->name} "; @@ -372,25 +528,71 @@ class Schema } } +/** + * A class encapsulating the structure of a table. + * + * @category Database + * @package StatusNet + * @author Evan Prodromou + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://status.net/ + */ + class TableDef { + /** name of the table */ public $name; + /** array of ColumnDef objects for the columns. */ public $columns; } +/** + * A class encapsulating the structure of a column in a table. + * + * @category Database + * @package StatusNet + * @author Evan Prodromou + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://status.net/ + */ + class ColumnDef { + /** name of the column. */ public $name; + /** type of column, e.g. 'int', 'varchar' */ public $type; + /** size of the column. */ public $size; + /** boolean flag; can it be null? */ public $nullable; + /** + * type of key: null = no key; 'PRI' => primary; + * 'UNI' => unique key; 'MUL' => multiple values. + */ public $key; + /** default value if any. */ public $default; + /** 'extra' stuff. Returned by MySQL, largely + * unused. */ public $extra; + /** + * Constructor. + * + * @param string $name name of the column + * @param string $type type of the column + * @param int $size size of the column + * @param boolean $nullable can this be null? + * @param string $key type of key + * @param value $default default value + * @param value $extra unused + */ + function __construct($name=null, $type=null, $size=null, $nullable=true, $key=null, $default=null, - $extra=null) { + $extra=null) + { $this->name = strtolower($name); $this->type = strtolower($type); $this->size = $size+0; @@ -400,6 +602,15 @@ class ColumnDef $this->extra = $extra; } + /** + * Compares this columndef with another to see + * if they're functionally equivalent. + * + * @param ColumnDef $other column to compare + * + * @return boolean true if equivalent, otherwise false. + */ + function equals($other) { return ($this->name == $other->name && @@ -409,37 +620,61 @@ class ColumnDef $this->key == $other->key); } - function _typeMatch($other) + /** + * Does the type of this column match the + * type of the other column? + * + * Checks the type and size of a column. Tries + * to ignore differences between synonymous + * data types, like 'integer' and 'int'. + * + * @param ColumnDef $other other column to check + * + * @return boolean true if they're about equivalent + */ + + private function _typeMatch($other) { switch ($this->type) { - case 'integer': - case 'int': + case 'integer': + case 'int': return ($other->type == 'integer' || $other->type == 'int'); break; - default: + default: return ($this->type == $other->type && $this->size == $other->size); } } - function _defaultMatch($other) + /** + * Does the default behaviour of this column match + * the other? + * + * @param ColumnDef $other other column to check + * + * @return boolean true if defaults are effectively the same. + */ + + private function _defaultMatch($other) { return ((is_null($this->default) && is_null($other->default)) || ($this->default == $other->default)); } - function _nullMatch($other) + /** + * Does the null behaviour of this column match + * the other? + * + * @param ColumnDef $other other column to check + * + * @return boolean true if these columns 'null' the same. + */ + + private function _nullMatch($other) { return ((!is_null($this->default) && !is_null($other->default) && $this->default == $other->default) || ($this->nullable == $other->nullable)); } } - -class IndexDef -{ - public $name; - public $table; - public $columns; -} -- cgit v1.2.3-54-g00ecf