1
0
mirror of synced 2025-02-01 04:51:45 +03:00

[2.0] DDC-91 - Enhanced SchemaManager::listTableIndexes() considerably. Add primary keys to the index list, add a bool flag primary to each index, add an array of columns to each index. Moved a test to SchemaFunctionalTestCase to check that every database (Mysql, Pgsql, Sqlite, Oracle) returns exactly the same data from this function.

This commit is contained in:
beberlei 2009-11-03 08:58:03 +00:00
parent 37824abffe
commit cfea7883e0
13 changed files with 259 additions and 145 deletions

View File

@ -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.

View File

@ -27,6 +27,7 @@ namespace Doctrine\DBAL\Platforms;
* @since 2.0
* @author Roman Borschel <roman@code-factory.org>
* @author Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library)
* @author Benjamin Eberlei <kontakt@beberlei.de>
*/
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()

View File

@ -27,6 +27,7 @@ namespace Doctrine\DBAL\Platforms;
* @since 2.0
* @author Roman Borschel <roman@code-factory.org>
* @author Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library)
* @author Benjamin Eberlei <kontakt@beberlei.de>
*/
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
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)

View File

@ -33,6 +33,7 @@ use \Doctrine\Common\DoctrineException;
* @author Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library)
* @author Roman Borschel <roman@code-factory.org>
* @author Jonathan H. Wage <jonwage@gmail.com>
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @version $Revision$
* @since 2.0
*/
@ -183,6 +184,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;
}
}
return $list;
$result = array();
foreach($tableIndexes AS $tableIndex) {
$indexName = $keyName = $tableIndex['key_name'];
if($tableIndex['primary']) {
$keyName = 'primary';
}
protected function _getPortableTableIndexDefinition($tableIndex)
{
return $tableIndex;
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 $result;
}
protected function _getPortableTablesList($tables)

View File

@ -28,6 +28,7 @@ namespace Doctrine\DBAL\Schema;
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
* @author Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library)
* @author Roman Borschel <roman@code-factory.org>
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @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)

View File

@ -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)

View File

@ -27,6 +27,7 @@ namespace Doctrine\DBAL\Schema;
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
* @author Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library)
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @version $Revision$
* @since 2.0
*/
@ -70,13 +71,36 @@ 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)
{

View File

@ -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(

View File

@ -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');

View File

@ -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');

View File

@ -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');

View File

@ -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();

View File

@ -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
*/