Commit ff5f1fdc authored by jsor's avatar jsor

Add event dispatching for drop table and column definition

parent 3f15fc80
<?php
/*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\DBAL\Event;
use Doctrine\Common\EventArgs,
Doctrine\DBAL\Connection,
Doctrine\DBAL\Schema\Column;
/**
* Event Arguments used when the portable column definition is generated inside Doctrine\DBAL\Schema\AbstractSchemaManager.
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.com
* @since 2.2
* @version $Revision$
* @author Jan Sorgalla <jsorgalla@googlemail.com>
*/
class SchemaColumnDefinitionEventArgs extends SchemaEventArgs
{
/**
* @var array
*/
private $_column = null;
/**
* @var string
*/
private $_table = null;
/**
* @var string
*/
private $_database = null;
/**
* @var \Doctrine\DBAL\Connection
*/
private $_connection = null;
/**
* @var \Doctrine\DBAL\Schema\Column $columnDefinition
*/
private $_columnDefinition = null;
/**
* @param type $column
* @param type $table
* @param type $database
* @param \Doctrine\DBAL\Connection $conn
*/
public function __construct($column, $table, $database, Connection $connection)
{
$this->_column = $column;
$this->_table = $table;
$this->_database = $database;
$this->_connection = $connection;
}
/**
* @return array
*/
public function getColumn()
{
return $this->_column;
}
/**
* @return string
*/
public function getTable()
{
return $this->_table;
}
/**
* @return string
*/
public function getDatabase()
{
return $this->_platform;
}
/**
* @return \Doctrine\DBAL\Connection
*/
public function getConnection()
{
return $this->_connection;
}
/**
* @return Doctrine\DBAL\Platforms\AbstractPlatform
*/
public function getDatabasePlatform()
{
return $this->_connection->getDatabasePlatform();
}
/**
* @param \Doctrine\DBAL\Schema\Column $columnDefinition
* @return SchemaColumnDefinitionEventArgs
*/
public function setColumnDefinition(Column $columnDefinition)
{
$this->_columnDefinition = $columnDefinition;
return $this;
}
/**
* @return \Doctrine\DBAL\Schema\Column
*/
public function getColumnDefinition()
{
return $this->_columnDefinition;
}
}
<?php
/*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\DBAL\Event;
use Doctrine\Common\EventArgs,
Doctrine\DBAL\Platforms\AbstractPlatform,
Doctrine\DBAL\Schema\Table;
/**
* Event Arguments used when the SQL query for dropping tables are generated inside Doctrine\DBAL\Platform\AbstractPlatform.
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.com
* @since 2.2
* @version $Revision$
* @author Jan Sorgalla <jsorgalla@googlemail.com>
*/
class SchemaDropTableEventArgs extends SchemaEventArgs
{
/**
* @var string|Table
*/
private $_table = null;
/**
* @var AbstractPlatform
*/
private $_platform = null;
/**
* @var string
*/
private $_sql = null;
/**
* @param string|Table $table
* @param AbstractPlatform $platform
*/
public function __construct($table, AbstractPlatform $platform)
{
if ($table instanceof Table || is_string($table)) {
$this->_table = $table;
} else {
throw new \InvalidArgumentException('SchemaCreateTableEventArgs expects $table parameter to be string or \Doctrine\DBAL\Schema\Table.');
}
$this->_platform = $platform;
}
/**
* @return string|Doctrine\DBAL\Schema\Table
*/
public function getTable()
{
return $this->_table;
}
/**
* @return Doctrine\DBAL\Platforms\AbstractPlatform
*/
public function getPlatform()
{
return $this->_platform;
}
/**
* @param string $sql
* @return SchemaDropTableEventArgs
*/
public function setSql($sql)
{
$this->_sql = $sql;
return $this;
}
/**
* @return string
*/
public function getSql()
{
return $this->_sql;
}
}
......@@ -38,5 +38,7 @@ final class Events
const preSchemaCreateTable = 'preSchemaCreateTable';
const onSchemaCreateTableColumn = 'onSchemaCreateTableColumn';
const postSchemaCreateTable = 'postSchemaCreateTable';
const onSchemaDropTable = 'onSchemaDropTable';
const onSchemaColumnDefinition = 'onSchemaColumnDefinition';
}
......@@ -31,7 +31,8 @@ use Doctrine\DBAL\DBALException,
Doctrine\DBAL\Events,
Doctrine\Common\EventManager,
Doctrine\DBAL\Event\SchemaCreateTableEventArgs,
Doctrine\DBAL\Event\SchemaCreateTableColumnEventArgs;
Doctrine\DBAL\Event\SchemaCreateTableColumnEventArgs,
Doctrine\DBAL\Event\SchemaDropTableEventArgs;
/**
* Base class for all DatabasePlatforms. The DatabasePlatforms are the central
......@@ -877,6 +878,15 @@ abstract class AbstractPlatform
throw new \InvalidArgumentException('getDropTableSQL() expects $table parameter to be string or \Doctrine\DBAL\Schema\Table.');
}
if (null !== $this->_eventManager && $this->_eventManager->hasListeners(Events::onSchemaDropTable)) {
$eventArgs = new SchemaDropTableEventArgs($table, $this);
$this->_eventManager->dispatchEvent(Events::onSchemaDropTable, $eventArgs);
if ($eventArgs->isDefaultPrevented()) {
return $eventArgs->getSql();
}
}
return 'DROP TABLE ' . $table;
}
......
......@@ -19,6 +19,8 @@
namespace Doctrine\DBAL\Schema;
use Doctrine\DBAL\Events;
use Doctrine\DBAL\Event\SchemaColumnDefinitionEventArgs;
use Doctrine\DBAL\Types;
use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Platforms\AbstractPlatform;
......@@ -153,7 +155,7 @@ abstract class AbstractSchemaManager
$tableColumns = $this->_conn->fetchAll($sql);
return $this->_getPortableTableColumnList($tableColumns);
return $this->_getPortableTableColumnList($table, $database, $tableColumns);
}
/**
......@@ -618,16 +620,35 @@ abstract class AbstractSchemaManager
*
* The name of the created column instance however is kept in its case.
*
* @param array $tableColumns
* @param string $table The name of the table.
* @param string $database
* @param array $tableColumns
* @return array
*/
protected function _getPortableTableColumnList($tableColumns)
protected function _getPortableTableColumnList($table, $database, $tableColumns)
{
$eventManager = $this->_platform->getEventManager();
$list = array();
foreach ($tableColumns as $key => $column) {
if ($column = $this->_getPortableTableColumnDefinition($column)) {
$name = strtolower($column->getQuotedName($this->_platform));
$list[$name] = $column;
$columnDefinition = null;
$defaultPrevented = false;
if (null !== $eventManager && $eventManager->hasListeners(Events::onSchemaColumnDefinition)) {
$eventArgs = new SchemaColumnDefinitionEventArgs($column, $table, $database, $this->_conn);
$eventManager->dispatchEvent(Events::onSchemaColumnDefinition, $eventArgs);
$defaultPrevented = $eventArgs->isDefaultPrevented();
$columnDefinition = $eventArgs->getColumnDefinition();
}
if (!$defaultPrevented) {
$columnDefinition = $this->_getPortableTableColumnDefinition($column);
}
if ($columnDefinition) {
$name = strtolower($columnDefinition->getQuotedName($this->_platform));
$list[$name] = $columnDefinition;
}
}
return $list;
......
......@@ -5,6 +5,8 @@ namespace Doctrine\Tests\DBAL\Functional\Schema;
use Doctrine\DBAL\Types\Type,
Doctrine\DBAL\Schema\AbstractSchemaManager;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\Common\EventManager;
use Doctrine\DBAL\Events;
require_once __DIR__ . '/../../../TestInit.php';
......@@ -171,6 +173,29 @@ class SchemaManagerFunctionalTestCase extends \Doctrine\Tests\DbalFunctionalTest
$this->assertInternalType('array', $columns['baz3']->getPlatformOptions());
}
public function testListTableColumnsDispatchEvent()
{
$table = $this->createListTableColumns();
$this->_sm->dropAndCreateTable($table);
$listenerMock = $this->getMock('ListTableColumnsDispatchEventListener', array('onSchemaColumnDefinition'));
$listenerMock
->expects($this->exactly(7))
->method('onSchemaColumnDefinition');
$oldEventManager = $this->_sm->getDatabasePlatform()->getEventManager();
$eventManager = new EventManager();
$eventManager->addEventListener(array(Events::onSchemaColumnDefinition), $listenerMock);
$this->_sm->getDatabasePlatform()->setEventManager($eventManager);
$this->_sm->listTableColumns('list_table_columns');
$this->_sm->getDatabasePlatform()->setEventManager($oldEventManager);
}
public function testDiffListTableColumns()
{
if ($this->_sm->getDatabasePlatform()->getName() == 'oracle') {
......
......@@ -87,31 +87,6 @@ abstract class AbstractPlatformTestCase extends \Doctrine\Tests\DbalTestCase
abstract public function getGenerateTableWithMultiColumnUniqueIndexSql();
public function testGetTableSqlDispatchEvent()
{
$listenerMock = $this->getMock('GetTableSqlDispatchEventListener', array('preSchemaCreateTable', 'onSchemaCreateTableColumn', 'postSchemaCreateTable'));
$listenerMock
->expects($this->once())
->method('preSchemaCreateTable');
$listenerMock
->expects($this->exactly(2))
->method('onSchemaCreateTableColumn');
$listenerMock
->expects($this->once())
->method('postSchemaCreateTable');
$eventManager = new EventManager();
$eventManager->addEventListener(array(Events::preSchemaCreateTable, Events::onSchemaCreateTableColumn, Events::postSchemaCreateTable), $listenerMock);
$this->_platform->setEventManager($eventManager);
$table = new \Doctrine\DBAL\Schema\Table('test');
$table->addColumn('foo', 'string', array('notnull' => false, 'length' => 255));
$table->addColumn('bar', 'string', array('notnull' => false, 'length' => 255));
$this->_platform->getCreateTableSQL($table);
}
public function testGeneratesIndexCreationSql()
{
$indexDef = new \Doctrine\DBAL\Schema\Index('my_idx', array('user_name', 'last_login'));
......@@ -204,6 +179,46 @@ abstract class AbstractPlatformTestCase extends \Doctrine\Tests\DbalTestCase
$this->assertEquals('foo MEDIUMINT(6) UNSIGNED', $this->_platform->getColumnDeclarationSQL('foo', $field));
}
public function testGetCreateTableSqlDispatchEvent()
{
$listenerMock = $this->getMock('GetCreateTableSqlDispatchEvenListener', array('preSchemaCreateTable', 'onSchemaCreateTableColumn', 'postSchemaCreateTable'));
$listenerMock
->expects($this->once())
->method('preSchemaCreateTable');
$listenerMock
->expects($this->exactly(2))
->method('onSchemaCreateTableColumn');
$listenerMock
->expects($this->once())
->method('postSchemaCreateTable');
$eventManager = new EventManager();
$eventManager->addEventListener(array(Events::preSchemaCreateTable, Events::onSchemaCreateTableColumn, Events::postSchemaCreateTable), $listenerMock);
$this->_platform->setEventManager($eventManager);
$table = new \Doctrine\DBAL\Schema\Table('test');
$table->addColumn('foo', 'string', array('notnull' => false, 'length' => 255));
$table->addColumn('bar', 'string', array('notnull' => false, 'length' => 255));
$this->_platform->getCreateTableSQL($table);
}
public function testGetDropTableSqlDispatchEvent()
{
$listenerMock = $this->getMock('GetDropTableSqlDispatchEventListener', array('onSchemaDropTable'));
$listenerMock
->expects($this->once())
->method('onSchemaDropTable');
$eventManager = new EventManager();
$eventManager->addEventListener(array(Events::onSchemaDropTable), $listenerMock);
$this->_platform->setEventManager($eventManager);
$this->_platform->getDropTableSQL('TABLE');
}
/**
* @group DBAL-42
*/
......
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