[2.0] - DDC-169 - Began refactoring of DBAL code, introduced object notation for a database schema, including Tables, Indexes, Constraints, Sequences and Columns. Added a CreateSql Visitor which transforms a schema object graph into the required SQL statements to create it. Next: Replacing SchemaTool::getCreateSql() with new syntax...
This commit is contained in:
parent
fdd9b05158
commit
22cfa37f43
62
lib/Doctrine/DBAL/Schema/AbstractAsset.php
Normal file
62
lib/Doctrine/DBAL/Schema/AbstractAsset.php
Normal file
@ -0,0 +1,62 @@
|
||||
<?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\Schema;
|
||||
|
||||
/**
|
||||
* The abstract asset allows to reset the name of all assets without publishing this to the public userland.
|
||||
*
|
||||
* This encapsulation hack is necessary to keep a consistent state of the database schema. Say we have a list of tables
|
||||
* array($tableName => Table($tableName)); if you want to rename the table, you have to make sure
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @version $Revision$
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
*/
|
||||
abstract class AbstractAsset
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $_name;
|
||||
|
||||
/**
|
||||
* Set name of this asset
|
||||
*
|
||||
* @param string $name
|
||||
*/
|
||||
protected function _setName($name)
|
||||
{
|
||||
$this->_name = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return name of this schema asset.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->_name;
|
||||
}
|
||||
}
|
@ -942,14 +942,14 @@ abstract class AbstractSchemaManager
|
||||
/**
|
||||
* Aggregate and group the index results according to the required data result.
|
||||
*
|
||||
* @param array $tableIndexes
|
||||
* @param array $tableIndexRows
|
||||
* @param string $tableName
|
||||
* @return array
|
||||
*/
|
||||
protected function _getPortableTableIndexesList($tableIndexes, $tableName=null)
|
||||
protected function _getPortableTableIndexesList($tableIndexRows, $tableName=null)
|
||||
{
|
||||
$result = array();
|
||||
foreach($tableIndexes AS $tableIndex) {
|
||||
foreach($tableIndexRows AS $tableIndex) {
|
||||
$indexName = $keyName = $tableIndex['key_name'];
|
||||
if($tableIndex['primary']) {
|
||||
$keyName = 'primary';
|
||||
|
286
lib/Doctrine/DBAL/Schema/Column.php
Normal file
286
lib/Doctrine/DBAL/Schema/Column.php
Normal file
@ -0,0 +1,286 @@
|
||||
<?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\Schema;
|
||||
|
||||
use \Doctrine\DBAL\Types\Type;
|
||||
|
||||
/**
|
||||
* Object representation of a database column
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @version $Revision$
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
*/
|
||||
class Column extends AbstractAsset
|
||||
{
|
||||
/**
|
||||
* @var \Doctrine\DBAL\Types\Type
|
||||
*/
|
||||
protected $_type;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $_length = 255;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $_precision = 0;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $_scale = 0;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $_unsigned = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $_fixed = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $_notnull = true;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $_default;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_platformOptions = array();
|
||||
|
||||
/**
|
||||
* Create a new Column
|
||||
*
|
||||
* @param string $columnName
|
||||
* @param Doctrine\DBAL\Types\Type $type
|
||||
* @param int $length
|
||||
* @param bool $notNull
|
||||
* @param mixed $default
|
||||
* @param bool $unsigned
|
||||
* @param bool $fixed
|
||||
* @param int $precision
|
||||
* @param int $scale
|
||||
* @param array $platformOptions
|
||||
*/
|
||||
public function __construct($columnName, Type $type, array $options=array())
|
||||
{
|
||||
$this->_setName($columnName);
|
||||
$this->setType($type);
|
||||
$this->setOptions($options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $options
|
||||
* @return Column
|
||||
*/
|
||||
public function setOptions(array $options)
|
||||
{
|
||||
foreach ($options AS $name => $value) {
|
||||
$method = "set".$name;
|
||||
if (method_exists($this, $method)) {
|
||||
$this->$method($value);
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Type $type
|
||||
* @return Column
|
||||
*/
|
||||
public function setType(Type $type)
|
||||
{
|
||||
$this->_type = $type;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $length
|
||||
* @return Column
|
||||
*/
|
||||
public function setLength($length)
|
||||
{
|
||||
$this->_length = (int)$length;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $precision
|
||||
* @return Column
|
||||
*/
|
||||
public function setPrecision($precision)
|
||||
{
|
||||
$this->_precision = (int)$precision;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $scale
|
||||
* @return Column
|
||||
*/
|
||||
public function setScale($scale)
|
||||
{
|
||||
$this->_scale = $scale;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param bool $unsigned
|
||||
* @return Column
|
||||
*/
|
||||
public function setUnsigned($unsigned)
|
||||
{
|
||||
$this->_unsigned = (bool)$unsigned;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param bool $fixed
|
||||
* @return Column
|
||||
*/
|
||||
public function setFixed($fixed)
|
||||
{
|
||||
$this->_fixed = (bool)$fixed;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $notnull
|
||||
* @return Column
|
||||
*/
|
||||
public function setNotnull($notnull)
|
||||
{
|
||||
$this->_notnull = (bool)$notnull;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param mixed $default
|
||||
* @return Column
|
||||
*/
|
||||
public function setDefault($default)
|
||||
{
|
||||
$this->_default = $default;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array $platformOptions
|
||||
* @return Column
|
||||
*/
|
||||
public function setPlatformOptions(array $platformOptions)
|
||||
{
|
||||
$this->_platformOptions = $platformOptions;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @return Column
|
||||
*/
|
||||
public function setPlatformOption($name, $value)
|
||||
{
|
||||
$this->_platformOptions[$name] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getType()
|
||||
{
|
||||
return $this->_type;
|
||||
}
|
||||
|
||||
public function getLength()
|
||||
{
|
||||
return $this->_length;
|
||||
}
|
||||
|
||||
public function getPrecision()
|
||||
{
|
||||
return $this->_precision;
|
||||
}
|
||||
|
||||
public function getScale()
|
||||
{
|
||||
return $this->_scale;
|
||||
}
|
||||
|
||||
public function getUnsigned()
|
||||
{
|
||||
return $this->_unsigned;
|
||||
}
|
||||
|
||||
public function getFixed()
|
||||
{
|
||||
return $this->_fixed;
|
||||
}
|
||||
|
||||
public function getNotnull()
|
||||
{
|
||||
return $this->_notnull;
|
||||
}
|
||||
|
||||
public function getDefault()
|
||||
{
|
||||
return $this->_default;
|
||||
}
|
||||
|
||||
public function getPlatformOptions()
|
||||
{
|
||||
return $this->_platformOptions;
|
||||
}
|
||||
|
||||
public function hasPlatformOption($name)
|
||||
{
|
||||
return isset($this->_platformOptions[$name]);
|
||||
}
|
||||
|
||||
public function getPlatformOption($name)
|
||||
{
|
||||
return $this->_platformOptions[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Visitor $visitor
|
||||
*/
|
||||
public function visit(\Doctrine\DBAL\Schema\Visitor $visitor)
|
||||
{
|
||||
$visitor->accept($this);
|
||||
}
|
||||
}
|
36
lib/Doctrine/DBAL/Schema/Constraint.php
Normal file
36
lib/Doctrine/DBAL/Schema/Constraint.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?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\Schema;
|
||||
|
||||
/**
|
||||
* Marker interface for contraints
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @version $Revision$
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
*/
|
||||
interface Constraint
|
||||
{
|
||||
|
||||
}
|
82
lib/Doctrine/DBAL/Schema/ForeignKeyConstraint.php
Normal file
82
lib/Doctrine/DBAL/Schema/ForeignKeyConstraint.php
Normal file
@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\DBAL\Schema;
|
||||
|
||||
class ForeignKeyConstraint extends AbstractAsset implements Constraint
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_localColumnNames;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $_foreignTableName;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_foreignColumnNames;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $_cascade = '';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_options;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array $localColumnNames
|
||||
* @param string $foreignTableName
|
||||
* @param array $foreignColumnNames
|
||||
* @param string $cascade
|
||||
* @param string|null $name
|
||||
*/
|
||||
public function __construct(array $localColumnNames, $foreignTableName, array $foreignColumnNames, $name=null, array $options=array())
|
||||
{
|
||||
$this->_setName($name);
|
||||
$this->_localColumnNames = $localColumnNames;
|
||||
$this->_foreignTableName = $foreignTableName;
|
||||
$this->_foreignColumnNames = $foreignColumnNames;
|
||||
$this->_options = $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getLocalColumnNames()
|
||||
{
|
||||
return $this->_localColumnNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getForeignTableName()
|
||||
{
|
||||
return $this->_foreignTableName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getForeignColumnNames()
|
||||
{
|
||||
return $this->_foreignColumnNames;
|
||||
}
|
||||
|
||||
public function hasOption($name)
|
||||
{
|
||||
return isset($this->_options[$name]);
|
||||
}
|
||||
|
||||
public function getOption($name)
|
||||
{
|
||||
return $this->_options[$name];
|
||||
}
|
||||
}
|
98
lib/Doctrine/DBAL/Schema/Index.php
Normal file
98
lib/Doctrine/DBAL/Schema/Index.php
Normal file
@ -0,0 +1,98 @@
|
||||
<?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\Schema;
|
||||
|
||||
class Index extends AbstractAsset
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $_indexName;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_columns;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $_isUnique = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $_isPrimary = false;
|
||||
|
||||
/**
|
||||
* @param string $indexName
|
||||
* @param array $column
|
||||
* @param bool $isUnique
|
||||
* @param bool $isPrimary
|
||||
*/
|
||||
public function __construct($indexName, array $columns, $isUnique=false, $isPrimary=false)
|
||||
{
|
||||
$this->_setName($indexName);
|
||||
$this->_isUnique = $isUnique;
|
||||
$this->_isPrimary = $isPrimary;
|
||||
|
||||
foreach($columns AS $column) {
|
||||
$this->_addColumn($column);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $column
|
||||
*/
|
||||
protected function _addColumn($column)
|
||||
{
|
||||
if(is_string($column)) {
|
||||
$this->_columns[] = $column;
|
||||
} else {
|
||||
throw new \InvalidArgumentException("Expecting a string as Index Column");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getColumns()
|
||||
{
|
||||
return $this->_columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isUnique()
|
||||
{
|
||||
return $this->_isUnique;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isPrimary()
|
||||
{
|
||||
return $this->_isPrimary;
|
||||
}
|
||||
}
|
243
lib/Doctrine/DBAL/Schema/Schema.php
Normal file
243
lib/Doctrine/DBAL/Schema/Schema.php
Normal file
@ -0,0 +1,243 @@
|
||||
<?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\Schema;
|
||||
|
||||
use Doctrine\DBAL\Schema\Visitor\CreateSchemaSqlCollector;
|
||||
|
||||
/**
|
||||
* Object representation of a database schema
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @version $Revision$
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
*/
|
||||
class Schema extends AbstractAsset
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_tables = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_sequences = array();
|
||||
|
||||
/**
|
||||
* @param array $tables
|
||||
* @param array $sequences
|
||||
*/
|
||||
public function __construct(array $tables=array(), array $sequences=array())
|
||||
{
|
||||
foreach ($tables AS $table) {
|
||||
$this->_addTable($table);
|
||||
}
|
||||
foreach ($sequences AS $sequence) {
|
||||
$this->_addSequence($sequence);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Table $table
|
||||
*/
|
||||
protected function _addTable(Table $table)
|
||||
{
|
||||
$tableName = $table->getName();
|
||||
if(isset($this->_tables[$tableName])) {
|
||||
throw SchemaException::tableAlreadyExists($tableName);
|
||||
}
|
||||
|
||||
$this->_tables[$tableName] = $table;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Sequence $sequence
|
||||
*/
|
||||
protected function _addSequence(Sequence $sequence)
|
||||
{
|
||||
$seqName = $sequence->getName();
|
||||
if (isset($this->_sequences[$seqName])) {
|
||||
throw SchemaException::sequenceAlreadyExists($seqName);
|
||||
}
|
||||
$this->_sequences[$seqName] = $sequence;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all tables of this schema.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getTables()
|
||||
{
|
||||
return $this->_tables;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $tableName
|
||||
* @return Table
|
||||
*/
|
||||
public function getTable($tableName)
|
||||
{
|
||||
if (!isset($this->_tables[$tableName])) {
|
||||
throw SchemaException::tableDoesNotExist($tableName);
|
||||
}
|
||||
|
||||
return $this->_tables[$tableName];
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this schema have a table with the given name?
|
||||
*
|
||||
* @param string $tableName
|
||||
* @return Schema
|
||||
*/
|
||||
public function hasTable($tableName)
|
||||
{
|
||||
return isset($this->_tables[$tableName]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sequenceName
|
||||
* @return bool
|
||||
*/
|
||||
public function hasSequence($sequenceName)
|
||||
{
|
||||
return isset($this->_sequences[$sequenceName]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws SchemaException
|
||||
* @param string $sequenceName
|
||||
* @return Doctrine\DBAL\Schema\Sequence
|
||||
*/
|
||||
public function getSequence($sequenceName)
|
||||
{
|
||||
if(!$this->hasSequence($sequenceName)) {
|
||||
throw SchemaException::sequenceDoesNotExist($sequenceName);
|
||||
}
|
||||
return $this->_sequences[$sequenceName];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Doctrine\DBAL\Schema\Sequence[]
|
||||
*/
|
||||
public function getSequences()
|
||||
{
|
||||
return $this->_sequences;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new table
|
||||
*
|
||||
* @param string $tableName
|
||||
* @return Table
|
||||
*/
|
||||
public function createTable($tableName)
|
||||
{
|
||||
$table = new Table($tableName);
|
||||
$this->_addTable($table);
|
||||
return $table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename a table
|
||||
*
|
||||
* @param string $oldTableName
|
||||
* @param string $newTableName
|
||||
* @return Schema
|
||||
*/
|
||||
public function renameTable($oldTableName, $newTableName)
|
||||
{
|
||||
$table = $this->getTable($oldTableName);
|
||||
$table->_setName($newTableName);
|
||||
|
||||
$this->dropTable($oldTableName);
|
||||
$this->_addTable($table);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop a table from the schema.
|
||||
*
|
||||
* @param string $tableName
|
||||
* @return Schema
|
||||
*/
|
||||
public function dropTable($tableName)
|
||||
{
|
||||
$table = $this->getTable($tableName);
|
||||
unset($this->_tables[$tableName]);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new sequence
|
||||
*
|
||||
* @param string $sequenceName
|
||||
* @param int $allocationSize
|
||||
* @param int $initialValue
|
||||
* @return Schema
|
||||
*/
|
||||
public function createSequence($sequenceName, $allocationSize=1, $initialValue=1)
|
||||
{
|
||||
$seq = new Sequence($sequenceName, $allocationSize, $initialValue);
|
||||
$this->_addSequence($seq);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sequenceName
|
||||
* @return Schema
|
||||
*/
|
||||
public function dropSequence($sequenceName)
|
||||
{
|
||||
unset($this->_sequences[$sequenceName]);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AbstractPlatform $platform
|
||||
*/
|
||||
public function toSql(\Doctrine\DBAL\Platforms\AbstractPlatform $platform)
|
||||
{
|
||||
$sqlCollector = new CreateSchemaSqlCollector($platform);
|
||||
$this->visit($sqlCollector);
|
||||
|
||||
return $sqlCollector->getQueries();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Visitor $visitor
|
||||
*/
|
||||
public function visit(Visitor $visitor)
|
||||
{
|
||||
$visitor->acceptSchema($this);
|
||||
|
||||
foreach ($this->_tables AS $table) {
|
||||
$table->visit($visitor);
|
||||
}
|
||||
foreach ($this->_sequences AS $sequence) {
|
||||
$sequence->visit($visitor);
|
||||
}
|
||||
}
|
||||
}
|
102
lib/Doctrine/DBAL/Schema/SchemaException.php
Normal file
102
lib/Doctrine/DBAL/Schema/SchemaException.php
Normal file
@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\DBAL\Schema;
|
||||
|
||||
class SchemaException extends \Doctrine\DBAL\DBALException
|
||||
{
|
||||
const TABLE_DOESNT_EXIST = 10;
|
||||
const TABLE_ALREADY_EXISTS = 20;
|
||||
const COLUMN_DOESNT_EXIST = 30;
|
||||
const COLUMN_ALREADY_EXISTS = 40;
|
||||
const INDEX_DOESNT_EXIST = 50;
|
||||
const INDEX_ALREADY_EXISTS = 60;
|
||||
const SEQUENCE_DOENST_EXIST = 70;
|
||||
const SEQUENCE_ALREADY_EXISTS = 80;
|
||||
const INDEX_INVALID_NAME = 90;
|
||||
|
||||
/**
|
||||
* @param string $tableName
|
||||
* @return SchemaException
|
||||
*/
|
||||
static public function tableDoesNotExist($tableName)
|
||||
{
|
||||
return new self("There is no table with name '".$tableName."' in the schema.", self::TABLE_DOESNT_EXIST);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $indexName
|
||||
* @return SchemaException
|
||||
*/
|
||||
static public function indexNameInvalid($indexName)
|
||||
{
|
||||
return new self("Invalid index-name $indexName given, has to be [a-zA-Z0-9_]", self::INDEX_INVALID_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $indexName
|
||||
* @return SchemaException
|
||||
*/
|
||||
static public function indexDoesNotExist($indexName)
|
||||
{
|
||||
return new self("Index '".$indexName."' does not exist.", self::INDEX_DOESNT_EXIST);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $indexName
|
||||
* @return SchemaException
|
||||
*/
|
||||
static public function indexAlreadyExists($indexName)
|
||||
{
|
||||
return new self("An index with name $indexName was already defined.", self::INDEX_ALREADY_EXISTS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $columnName
|
||||
* @return SchemaException
|
||||
*/
|
||||
static public function columnDoesNotExist($columnName)
|
||||
{
|
||||
return new self("An unknown column-name $columnName was given.", self::COLUMN_DOESNT_EXIST);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $tableName
|
||||
* @return SchemaException
|
||||
*/
|
||||
static public function tableAlreadyExists($tableName)
|
||||
{
|
||||
return new self("The table with name '".$tableName."' already exists.", self::TABLE_ALREADY_EXISTS);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $tableName
|
||||
* @param string $columnName
|
||||
* @return SchemaException
|
||||
*/
|
||||
static public function columnAlreadyExists($tableName, $columnName)
|
||||
{
|
||||
return new self(
|
||||
"The column '".$columnName."' on table '".$tableName."' already exists.", self::COLUMN_ALREADY_EXISTS
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sequenceName
|
||||
* @return SchemaException
|
||||
*/
|
||||
static public function sequenceAlreadyExists($sequenceName)
|
||||
{
|
||||
return new self("The sequence '".$sequenceName."' already exists.", self::SEQUENCE_ALREADY_EXISTS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sequenceName
|
||||
* @return SchemaException
|
||||
*/
|
||||
static public function sequenceDoesNotExist($sequenceName)
|
||||
{
|
||||
return new self("There exists no sequence with the name '".$sequenceName."'.", self::SEQUENCE_DOENST_EXIST);
|
||||
}
|
||||
}
|
75
lib/Doctrine/DBAL/Schema/Sequence.php
Normal file
75
lib/Doctrine/DBAL/Schema/Sequence.php
Normal file
@ -0,0 +1,75 @@
|
||||
<?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\Schema;
|
||||
|
||||
/**
|
||||
* Sequence Structure
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @version $Revision$
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
*/
|
||||
class Sequence extends AbstractAsset
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $_allocationSize = 1;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $_initialValue = 1;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $name
|
||||
* @param int $allocationSize
|
||||
* @param int $initialValue
|
||||
*/
|
||||
public function __construct($name, $allocationSize=1, $initialValue=1)
|
||||
{
|
||||
$this->_setName($name);
|
||||
$this->_allocationSize = (is_int($allocationSize))?:1;
|
||||
$this->_initialValue = (is_int($initialValue))?:1;
|
||||
}
|
||||
|
||||
public function getAllocationSize()
|
||||
{
|
||||
return $this->_allocationSize;
|
||||
}
|
||||
|
||||
public function getInitialValue()
|
||||
{
|
||||
return $this->_initialValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Visitor $visitor
|
||||
*/
|
||||
public function visit(Visitor $visitor)
|
||||
{
|
||||
$visitor->acceptSequence($this);
|
||||
}
|
||||
}
|
459
lib/Doctrine/DBAL/Schema/Table.php
Normal file
459
lib/Doctrine/DBAL/Schema/Table.php
Normal file
@ -0,0 +1,459 @@
|
||||
<?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\Schema;
|
||||
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
|
||||
/**
|
||||
* Object Representation of a table
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @version $Revision$
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
*/
|
||||
class Table extends AbstractAsset
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
const ID_NONE = 0;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
const ID_SEQUENCE = 1;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
const ID_IDENTITY = 2;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $_name = null;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_columns = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_indexes = array();
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $_primaryKeyName = false;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_constraints = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_options = array();
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $_idGeneratorType = self::ID_NONE;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $tableName
|
||||
* @param array $columns
|
||||
* @param array $indexes
|
||||
* @param array $constraints
|
||||
* @param int $idGeneratorType
|
||||
* @param array $options
|
||||
*/
|
||||
public function __construct($tableName, array $columns=array(), array $indexes=array(), array $constraints=array(), $idGeneratorType=self::ID_NONE, array $options=array())
|
||||
{
|
||||
$this->_name = $tableName;
|
||||
$this->_idGeneratorType = $idGeneratorType;
|
||||
|
||||
foreach ($columns AS $column) {
|
||||
$this->_addColumn($column);
|
||||
}
|
||||
|
||||
foreach ($indexes AS $idx) {
|
||||
$this->_addIndex($idx);
|
||||
}
|
||||
|
||||
foreach ($constraints AS $constraint) {
|
||||
$this->_addConstraint($constraint);
|
||||
}
|
||||
|
||||
$this->_options = $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Primary Key
|
||||
*
|
||||
* @param array $columns
|
||||
* @param string $indexName
|
||||
* @return Table
|
||||
*/
|
||||
public function setPrimaryKey(array $columns, $indexName=false)
|
||||
{
|
||||
return $this->_createIndex($columns, $indexName?:"primary", true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
* @return Table
|
||||
*/
|
||||
public function setIdGeneratorType($type)
|
||||
{
|
||||
$this->_idGeneratorType = $type;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $columnNames
|
||||
* @param string $indexName
|
||||
* @return Table
|
||||
*/
|
||||
public function addIndex(array $columnNames, $indexName=null)
|
||||
{
|
||||
return $this->_createIndex($columnNames, $indexName, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array $columnNames
|
||||
* @param string $indexName
|
||||
* @return Table
|
||||
*/
|
||||
public function addUniqueIndex(array $columnNames, $indexName=null)
|
||||
{
|
||||
return $this->_createIndex($columnNames, $indexName, true, false);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array $columnNames
|
||||
* @param string $indexName
|
||||
* @param bool $isUnique
|
||||
* @param bool $isPrimary
|
||||
* @return Table
|
||||
*/
|
||||
private function _createIndex(array $columnNames, $indexName, $isUnique, $isPrimary)
|
||||
{
|
||||
if (preg_match('(([^a-zA-Z0-9_]+))', $indexName)) {
|
||||
throw SchemaException::indexNameInvalid($indexName);
|
||||
}
|
||||
|
||||
foreach ($columnNames AS $columnName) {
|
||||
if (!isset($this->_columns[$columnName])) {
|
||||
throw SchemaException::columnDoesNotExist($columnName);
|
||||
}
|
||||
}
|
||||
$this->_addIndex(new Index($indexName, $columnNames, $isUnique, $isPrimary));
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $columnName
|
||||
* @param string $columnType
|
||||
* @param array $options
|
||||
* @return Table
|
||||
*/
|
||||
public function createColumn($columnName, $typeName, array $options=array())
|
||||
{
|
||||
$column = new Column($columnName, Type::getType($typeName), $options);
|
||||
|
||||
$this->_addColumn($column);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename Column
|
||||
*
|
||||
* @param string $oldColumnName
|
||||
* @param string $newColumnName
|
||||
* @return Table
|
||||
*/
|
||||
public function renameColumn($oldColumnName, $newColumnName)
|
||||
{
|
||||
$column = $this->getColumn($oldColumnName);
|
||||
$this->dropColumn($oldColumnName);
|
||||
|
||||
$column->_setName($newColumnName);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change Column Details
|
||||
*
|
||||
* @param string $columnName
|
||||
* @param array $options
|
||||
* @return Table
|
||||
*/
|
||||
public function changeColumn($columnName, array $options)
|
||||
{
|
||||
$column = $this->getColumn($columnName);
|
||||
$column->setOptions($options);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop Column from Table
|
||||
*
|
||||
* @param string $columnName
|
||||
* @return Table
|
||||
*/
|
||||
public function dropColumn($columnName)
|
||||
{
|
||||
$column = $this->getColumn($columnName);
|
||||
unset($this->_columns[$columnName]);
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a foreign key constraint
|
||||
*
|
||||
* @param Table $foreignTable
|
||||
* @param array $localColumns
|
||||
* @param array $foreignColumns
|
||||
* @param array $options
|
||||
* @return Table
|
||||
*/
|
||||
public function addForeignKeyConstraint(Table $foreignTable, array $localColumnNames, array $foreignColumnNames, $name=null, array $options=array())
|
||||
{
|
||||
foreach ($localColumnNames AS $columnName) {
|
||||
if (!$this->hasColumn($columnName)) {
|
||||
throw SchemaException::columnDoesNotExist($columnName);
|
||||
}
|
||||
}
|
||||
foreach ($foreignColumnNames AS $columnName) {
|
||||
if (!$foreignTable->hasColumn($columnName)) {
|
||||
throw SchemaException::columnDoesNotExist($columnName);
|
||||
}
|
||||
}
|
||||
|
||||
$constraint = new ForeignKeyConstraint(
|
||||
$localColumnNames, $foreignTable->getName(), $foreignColumnNames, $name, $options
|
||||
);
|
||||
$this->_addConstraint($constraint);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param string $value
|
||||
* @return Table
|
||||
*/
|
||||
public function addOption($name, $value)
|
||||
{
|
||||
$this->_options[$name] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Column $column
|
||||
*/
|
||||
protected function _addColumn(Column $column)
|
||||
{
|
||||
$columnName = $column->getName();
|
||||
if (isset($this->_columns[$columnName])) {
|
||||
throw SchemaException::columnAlreadyExists($this->_name, $columnName);
|
||||
}
|
||||
|
||||
$this->_columns[$columnName] = $column;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add index to table
|
||||
*
|
||||
* @param Index $index
|
||||
* @return Table
|
||||
*/
|
||||
protected function _addIndex(Index $index)
|
||||
{
|
||||
$indexName = $index->getName();
|
||||
|
||||
if (isset($this->_indexes[$indexName]) || ($this->_primaryKeyName != false && $index->isPrimary())) {
|
||||
throw SchemaException::indexAlreadyExists($indexName);
|
||||
}
|
||||
|
||||
if ($index->isPrimary()) {
|
||||
$this->_primaryKeyName = $indexName;
|
||||
}
|
||||
|
||||
$this->_indexes[$indexName] = $index;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Constraint $constraint
|
||||
*/
|
||||
protected function _addConstraint(Constraint $constraint)
|
||||
{
|
||||
$this->_constraints[] = $constraint;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isIdGeneratorIdentity()
|
||||
{
|
||||
return ($this->_idGeneratorType==self::ID_IDENTITY);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function isIdGeneratorSequence()
|
||||
{
|
||||
return ($this->_idGeneratorType==self::ID_SEQUENCE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Column[]
|
||||
*/
|
||||
public function getColumns()
|
||||
{
|
||||
return $this->_columns;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Does this table have a column with the given name?
|
||||
*
|
||||
* @param string $columnName
|
||||
* @return bool
|
||||
*/
|
||||
public function hasColumn($columnName)
|
||||
{
|
||||
return isset($this->_columns[$columnName]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a column instance
|
||||
*
|
||||
* @param string $columnName
|
||||
* @return Column
|
||||
*/
|
||||
public function getColumn($columnName)
|
||||
{
|
||||
if (!$this->hasColumn($columnName)) {
|
||||
throw SchemaException::columnDoesNotExist($columnName);
|
||||
}
|
||||
|
||||
return $this->_columns[$columnName];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Index
|
||||
*/
|
||||
public function getPrimaryKey()
|
||||
{
|
||||
return $this->getIndex($this->_primaryKeyName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $indexName
|
||||
* @return bool
|
||||
*/
|
||||
public function hasIndex($indexName)
|
||||
{
|
||||
return (isset($this->_indexes[$indexName]));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $indexName
|
||||
* @return Index
|
||||
*/
|
||||
public function getIndex($indexName)
|
||||
{
|
||||
if (!$this->hasIndex($indexName)) {
|
||||
throw SchemaException::indexDoesNotExist($indexName);
|
||||
}
|
||||
return $this->_indexes[$indexName];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getIndexes()
|
||||
{
|
||||
return $this->_indexes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Constraints
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getConstraints()
|
||||
{
|
||||
return $this->_constraints;
|
||||
}
|
||||
|
||||
public function hasOption($name)
|
||||
{
|
||||
return isset($this->_options[$name]);
|
||||
}
|
||||
|
||||
public function getOption($name)
|
||||
{
|
||||
return $this->_options[$name];
|
||||
}
|
||||
|
||||
public function getOptions()
|
||||
{
|
||||
return $this->_options;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Visitor $visitor
|
||||
*/
|
||||
public function visit(Visitor $visitor)
|
||||
{
|
||||
$visitor->acceptTable($this);
|
||||
|
||||
foreach($this->getColumns() AS $column) {
|
||||
$visitor->acceptColunn($this, $column);
|
||||
}
|
||||
|
||||
foreach($this->getIndexes() AS $index) {
|
||||
$visitor->acceptIndex($this, $index);
|
||||
}
|
||||
|
||||
foreach($this->getConstraints() AS $constraint) {
|
||||
if($constraint instanceof ForeignKeyConstraint) {
|
||||
$visitor->acceptForeignKey($this, $constraint);
|
||||
} else {
|
||||
$visitor->acceptCheckConstraint($this, $constraint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
72
lib/Doctrine/DBAL/Schema/Visitor.php
Normal file
72
lib/Doctrine/DBAL/Schema/Visitor.php
Normal file
@ -0,0 +1,72 @@
|
||||
<?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\Schema;
|
||||
|
||||
/**
|
||||
* Schema Visitor used for Validation or Generation purposes.
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @version $Revision$
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
*/
|
||||
interface Visitor
|
||||
{
|
||||
/**
|
||||
* @param Schema $schema
|
||||
*/
|
||||
public function acceptSchema(Schema $schema);
|
||||
|
||||
/**
|
||||
* @param Table $table
|
||||
*/
|
||||
public function acceptTable(Table $table);
|
||||
|
||||
/**
|
||||
* @param Column $column
|
||||
*/
|
||||
public function acceptColunn(Table $table, Column $column);
|
||||
|
||||
/**
|
||||
* @param Table $localTable
|
||||
* @param ForeignKeyConstraint $fkConstraint
|
||||
*/
|
||||
public function acceptForeignKey(Table $localTable, ForeignKeyConstraint $fkConstraint);
|
||||
|
||||
/**
|
||||
* @param Table $table
|
||||
* @param Constraint $constraint
|
||||
*/
|
||||
public function acceptCheckConstraint(Table $table, Constraint $constraint);
|
||||
|
||||
/**
|
||||
* @param Table $table
|
||||
* @param Index $index
|
||||
*/
|
||||
public function acceptIndex(Table $table, Index $index);
|
||||
|
||||
/**
|
||||
* @param Sequence $sequence
|
||||
*/
|
||||
public function acceptSequence(Sequence $sequence);
|
||||
}
|
234
lib/Doctrine/DBAL/Schema/Visitor/CreateSchemaSqlCollector.php
Normal file
234
lib/Doctrine/DBAL/Schema/Visitor/CreateSchemaSqlCollector.php
Normal file
@ -0,0 +1,234 @@
|
||||
<?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\Schema\Visitor;
|
||||
|
||||
use Doctrine\DBAL\Schema\Visitor,
|
||||
Doctrine\DBAL\Platforms\AbstractPlatform,
|
||||
Doctrine\DBAL\Schema\Table,
|
||||
Doctrine\DBAL\Schema\Schema,
|
||||
Doctrine\DBAL\Schema\Column,
|
||||
Doctrine\DBAL\Schema\ForeignKeyConstraint,
|
||||
Doctrine\DBAL\Schema\Constraint,
|
||||
Doctrine\DBAL\Schema\Sequence,
|
||||
Doctrine\DBAL\Schema\Index;
|
||||
|
||||
class CreateSchemaSqlCollector implements Visitor
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $_createTableQueries = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $_createSequenceQueries = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $_createFkConstraintQueries = array();
|
||||
|
||||
/**
|
||||
*
|
||||
* @var \Doctrine\DBAL\Platforms\AbstractPlatform
|
||||
*/
|
||||
private $_platform = null;
|
||||
|
||||
/**
|
||||
* @param AbstractPlatform $platform
|
||||
*/
|
||||
public function __construct(AbstractPlatform $platform)
|
||||
{
|
||||
$this->_platform = $platform;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Schema $schema
|
||||
*/
|
||||
public function acceptSchema(Schema $schema)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate DDL Statements to create the accepted table with all its dependencies.
|
||||
*
|
||||
* @param Table $table
|
||||
*/
|
||||
public function acceptTable(Table $table)
|
||||
{
|
||||
$options = $table->getOptions();
|
||||
$options['uniqueConstraints'] = array();
|
||||
$options['indexes'] = array();
|
||||
$options['primary'] = array();
|
||||
|
||||
foreach($table->getIndexes() AS $index) {
|
||||
/* @var $index Index */
|
||||
if(!$index->isPrimary() && !$index->isUnique()) {
|
||||
$options['indexes'][$index->getName()] = $index->getColumns();
|
||||
} else {
|
||||
if($index->isPrimary()) {
|
||||
$options['primary'] = $index->getColumns();
|
||||
} else {
|
||||
$options['uniqueConstraints'][$index->getName()] = $index->getColumns();
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
$column = array();
|
||||
$column['name'] = $class->getQuotedColumnName($mapping['fieldName'], $this->_platform);
|
||||
$column['type'] = Type::getType($mapping['type']);
|
||||
$column['length'] = isset($mapping['length']) ? $mapping['length'] : null;
|
||||
$column['notnull'] = isset($mapping['nullable']) ? ! $mapping['nullable'] : true;
|
||||
$column['unique'] = isset($mapping['unique']) ? $mapping['unique'] : false;
|
||||
$column['version'] = $class->isVersioned && $class->versionField == $mapping['fieldName'] ? true : false;
|
||||
|
||||
if(strtolower($column['type']) == 'string' && $column['length'] === null) {
|
||||
$column['length'] = 255;
|
||||
}
|
||||
|
||||
if (isset($mapping['precision'])) {
|
||||
$column['precision'] = $mapping['precision'];
|
||||
}
|
||||
|
||||
if (isset($mapping['scale'])) {
|
||||
$column['scale'] = $mapping['scale'];
|
||||
*/
|
||||
$columns = array();
|
||||
foreach($columns AS $column) {
|
||||
/* @var \Doctrine\DBAL\Schema\Column $column */
|
||||
$columnData = array();
|
||||
$columnData['name'] = $column->getName();
|
||||
$columnData['type'] = $column->getType();
|
||||
$columnData['length'] = $column->getLength();
|
||||
$columnData['notnull'] = $column->notNull();
|
||||
$columnData['unique'] = false;
|
||||
$columnData['version'] = ($column->hasPlatformOption("version"))?$column->getPlatformOptions('version'):false;
|
||||
if(strtolower($columnData['type']) == "string" && $columnData['length'] === null) {
|
||||
$columnData['length'] = 255;
|
||||
}
|
||||
$columnData['precision'] = $column->getPrecision();
|
||||
$columnData['scale'] = $column->getScale();
|
||||
$columnData['default'] = $column->getDefault();
|
||||
// TODO: Fixed? Unsigned?
|
||||
|
||||
if(in_array($column->getName(), $options['primary'])) {
|
||||
$columnData['primary'] = true;
|
||||
|
||||
if($table->isIdGeneratorIdentity()) {
|
||||
$columnData['autoincrement'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
$columns[] = $columnData;
|
||||
}
|
||||
|
||||
$this->_createTableQueries = array_merge($this->_createTableQueries,
|
||||
$this->_platform->getCreateTableSql($table->getName(), $columns, $options)
|
||||
);
|
||||
}
|
||||
|
||||
public function acceptColunn(Table $table, Column $column)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Table $localTable
|
||||
* @param ForeignKeyConstraint $fkConstraint
|
||||
*/
|
||||
public function acceptForeignKey(Table $localTable, ForeignKeyConstraint $fkConstraint)
|
||||
{
|
||||
$fkConstraintArray = array(
|
||||
'tableName' => $fkConstraint->getName(),
|
||||
'foreignTable' => $fkConstraint->getForeignTableName(),
|
||||
'local' => $fkConstraint->getLocalColumnNames(),
|
||||
'foreign' => $fkConstraint->getForeignColumnNames(),
|
||||
'onUpdate' => ($fkConstraint->hasOption('onUpdate')?$fkConstraint->getOption('onUpdate'):null),
|
||||
'onDelete' => ($fkConstraint->hasOption('onDelete')?$fkConstraint->getOption('onDelete'):null),
|
||||
);
|
||||
|
||||
// Append the foreign key constraints SQL
|
||||
if ($this->_platform->supportsForeignKeyConstraints()) {
|
||||
$this->_createFkConstraintQueries = array_merge($this->_createFkConstraintQueries,
|
||||
(array) $this->_platform->getCreateForeignKeySql($localTable->getName(), $fkConstraintArray)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Table $table
|
||||
* @param Index $index
|
||||
*/
|
||||
public function acceptIndex(Table $table, Index $index)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Table $table
|
||||
* @param Constraint $constraint
|
||||
*/
|
||||
public function acceptCheckConstraint(Table $table, Constraint $constraint)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Sequence $sequence
|
||||
*/
|
||||
public function acceptSequence(Sequence $sequence)
|
||||
{
|
||||
$this->_createSequenceQueries = array_merge($this->_createSequenceQueries,
|
||||
(array)$this->_platform->getCreateSequenceSql(
|
||||
$sequence->getName(),
|
||||
$sequence->getInitialValue(),
|
||||
$sequence->getAllocationSize()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function resetQueries()
|
||||
{
|
||||
$this->_createTableQueries = array();
|
||||
$this->_createSequenceQueries = array();
|
||||
$this->_createFkConstraintQueries = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all queries collected so far.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getQueries()
|
||||
{
|
||||
return array_merge(
|
||||
$this->_createTableQueries,
|
||||
$this->_createSequenceQueries,
|
||||
$this->_createFkConstraintQueries
|
||||
);
|
||||
}
|
||||
}
|
43
tests/Doctrine/Tests/DBAL/Schema/ColumnTest.php
Normal file
43
tests/Doctrine/Tests/DBAL/Schema/ColumnTest.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\DBAL\Schema;
|
||||
|
||||
require_once __DIR__ . '/../../TestInit.php';
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\DBAL\Schema\Table;
|
||||
use Doctrine\DBAL\Schema\Column;
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
|
||||
class ColumnTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testGet()
|
||||
{
|
||||
$options = array(
|
||||
'length' => 200,
|
||||
'precision' => 5,
|
||||
'scale' => 2,
|
||||
'unsigned' => true,
|
||||
'notnull' => false,
|
||||
'fixed' => true,
|
||||
'default' => 'baz',
|
||||
'platformOptions' => array('foo' => 'bar'),
|
||||
);
|
||||
|
||||
$string = Type::getType('string');
|
||||
$column = new Column("foo", $string, $options);
|
||||
|
||||
$this->assertEquals("foo", $column->getName());
|
||||
$this->assertSame($string, $column->getType());
|
||||
|
||||
$this->assertEquals(200, $column->getLength());
|
||||
$this->assertEquals(5, $column->getPrecision());
|
||||
$this->assertEquals(2, $column->getScale());
|
||||
$this->assertTrue($column->getUnsigned());
|
||||
$this->assertFalse($column->getNotNull());
|
||||
$this->assertTrue($column->getFixed());
|
||||
$this->assertEquals("baz", $column->getDefault());
|
||||
|
||||
$this->assertEquals(array('foo' => 'bar'), $column->getPlatformOptions());
|
||||
}
|
||||
}
|
43
tests/Doctrine/Tests/DBAL/Schema/IndexTest.php
Normal file
43
tests/Doctrine/Tests/DBAL/Schema/IndexTest.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\DBAL\Schema;
|
||||
|
||||
require_once __DIR__ . '/../../TestInit.php';
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\DBAL\Schema\Table;
|
||||
use Doctrine\DBAL\Schema\Column;
|
||||
use Doctrine\DBAL\Schema\Index;
|
||||
|
||||
class IndexTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function createIndex($unique=false, $primary=false)
|
||||
{
|
||||
return new Index("foo", array("bar", "baz"), $unique, $primary);
|
||||
}
|
||||
|
||||
public function testCreateIndex()
|
||||
{
|
||||
$idx = $this->createIndex();
|
||||
$this->assertEquals("foo", $idx->getName());
|
||||
$columns = $idx->getColumns();
|
||||
$this->assertEquals(2, count($columns));
|
||||
$this->assertEquals(array("bar", "baz"), $columns);
|
||||
$this->assertFalse($idx->isUnique());
|
||||
$this->assertFalse($idx->isPrimary());
|
||||
}
|
||||
|
||||
public function testCreatePrimary()
|
||||
{
|
||||
$idx = $this->createIndex(false, true);
|
||||
$this->assertFalse($idx->isUnique());
|
||||
$this->assertTrue($idx->isPrimary());
|
||||
}
|
||||
|
||||
public function testCreateUnique()
|
||||
{
|
||||
$idx = $this->createIndex(true, false);
|
||||
$this->assertTrue($idx->isUnique());
|
||||
$this->assertFalse($idx->isPrimary());
|
||||
}
|
||||
}
|
138
tests/Doctrine/Tests/DBAL/Schema/SchemaTest.php
Normal file
138
tests/Doctrine/Tests/DBAL/Schema/SchemaTest.php
Normal file
@ -0,0 +1,138 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\DBAL\Schema;
|
||||
|
||||
require_once __DIR__ . '/../../TestInit.php';
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\DBAL\Schema\Table;
|
||||
use Doctrine\DBAL\Schema\Sequence;
|
||||
|
||||
class SchemaTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testAddTable()
|
||||
{
|
||||
$tableName = "foo";
|
||||
$table = new Table($tableName);
|
||||
|
||||
$schema = new Schema(array($table));
|
||||
|
||||
$this->assertTrue($schema->hasTable($tableName));
|
||||
|
||||
$tables = $schema->getTables();
|
||||
$this->assertTrue( isset($tables[$tableName]) );
|
||||
$this->assertSame($table, $tables[$tableName]);
|
||||
$this->assertSame($table, $schema->getTable($tableName));
|
||||
$this->assertTrue($schema->hasTable($tableName));
|
||||
}
|
||||
|
||||
public function testGetUnknownTableThrowsException()
|
||||
{
|
||||
$this->setExpectedException("Doctrine\DBAL\Schema\SchemaException");
|
||||
|
||||
$schema = new Schema();
|
||||
$schema->getTable("unknown");
|
||||
}
|
||||
|
||||
public function testCreateTableTwiceThrowsException()
|
||||
{
|
||||
$this->setExpectedException("Doctrine\DBAL\Schema\SchemaException");
|
||||
|
||||
$tableName = "foo";
|
||||
$table = new Table($tableName);
|
||||
$tables = array($table, $table);
|
||||
|
||||
$schema = new Schema($tables);
|
||||
}
|
||||
|
||||
public function testRenameTable()
|
||||
{
|
||||
$tableName = "foo";
|
||||
$table = new Table($tableName);
|
||||
$schema = new Schema(array($table));
|
||||
|
||||
$this->assertTrue($schema->hasTable("foo"));
|
||||
$schema->renameTable("foo", "bar");
|
||||
$this->assertFalse($schema->hasTable("foo"));
|
||||
$this->assertTrue($schema->hasTable("bar"));
|
||||
$this->assertSame($table, $schema->getTable("bar"));
|
||||
}
|
||||
|
||||
public function testDropTable()
|
||||
{
|
||||
$tableName = "foo";
|
||||
$table = new Table($tableName);
|
||||
$schema = new Schema(array($table));
|
||||
|
||||
$this->assertTrue($schema->hasTable("foo"));
|
||||
|
||||
$schema->dropTable("foo");
|
||||
|
||||
$this->assertFalse($schema->hasTable("foo"));
|
||||
}
|
||||
|
||||
public function testCreateTable()
|
||||
{
|
||||
$schema = new Schema();
|
||||
|
||||
$this->assertFalse($schema->hasTable("foo"));
|
||||
|
||||
$table = $schema->createTable("foo");
|
||||
|
||||
$this->assertType('Doctrine\DBAL\Schema\Table', $table);
|
||||
$this->assertEquals("foo", $table->getName());
|
||||
$this->assertTrue($schema->hasTable("foo"));
|
||||
}
|
||||
|
||||
public function testAddSequences()
|
||||
{
|
||||
$sequence = new Sequence("a_seq", 1, 1);
|
||||
|
||||
$schema = new Schema(array(), array($sequence));
|
||||
|
||||
$this->assertTrue($schema->hasSequence("a_seq"));
|
||||
$this->assertType('Doctrine\DBAL\Schema\Sequence', $schema->getSequence("a_seq"));
|
||||
|
||||
$sequences = $schema->getSequences();
|
||||
$this->assertArrayHasKey('a_seq', $sequences);
|
||||
}
|
||||
|
||||
public function testGetUnknownSequenceThrowsException()
|
||||
{
|
||||
$this->setExpectedException("Doctrine\DBAL\Schema\SchemaException");
|
||||
|
||||
$schema = new Schema();
|
||||
$schema->getSequence("unknown");
|
||||
}
|
||||
|
||||
public function testCreateSequence()
|
||||
{
|
||||
$schema = new Schema();
|
||||
$schema->createSequence('a_seq');
|
||||
|
||||
$this->assertTrue($schema->hasSequence("a_seq"));
|
||||
$this->assertType('Doctrine\DBAL\Schema\Sequence', $schema->getSequence("a_seq"));
|
||||
|
||||
$sequences = $schema->getSequences();
|
||||
$this->assertArrayHasKey('a_seq', $sequences);
|
||||
}
|
||||
|
||||
public function testDropSequence()
|
||||
{
|
||||
$sequence = new Sequence("a_seq", 1, 1);
|
||||
|
||||
$schema = new Schema(array(), array($sequence));
|
||||
|
||||
$schema->dropSequence("a_seq");
|
||||
$this->assertFalse($schema->hasSequence("a_seq"));
|
||||
}
|
||||
|
||||
public function testAddSequenceTwiceThrowsException()
|
||||
{
|
||||
$this->setExpectedException("Doctrine\DBAL\Schema\SchemaException");
|
||||
|
||||
$sequence = new Sequence("a_seq", 1, 1);
|
||||
|
||||
$schema = new Schema(array(), array($sequence, $sequence));
|
||||
}
|
||||
}
|
294
tests/Doctrine/Tests/DBAL/Schema/TableTest.php
Normal file
294
tests/Doctrine/Tests/DBAL/Schema/TableTest.php
Normal file
@ -0,0 +1,294 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\DBAL\Schema;
|
||||
|
||||
require_once __DIR__ . '/../../TestInit.php';
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\DBAL\Schema\Table;
|
||||
use Doctrine\DBAL\Schema\TableBuilder;
|
||||
use Doctrine\DBAL\Schema\Column;
|
||||
use Doctrine\DBAL\Schema\Index;
|
||||
use Doctrine\DBAL\Schema\ForeignKeyConstraint;
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
|
||||
class TableTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testGetName()
|
||||
{
|
||||
$table = new Table("foo", array(), array(), array());
|
||||
$this->assertEquals("foo", $table->getName());
|
||||
}
|
||||
|
||||
public function testColumns()
|
||||
{
|
||||
$type = Type::getType('integer');
|
||||
$columns = array();
|
||||
$columns[] = new Column("foo", $type);
|
||||
$columns[] = new Column("bar", $type);
|
||||
$table = new Table("foo", $columns, array(), array());
|
||||
|
||||
$this->assertTrue($table->hasColumn("foo"));
|
||||
$this->assertTrue($table->hasColumn("bar"));
|
||||
$this->assertFalse($table->hasColumn("baz"));
|
||||
|
||||
$this->assertType('Doctrine\DBAL\Schema\Column', $table->getColumn("foo"));
|
||||
$this->assertType('Doctrine\DBAL\Schema\Column', $table->getColumn("bar"));
|
||||
|
||||
$this->assertEquals(2, count($table->getColumns()));
|
||||
}
|
||||
|
||||
public function testCreateColumn()
|
||||
{
|
||||
$type = Type::getType('integer');
|
||||
|
||||
$table = new Table("foo");
|
||||
|
||||
$this->assertFalse($table->hasColumn("bar"));
|
||||
$table->createColumn("bar", 'integer');
|
||||
$this->assertTrue($table->hasColumn("bar"));
|
||||
$this->assertSame($type, $table->getColumn("bar")->getType());
|
||||
}
|
||||
|
||||
public function testDropColumn()
|
||||
{
|
||||
$type = Type::getType('integer');
|
||||
$columns = array();
|
||||
$columns[] = new Column("foo", $type);
|
||||
$columns[] = new Column("bar", $type);
|
||||
$table = new Table("foo", $columns, array(), array());
|
||||
|
||||
$this->assertTrue($table->hasColumn("foo"));
|
||||
$this->assertTrue($table->hasColumn("bar"));
|
||||
|
||||
$table->dropColumn("foo")->dropColumn("bar");
|
||||
|
||||
$this->assertFalse($table->hasColumn("foo"));
|
||||
$this->assertFalse($table->hasColumn("bar"));
|
||||
}
|
||||
|
||||
public function testGetUnknownColumnThrowsException()
|
||||
{
|
||||
$this->setExpectedException("Doctrine\DBAL\Schema\SchemaException");
|
||||
|
||||
$table = new Table("foo", array(), array(), array());
|
||||
$table->getColumn('unknown');
|
||||
}
|
||||
|
||||
public function testAddColumnTwiceThrowsException()
|
||||
{
|
||||
$this->setExpectedException("Doctrine\DBAL\Schema\SchemaException");
|
||||
|
||||
$type = \Doctrine\DBAL\Types\Type::getType('integer');
|
||||
$columns = array();
|
||||
$columns[] = new Column("foo", $type);
|
||||
$columns[] = new Column("foo", $type);
|
||||
$table = new Table("foo", $columns, array(), array());
|
||||
}
|
||||
|
||||
public function testAddIndexes()
|
||||
{
|
||||
$type = \Doctrine\DBAL\Types\Type::getType('integer');
|
||||
$columns = array(new Column("foo", $type));
|
||||
$indexes = array(
|
||||
new Index("the_primary", array("foo"), true, true),
|
||||
new Index("foo_idx", array("foo"), false, false),
|
||||
);
|
||||
$table = new Table("foo", $columns, $indexes, array());
|
||||
|
||||
$this->assertTrue($table->hasIndex("the_primary"));
|
||||
$this->assertTrue($table->hasIndex("foo_idx"));
|
||||
$this->assertFalse($table->hasIndex("some_idx"));
|
||||
|
||||
$this->assertType('Doctrine\DBAL\Schema\Index', $table->getPrimaryKey());
|
||||
$this->assertType('Doctrine\DBAL\Schema\Index', $table->getIndex('the_primary'));
|
||||
$this->assertType('Doctrine\DBAL\Schema\Index', $table->getIndex('foo_idx'));
|
||||
}
|
||||
|
||||
public function testGetUnknownIndexThrowsException()
|
||||
{
|
||||
$this->setExpectedException("Doctrine\DBAL\Schema\SchemaException");
|
||||
|
||||
$table = new Table("foo", array(), array(), array());
|
||||
$table->getIndex("unknownIndex");
|
||||
}
|
||||
|
||||
public function testAddTwoPrimaryThrowsException()
|
||||
{
|
||||
$this->setExpectedException("Doctrine\DBAL\Schema\SchemaException");
|
||||
|
||||
$type = \Doctrine\DBAL\Types\Type::getType('integer');
|
||||
$columns = array(new Column("foo", $type));
|
||||
$indexes = array(
|
||||
new Index("the_primary", array("foo"), true, true),
|
||||
new Index("other_primary", array("foo"), true, true),
|
||||
);
|
||||
$table = new Table("foo", $columns, $indexes, array());
|
||||
}
|
||||
|
||||
public function testAddTwoIndexesWithSameNameThrowsException()
|
||||
{
|
||||
$this->setExpectedException("Doctrine\DBAL\Schema\SchemaException");
|
||||
|
||||
$type = \Doctrine\DBAL\Types\Type::getType('integer');
|
||||
$columns = array(new Column("foo", $type));
|
||||
$indexes = array(
|
||||
new Index("an_idx", array("foo"), false, false),
|
||||
new Index("an_idx", array("foo"), false, false),
|
||||
);
|
||||
$table = new Table("foo", $columns, $indexes, array());
|
||||
}
|
||||
|
||||
public function testIdGenerator()
|
||||
{
|
||||
$tableA = new Table("foo", array(), array(), array(), Table::ID_NONE);
|
||||
$this->assertFalse($tableA->isIdGeneratorIdentity());
|
||||
$this->assertFalse($tableA->isIdGeneratorSequence());;
|
||||
|
||||
$tableB = new Table("foo", array(), array(), array(), Table::ID_IDENTITY);
|
||||
$this->assertTrue($tableB->isIdGeneratorIdentity());
|
||||
$this->assertFalse($tableB->isIdGeneratorSequence());;
|
||||
|
||||
$tableC = new Table("foo", array(), array(), array(), Table::ID_SEQUENCE);
|
||||
$this->assertFalse($tableC->isIdGeneratorIdentity());
|
||||
$this->assertTrue($tableC->isIdGeneratorSequence());;
|
||||
}
|
||||
|
||||
public function testConstraints()
|
||||
{
|
||||
$constraint = new ForeignKeyConstraint(array(), "foo", array());
|
||||
|
||||
$tableA = new Table("foo", array(), array(), array($constraint));
|
||||
$constraints = $tableA->getConstraints();
|
||||
|
||||
$this->assertEquals(1, count($constraints));
|
||||
$this->assertSame($constraint, $constraints[0]);
|
||||
}
|
||||
|
||||
public function testOptions()
|
||||
{
|
||||
$table = new Table("foo", array(), array(), array(), Table::ID_NONE, array("foo" => "bar"));
|
||||
|
||||
$this->assertTrue($table->hasOption("foo"));
|
||||
$this->assertEquals("bar", $table->getOption("foo"));
|
||||
}
|
||||
|
||||
public function testBuilderSetPrimaryKey()
|
||||
{
|
||||
$table = new Table("foo");
|
||||
|
||||
$table->createColumn("bar", 'integer');
|
||||
$table->setPrimaryKey(array("bar"));
|
||||
|
||||
$this->assertTrue($table->hasIndex("primary"));
|
||||
$this->assertType('Doctrine\DBAL\Schema\Index', $table->getPrimaryKey());
|
||||
$this->assertTrue($table->getIndex("primary")->isUnique());
|
||||
$this->assertTrue($table->getIndex("primary")->isPrimary());
|
||||
}
|
||||
|
||||
public function testBuilderAddUniqueIndex()
|
||||
{
|
||||
$table = new Table("foo");
|
||||
|
||||
$table->createColumn("bar", 'integer');
|
||||
$table->addUniqueIndex(array("bar"), "my_idx");
|
||||
|
||||
$this->assertTrue($table->hasIndex("my_idx"));
|
||||
$this->assertTrue($table->getIndex("my_idx")->isUnique());
|
||||
$this->assertFalse($table->getIndex("my_idx")->isPrimary());
|
||||
}
|
||||
|
||||
public function testBuilderAddIndex()
|
||||
{
|
||||
$table = new Table("foo");
|
||||
|
||||
$table->createColumn("bar", 'integer');
|
||||
$table->addIndex(array("bar"), "my_idx");
|
||||
|
||||
$this->assertTrue($table->hasIndex("my_idx"));
|
||||
$this->assertFalse($table->getIndex("my_idx")->isUnique());
|
||||
$this->assertFalse($table->getIndex("my_idx")->isPrimary());
|
||||
}
|
||||
|
||||
public function testBuilderAddIndexWithInvalidNameThrowsException()
|
||||
{
|
||||
$this->setExpectedException("Doctrine\DBAL\Schema\SchemaException");
|
||||
|
||||
$table = new Table("foo");
|
||||
$table->createColumn("bar",'integer');
|
||||
$table->addIndex(array("bar"), "invalid name %&/");
|
||||
}
|
||||
|
||||
public function testBuilderAddIndexWithUnknownColumnThrowsException()
|
||||
{
|
||||
$this->setExpectedException("Doctrine\DBAL\Schema\SchemaException");
|
||||
|
||||
$table = new Table("foo");
|
||||
$table->addIndex(array("bar"), "invalidName");
|
||||
}
|
||||
|
||||
public function testBuilderOptions()
|
||||
{
|
||||
$table = new Table("foo");
|
||||
$table->addOption("foo", "bar");
|
||||
$this->assertTrue($table->hasOption("foo"));
|
||||
$this->assertEquals("bar", $table->getOption("foo"));
|
||||
}
|
||||
|
||||
public function testIdGeneratorType()
|
||||
{
|
||||
$table = new Table("foo");
|
||||
|
||||
$table->setIdGeneratorType(Table::ID_IDENTITY);
|
||||
$this->assertTrue($table->isIdGeneratorIdentity());
|
||||
|
||||
$table->setIdGeneratorType(Table::ID_SEQUENCE);
|
||||
$this->assertTrue($table->isIdGeneratorSequence());
|
||||
}
|
||||
|
||||
public function testAddForeignKeyConstraint_UnknownLocalColumn_ThrowsException()
|
||||
{
|
||||
$this->setExpectedException("Doctrine\DBAL\Schema\SchemaException");
|
||||
|
||||
$table = new Table("foo");
|
||||
$table->createColumn("id", 'int');
|
||||
|
||||
$foreignTable = new Table("bar");
|
||||
$foreignTable->createColumn("id", 'int');
|
||||
|
||||
$table->addForeignKeyConstraint($foreignTable, array("foo"), array("id"), array());
|
||||
}
|
||||
|
||||
public function testAddForeignKeyConstraint_UnknownForeignColumn_ThrowsException()
|
||||
{
|
||||
$this->setExpectedException("Doctrine\DBAL\Schema\SchemaException");
|
||||
|
||||
$table = new Table("foo");
|
||||
$table->createColumn("id", 'integer');
|
||||
|
||||
$foreignTable = new Table("bar");
|
||||
$foreignTable->createColumn("id", 'integer');
|
||||
|
||||
$table->addForeignKeyConstraint($foreignTable, array("id"), array("foo"), array());
|
||||
}
|
||||
|
||||
public function testAddForeignKeyConstraint()
|
||||
{
|
||||
$table = new Table("foo");
|
||||
$table->createColumn("id", 'integer');
|
||||
|
||||
$foreignTable = new Table("bar");
|
||||
$foreignTable->createColumn("id", 'integer');
|
||||
|
||||
$table->addForeignKeyConstraint($foreignTable, array("id"), array("id"), "fkName", array("foo" => "bar"));
|
||||
|
||||
$constraints = $table->getConstraints();
|
||||
$this->assertEquals(1, count($constraints));
|
||||
$this->assertType('Doctrine\DBAL\Schema\ForeignKeyConstraint', $constraints[0]);
|
||||
|
||||
$this->assertEquals("fkName", $constraints[0]->getName());
|
||||
$this->assertTrue($constraints[0]->hasOption("foo"));
|
||||
$this->assertEquals("bar", $constraints[0]->getOption("foo"));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\DBAL\Schema\Visitor;
|
||||
|
||||
require_once __DIR__ . '/../../../TestInit.php';
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\DBAL\Schema\Table;
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
|
||||
class CreateSchemaSqlCollectorTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testCreateSchema()
|
||||
{
|
||||
$platformMock = $this->getMock(
|
||||
'Doctrine\DBAL\Platforms\MySqlPlatform',
|
||||
array('getCreateTableSql', 'getCreateSequenceSql', 'getCreateForeignKeySql')
|
||||
);
|
||||
$platformMock->expects($this->exactly(2))
|
||||
->method('getCreateTableSql')
|
||||
->will($this->returnValue(array("foo" => "bar")));
|
||||
$platformMock->expects($this->exactly(1))
|
||||
->method('getCreateSequenceSql')
|
||||
->will($this->returnValue(array("bar" => "baz")));
|
||||
$platformMock->expects($this->exactly(1))
|
||||
->method('getCreateForeignKeySql')
|
||||
->will($this->returnValue(array("baz" => "foo")));
|
||||
|
||||
$schema = new Schema();
|
||||
$tableA = $schema->createTable("foo");
|
||||
$tableA->createColumn("id", 'integer');
|
||||
$tableA->createColumn("bar", 'string', array('length' => 255));
|
||||
$tableA->setPrimaryKey(array("id"));
|
||||
$tableA->setIdGeneratorType(Table::ID_SEQUENCE);
|
||||
|
||||
$schema->createSequence("foo_seq");
|
||||
|
||||
$tableB = $schema->createTable("bar");
|
||||
$tableB->createColumn("id", 'integer');
|
||||
$tableB->setPrimaryKey(array("id"));
|
||||
|
||||
$tableA->addForeignKeyConstraint($tableB, array("bar"), array("id"));
|
||||
|
||||
$sql = $schema->toSql($platformMock);
|
||||
|
||||
$this->assertEquals(array("foo" => "bar", "bar" => "baz", "baz" => "foo"), $sql);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user