From 22edbcec336e138e829515f67e61485672e1e617 Mon Sep 17 00:00:00 2001 From: beberlei Date: Wed, 10 Feb 2010 23:41:35 +0000 Subject: [PATCH] [2.0] DDC-312 - Refactored View support of all platforms a little - Oracle now also supports the retrieval of the sql used to generate a view so that a common datastructure View is a viable option. --- .../DBAL/Platforms/AbstractPlatform.php | 8 ++- lib/Doctrine/DBAL/Platforms/MySqlPlatform.php | 8 +-- .../DBAL/Platforms/OraclePlatform.php | 4 +- .../DBAL/Platforms/PostgreSqlPlatform.php | 2 +- .../DBAL/Platforms/SqlitePlatform.php | 7 +- .../DBAL/Schema/AbstractSchemaManager.php | 33 ++++----- .../DBAL/Schema/MySqlSchemaManager.php | 5 +- .../DBAL/Schema/OracleSchemaManager.php | 5 +- .../DBAL/Schema/PostgreSqlSchemaManager.php | 5 +- lib/Doctrine/DBAL/Schema/Schema.php | 2 +- .../DBAL/Schema/SqliteSchemaManager.php | 5 ++ lib/Doctrine/DBAL/Schema/View.php | 53 +++++++++++++++ .../Schema/MySqlSchemaManagerTest.php | 5 -- .../Schema/PostgreSqlSchemaManagerTest.php | 5 -- .../SchemaManagerFunctionalTestCase.php | 68 ++++++++----------- .../Schema/SqliteSchemaManagerTest.php | 6 -- 16 files changed, 119 insertions(+), 102 deletions(-) create mode 100644 lib/Doctrine/DBAL/Schema/View.php diff --git a/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php b/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php index 8a5e7b968..d4ac0a958 100644 --- a/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php @@ -1484,7 +1484,13 @@ abstract class AbstractPlatform throw DBALException::notSupported(__METHOD__); } - public function getListViewsSql() + /** + * Get the SQL to list all views of a database or user. + * + * @param string $database + * @return string + */ + public function getListViewsSql($database) { throw DBALException::notSupported(__METHOD__); } diff --git a/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php b/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php index bc396b073..04ae02615 100644 --- a/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php @@ -192,13 +192,9 @@ class MySqlPlatform extends AbstractPlatform return $sql; } - public function getListViewsSql($database = null) + public function getListViewsSql($database) { - $sql = 'SELECT * FROM information_schema.VIEWS'; - if($database !== null) { - $sql .= " WHERE TABLE_SCHEMA = '".$database."'"; - } - return $sql; + return "SELECT * FROM information_schema.VIEWS WHERE TABLE_SCHEMA = '".$database."'"; } public function getListTableForeignKeysSql($table, $database = null) diff --git a/lib/Doctrine/DBAL/Platforms/OraclePlatform.php b/lib/Doctrine/DBAL/Platforms/OraclePlatform.php index 78bd48df7..c360585f6 100644 --- a/lib/Doctrine/DBAL/Platforms/OraclePlatform.php +++ b/lib/Doctrine/DBAL/Platforms/OraclePlatform.php @@ -332,9 +332,9 @@ class OraclePlatform extends AbstractPlatform return 'SELECT * FROM all_users'; } - public function getListViewsSql() + public function getListViewsSql($database) { - return 'SELECT view_name FROM sys.user_views'; + return 'SELECT view_name, text FROM sys.user_views'; } public function getCreateViewSql($name, $sql) diff --git a/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php b/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php index bfd6ae362..fe7e4f908 100644 --- a/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php @@ -317,7 +317,7 @@ class PostgreSqlPlatform extends AbstractPlatform AND c.relname !~ '^pg_'"; } - public function getListViewsSql() + public function getListViewsSql($database) { return 'SELECT viewname, definition FROM pg_views'; } diff --git a/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php b/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php index 2c8b15ae3..e7ad79be2 100644 --- a/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php +++ b/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php @@ -404,12 +404,7 @@ class SqlitePlatform extends AbstractPlatform . "WHERE type = 'table' ORDER BY name"; } - public function getListTableViews() - { - return "SELECT name, sql FROM sqlite_master WHERE type='view' AND sql NOT NULL"; - } - - public function getListViewsSql() + public function getListViewsSql($database) { return "SELECT name, sql FROM sqlite_master WHERE type='view' AND sql NOT NULL"; } diff --git a/lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php b/lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php index 945807b5b..083dfaf22 100644 --- a/lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php +++ b/lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php @@ -279,16 +279,12 @@ abstract class AbstractSchemaManager /** * List the views this connection has * - * @example array( - * array('name' => 'ViewA', 'sql' => 'SELECT * FROM foo'), - * array('name' => 'ViewB', 'sql' => 'SELECT * FROM bar'), - * ) - * @return array $views + * @return View[] */ public function listViews() { - $sql = $this->_platform->getListViewsSql(); - + $database = $this->_conn->getDatabase(); + $sql = $this->_platform->getListViewsSql($database); $views = $this->_conn->fetchAll($sql); return $this->_getPortableViewsList($views); @@ -465,12 +461,11 @@ abstract class AbstractSchemaManager /** * Create a new view * - * @param string $name The name of the view - * @param string $sql The sql to set to the view + * @param View $view */ - public function createView($name, $sql) + public function createView(View $view) { - $this->_execSql($this->_platform->getCreateViewSql($name, $sql)); + $this->_execSql($this->_platform->getCreateViewSql($view->getName(), $view->getSql())); } /* dropAndCreate*() Methods */ @@ -550,13 +545,12 @@ abstract class AbstractSchemaManager /** * Drop and create a new view * - * @param string $name The name of the view - * @param string $sql The sql to set to the view + * @param View $view */ - public function dropAndCreateView($name, $sql) + public function dropAndCreateView(View $view) { - $this->tryMethod('dropView', $name); - $this->createView($name, $sql); + $this->tryMethod('dropView', $view->getName()); + $this->createView($view); } /* alterTable() Methods */ @@ -763,8 +757,9 @@ abstract class AbstractSchemaManager { $list = array(); foreach ($views as $key => $value) { - if ($value = $this->_getPortableViewDefinition($value)) { - $list[] = $value; + if ($view = $this->_getPortableViewDefinition($value)) { + $viewName = strtolower($view->getName()); + $list[$viewName] = $view; } } return $list; @@ -772,7 +767,7 @@ abstract class AbstractSchemaManager protected function _getPortableViewDefinition($view) { - return $view; + return false; } protected function _getPortableTableForeignKeysList($tableForeignKeys) diff --git a/lib/Doctrine/DBAL/Schema/MySqlSchemaManager.php b/lib/Doctrine/DBAL/Schema/MySqlSchemaManager.php index 2b1ed9944..a2df8a1c7 100644 --- a/lib/Doctrine/DBAL/Schema/MySqlSchemaManager.php +++ b/lib/Doctrine/DBAL/Schema/MySqlSchemaManager.php @@ -36,10 +36,7 @@ class MySqlSchemaManager extends AbstractSchemaManager { protected function _getPortableViewDefinition($view) { - return array( - 'name' => $view['TABLE_NAME'], - 'sql' => $view['VIEW_DEFINITION'] - ); + return new View($view['TABLE_NAME'], $view['VIEW_DEFINITION']); } protected function _getPortableTableDefinition($table) diff --git a/lib/Doctrine/DBAL/Schema/OracleSchemaManager.php b/lib/Doctrine/DBAL/Schema/OracleSchemaManager.php index 46a2a3265..0f15a3294 100644 --- a/lib/Doctrine/DBAL/Schema/OracleSchemaManager.php +++ b/lib/Doctrine/DBAL/Schema/OracleSchemaManager.php @@ -37,10 +37,7 @@ class OracleSchemaManager extends AbstractSchemaManager { $view = \array_change_key_case($view, CASE_LOWER); - return array( - 'name' => $view['view_name'], - 'sql' => '', - ); + return new View($view['view_name'], $view['text']); } protected function _getPortableUserDefinition($user) diff --git a/lib/Doctrine/DBAL/Schema/PostgreSqlSchemaManager.php b/lib/Doctrine/DBAL/Schema/PostgreSqlSchemaManager.php index 8e1bbd8b7..30df271c9 100644 --- a/lib/Doctrine/DBAL/Schema/PostgreSqlSchemaManager.php +++ b/lib/Doctrine/DBAL/Schema/PostgreSqlSchemaManager.php @@ -96,10 +96,7 @@ class PostgreSqlSchemaManager extends AbstractSchemaManager protected function _getPortableViewDefinition($view) { - return array( - 'name' => $view['viewname'], - 'sql' => $view['definition'] - ); + return new View($view['viewname'], $view['definition']); } protected function _getPortableUserDefinition($user) diff --git a/lib/Doctrine/DBAL/Schema/Schema.php b/lib/Doctrine/DBAL/Schema/Schema.php index dea20ec30..8d0f6e6a1 100644 --- a/lib/Doctrine/DBAL/Schema/Schema.php +++ b/lib/Doctrine/DBAL/Schema/Schema.php @@ -40,7 +40,7 @@ class Schema extends AbstractAsset * @var array */ protected $_tables = array(); - + /** * @var array */ diff --git a/lib/Doctrine/DBAL/Schema/SqliteSchemaManager.php b/lib/Doctrine/DBAL/Schema/SqliteSchemaManager.php index ca76a68f6..3ad0a4f21 100644 --- a/lib/Doctrine/DBAL/Schema/SqliteSchemaManager.php +++ b/lib/Doctrine/DBAL/Schema/SqliteSchemaManager.php @@ -257,4 +257,9 @@ class SqliteSchemaManager extends AbstractSchemaManager return new Column($tableColumn['name'], \Doctrine\DBAL\Types\Type::getType($type), $options); } + + protected function _getPortableViewDefinition($view) + { + return new View($view['name'], $view['sql']); + } } \ No newline at end of file diff --git a/lib/Doctrine/DBAL/Schema/View.php b/lib/Doctrine/DBAL/Schema/View.php new file mode 100644 index 000000000..4a8329de6 --- /dev/null +++ b/lib/Doctrine/DBAL/Schema/View.php @@ -0,0 +1,53 @@ +. +*/ + +namespace Doctrine\DBAL\Schema; + +/** + * Representation of a Database View + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.com + * @since 1.0 + * @version $Revision$ + * @author Benjamin Eberlei + */ +class View extends AbstractAsset +{ + /** + * @var string + */ + private $_sql; + + public function __construct($name, $sql) + { + $this->_setName($name); + $this->_sql = $sql; + } + + /** + * @return string + */ + public function getSql() + { + return $this->_sql; + } +} \ No newline at end of file diff --git a/tests/Doctrine/Tests/DBAL/Functional/Schema/MySqlSchemaManagerTest.php b/tests/Doctrine/Tests/DBAL/Functional/Schema/MySqlSchemaManagerTest.php index cd6a50b2a..2f212e9bf 100644 --- a/tests/Doctrine/Tests/DBAL/Functional/Schema/MySqlSchemaManagerTest.php +++ b/tests/Doctrine/Tests/DBAL/Functional/Schema/MySqlSchemaManagerTest.php @@ -22,9 +22,4 @@ class MySqlSchemaManagerTest extends SchemaManagerFunctionalTestCase } $this->assertEquals(true, $found); } - - protected function getCreateExampleViewSql() - { - return 'SELECT * from mysql.user'; - } } \ 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 index ce0c10d9b..efb17572c 100644 --- a/tests/Doctrine/Tests/DBAL/Functional/Schema/PostgreSqlSchemaManagerTest.php +++ b/tests/Doctrine/Tests/DBAL/Functional/Schema/PostgreSqlSchemaManagerTest.php @@ -22,9 +22,4 @@ class PostgreSqlSchemaManagerTest extends SchemaManagerFunctionalTestCase } $this->assertEquals(true, $found); } - - protected function getCreateExampleViewSql() - { - return 'SELECT usename, passwd FROM pg_user'; - } } \ No newline at end of file diff --git a/tests/Doctrine/Tests/DBAL/Functional/Schema/SchemaManagerFunctionalTestCase.php b/tests/Doctrine/Tests/DBAL/Functional/Schema/SchemaManagerFunctionalTestCase.php index c3715f2a5..83845aaa2 100644 --- a/tests/Doctrine/Tests/DBAL/Functional/Schema/SchemaManagerFunctionalTestCase.php +++ b/tests/Doctrine/Tests/DBAL/Functional/Schema/SchemaManagerFunctionalTestCase.php @@ -9,6 +9,28 @@ require_once __DIR__ . '/../../../TestInit.php'; class SchemaManagerFunctionalTestCase extends \Doctrine\Tests\DbalFunctionalTestCase { + /** + * @var \Doctrine\DBAL\Schema\AbstractSchemaManager + */ + protected $_sm; + + protected function setUp() + { + parent::setUp(); + + $class = get_class($this); + $e = explode('\\', $class); + $testClass = end($e); + $dbms = strtolower(str_replace('SchemaManagerTest', null, $testClass)); + + if ($this->_conn->getDatabasePlatform()->getName() !== $dbms) + { + $this->markTestSkipped('The ' . $testClass .' requires the use of ' . $dbms); + } + + $this->_sm = $this->_conn->getSchemaManager(); + } + public function testListSequences() { if(!$this->_conn->getDatabasePlatform()->supportsSequences()) { @@ -255,28 +277,6 @@ class SchemaManagerFunctionalTestCase extends \Doctrine\Tests\DbalFunctionalTest $this->markTestSkipped('No Create Example View SQL was defined for this SchemaManager'); } - public function testListViews() - { - $this->_sm->dropAndCreateView('test_create_view', $this->getCreateExampleViewSql()); - $views = $this->_sm->listViews(); - $this->assertTrue(count($views) >= 1, "There should be at least the fixture view created in the database, but none were found."); - - $found = false; - foreach($views AS $view) { - if(!isset($view['name']) || !isset($view['sql'])) { - $this->fail( - "listViews() has to return entries with both name ". - "and sql keys, but only ".implode(", ", array_keys($view))." are present." - ); - } - - if($view['name'] == 'test_create_view') { - $found = true; - } - } - $this->assertTrue($found, "'test_create_view' View was not found in listViews()."); - } - public function testCreateSchema() { $this->createTestTable('test_table'); @@ -353,26 +353,18 @@ class SchemaManagerFunctionalTestCase extends \Doctrine\Tests\DbalFunctionalTest $this->assertEquals(array('id'), array_map('strtolower', $foreignKey->getForeignColumns())); } - /** - * @var \Doctrine\DBAL\Schema\AbstractSchemaManager - */ - protected $_sm; - - protected function setUp() + public function testCreateAndListViews() { - parent::setUp(); + $this->createTestTable('view_test_table'); - $class = get_class($this); - $e = explode('\\', $class); - $testClass = end($e); - $dbms = strtolower(str_replace('SchemaManagerTest', null, $testClass)); + $name = "doctrine_test_view"; + $sql = "SELECT * FROM view_test_table"; - if ($this->_conn->getDatabasePlatform()->getName() !== $dbms) - { - $this->markTestSkipped('The ' . $testClass .' requires the use of ' . $dbms); - } + $view = new \Doctrine\DBAL\Schema\View($name, $sql); - $this->_sm = $this->_conn->getSchemaManager(); + $this->_sm->dropAndCreateView($view); + + $views = $this->_sm->listViews(); } protected function createTestTable($name = 'test_table', $data = array()) diff --git a/tests/Doctrine/Tests/DBAL/Functional/Schema/SqliteSchemaManagerTest.php b/tests/Doctrine/Tests/DBAL/Functional/Schema/SqliteSchemaManagerTest.php index df84282c4..78d13c6d9 100644 --- a/tests/Doctrine/Tests/DBAL/Functional/Schema/SqliteSchemaManagerTest.php +++ b/tests/Doctrine/Tests/DBAL/Functional/Schema/SqliteSchemaManagerTest.php @@ -44,12 +44,6 @@ class SqliteSchemaManagerTest extends SchemaManagerFunctionalTestCase $this->_sm->listUsers(); } - protected function getCreateExampleViewSql() - { - $this->createTestTable('test_views'); - return 'SELECT * from test_views'; - } - public function testCreateAndDropDatabase() { $path = dirname(__FILE__).'/test_create_and_drop_sqlite_database.sqlite';