From f994680d54b066f13d11e611bfb4c07448054f2f Mon Sep 17 00:00:00 2001 From: jwage Date: Thu, 28 May 2009 21:34:35 +0000 Subject: [PATCH] [2.0] More general work on the Platform and SchemaManager classes(primarily pgsql) --- .../DBAL/Platforms/AbstractPlatform.php | 7 +- .../DBAL/Platforms/FirebirdPlatform.php | 29 +- .../DBAL/Platforms/InformixPlatform.php | 5 - lib/Doctrine/DBAL/Platforms/MsSqlPlatform.php | 20 +- lib/Doctrine/DBAL/Platforms/MySqlPlatform.php | 42 +-- .../DBAL/Platforms/OraclePlatform.php | 8 +- .../DBAL/Platforms/PostgreSqlPlatform.php | 129 ++++--- .../DBAL/Platforms/SqlitePlatform.php | 14 +- .../DBAL/Schema/AbstractSchemaManager.php | 47 ++- .../DBAL/Schema/MySqlSchemaManager.php | 69 +--- .../DBAL/Schema/PostgreSqlSchemaManager.php | 320 ++++++++++++------ .../DBAL/Schema/SqliteSchemaManager.php | 2 - lib/Doctrine/ORM/Id/AbstractIdGenerator.php | 3 - .../ORM/Internal/CommitOrderCalculator.php | 16 +- .../Query/Exec/MultiTableDeleteExecutor.php | 5 - lib/Doctrine/ORM/UnitOfWork.php | 7 - .../Tests/DBAL/Functional/AllTests.php | 1 + .../Schema/MySqlSchemaManagerTest.php | 116 +++++-- .../Schema/PostgreSqlSchemaManagerTest.php | 318 +++++++++++++++++ .../Schema/SqliteSchemaManagerTest.php | 96 +++--- tests/Doctrine/Tests/Mocks/SequenceMock.php | 16 +- 21 files changed, 823 insertions(+), 447 deletions(-) create mode 100644 tests/Doctrine/Tests/DBAL/Functional/Schema/PostgreSqlSchemaManagerTest.php diff --git a/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php b/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php index 684a94ff8..794849065 100644 --- a/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php @@ -1299,7 +1299,7 @@ abstract class AbstractPlatform throw DoctrineException::updateMe('List functions not supported by this driver.'); } - public function getListTriggersSql() + public function getListTriggersSql($table = null) { throw DoctrineException::updateMe('List triggers not supported by this driver.'); } @@ -1339,6 +1339,11 @@ abstract class AbstractPlatform throw DoctrineException::updateMe('List table indexes not supported by this driver.'); } + public function getListTableForeignKeysSql($table) + { + throw DoctrineException::updateMe('List table foreign keys not supported by this driver.'); + } + public function getCreateViewSql($name, $sql) { throw DoctrineException::updateMe('Create view not supported by this driver'); diff --git a/lib/Doctrine/DBAL/Platforms/FirebirdPlatform.php b/lib/Doctrine/DBAL/Platforms/FirebirdPlatform.php index 41e845898..c005d58e9 100644 --- a/lib/Doctrine/DBAL/Platforms/FirebirdPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/FirebirdPlatform.php @@ -2,11 +2,6 @@ namespace Doctrine\DBAL\Platforms; -/** - * Enter description here... - * - * @since 2.0 - */ class FirebirdPlatform extends AbstractPlatform { /** @@ -84,24 +79,12 @@ class FirebirdPlatform extends AbstractPlatform { return 'COLLATE ' . $collation; } - - /** - * Enter description here... - * - * @param unknown_type $sequenceName - * @override - */ + public function getSequenceNextValSql($sequenceName) { return 'SELECT GEN_ID(' . $this->quoteIdentifier($sequenceName) . ', 1) FROM RDB$DATABASE'; } - - /** - * Enter description here... - * - * @param unknown_type $level - * @override - */ + protected function _getTransactionIsolationLevelSql($level) { switch ($level) { @@ -117,13 +100,7 @@ class FirebirdPlatform extends AbstractPlatform return parent::_getTransactionIsolationLevelSql($level); } } - - /** - * Enter description here... - * - * @param unknown_type $level - * @override - */ + public function getSetTransactionIsolationSql($level) { return 'SET TRANSACTION ISOLATION LEVEL ' . $this->_getTransactionIsolationLevelSql($level); diff --git a/lib/Doctrine/DBAL/Platforms/InformixPlatform.php b/lib/Doctrine/DBAL/Platforms/InformixPlatform.php index 3e0b5a427..56b101014 100644 --- a/lib/Doctrine/DBAL/Platforms/InformixPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/InformixPlatform.php @@ -2,11 +2,6 @@ namespace Doctrine\DBAL\Platforms; -/** - * Enter description here... - * - * @since 2.0 - */ class InformixPlatform extends AbstractPlatform { public function __construct() diff --git a/lib/Doctrine/DBAL/Platforms/MsSqlPlatform.php b/lib/Doctrine/DBAL/Platforms/MsSqlPlatform.php index 55e425750..545344f8b 100644 --- a/lib/Doctrine/DBAL/Platforms/MsSqlPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/MsSqlPlatform.php @@ -302,23 +302,11 @@ class MsSqlPlatform extends AbstractPlatform return false; } - /** - * Enter description here... - * - * @return unknown - * @override - */ public function getShowDatabasesSql() { return 'SHOW DATABASES'; } - - /** - * Enter description here... - * - * @todo Throw exception by default? - * @override - */ + public function getListTablesSql() { return 'SHOW TABLES'; @@ -348,12 +336,6 @@ class MsSqlPlatform extends AbstractPlatform return 'DROP DATABASE ' . $this->quoteIdentifier($name); } - /** - * Enter description here... - * - * @param unknown_type $level - * @override - */ public function getSetTransactionIsolationSql($level) { return 'SET TRANSACTION ISOLATION LEVEL ' . $this->_getTransactionIsolationLevelSql($level); diff --git a/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php b/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php index 709bb3856..a80070b5b 100644 --- a/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php @@ -185,6 +185,19 @@ class MySqlPlatform extends AbstractPlatform } } + public function getListTableForeignKeysSql($table, $database = null) + { + $sql = "SELECT column_name, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME FROM information_schema.key_column_usage WHERE table_name = '" . $table . "'"; + + if ( ! is_null($database)) { + $sql .= " AND table_schema = 'doctrine_tests'"; + } + + $sql .= " AND REFERENCED_COLUMN_NAME is not NULL"; + + return $sql; + } + public function getCreateViewSql($name, $sql) { return 'CREATE VIEW ' . $name . ' AS ' . $sql; @@ -216,12 +229,7 @@ class MySqlPlatform extends AbstractPlatform return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(255)') : ($length ? 'VARCHAR(' . $length . ')' : 'TEXT'); } - - /** - * Enter description here... - * - * @param array $field - */ + public function getClobDeclarationSql(array $field) { if ( ! empty($field['length'])) { @@ -298,24 +306,12 @@ class MySqlPlatform extends AbstractPlatform { return false; } - - /** - * Enter description here... - * - * @return unknown - * @override - */ + public function getShowDatabasesSql() { return 'SHOW DATABASES'; } - /** - * Enter description here... - * - * @todo Throw exception by default? - * @override - */ public function getListTablesSql() { return 'SHOW TABLES'; @@ -899,13 +895,7 @@ class MySqlPlatform extends AbstractPlatform { return 'DROP TABLE ' . $this->quoteIdentifier($table); } - - /** - * Enter description here... - * - * @param unknown_type $level - * @override - */ + public function getSetTransactionIsolationSql($level) { return 'SET SESSION TRANSACTION ISOLATION LEVEL ' . $this->_getTransactionIsolationLevelSql($level); diff --git a/lib/Doctrine/DBAL/Platforms/OraclePlatform.php b/lib/Doctrine/DBAL/Platforms/OraclePlatform.php index b5a13c9b4..5f878d185 100644 --- a/lib/Doctrine/DBAL/Platforms/OraclePlatform.php +++ b/lib/Doctrine/DBAL/Platforms/OraclePlatform.php @@ -134,13 +134,7 @@ class OraclePlatform extends AbstractPlatform { return 'SET TRANSACTION ISOLATION LEVEL ' . $this->_getTransactionIsolationLevelSql($level); } - - /** - * Enter description here... - * - * @param integer $level - * @override - */ + protected function _getTransactionIsolationLevelSql($level) { switch ($level) { diff --git a/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php b/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php index 13b1a6ed2..ca2b9229a 100644 --- a/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php @@ -484,22 +484,12 @@ class PostgreSqlPlatform extends AbstractPlatform { return true; } - - /** - * Enter description here... - * - * @override - */ + public function getListDatabasesSql() { return 'SELECT datname FROM pg_database'; } - - /** - * Enter description here... - * - * @override - */ + public function getListFunctionsSql() { return "SELECT @@ -514,12 +504,7 @@ class PostgreSqlPlatform extends AbstractPlatform (SELECT oid FROM pg_namespace WHERE nspname NOT LIKE 'pg_%' AND nspname != 'information_schema'"; } - - /** - * Enter description here... - * - * @override - */ + public function getListSequencesSql($database) { return "SELECT @@ -530,12 +515,7 @@ class PostgreSqlPlatform extends AbstractPlatform (SELECT oid FROM pg_namespace WHERE nspname NOT LIKE 'pg_%' AND nspname != 'information_schema')"; } - - /** - * Enter description here... - * - * @override - */ + public function getListTablesSql() { return "SELECT @@ -553,32 +533,55 @@ class PostgreSqlPlatform extends AbstractPlatform AND NOT EXISTS (SELECT 1 FROM pg_user WHERE usesysid = c.relowner) AND c.relname !~ '^pg_'"; } - - /** - * Enter description here... - * - * @override - */ + public function getListViewsSql() { - return 'SELECT viewname FROM pg_views'; + return 'SELECT viewname, definition FROM pg_views'; } - - /** - * Enter description here... - * - * @override - */ + + public function getListTriggersSql($table = null) + { + $sql = 'SELECT trg.tgname AS trigger_name + FROM pg_trigger trg, + pg_class tbl + WHERE trg.tgrelid = tbl.oid'; + + if ( ! is_null($table)) { + $sql .= " AND tbl.relname = ".$this->quoteIdentifier($table); + } + + return $sql; + } + public function getListUsersSql() { - return 'SELECT usename FROM pg_user'; + return 'SELECT usename, passwd FROM pg_user'; } - - /** - * Enter description here... - * - * @override - */ + + public function getListTableForeignKeysSql($table, $database = null) + { + return "SELECT pg_catalog.pg_get_constraintdef(oid, true) as condef + FROM pg_catalog.pg_constraint r + WHERE r.conrelid = + ( + SELECT c.oid + FROM pg_catalog.pg_class c + LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace + WHERE c.relname = '" . $table . "' AND pg_catalog.pg_table_is_visible(c.oid) + ) + AND r.contype = 'f'"; + } + + public function getCreateViewSql($name, $sql) + { + return 'CREATE VIEW ' . $name . ' AS ' . $sql; + } + + public function getDropViewSql($name) + { + return 'DROP VIEW '. $name; + } + public function getListTableConstraintsSql($table) { return "SELECT @@ -593,16 +596,16 @@ class PostgreSqlPlatform extends AbstractPlatform AND (indisunique = 't' OR indisprimary = 't') )"; } - - /** - * Enter description here... - * - * @override - */ + public function getListTableIndexesSql($table) { return "SELECT - relname + relname, + ( + SELECT indisunique + FROM pg_index + WHERE oid = indexrelid + ) as unique FROM pg_class WHERE oid IN ( @@ -610,16 +613,10 @@ class PostgreSqlPlatform extends AbstractPlatform FROM pg_index, pg_class WHERE pg_class.relname = '$table' AND pg_class.oid=pg_index.indrelid - AND indisunique != 't' AND indisprimary != 't' )"; } - - /** - * Enter description here... - * - * @override - */ + public function getListTableColumnsSql($table) { return "SELECT @@ -877,24 +874,12 @@ class PostgreSqlPlatform extends AbstractPlatform } return $item; } - - /** - * Enter description here... - * - * @param string $sequenceName - * @override - */ + public function getSequenceNextValSql($sequenceName) { return "SELECT NEXTVAL('" . $sequenceName . "')"; } - - /** - * Enter description here... - * - * @param unknown_type $level - * @override - */ + public function getSetTransactionIsolationSql($level) { return 'SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL ' diff --git a/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php b/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php index 7e9d25d0a..17cbf989d 100644 --- a/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php +++ b/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php @@ -174,12 +174,6 @@ class SqlitePlatform extends AbstractPlatform return 'SUBSTR(' . $value . ', ' . $position . ', LENGTH(' . $value . '))'; } - /** - * Enter description here... - * - * @param unknown_type $level - * @override - */ protected function _getTransactionIsolationLevelSql($level) { switch ($level) { @@ -193,13 +187,7 @@ class SqlitePlatform extends AbstractPlatform return parent::_getTransactionIsolationLevelSql($level); } } - - /** - * Enter description here... - * - * @param unknown_type $level - * @override - */ + public function getSetTransactionIsolationSql($level) { return 'PRAGMA read_uncommitted = ' . $this->_getTransactionIsolationLevelSql($level); diff --git a/lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php b/lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php index 0a7907851..851bb33d5 100644 --- a/lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php +++ b/lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php @@ -54,7 +54,7 @@ abstract class AbstractSchemaManager /** * Constructor. Accepts the Connection instance to manage the schema for * - * @param \Doctrine\DBAL\Connection $conn + * @param \Doctrine\DBAL\Connection $conn */ public function __construct(\Doctrine\DBAL\Connection $conn) { @@ -208,6 +208,24 @@ abstract class AbstractSchemaManager return $this->_getPortableViewsList($views); } + /** + * List the foreign keys for the given table + * + * @param string $table The name of the table + * @return array $tableForeignKeys + */ + public function listTableForeignKeys($table, $database = null) + { + if (is_null($database)) { + $database = $this->_conn->getDatabase(); + } + $sql = $this->_platform->getListTableForeignKeysSql($table, $database); + + $tableForeignKeys = $this->_conn->fetchAll($sql); + + return $this->_getPortableTableForeignKeysList($tableForeignKeys); + } + /** * Drop the database for this connection * @@ -227,7 +245,7 @@ abstract class AbstractSchemaManager /** * Drop the given table * - * @param string $table The name of the table to drop + * @param string $table The name of the table to drop * @return boolean $result */ public function dropTable($table) @@ -442,7 +460,7 @@ abstract class AbstractSchemaManager /** * Create a new view * - * @param string $name The name of the view + * @param string $name The name of the view * @param string $sql The sql to set to the view * @return boolean $result */ @@ -456,7 +474,7 @@ abstract class AbstractSchemaManager /** * Drop a view * - * @param string $name The name of the view + * @param string $name The name of the view * @return boolean $result */ public function dropView($name) @@ -600,7 +618,7 @@ abstract class AbstractSchemaManager * Remove a column from a table * * @param string $tableName The name of the table - * @param array|string $column The column name or array of names + * @param array|string $column The column name or array of names * @return boolean $result */ public function removeTableColumn($name, $column) @@ -745,6 +763,9 @@ abstract class AbstractSchemaManager $list = array(); foreach ($tableColumns as $key => $value) { if ($value = $this->_getPortableTableColumnDefinition($value)) { + if (is_string($value['type'])) { + $value['type'] = \Doctrine\DBAL\Types\Type::getType($value['type']); + } $list[] = $value; } } @@ -820,6 +841,22 @@ abstract class AbstractSchemaManager return $view; } + protected function _getPortableTableForeignKeysList($tableForeignKeys) + { + $list = array(); + foreach ($tableForeignKeys as $key => $value) { + if ($value = $this->_getPortableTableForeignKeyDefinition($value)) { + $list[] = $value; + } + } + return $list; + } + + protected function _getPortableTableForeignKeyDefinition($tableForeignKey) + { + return $tableForeignKey; + } + protected function _executeSql($sql, $method = 'exec') { $result = true; diff --git a/lib/Doctrine/DBAL/Schema/MySqlSchemaManager.php b/lib/Doctrine/DBAL/Schema/MySqlSchemaManager.php index 5ac017f4c..c5e2c2fec 100644 --- a/lib/Doctrine/DBAL/Schema/MySqlSchemaManager.php +++ b/lib/Doctrine/DBAL/Schema/MySqlSchemaManager.php @@ -71,15 +71,12 @@ class MySqlSchemaManager extends AbstractSchemaManager { $tableConstraint = array_change_key_case($tableConstraint, CASE_LOWER); - $result = array(); if ( ! $tableConstraint['non_unique']) { $index = $tableConstraint['key_name']; if ( ! empty($index)) { - $result[] = $index; + return $index; } } - - return $result; } protected function _getPortableSequenceDefinition($sequence) @@ -275,8 +272,6 @@ class MySqlSchemaManager extends AbstractSchemaManager $values = isset($def['values']) ? $def['values'] : array(); - $def['type'] = \Doctrine\DBAL\Types\Type::getType($def['type']); - $column = array( 'name' => $tableColumn['field'], 'values' => $values, @@ -291,48 +286,17 @@ class MySqlSchemaManager extends AbstractSchemaManager return $column; } - /** - * lists table foreign keys - * - * @param string $table database table name - * @return array - * @override - */ - public function listTableForeignKeys($table) + public function _getPortableTableForeignKeyDefinition($tableForeignKey) { - $sql = 'SHOW CREATE TABLE ' . $this->_conn->quoteIdentifier($table, true); - $definition = $this->_conn->fetchOne($sql); - if (!empty($definition)) { - $pattern = '/\bCONSTRAINT\s+([^\s]+)\s+FOREIGN KEY\b/i'; - if (preg_match_all($pattern, str_replace('`', '', $definition), $matches) > 1) { - foreach ($matches[1] as $constraint) { - $result[$constraint] = true; - } - } - } - - if ($this->_conn->getAttribute(Doctrine::ATTR_PORTABILITY) & Doctrine::PORTABILITY_FIX_CASE) { - $result = array_change_key_case($result, $this->_conn->getAttribute(Doctrine::ATTR_FIELD_CASE)); - } - - return $result; + $tableForeignKey = array_change_key_case($tableForeignKey, CASE_LOWER); + $foreignKey = array( + 'table' => $tableForeignKey['referenced_table_name'], + 'local' => $tableForeignKey['column_name'], + 'foreign' => $tableForeignKey['referenced_column_name'] + ); + return $foreignKey; } - /** - * create sequence - * - * @param string $sequenceName name of the sequence to be created - * @param string $start start value of the sequence; default is 1 - * @param array $options An associative array of table options: - * array( - * 'comment' => 'Foo', - * 'charset' => 'utf8', - * 'collate' => 'utf8_unicode_ci', - * 'type' => 'innodb', - * ); - * @return boolean - * @override - */ public function createSequence($sequenceName, $start = 1, array $options = array()) { $sequenceName = $this->_conn->quoteIdentifier($this->_conn->getSequenceName($sequenceName), true); @@ -395,19 +359,4 @@ class MySqlSchemaManager extends AbstractSchemaManager return $res; } - - /** - * Enter description here... - * - * @param unknown_type $table - * @param unknown_type $name - * @return unknown - * @override - */ - public function dropForeignKey($table, $name) - { - $table = $this->_conn->quoteIdentifier($table); - $name = $this->_conn->quoteIdentifier($name); - return $this->_conn->exec('ALTER TABLE ' . $table . ' DROP FOREIGN KEY ' . $name); - } } \ No newline at end of file diff --git a/lib/Doctrine/DBAL/Schema/PostgreSqlSchemaManager.php b/lib/Doctrine/DBAL/Schema/PostgreSqlSchemaManager.php index 08c854753..734ec7ed5 100644 --- a/lib/Doctrine/DBAL/Schema/PostgreSqlSchemaManager.php +++ b/lib/Doctrine/DBAL/Schema/PostgreSqlSchemaManager.php @@ -32,109 +32,237 @@ namespace Doctrine\DBAL\Schema; */ class PostgreSqlSchemaManager extends AbstractSchemaManager { - /** - * lists table constraints - * - * @param string $table database table name - * @return array - */ - public function listTableColumns($table) + protected function _getPortableTableForeignKeyDefinition($tableForeignKey) { - $table = $this->conn->quote($table); - $query = sprintf($this->sql['listTableColumns'], $table); - $result = $this->conn->fetchAssoc($query); + preg_match('/FOREIGN KEY \((.+)\) REFERENCES (.+)\((.+)\)/', $tableForeignKey['condef'], $values); - $columns = array(); - foreach ($result as $key => $val) { - $val = array_change_key_case($val, CASE_LOWER); - - if (strtolower($val['type']) === 'varchar') { - // get length from varchar definition - $length = preg_replace('~.*\(([0-9]*)\).*~', '$1', $val['complete_type']); - $val['length'] = $length; - } - - $decl = $this->_conn->getDatabasePlatform()->getPortableDeclaration($val); - - $description = array( - 'name' => $val['field'], - 'ntype' => $val['type'], - 'type' => $decl['type'][0], - 'alltypes' => $decl['type'], - 'length' => $decl['length'], - 'fixed' => $decl['fixed'], - 'unsigned' => $decl['unsigned'], - 'notnull' => ($val['isnotnull'] == true), - 'default' => $val['default'], - 'primary' => ($val['pri'] == 't'), + if ((strpos(',', $values[1]) === false) && (strpos(',', $values[3]) === false)) { + return array( + 'table' => $values[2], + 'local' => $values[1], + 'foreign' => $values[3] ); - - $matches = array(); + } + } - if (preg_match("/^nextval\('(.*)'(::.*)?\)$/", $description['default'], $matches)) { - - $description['sequence'] = $this->_conn->formatter->fixSequenceName($matches[1]); - $description['default'] = null; - } - - $columns[$val['field']] = $description; + protected function _getPortableTriggerDefinition($trigger) + { + return $trigger['trigger_name']; + } + + protected function _getPortableViewDefinition($view) + { + return array( + 'name' => $view['viewname'], + 'sql' => $view['definition'] + ); + } + + protected function _getPortableUserDefinition($user) + { + return array( + 'user' => $user['usename'], + 'password' => $user['passwd'] + ); + } + + protected function _getPortableTableDefinition($table) + { + return $table['table_name']; + } + + protected function _getPortableTableIndexDefinition($index) + { + return array( + 'name' => $index['relname'], + 'unique' => (bool) $index['unique'] + ); + } + + protected function _getPortableDatabaseDefinition($database) + { + return $database['datname']; + } + + protected function _getPortableSequenceDefinition($sequence) + { + return $sequence['relname']; + } + + protected function _getPortableTableConstraintDefinition($tableConstraint) + { + return $tableConstraint['relname']; + } + + protected function _getPortableTableColumnDefinition($tableColumn) + { + $tableColumn = array_change_key_case($tableColumn, CASE_LOWER); + + if (strtolower($tableColumn['type']) === 'varchar') { + // get length from varchar definition + $length = preg_replace('~.*\(([0-9]*)\).*~', '$1', $tableColumn['complete_type']); + $tableColumn['length'] = $length; } - return $columns; - } - - /** - * list all indexes in a table - * - * @param string $table database table name - * @return array - */ - public function listTableIndexes($table) - { - $table = $this->_conn->quote($table); - $query = sprintf($this->sql['listTableIndexes'], $table); - - return $this->_conn->fetchColumn($query); - } - - /** - * lists tables - * - * @param string|null $database - * @return array - */ - public function listTables($database = null) - { - return $this->_conn->fetchColumn($this->sql['listTables']); - } - - /** - * lists table triggers - * - * @param string $table database table name - * @return array - */ - public function listTableTriggers($table) - { - $query = 'SELECT trg.tgname AS trigger_name - FROM pg_trigger trg, - pg_class tbl - WHERE trg.tgrelid = tbl.oid'; - if ($table !== null) { - $table = $this->_conn->quote(strtoupper($table), 'string'); - $query .= " AND tbl.relname = $table"; + $matches = array(); + + if (preg_match("/^nextval\('(.*)'(::.*)?\)$/", $tableColumn['default'], $matches)) { + $tableColumn['sequence'] = $matches[1]; + $tableColumn['default'] = null; + } + + if (stripos($tableColumn['default'], 'NULL') !== null) { + $tableColumn['default'] = null; + } + + $length = (isset($tableColumn['length'])) ? $tableColumn['length'] : null; + if ($length == '-1' && isset($tableColumn['atttypmod'])) { + $length = $tableColumn['atttypmod'] - 4; + } + if ((int)$length <= 0) { + $length = null; + } + $type = array(); + $unsigned = $fixed = null; + + if ( ! isset($tableColumn['name'])) { + $tableColumn['name'] = ''; + } + + $dbType = strtolower($tableColumn['type']); + + switch ($dbType) { + case 'inet': + $type = 'inet'; + break; + case 'bit': + case 'varbit': + $type = 'bit'; + break; + case 'smallint': + case 'int2': + $type = 'integer'; + $unsigned = false; + $length = 2; + if ($length == '2') { + if (preg_match('/^(is|has)/', $tableColumn['name'])) { + $type = 'boolean'; + } + } + break; + case 'int': + case 'int4': + case 'integer': + case 'serial': + case 'serial4': + $type = 'integer'; + $unsigned = false; + $length = 4; + break; + case 'bigint': + case 'int8': + case 'bigserial': + case 'serial8': + $type = 'integer'; + $unsigned = false; + $length = 8; + break; + case 'bool': + case 'boolean': + $type = 'boolean'; + $length = 1; + break; + case 'text': + case 'varchar': + case 'interval': + case '_varchar': + $fixed = false; + case 'tsvector': + case 'unknown': + case 'char': + case 'bpchar': + $type = 'string'; + if ($length == '1') { + if (preg_match('/^(is|has)/', $tableColumn['name'])) { + $type = 'boolean'; + } + } elseif (strstr($dbType, 'text')) { + $type = 'clob'; + } + if ($fixed !== false) { + $fixed = true; + } + break; + case 'date': + $type = 'date'; + $length = null; + break; + case 'datetime': + case 'timestamp': + case 'timetz': + case 'timestamptz': + $type = 'timestamp'; + $length = null; + break; + case 'time': + $type = 'time'; + $length = null; + break; + case 'float': + case 'float4': + case 'float8': + case 'double': + case 'double precision': + case 'real': + $type = 'float'; + break; + case 'decimal': + case 'money': + case 'numeric': + $type = 'decimal'; + break; + case 'tinyblob': + case 'mediumblob': + case 'longblob': + case 'blob': + case 'bytea': + case 'geometry': + case 'geometrycollection': + case 'point': + case 'multipoint': + case 'linestring': + case 'multilinestring': + case 'polygon': + case 'multipolygon': + $type = 'blob'; + $length = null; + break; + case 'oid': + $type = 'blob'; + $length = null; + break; + case 'year': + $type = 'date'; + $length = null; + break; + default: + $type = 'string'; } - return $this->_conn->fetchColumn($query); - } - /** - * list the views in the database that reference a given table - * - * @param string $table database table name - * @return array - */ - public function listTableViews($table) - { - return $this->_conn->fetchColumn($query); + $decl = array( + 'type' => $type, + 'length' => $length, + 'unsigned' => $unsigned, + 'fixed' => $fixed + ); + + $description = array( + 'name' => $tableColumn['field'], + 'notnull' => (bool) $tableColumn['isnotnull'], + 'default' => $tableColumn['default'], + 'primary' => (bool) ($tableColumn['pri'] == 't'), + ); + + return array_merge($decl, $description); } } \ No newline at end of file diff --git a/lib/Doctrine/DBAL/Schema/SqliteSchemaManager.php b/lib/Doctrine/DBAL/Schema/SqliteSchemaManager.php index 6a6ebd8d3..093979982 100644 --- a/lib/Doctrine/DBAL/Schema/SqliteSchemaManager.php +++ b/lib/Doctrine/DBAL/Schema/SqliteSchemaManager.php @@ -191,8 +191,6 @@ class SqliteSchemaManager extends AbstractSchemaManager $length = null; } - $type = \Doctrine\DBAL\Types\Type::getType($type); - return array('name' => $tableColumn['name'], 'primary' => (bool) $tableColumn['pk'], 'type' => $type, diff --git a/lib/Doctrine/ORM/Id/AbstractIdGenerator.php b/lib/Doctrine/ORM/Id/AbstractIdGenerator.php index f7d8441c6..ffbad370e 100644 --- a/lib/Doctrine/ORM/Id/AbstractIdGenerator.php +++ b/lib/Doctrine/ORM/Id/AbstractIdGenerator.php @@ -4,9 +4,6 @@ namespace Doctrine\ORM\Id; use Doctrine\ORM\EntityManager; -/** - * Enter description here... - */ abstract class AbstractIdGenerator { /** diff --git a/lib/Doctrine/ORM/Internal/CommitOrderCalculator.php b/lib/Doctrine/ORM/Internal/CommitOrderCalculator.php index 1913ba3bd..06d1a4f10 100644 --- a/lib/Doctrine/ORM/Internal/CommitOrderCalculator.php +++ b/lib/Doctrine/ORM/Internal/CommitOrderCalculator.php @@ -97,24 +97,12 @@ class CommitOrderCalculator { $this->_nodes[$key] = $node; } - - /** - * Enter description here... - * - * @param unknown_type $key - * @param unknown_type $item - */ + public function addNodeWithItem($key, $item) { $this->_nodes[$key] = new CommitOrderNode($item, $this); } - - /** - * Enter description here... - * - * @param unknown_type $key - * @return unknown - */ + public function getNodeForKey($key) { return $this->_nodes[$key]; diff --git a/lib/Doctrine/ORM/Query/Exec/MultiTableDeleteExecutor.php b/lib/Doctrine/ORM/Query/Exec/MultiTableDeleteExecutor.php index 7002b2039..d69a68f6a 100644 --- a/lib/Doctrine/ORM/Query/Exec/MultiTableDeleteExecutor.php +++ b/lib/Doctrine/ORM/Query/Exec/MultiTableDeleteExecutor.php @@ -35,11 +35,6 @@ namespace Doctrine\ORM\Query\Exec; */ class MultiTableDeleteExecutor extends AbstractExecutor { - /** - * Enter description here... - * - * @param Node $AST - */ public function __construct($AST) { // 1. Create a INSERT INTO temptable ... VALUES ( SELECT statement where the SELECT statement diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php index 84ad3b070..d56850dd2 100644 --- a/lib/Doctrine/ORM/UnitOfWork.php +++ b/lib/Doctrine/ORM/UnitOfWork.php @@ -787,13 +787,6 @@ class UnitOfWork implements PropertyChangedListener $this->_entityStates[$oid]); } - /** - * Enter description here... - * - * @param object $entity - * @return boolean - * @todo Rename to isScheduled() - */ public function isEntityRegistered($entity) { $oid = spl_object_hash($entity); diff --git a/tests/Doctrine/Tests/DBAL/Functional/AllTests.php b/tests/Doctrine/Tests/DBAL/Functional/AllTests.php index 4d6d19a5c..44dee354b 100644 --- a/tests/Doctrine/Tests/DBAL/Functional/AllTests.php +++ b/tests/Doctrine/Tests/DBAL/Functional/AllTests.php @@ -23,6 +23,7 @@ class AllTests $suite->addTestSuite('Doctrine\Tests\DBAL\Functional\Schema\SqliteSchemaManagerTest'); $suite->addTestSuite('Doctrine\Tests\DBAL\Functional\Schema\MySqlSchemaManagerTest'); + $suite->addTestSuite('Doctrine\Tests\DBAL\Functional\Schema\PostgreSQLSchemaManagerTest'); return $suite; } diff --git a/tests/Doctrine/Tests/DBAL/Functional/Schema/MySqlSchemaManagerTest.php b/tests/Doctrine/Tests/DBAL/Functional/Schema/MySqlSchemaManagerTest.php index a384e6b9e..2e8f9ee11 100644 --- a/tests/Doctrine/Tests/DBAL/Functional/Schema/MySqlSchemaManagerTest.php +++ b/tests/Doctrine/Tests/DBAL/Functional/Schema/MySqlSchemaManagerTest.php @@ -19,7 +19,7 @@ class MysqlSchemaManagerTest extends \Doctrine\Tests\DbalFunctionalTestCase { $this->markTestSkipped('The MySqlSchemaTest requires the use of mysql'); } - $this->_sm = new Schema\MySqlSchemaManager($this->_conn); + $this->_sm = $this->_conn->getSchemaManager(); } public function testListDatabases() @@ -31,7 +31,7 @@ class MysqlSchemaManagerTest extends \Doctrine\Tests\DbalFunctionalTestCase $this->_sm->createDatabase('test_mysql_create_database'); $databases = $this->_sm->listDatabases(); - $this->assertEquals(in_array('test_mysql_create_database', $databases), true); + $this->assertEquals(true, in_array('test_mysql_create_database', $databases)); } public function testListFunctions() @@ -80,7 +80,7 @@ class MysqlSchemaManagerTest extends \Doctrine\Tests\DbalFunctionalTestCase $this->_sm->createTable('list_sequences_test', $columns, $options); $sequences = $this->_sm->listSequences(); - $this->assertEquals(in_array('list_sequences_test', $sequences), true); + $this->assertEquals(true, in_array('list_sequences_test', $sequences)); } public function testListTableConstraints() @@ -108,7 +108,7 @@ class MysqlSchemaManagerTest extends \Doctrine\Tests\DbalFunctionalTestCase $tableConstraints = $this->_sm->listTableConstraints('list_table_constraints_test'); - $this->assertEquals($tableConstraints, array(array('PRIMARY'))); + $this->assertEquals(array('PRIMARY'), $tableConstraints); } public function testListTableColumns() @@ -136,23 +136,23 @@ class MysqlSchemaManagerTest extends \Doctrine\Tests\DbalFunctionalTestCase $columns = $this->_sm->listTableColumns('list_tables_test'); - $this->assertEquals($columns[0]['name'], 'id'); - $this->assertEquals($columns[0]['primary'], true); - $this->assertEquals(get_class($columns[0]['type']), 'Doctrine\DBAL\Types\IntegerType'); - $this->assertEquals($columns[0]['length'], 4); - $this->assertEquals($columns[0]['unsigned'], false); - $this->assertEquals($columns[0]['fixed'], false); - $this->assertEquals($columns[0]['notnull'], true); - $this->assertEquals($columns[0]['default'], null); + $this->assertEquals('id', $columns[0]['name']); + $this->assertEquals(true, $columns[0]['primary']); + $this->assertEquals('Doctrine\DBAL\Types\IntegerType', get_class($columns[0]['type'])); + $this->assertEquals(4, $columns[0]['length']); + $this->assertEquals(false, $columns[0]['unsigned']); + $this->assertEquals(false, $columns[0]['fixed']); + $this->assertEquals(true, $columns[0]['notnull']); + $this->assertEquals(null, $columns[0]['default']); - $this->assertEquals($columns[1]['name'], 'test'); - $this->assertEquals($columns[1]['primary'], false); - $this->assertEquals(get_class($columns[1]['type']), 'Doctrine\DBAL\Types\StringType'); - $this->assertEquals($columns[1]['length'], 255); - $this->assertEquals($columns[1]['unsigned'], false); - $this->assertEquals($columns[1]['fixed'], false); - $this->assertEquals($columns[1]['notnull'], false); - $this->assertEquals($columns[1]['default'], null); + $this->assertEquals('test', $columns[1]['name']); + $this->assertEquals(false, $columns[1]['primary']); + $this->assertEquals('Doctrine\DBAL\Types\StringType', get_class($columns[1]['type'])); + $this->assertEquals(255, $columns[1]['length']); + $this->assertEquals(false, $columns[1]['unsigned']); + $this->assertEquals(false, $columns[1]['fixed']); + $this->assertEquals(false, $columns[1]['notnull']); + $this->assertEquals(null, $columns[1]['default']); } public function testListTableIndexes() @@ -189,12 +189,12 @@ class MysqlSchemaManagerTest extends \Doctrine\Tests\DbalFunctionalTestCase $tableIndexes = $this->_sm->listTableIndexes('list_table_indexes_test'); - $this->assertEquals($tableIndexes[0]['name'], 'test_index_name'); - $this->assertEquals($tableIndexes[0]['column'], 'test'); - $this->assertEquals($tableIndexes[0]['unique'], true); + $this->assertEquals('test_index_name', $tableIndexes[0]['name']); + $this->assertEquals('test', $tableIndexes[0]['column']); + $this->assertEquals(true, $tableIndexes[0]['unique']); } - public function testListTable() + public function testListTables() { $columns = array( 'id' => array( @@ -219,13 +219,13 @@ class MysqlSchemaManagerTest extends \Doctrine\Tests\DbalFunctionalTestCase $tables = $this->_sm->listTables(); - $this->assertEquals(in_array('list_tables_test', $tables), true); + $this->assertEquals(true, in_array('list_tables_test', $tables)); } public function testListUsers() { $users = $this->_sm->listUsers(); - $this->assertEquals(is_array($users), true); + $this->assertEquals(true, is_array($users)); $params = $this->_conn->getParams(); $testUser = $params['user']; $found = false; @@ -234,7 +234,7 @@ class MysqlSchemaManagerTest extends \Doctrine\Tests\DbalFunctionalTestCase $found = true; } } - $this->assertEquals($found, true); + $this->assertEquals(true, $found); } public function testListViews() @@ -249,4 +249,66 @@ class MysqlSchemaManagerTest extends \Doctrine\Tests\DbalFunctionalTestCase $this->assertEquals('test_create_view', $views[0]['name']); $this->assertEquals('/* ALGORITHM=UNDEFINED */ select `mysql`.`user`.`Host` AS `Host`,`mysql`.`user`.`User` AS `User`,`mysql`.`user`.`Password` AS `Password`,`mysql`.`user`.`Select_priv` AS `Select_priv`,`mysql`.`user`.`Insert_priv` AS `Insert_priv`,`mysql`.`user`.`Update_priv` AS `Update_priv`,`mysql`.`user`.`Delete_priv` AS `Delete_priv`,`mysql`.`user`.`Create_priv` AS `Create_priv`,`mysql`.`user`.`Drop_priv` AS `Drop_priv`,`mysql`.`user`.`Reload_priv` AS `Reload_priv`,`mysql`.`user`.`Shutdown_priv` AS `Shutdown_priv`,`mysql`.`user`.`Process_priv` AS `Process_priv`,`mysql`.`user`.`File_priv` AS `File_priv`,`mysql`.`user`.`Grant_priv` AS `Grant_priv`,`mysql`.`user`.`References_priv` AS `References_priv`,`mysql`.`user`.`Index_priv` AS `Index_priv`,`mysql`.`user`.`Alter_priv` AS `Alter_priv`,`mysql`.`user`.`Show_db_priv` AS `Show_db_priv`,`mysql`.`user`.`Super_priv` AS `Super_priv`,`mysql`.`user`.`Create_tmp_table_priv` AS `Create_tmp_table_priv`,`mysql`.`user`.`Lock_tables_priv` AS `Lock_tables_priv`,`mysql`.`user`.`Execute_priv` AS `Execute_priv`,`mysql`.`user`.`Repl_slave_priv` AS `Repl_slave_priv`,`mysql`.`user`.`Repl_client_priv` AS `Repl_client_priv`,`mysql`.`user`.`Create_view_priv` AS `Create_view_priv`,`mysql`.`user`.`Show_view_priv` AS `Show_view_priv`,`mysql`.`user`.`Create_routine_priv` AS `Create_routine_priv`,`mysql`.`user`.`Alter_routine_priv` AS `Alter_routine_priv`,`mysql`.`user`.`Create_user_priv` AS `Create_user_priv`,`mysql`.`user`.`ssl_type` AS `ssl_type`,`mysql`.`user`.`ssl_cipher` AS `ssl_cipher`,`mysql`.`user`.`x509_issuer` AS `x509_issuer`,`mysql`.`user`.`x509_subject` AS `x509_subject`,`mysql`.`user`.`max_questions` AS `max_questions`,`mysql`.`user`.`max_updates` AS `max_updates`,`mysql`.`user`.`max_connections` AS `max_connections`,`mysql`.`user`.`max_user_connections` AS `max_user_connections` from `mysql`.`user`', $views[0]['sql']); } + + public function testListTableForeignKeys() + { + // Create table that has foreign key + $columns = array( + 'id' => array( + 'type' => Type::getType('integer'), + 'autoincrement' => true, + 'primary' => true, + 'notnull' => true + ), + 'test' => array( + 'type' => Type::getType('integer'), + 'length' => 4 + ) + ); + + $options = array('type' => 'innodb'); + + try { + $this->_sm->dropTable('list_table_foreign_keys_test2'); + } catch (\Exception $e) {} + + $this->_sm->createTable('list_table_foreign_keys_test2', $columns, $options); + + // Create the table that is being referenced in the foreign key + $columns = array( + 'id' => array( + 'type' => Type::getType('integer'), + 'autoincrement' => true, + 'primary' => true, + 'notnull' => true + ), + 'whatever' => array( + 'type' => Type::getType('string'), + 'length' => 255 + ) + ); + + $options = array('type' => 'innodb'); + + try { + $this->_sm->dropTable('list_table_foreign_keys_test'); + } catch (\Exception $e) {} + + $this->_sm->createTable('list_table_foreign_keys_test', $columns, $options); + + // Create the foreign key between the tables + $definition = array( + 'name' => 'testing', + 'local' => 'test', + 'foreign' => 'id', + 'foreignTable' => 'list_table_foreign_keys_test' + ); + $this->_sm->createForeignKey('list_table_foreign_keys_test2', $definition); + + $tableForeignKeys = $this->_sm->listTableForeignKeys('list_table_foreign_keys_test2'); + $this->assertEquals(1, count($tableForeignKeys)); + $this->assertEquals('list_table_foreign_keys_test', $tableForeignKeys[0]['table']); + $this->assertEquals('test', $tableForeignKeys[0]['local']); + $this->assertEquals('id', $tableForeignKeys[0]['foreign']); + } } \ No newline at end of file diff --git a/tests/Doctrine/Tests/DBAL/Functional/Schema/PostgreSqlSchemaManagerTest.php b/tests/Doctrine/Tests/DBAL/Functional/Schema/PostgreSqlSchemaManagerTest.php new file mode 100644 index 000000000..f8b5215df --- /dev/null +++ b/tests/Doctrine/Tests/DBAL/Functional/Schema/PostgreSqlSchemaManagerTest.php @@ -0,0 +1,318 @@ +_conn = TestUtil::getConnection(); + if ($this->_conn->getDatabasePlatform()->getName() !== 'postgresql') + { + $this->markTestSkipped('The PostgreSQLSchemaTest requires the use of postgresql'); + } + $this->_sm = $this->_conn->getSchemaManager(); + } + + public function testListDatabases() + { + try { + $this->_sm->dropDatabase('test_pgsql_create_database'); + } catch (\Exception $e) {} + + $this->_sm->createDatabase('test_pgsql_create_database'); + + $databases = $this->_sm->listDatabases(); + + $this->assertEquals(in_array('test_pgsql_create_database', $databases), true); + } + + public function testListFunctions() + { + try { + $this->_sm->listFunctions(); + } catch (\Exception $e) { + return; + } + + $this->fail('PostgreSql listFunctions() should throw an exception because it is not supported'); + } + + public function testListTriggers() + { + $triggers = $this->_sm->listTriggers(); + $this->assertEquals(true, is_array($triggers)); + $this->assertEquals(true, count($triggers) > 0); + } + + public function testListSequences() + { + $columns = array( + 'id' => array( + 'type' => Type::getType('integer'), + 'autoincrement' => true, + 'primary' => true, + 'notnull' => true + ), + 'test' => array( + 'type' => Type::getType('string'), + 'length' => 255 + ) + ); + + $options = array(); + + try { + $this->_sm->dropTable('list_sequences_test'); + } catch (\Exception $e) {} + + $this->_sm->createTable('list_sequences_test', $columns, $options); + + $sequences = $this->_sm->listSequences(); + + $this->assertEquals(true, in_array('list_sequences_test_id_seq', $sequences)); + } + + public function testListTableConstraints() + { + $columns = array( + 'id' => array( + 'type' => Type::getType('integer'), + 'autoincrement' => true, + 'primary' => true, + 'notnull' => true + ), + 'test' => array( + 'type' => Type::getType('string'), + 'length' => 255 + ) + ); + + $options = array(); + + try { + $this->_sm->dropTable('list_table_constraints_test'); + } catch (\Exception $e) {} + + $this->_sm->createTable('list_table_constraints_test', $columns, $options); + + $tableConstraints = $this->_sm->listTableConstraints('list_table_constraints_test'); + + $this->assertEquals(array('list_table_constraints_test_pkey'), $tableConstraints); + } + + public function testListTableColumns() + { + $columns = array( + 'id' => array( + 'type' => Type::getType('integer'), + 'autoincrement' => true, + 'primary' => true, + 'notnull' => true + ), + 'test' => array( + 'type' => Type::getType('string'), + 'length' => 255 + ) + ); + + $options = array(); + + try { + $this->_sm->dropTable('list_tables_test'); + } catch (\Exception $e) {} + + $this->_sm->createTable('list_tables_test', $columns, $options); + + $columns = $this->_sm->listTableColumns('list_tables_test'); + + $this->assertEquals('id', $columns[0]['name']); + $this->assertEquals(true, $columns[0]['primary']); + $this->assertEquals('Doctrine\DBAL\Types\IntegerType', get_class($columns[0]['type'])); + $this->assertEquals(4, $columns[0]['length']); + $this->assertEquals(false, $columns[0]['unsigned']); + $this->assertEquals(false, $columns[0]['fixed']); + $this->assertEquals(true, $columns[0]['notnull']); + $this->assertEquals(null, $columns[0]['default']); + + $this->assertEquals('test', $columns[1]['name']); + $this->assertEquals(false, $columns[1]['primary']); + $this->assertEquals('Doctrine\DBAL\Types\StringType', get_class($columns[1]['type'])); + $this->assertEquals(255, $columns[1]['length']); + $this->assertEquals(false, $columns[1]['unsigned']); + $this->assertEquals(false, $columns[1]['fixed']); + $this->assertEquals(false, $columns[1]['notnull']); + $this->assertEquals(null, $columns[1]['default']); + } + + public function testListTableIndexes() + { + $columns = array( + 'id' => array( + 'type' => Type::getType('integer'), + 'autoincrement' => true, + 'primary' => true, + 'notnull' => true + ), + 'test' => array( + 'type' => Type::getType('string'), + 'length' => 255 + ) + ); + + $options = array( + 'indexes' => array( + 'test' => array( + 'fields' => array( + 'test' => array() + ), + 'type' => 'unique' + ) + ) + ); + + try { + $this->_sm->dropTable('list_table_indexes_test'); + } catch (\Exception $e) {} + + $this->_sm->createTable('list_table_indexes_test', $columns, $options); + + $tableIndexes = $this->_sm->listTableIndexes('list_table_indexes_test'); + + $this->assertEquals('test', $tableIndexes[0]['name']); + $this->assertEquals(true, $tableIndexes[0]['unique']); + } + + public function testListTables() + { + $columns = array( + 'id' => array( + 'type' => Type::getType('integer'), + 'autoincrement' => true, + 'primary' => true, + 'notnull' => true + ), + 'test' => array( + 'type' => Type::getType('string'), + 'length' => 255 + ) + ); + + $options = array(); + + try { + $this->_sm->dropTable('list_tables_test'); + } catch (\Exception $e) {} + + $this->_sm->createTable('list_tables_test', $columns, $options); + + $tables = $this->_sm->listTables(); + $this->assertEquals(true, in_array('list_tables_test', $tables)); + } + + public function testListUsers() + { + $users = $this->_sm->listUsers(); + $this->assertEquals(true, is_array($users)); + $params = $this->_conn->getParams(); + $testUser = $params['user']; + $found = false; + foreach ($users as $user) { + if ($user['user'] == $testUser) { + $found = true; + } + } + $this->assertEquals(true, $found); + } + + public function testListViews() + { + try { + $this->_sm->dropView('test_create_view'); + } catch (\Exception $e) {} + + $this->_sm->createView('test_create_view', 'SELECT usename, passwd FROM pg_user'); + $views = $this->_sm->listViews(); + + $found = false; + foreach ($views as $view) { + if ($view['name'] == 'test_create_view') { + $found = true; + break; + } + } + + $this->assertEquals(true, $found); + $this->assertEquals('SELECT pg_user.usename, pg_user.passwd FROM pg_user;', $view['sql']); + } + + public function testListTableForeignKeys() + { + // Create table that has foreign key + $columns = array( + 'id' => array( + 'type' => Type::getType('integer'), + 'autoincrement' => true, + 'primary' => true, + 'notnull' => true + ), + 'test' => array( + 'type' => Type::getType('integer'), + 'length' => 4 + ) + ); + + $options = array('type' => 'innodb'); + + try { + $this->_sm->dropTable('list_table_foreign_keys_test2'); + } catch (\Exception $e) {} + + $this->_sm->createTable('list_table_foreign_keys_test2', $columns, $options); + + // Create the table that is being referenced in the foreign key + $columns = array( + 'id' => array( + 'type' => Type::getType('integer'), + 'autoincrement' => true, + 'primary' => true, + 'notnull' => true + ), + 'whatever' => array( + 'type' => Type::getType('string'), + 'length' => 255 + ) + ); + + $options = array('type' => 'innodb'); + + try { + $this->_sm->dropTable('list_table_foreign_keys_test'); + } catch (\Exception $e) {} + + $this->_sm->createTable('list_table_foreign_keys_test', $columns, $options); + + // Create the foreign key between the tables + $definition = array( + 'name' => 'testing', + 'local' => 'test', + 'foreign' => 'id', + 'foreignTable' => 'list_table_foreign_keys_test' + ); + $this->_sm->createForeignKey('list_table_foreign_keys_test2', $definition); + + $tableForeignKeys = $this->_sm->listTableForeignKeys('list_table_foreign_keys_test2'); + $this->assertEquals(1, count($tableForeignKeys)); + $this->assertEquals('list_table_foreign_keys_test', $tableForeignKeys[0]['table']); + $this->assertEquals('test', $tableForeignKeys[0]['local']); + $this->assertEquals('id', $tableForeignKeys[0]['foreign']); + } +} \ No newline at end of file diff --git a/tests/Doctrine/Tests/DBAL/Functional/Schema/SqliteSchemaManagerTest.php b/tests/Doctrine/Tests/DBAL/Functional/Schema/SqliteSchemaManagerTest.php index 82f7c0819..9d4dbf62a 100644 --- a/tests/Doctrine/Tests/DBAL/Functional/Schema/SqliteSchemaManagerTest.php +++ b/tests/Doctrine/Tests/DBAL/Functional/Schema/SqliteSchemaManagerTest.php @@ -19,7 +19,7 @@ class SqliteSchemaManagerTest extends \Doctrine\Tests\DbalFunctionalTestCase { $this->markTestSkipped('The SqliteSchemaTest requires the use of sqlite'); } - $this->_sm = new Schema\SqliteSchemaManager($this->_conn); + $this->_sm = $this->_conn->getSchemaManager(); } public function testListDatabases() @@ -75,8 +75,8 @@ class SqliteSchemaManagerTest extends \Doctrine\Tests\DbalFunctionalTestCase $this->_sm->createTable('list_sequences_test', $columns, $options); $sequences = $this->_sm->listSequences(); - $this->assertEquals($sequences[0]['name'], 'list_sequences_test'); - $this->assertEquals($sequences[1]['name'], 'sqlite_sequence'); + $this->assertEquals('list_sequences_test', $sequences[0]['name']); + $this->assertEquals('sqlite_sequence', $sequences[1]['name']); } public function testListTableConstraints() @@ -85,7 +85,7 @@ class SqliteSchemaManagerTest extends \Doctrine\Tests\DbalFunctionalTestCase // when creating tables. Sqlite does not support adding them after // the table has already been created $tableConstraints = $this->_sm->listTableConstraints('list_table_constraints_test'); - $this->assertEquals($tableConstraints, array()); + $this->assertEquals(array(), $tableConstraints); } public function testListTableColumns() @@ -109,23 +109,23 @@ class SqliteSchemaManagerTest extends \Doctrine\Tests\DbalFunctionalTestCase $tableColumns = $this->_sm->listTableColumns('list_table_columns_test'); - $this->assertEquals($tableColumns[0]['name'], 'id'); - $this->assertEquals($tableColumns[0]['primary'], true); - $this->assertEquals(get_class($tableColumns[0]['type']), 'Doctrine\DBAL\Types\IntegerType'); - $this->assertEquals($tableColumns[0]['length'], 4); - $this->assertEquals($tableColumns[0]['unsigned'], false); - $this->assertEquals($tableColumns[0]['fixed'], false); - $this->assertEquals($tableColumns[0]['notnull'], true); - $this->assertEquals($tableColumns[0]['default'], null); + $this->assertEquals('id', $tableColumns[0]['name']); + $this->assertEquals(true, $tableColumns[0]['primary']); + $this->assertEquals('Doctrine\DBAL\Types\IntegerType', get_class($tableColumns[0]['type'])); + $this->assertEquals(4, $tableColumns[0]['length']); + $this->assertEquals(false, $tableColumns[0]['unsigned']); + $this->assertEquals(false, $tableColumns[0]['fixed']); + $this->assertEquals(true, $tableColumns[0]['notnull']); + $this->assertEquals(null, $tableColumns[0]['default']); - $this->assertEquals($tableColumns[1]['name'], 'test'); - $this->assertEquals($tableColumns[1]['primary'], false); - $this->assertEquals(get_class($tableColumns[1]['type']), 'Doctrine\DBAL\Types\StringType'); - $this->assertEquals($tableColumns[1]['length'], 255); - $this->assertEquals($tableColumns[1]['unsigned'], false); - $this->assertEquals($tableColumns[1]['fixed'], false); - $this->assertEquals($tableColumns[1]['notnull'], false); - $this->assertEquals($tableColumns[1]['default'], null); + $this->assertEquals('test', $tableColumns[1]['name']); + $this->assertEquals(false, $tableColumns[1]['primary']); + $this->assertEquals('Doctrine\DBAL\Types\StringType', get_class($tableColumns[1]['type'])); + $this->assertEquals(255, $tableColumns[1]['length']); + $this->assertEquals(false, $tableColumns[1]['unsigned']); + $this->assertEquals(false, $tableColumns[1]['fixed']); + $this->assertEquals(false, $tableColumns[1]['notnull']); + $this->assertEquals(null, $tableColumns[1]['default']); } public function testListTableIndexes() @@ -157,11 +157,11 @@ class SqliteSchemaManagerTest extends \Doctrine\Tests\DbalFunctionalTestCase $this->_sm->createTable('list_table_indexes_test', $columns, $options); $tableIndexes = $this->_sm->listTableIndexes('list_table_indexes_test'); - $this->assertEquals($tableIndexes[0]['name'], 'test'); - $this->assertEquals($tableIndexes[0]['unique'], true); + $this->assertEquals('test', $tableIndexes[0]['name']); + $this->assertEquals(true, $tableIndexes[0]['unique']); } - public function testListTable() + public function testListTables() { $columns = array( 'id' => array( @@ -181,7 +181,7 @@ class SqliteSchemaManagerTest extends \Doctrine\Tests\DbalFunctionalTestCase $this->_sm->createTable('list_tables_test', $columns, $options); $tables = $this->_sm->listTables(); - $this->assertEquals(in_array('list_tables_test', $tables), true); + $this->assertEquals(true, in_array('list_tables_test', $tables)); } public function testListUsers() @@ -221,8 +221,8 @@ class SqliteSchemaManagerTest extends \Doctrine\Tests\DbalFunctionalTestCase $this->_sm->createView('test_create_view', 'SELECT * from test_views'); $views = $this->_sm->listViews(); - $this->assertEquals($views[0]['name'], 'test_create_view'); - $this->assertEquals($views[0]['sql'], 'CREATE VIEW test_create_view AS SELECT * from test_views'); + $this->assertEquals('test_create_view', $views[0]['name']); + $this->assertEquals('CREATE VIEW test_create_view AS SELECT * from test_views', $views[0]['sql']); } public function testCreateAndDropDatabase() @@ -239,11 +239,11 @@ class SqliteSchemaManagerTest extends \Doctrine\Tests\DbalFunctionalTestCase $sm = $conn->getSchemaManager(); $sm->createDatabase(); - $this->assertEquals(file_exists($path), true); + $this->assertEquals(true, file_exists($path)); $sm->dropDatabase(); - $this->assertEquals(file_exists($path), false); + $this->assertEquals(false, file_exists($path)); $sm->createDatabase(); - $this->assertEquals(file_exists($path), true); + $this->assertEquals(true, file_exists($path)); $sm->dropDatabase(); } @@ -266,27 +266,27 @@ class SqliteSchemaManagerTest extends \Doctrine\Tests\DbalFunctionalTestCase $this->_sm->createTable('test_create_table', $columns, $options); $tables = $this->_sm->listTables(); - $this->assertEquals(in_array('test_create_table', $tables), true); + $this->assertEquals(true, in_array('test_create_table', $tables)); $tableColumns = $this->_sm->listTableColumns('test_create_table'); - $this->assertEquals($tableColumns[0]['name'], 'id'); - $this->assertEquals($tableColumns[0]['primary'], true); - $this->assertEquals(get_class($tableColumns[0]['type']), 'Doctrine\DBAL\Types\IntegerType'); - $this->assertEquals($tableColumns[0]['length'], 4); - $this->assertEquals($tableColumns[0]['unsigned'], false); - $this->assertEquals($tableColumns[0]['fixed'], false); - $this->assertEquals($tableColumns[0]['notnull'], true); - $this->assertEquals($tableColumns[0]['default'], null); + $this->assertEquals('id', $tableColumns[0]['name']); + $this->assertEquals(true, $tableColumns[0]['primary']); + $this->assertEquals('Doctrine\DBAL\Types\IntegerType', get_class($tableColumns[0]['type'])); + $this->assertEquals(4, $tableColumns[0]['length']); + $this->assertEquals(false, $tableColumns[0]['unsigned']); + $this->assertEquals(false, $tableColumns[0]['fixed']); + $this->assertEquals(true, $tableColumns[0]['notnull']); + $this->assertEquals(null, $tableColumns[0]['default']); - $this->assertEquals($tableColumns[1]['name'], 'test'); - $this->assertEquals($tableColumns[1]['primary'], false); - $this->assertEquals(get_class($tableColumns[1]['type']), 'Doctrine\DBAL\Types\StringType'); - $this->assertEquals($tableColumns[1]['length'], 255); - $this->assertEquals($tableColumns[1]['unsigned'], false); - $this->assertEquals($tableColumns[1]['fixed'], false); - $this->assertEquals($tableColumns[1]['notnull'], false); - $this->assertEquals($tableColumns[1]['default'], null); + $this->assertEquals('test', $tableColumns[1]['name']); + $this->assertEquals(false, $tableColumns[1]['primary']); + $this->assertEquals('Doctrine\DBAL\Types\StringType', get_class($tableColumns[1]['type'])); + $this->assertEquals(255, $tableColumns[1]['length']); + $this->assertEquals(false, $tableColumns[1]['unsigned']); + $this->assertEquals(false, $tableColumns[1]['fixed']); + $this->assertEquals(false, $tableColumns[1]['notnull']); + $this->assertEquals(null, $tableColumns[1]['default']); } public function testCreateSequence() @@ -339,8 +339,8 @@ class SqliteSchemaManagerTest extends \Doctrine\Tests\DbalFunctionalTestCase $this->_sm->createIndex('test_create_index', 'test', $index); $tableIndexes = $this->_sm->listTableIndexes('test_create_index'); - $this->assertEquals($tableIndexes[0]['name'], 'test'); - $this->assertEquals($tableIndexes[0]['unique'], true); + $this->assertEquals('test', $tableIndexes[0]['name']); + $this->assertEquals(true, $tableIndexes[0]['unique']); } public function testCreateForeignKey() diff --git a/tests/Doctrine/Tests/Mocks/SequenceMock.php b/tests/Doctrine/Tests/Mocks/SequenceMock.php index 69579ae6d..73a23d8c9 100644 --- a/tests/Doctrine/Tests/Mocks/SequenceMock.php +++ b/tests/Doctrine/Tests/Mocks/SequenceMock.php @@ -7,18 +7,12 @@ use Doctrine\ORM\EntityManager; class SequenceMock extends \Doctrine\ORM\Id\SequenceGenerator { private $_sequenceNumber = 0; - - /** - * Enter description here... - * - * @param object $entity - * @override - */ + public function generate(EntityManager $em, $entity) { return $this->_sequenceNumber++; } - + /** * @override */ @@ -42,14 +36,14 @@ class SequenceMock extends \Doctrine\ORM\Id\SequenceGenerator { return $this->_sequenceNumber; } - + /* Mock API */ - + public function reset() { $this->_sequenceNumber = 0; } - + public function autoinc() { $this->_sequenceNumber++;