diff --git a/COPYRIGHT b/COPYRIGHT index dfa08dabc..5616eb8e9 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -25,4 +25,15 @@ Zend Framework Doctrine contains ports of a few Zend components and has borrowed concepts and ideas from the Zend Framework project. Url: http://framework.zend.com -Copyright: Copyright © 2006-2007 by Zend Technologies, All rights reserved. +Copyright: Copyright © 2006-2009 by Zend Technologies, All rights reserved. +License: New BSD License + +eZ Components +------------ + +Doctrine SchemaTool, Platforms and SchemaManagers borrow ideas and concepts +from ezcDatabaseSchema. + +Url: http://www.ezcomponents.org +License: New BSD License +Copyright: Copyright (C) 2005-2009 eZ Systems AS. All rights reserved. \ No newline at end of file diff --git a/lib/Doctrine/DBAL/Platforms/OraclePlatform.php b/lib/Doctrine/DBAL/Platforms/OraclePlatform.php index 4c0c28197..e0d533caa 100644 --- a/lib/Doctrine/DBAL/Platforms/OraclePlatform.php +++ b/lib/Doctrine/DBAL/Platforms/OraclePlatform.php @@ -27,6 +27,7 @@ namespace Doctrine\DBAL\Platforms; * @since 2.0 * @author Roman Borschel * @author Lukas Smith (PEAR MDB2 library) + * @author Benjamin Eberlei */ class OraclePlatform extends AbstractPlatform { @@ -275,10 +276,22 @@ class OraclePlatform extends AbstractPlatform return $sql; } + /** + * + * @license New BSD License + * @link http://ezcomponents.org/docs/api/trunk/DatabaseSchema/ezcDbSchemaOracleReader.html + * @param string $table + * @return string + */ public function getListTableIndexesSql($table) { - return "SELECT * FROM user_indexes" - . " WHERE table_name = '" . strtoupper($table) . "'"; + return "SELECT uind.index_name AS name, " . + " uind.index_type AS type, " . + " decode( uind.uniqueness, 'NONUNIQUE', 0, 'UNIQUE', 1 ) AS is_unique, " . + " uind_col.column_name AS column_name, " . + " uind_col.column_position AS column_pos " . + "FROM user_indexes uind, user_ind_columns uind_col " . + "WHERE uind.index_name = uind_col.index_name AND uind_col.table_name = '$table'"; } public function getListTablesSql() diff --git a/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php b/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php index a9ee1b1ac..a245d7cc5 100644 --- a/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php @@ -27,6 +27,7 @@ namespace Doctrine\DBAL\Platforms; * @since 2.0 * @author Roman Borschel * @author Lukas Smith (PEAR MDB2 library) + * @author Benjamin Eberlei */ class PostgreSqlPlatform extends AbstractPlatform { @@ -377,24 +378,22 @@ class PostgreSqlPlatform extends AbstractPlatform )"; } + /** + * @license New BSD License + * @link http://ezcomponents.org/docs/api/trunk/DatabaseSchema/ezcDbSchemaPgsqlReader.html + * @param string $table + * @return string + */ public function getListTableIndexesSql($table) { - return "SELECT - relname, - ( - SELECT indisunique - FROM pg_index - WHERE oid = indexrelid - ) as unique - FROM - pg_class - WHERE oid IN ( + return "SELECT relname, pg_index.indisunique, pg_index.indisprimary, + pg_index.indkey, pg_index.indrelid + FROM pg_class, pg_index + WHERE oid IN ( SELECT indexrelid FROM pg_index, pg_class - WHERE pg_class.relname = '$table' - AND pg_class.oid=pg_index.indrelid - AND indisprimary != 't' - )"; + WHERE pg_class.relname='$table' AND pg_class.oid=pg_index.indrelid + ) AND pg_index.indexrelid = oid"; } public function getListTableColumnsSql($table) diff --git a/lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php b/lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php index 780b80a65..39e07040d 100644 --- a/lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php +++ b/lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php @@ -33,6 +33,7 @@ use \Doctrine\Common\DoctrineException; * @author Lukas Smith (PEAR MDB2 library) * @author Roman Borschel * @author Jonathan H. Wage + * @author Benjamin Eberlei * @version $Revision$ * @since 2.0 */ @@ -182,6 +183,28 @@ abstract class AbstractSchemaManager /** * List the indexes for a given table + * + * @example + * $indexes = array( + * 'primary' => array( + * 'name' => 'primary', + * 'columns' => array('id'), + * 'unique' => true, + * 'primary' => true, + * ), + * 'fieldUnq' => array( + * 'name' => 'fieldUnq', + * 'columns' => array('foo', 'bar'), + * 'unique' => true, + * 'primary' => false, + * ), + * 'fieldIdx' => array( + * 'name' => 'fieldIdx', + * 'columns' => array('baz'), + * 'unique' => false, + * 'primary' => false, + * ), + * ); * * @param string $table The name of the table * @return array $tableIndexes @@ -192,7 +215,7 @@ abstract class AbstractSchemaManager $tableIndexes = $this->_conn->fetchAll($sql); - return $this->_getPortableTableIndexesList($tableIndexes); + return $this->_getPortableTableIndexesList($tableIndexes, $table); } /** @@ -884,20 +907,35 @@ abstract class AbstractSchemaManager return $tableColumn; } - protected function _getPortableTableIndexesList($tableIndexes) + /** + * Aggregate and group the index results according to the required data result. + * + * @param array $tableIndexes + * @param string $tableName + * @return array + */ + protected function _getPortableTableIndexesList($tableIndexes, $tableName=null) { - $list = array(); - foreach ($tableIndexes as $key => $value) { - if ($value = $this->_getPortableTableIndexDefinition($value)) { - $list[] = $value; + $result = array(); + foreach($tableIndexes AS $tableIndex) { + $indexName = $keyName = $tableIndex['key_name']; + if($tableIndex['primary']) { + $keyName = 'primary'; + } + + if(!isset($result[$keyName])) { + $result[$keyName] = array( + 'name' => $indexName, + 'columns' => array($tableIndex['column_name']), + 'unique' => $tableIndex['non_unique'] ? false : true, + 'primary' => $tableIndex['primary'], + ); + } else { + $result[$keyName]['columns'][] = $tableIndex['column_name']; } } - return $list; - } - protected function _getPortableTableIndexDefinition($tableIndex) - { - return $tableIndex; + return $result; } protected function _getPortableTablesList($tables) diff --git a/lib/Doctrine/DBAL/Schema/MySqlSchemaManager.php b/lib/Doctrine/DBAL/Schema/MySqlSchemaManager.php index 3e334ae28..07f58b262 100644 --- a/lib/Doctrine/DBAL/Schema/MySqlSchemaManager.php +++ b/lib/Doctrine/DBAL/Schema/MySqlSchemaManager.php @@ -28,6 +28,7 @@ namespace Doctrine\DBAL\Schema; * @author Konsta Vesterinen * @author Lukas Smith (PEAR MDB2 library) * @author Roman Borschel + * @author Benjamin Eberlei * @version $Revision$ * @since 2.0 */ @@ -51,18 +52,19 @@ class MySqlSchemaManager extends AbstractSchemaManager ); } - protected function _getPortableTableIndexDefinition($tableIndex) + protected function _getPortableTableIndexesList($tableIndexes, $tableName=null) { - $tableIndex = array_change_key_case($tableIndex, CASE_LOWER); - - $result = array(); - if ($tableIndex['key_name'] != 'PRIMARY' && ($index = $tableIndex['key_name'])) { - $result['name'] = $index; - $result['column'] = $tableIndex['column_name']; - $result['unique'] = $tableIndex['non_unique'] ? false : true; + foreach($tableIndexes AS $k => $v) { + $v = array_change_key_case($v, CASE_LOWER); + if($v['key_name'] == 'PRIMARY') { + $v['primary'] = true; + } else { + $v['primary'] = false; + } + $tablesIndexes[$k] = $v; } - - return $result; + + return parent::_getPortableTableIndexesList($tablesIndexes, $tableName); } protected function _getPortableTableConstraintDefinition($tableConstraint) diff --git a/lib/Doctrine/DBAL/Schema/OracleSchemaManager.php b/lib/Doctrine/DBAL/Schema/OracleSchemaManager.php index d8a7c17a9..6a4ca0488 100644 --- a/lib/Doctrine/DBAL/Schema/OracleSchemaManager.php +++ b/lib/Doctrine/DBAL/Schema/OracleSchemaManager.php @@ -52,12 +52,32 @@ class OracleSchemaManager extends AbstractSchemaManager return $table['table_name']; } - protected function _getPortableTableIndexDefinition($tableIndex) + /** + * @license New BSD License + * @link http://ezcomponents.org/docs/api/trunk/DatabaseSchema/ezcDbSchemaPgsqlReader.html + * @param array $tableIndexes + * @param string $tableName + * @return array + */ + protected function _getPortableTableIndexesList($tableIndexes, $tableName=null) { - return array( - 'name' => $tableIndex['index_name'], - 'unique' => (isset($tableIndex['uniqueness']) && $tableIndex['uniqueness'] == 'UNIQUE') ? true : false - ); + $indexBuffer = array(); + foreach ( $tableIndexes as $tableIndex ) { + $keyName = $tableIndex['name']; + + if ( $keyName == $tableName.'_pkey' ) { + $keyName = 'primary'; + $buffer['primary'] = true; + $buffer['non_unique'] = false; + } else { + $buffer['primary'] = false; + $buffer['non_unique'] = ( $tableIndex['is_unique'] == 0 ) ? true : false; + } + $buffer['key_name'] = $keyName; + $buffer['column_name'] = $tableIndex['column_name']; + $indexBuffer[] = $buffer; + } + parent::_getPortableTableIndexesList($indexBuffer, $tableName); } protected function _getPortableTableColumnDefinition($tableColumn) diff --git a/lib/Doctrine/DBAL/Schema/PostgreSqlSchemaManager.php b/lib/Doctrine/DBAL/Schema/PostgreSqlSchemaManager.php index 81748021f..7e5b1a0d0 100644 --- a/lib/Doctrine/DBAL/Schema/PostgreSqlSchemaManager.php +++ b/lib/Doctrine/DBAL/Schema/PostgreSqlSchemaManager.php @@ -27,6 +27,7 @@ namespace Doctrine\DBAL\Schema; * @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @author Konsta Vesterinen * @author Lukas Smith (PEAR MDB2 library) + * @author Benjamin Eberlei * @version $Revision$ * @since 2.0 */ @@ -70,12 +71,35 @@ class PostgreSqlSchemaManager extends AbstractSchemaManager return $table['table_name']; } - protected function _getPortableTableIndexDefinition($index) + /** + * @license New BSD License + * @link http://ezcomponents.org/docs/api/trunk/DatabaseSchema/ezcDbSchemaPgsqlReader.html + * @param array $tableIndexes + * @param string $tableName + * @return array + */ + protected function _getPortableTableIndexesList($tableIndexes, $tableName=null) { - return array( - 'name' => $index['relname'], - 'unique' => (bool) $index['unique'] - ); + $buffer = array(); + foreach($tableIndexes AS $row) { + $colNumbers = explode( ' ', $row['indkey'] ); + $colNumbersSql = 'IN (' . join( ' ,', $colNumbers ) . ' )'; + $columnNameSql = "SELECT attname FROM pg_attribute + WHERE attrelid={$row['indrelid']} AND attnum $colNumbersSql;"; + + $stmt = $this->_conn->execute($columnNameSql); + $indexColumns = $stmt->fetchAll(); + + foreach ( $indexColumns as $colRow ) { + $buffer[] = array( + 'key_name' => $row['relname'], + 'column_name' => $colRow['attname'], + 'non_unique' => !$row['indisunique'], + 'primary' => $row['indisprimary'] + ); + } + } + return parent::_getPortableTableIndexesList($buffer); } protected function _getPortableDatabaseDefinition($database) diff --git a/lib/Doctrine/DBAL/Schema/SqliteSchemaManager.php b/lib/Doctrine/DBAL/Schema/SqliteSchemaManager.php index 9e0a07f76..d9a75d67d 100644 --- a/lib/Doctrine/DBAL/Schema/SqliteSchemaManager.php +++ b/lib/Doctrine/DBAL/Schema/SqliteSchemaManager.php @@ -68,6 +68,51 @@ class SqliteSchemaManager extends AbstractSchemaManager return $table['name']; } + /** + * @license New BSD License + * @link http://ezcomponents.org/docs/api/trunk/DatabaseSchema/ezcDbSchemaPgsqlReader.html + * @param array $tableIndexes + * @param string $tableName + * @return array + */ + protected function _getPortableTableIndexesList($tableIndexes, $tableName=null) + { + $indexBuffer = array(); + + // fetch primary + $stmt = $this->_conn->execute( "PRAGMA TABLE_INFO ('$tableName')" ); + $indexArray = $stmt->fetchAll(\Doctrine\DBAL\Connection::FETCH_ASSOC); + foreach($indexArray AS $indexColumnRow) { + if($indexColumnRow['pk'] == "1") { + $indexBuffer[] = array( + 'key_name' => 'primary', + 'primary' => true, + 'non_unique' => false, + 'column_name' => $indexColumnRow['name'] + ); + } + } + + // fetch regular indexes + foreach($tableIndexes AS $tableIndex) { + $keyName = $tableIndex['name']; + $idx = array(); + $idx['key_name'] = $keyName; + $idx['primary'] = false; + $idx['non_unique'] = $tableIndex['unique']?false:true; + + $stmt = $this->_conn->execute( "PRAGMA INDEX_INFO ( '{$keyName}' )" ); + $indexArray = $stmt->fetchAll(\Doctrine\DBAL\Connection::FETCH_ASSOC); + + foreach ( $indexArray as $indexColumnRow ) { + $idx['column_name'] = $indexColumnRow['name']; + $indexBuffer[] = $idx; + } + } + + return parent::_getPortableTableIndexesList($indexBuffer, $tableName); + } + protected function _getPortableTableIndexDefinition($tableIndex) { return array( diff --git a/tests/Doctrine/Tests/DBAL/Functional/Schema/MySqlSchemaManagerTest.php b/tests/Doctrine/Tests/DBAL/Functional/Schema/MySqlSchemaManagerTest.php index 36c240bd5..0bbc784fe 100644 --- a/tests/Doctrine/Tests/DBAL/Functional/Schema/MySqlSchemaManagerTest.php +++ b/tests/Doctrine/Tests/DBAL/Functional/Schema/MySqlSchemaManagerTest.php @@ -70,28 +70,6 @@ class MySqlSchemaManagerTest extends SchemaManagerFunctionalTestCase $this->assertEquals(null, $columns[1]['default']); } - public function testListTableIndexes() - { - $data['options'] = array( - 'indexes' => array( - 'test_index_name' => array( - 'columns' => array( - 'test' => array() - ), - 'type' => 'unique' - ) - ) - ); - - $this->createTestTable('list_table_indexes_test', $data); - - $tableIndexes = $this->_sm->listTableIndexes('list_table_indexes_test'); - - $this->assertEquals('test_index_name', $tableIndexes[0]['name']); - $this->assertEquals('test', $tableIndexes[0]['column']); - $this->assertEquals(true, $tableIndexes[0]['unique']); - } - public function testListTables() { $this->createTestTable('list_tables_test'); diff --git a/tests/Doctrine/Tests/DBAL/Functional/Schema/OracleSchemaManagerTest.php b/tests/Doctrine/Tests/DBAL/Functional/Schema/OracleSchemaManagerTest.php index 4cc1586f5..59cfbab21 100644 --- a/tests/Doctrine/Tests/DBAL/Functional/Schema/OracleSchemaManagerTest.php +++ b/tests/Doctrine/Tests/DBAL/Functional/Schema/OracleSchemaManagerTest.php @@ -66,25 +66,6 @@ class OracleSchemaManagerTest extends SchemaManagerFunctionalTestCase $this->assertEquals(null, $columns[2]['default']); } - public function testListTableIndexes() - { - $data['options'] = array( - 'indexes' => array( - 'test_index_name' => array( - 'columns' => array( - 'test' => array() - ), - 'type' => 'unique' - ) - ) - ); - - $this->createTestTable('list_table_indexes_test', $data); - $tableIndexes = $this->_sm->listTableIndexes('list_table_indexes_test'); - $this->assertEquals(true, is_string($tableIndexes[0]['name'])); - $this->assertEquals(true, $tableIndexes[0]['unique']); - } - public function testListTables() { $this->createTestTable('list_tables_test'); diff --git a/tests/Doctrine/Tests/DBAL/Functional/Schema/PostgreSqlSchemaManagerTest.php b/tests/Doctrine/Tests/DBAL/Functional/Schema/PostgreSqlSchemaManagerTest.php index 0980c56a7..b36ebb0dc 100644 --- a/tests/Doctrine/Tests/DBAL/Functional/Schema/PostgreSqlSchemaManagerTest.php +++ b/tests/Doctrine/Tests/DBAL/Functional/Schema/PostgreSqlSchemaManagerTest.php @@ -66,25 +66,6 @@ class PostgreSqlSchemaManagerTest extends SchemaManagerFunctionalTestCase $this->assertEquals(null, $columns[1]['default']); } - public function testListTableIndexes() - { - $data['options'] = array( - 'indexes' => array( - 'test' => array( - 'columns' => array( - 'test' => array() - ), - 'type' => 'unique' - ) - ) - ); - - $this->createTestTable('list_table_indexes_test', $data); - $tableIndexes = $this->_sm->listTableIndexes('list_table_indexes_test'); - $this->assertEquals('test', $tableIndexes[0]['name']); - $this->assertEquals(true, $tableIndexes[0]['unique']); - } - public function testListTables() { $this->createTestTable('list_tables_test'); diff --git a/tests/Doctrine/Tests/DBAL/Functional/Schema/SchemaManagerFunctionalTestCase.php b/tests/Doctrine/Tests/DBAL/Functional/Schema/SchemaManagerFunctionalTestCase.php index 6241bd5ee..6492e241b 100644 --- a/tests/Doctrine/Tests/DBAL/Functional/Schema/SchemaManagerFunctionalTestCase.php +++ b/tests/Doctrine/Tests/DBAL/Functional/Schema/SchemaManagerFunctionalTestCase.php @@ -8,6 +8,65 @@ require_once __DIR__ . '/../../../TestInit.php'; class SchemaManagerFunctionalTestCase extends \Doctrine\Tests\DbalFunctionalTestCase { + public function testListTableIndexes() + { + $data['options'] = array( + 'indexes' => array( + 'test_index_name' => array( + 'columns' => array( + 'test' => array() + ), + 'type' => 'unique' + ), + 'test_composite_idx' => array( + 'columns' => array( + 'id' => array(), 'test' => array(), + ) + ), + ) + ); + + $this->createTestTable('list_table_indexes_test', $data); + + $tableIndexes = $this->_sm->listTableIndexes('list_table_indexes_test'); + + $this->assertEquals(3, count($tableIndexes)); + + $this->assertEquals(array('id'), $tableIndexes['primary']['columns']); + $this->assertTrue($tableIndexes['primary']['unique']); + $this->assertTrue($tableIndexes['primary']['primary']); + + $this->assertEquals('test_index_name', $tableIndexes['test_index_name']['name']); + $this->assertEquals(array('test'), $tableIndexes['test_index_name']['columns']); + $this->assertTrue($tableIndexes['test_index_name']['unique']); + $this->assertFalse($tableIndexes['test_index_name']['primary']); + + $this->assertEquals('test_composite_idx', $tableIndexes['test_composite_idx']['name']); + $this->assertEquals(array('id', 'test'), $tableIndexes['test_composite_idx']['columns']); + $this->assertFalse($tableIndexes['test_composite_idx']['unique']); + $this->assertFalse($tableIndexes['test_composite_idx']['primary']); + } + + public function testDropAndCreateIndex() + { + $this->createTestTable('test_create_index'); + + $index = array( + 'columns' => array( + 'test' => array() + ), + 'type' => 'unique' + ); + + $this->_sm->dropAndCreateIndex('test_create_index', 'test', $index); + $tableIndexes = $this->_sm->listTableIndexes('test_create_index'); + + $this->assertEquals('test', $tableIndexes['test']['name']); + $this->assertEquals(array('test'), $tableIndexes['test']['columns']); + $this->assertTrue($tableIndexes['test']['unique']); + $this->assertFalse($tableIndexes['test']['primary']); + } + protected function setUp() { parent::setUp(); diff --git a/tests/Doctrine/Tests/DBAL/Functional/Schema/SqliteSchemaManagerTest.php b/tests/Doctrine/Tests/DBAL/Functional/Schema/SqliteSchemaManagerTest.php index 3838f1ca2..3d77fab10 100644 --- a/tests/Doctrine/Tests/DBAL/Functional/Schema/SqliteSchemaManagerTest.php +++ b/tests/Doctrine/Tests/DBAL/Functional/Schema/SqliteSchemaManagerTest.php @@ -74,26 +74,6 @@ class SqliteSchemaManagerTest extends SchemaManagerFunctionalTestCase $this->assertEquals(null, $tableColumns[1]['default']); } - public function testListTableIndexes() - { - $data['options'] = array( - 'indexes' => array( - 'test' => array( - 'columns' => array( - 'test' => array() - ), - 'type' => 'unique' - ) - ) - ); - - $this->createTestTable('list_table_indexes_test', $data); - - $tableIndexes = $this->_sm->listTableIndexes('list_table_indexes_test'); - $this->assertEquals('test', $tableIndexes[0]['name']); - $this->assertEquals(true, $tableIndexes[0]['unique']); - } - public function testListTables() { $this->createTestTable('list_tables_test'); @@ -164,23 +144,6 @@ class SqliteSchemaManagerTest extends SchemaManagerFunctionalTestCase $this->_sm->createSequence('seqname', 1, 1); } - public function testCreateIndex() - { - $this->createTestTable('test_create_index'); - - $index = array( - 'columns' => array( - 'test' => array() - ), - 'type' => 'unique' - ); - - $this->_sm->dropAndCreateIndex('test_create_index', 'test', $index); - $tableIndexes = $this->_sm->listTableIndexes('test_create_index'); - $this->assertEquals('test', $tableIndexes[0]['name']); - $this->assertEquals(true, $tableIndexes[0]['unique']); - } - /** * @expectedException \Exception */