Commit cfea7883 authored by beberlei's avatar beberlei

[2.0] DDC-91 - Enhanced SchemaManager::listTableIndexes() considerably. Add...

[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.
parent 37824abf
......@@ -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
......@@ -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()
......
......@@ -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
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)
......
......@@ -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
*/
......@@ -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)
......
......@@ -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)
......
......@@ -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)
......
......@@ -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,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)
......
......@@ -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(
......
......@@ -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');
......
......@@ -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');
......
......@@ -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');
......
......@@ -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();
......
......@@ -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
*/
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment