1
0
mirror of synced 2025-01-29 19:41:45 +03:00

Several fixes for mysql export module (incorrectly added indices)

Ticket: 408
This commit is contained in:
romanb 2007-07-30 11:47:36 +00:00
parent 7583a8d8ac
commit 8a0898d3ed
3 changed files with 963 additions and 959 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,289 +1,288 @@
<?php <?php
/* /*
* $Id$ * $Id$
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* This software consists of voluntary contributions made by many individuals * This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see * and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.com>. * <http://www.phpdoctrine.com>.
*/ */
/** /**
* Doctrine_Export_Mysql_TestCase * Doctrine_Export_Mysql_TestCase
* *
* @package Doctrine * @package Doctrine
* @author Konsta Vesterinen <kvesteri@cc.hut.fi> * @author Konsta Vesterinen <kvesteri@cc.hut.fi>
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @category Object Relational Mapping * @category Object Relational Mapping
* @link www.phpdoctrine.com * @link www.phpdoctrine.com
* @since 1.0 * @since 1.0
* @version $Revision$ * @version $Revision$
*/ */
class Doctrine_Export_Mysql_TestCase extends Doctrine_UnitTestCase class Doctrine_Export_Mysql_TestCase extends Doctrine_UnitTestCase
{ {
public function prepareTables() public function prepareTables()
{ } { }
public function prepareData() public function prepareData()
{ } { }
public function testAlterTableThrowsExceptionWithoutValidTableName() public function testAlterTableThrowsExceptionWithoutValidTableName()
{ {
try { try {
$this->export->alterTable(0, array(), array()); $this->export->alterTable(0, array(), array());
$this->fail(); $this->fail();
} catch(Doctrine_Export_Exception $e) { } catch(Doctrine_Export_Exception $e) {
$this->pass(); $this->pass();
} }
} }
public function testCreateTableExecutesSql() public function testCreateTableExecutesSql()
{ {
$name = 'mytable'; $name = 'mytable';
$fields = array('id' => array('type' => 'integer', 'unsigned' => 1)); $fields = array('id' => array('type' => 'integer', 'unsigned' => 1));
$options = array('type' => 'MYISAM'); $options = array('type' => 'MYISAM');
$this->export->createTable($name, $fields, $options); $this->export->createTable($name, $fields, $options);
$this->assertEqual($this->adapter->pop(), 'CREATE TABLE mytable (id INT UNSIGNED) ENGINE = MYISAM'); $this->assertEqual($this->adapter->pop(), 'CREATE TABLE mytable (id INT UNSIGNED) ENGINE = MYISAM');
} }
public function testCreateTableSupportsDefaultTableType() public function testCreateTableSupportsDefaultTableType()
{ {
$name = 'mytable'; $name = 'mytable';
$fields = array('id' => array('type' => 'integer', 'unsigned' => 1)); $fields = array('id' => array('type' => 'integer', 'unsigned' => 1));
$this->export->createTable($name, $fields); $this->export->createTable($name, $fields);
// INNODB is the default type // INNODB is the default type
$this->assertEqual($this->adapter->pop(), 'CREATE TABLE mytable (id INT UNSIGNED) ENGINE = INNODB'); $this->assertEqual($this->adapter->pop(), 'CREATE TABLE mytable (id INT UNSIGNED) ENGINE = INNODB');
} }
public function testCreateTableSupportsMultiplePks() public function testCreateTableSupportsMultiplePks()
{ {
$name = 'mytable'; $name = 'mytable';
$fields = array('name' => array('type' => 'char', 'length' => 10), $fields = array('name' => array('type' => 'char', 'length' => 10),
'type' => array('type' => 'integer', 'length' => 3)); 'type' => array('type' => 'integer', 'length' => 3));
$options = array('primary' => array('name', 'type')); $options = array('primary' => array('name', 'type'));
$this->export->createTable($name, $fields, $options); $this->export->createTable($name, $fields, $options);
$this->assertEqual($this->adapter->pop(), 'CREATE TABLE mytable (name CHAR(10), type MEDIUMINT, PRIMARY KEY(name, type)) ENGINE = INNODB'); $this->assertEqual($this->adapter->pop(), 'CREATE TABLE mytable (name CHAR(10), type MEDIUMINT, PRIMARY KEY(name, type)) ENGINE = INNODB');
} }
public function testCreateTableSupportsAutoincPks() public function testCreateTableSupportsAutoincPks()
{ {
$name = 'mytable'; $name = 'mytable';
$fields = array('id' => array('type' => 'integer', 'unsigned' => 1, 'autoincrement' => true)); $fields = array('id' => array('type' => 'integer', 'unsigned' => 1, 'autoincrement' => true));
$options = array('primary' => array('id'), $options = array('primary' => array('id'),
'type' => 'INNODB'); 'type' => 'INNODB');
$this->export->createTable($name, $fields, $options); $this->export->createTable($name, $fields, $options);
$this->assertEqual($this->adapter->pop(), 'CREATE TABLE mytable (id INT UNSIGNED AUTO_INCREMENT, PRIMARY KEY(id)) ENGINE = INNODB'); $this->assertEqual($this->adapter->pop(), 'CREATE TABLE mytable (id INT UNSIGNED AUTO_INCREMENT, PRIMARY KEY(id)) ENGINE = INNODB');
} }
public function testCreateTableSupportsCharType() public function testCreateTableSupportsCharType()
{ {
$name = 'mytable'; $name = 'mytable';
$fields = array('id' => array('type' => 'char', 'length' => 3)); $fields = array('id' => array('type' => 'char', 'length' => 3));
$options = array('type' => 'MYISAM'); $options = array('type' => 'MYISAM');
$this->export->createTable($name, $fields, $options); $this->export->createTable($name, $fields, $options);
$this->assertEqual($this->adapter->pop(), 'CREATE TABLE mytable (id CHAR(3)) ENGINE = MYISAM'); $this->assertEqual($this->adapter->pop(), 'CREATE TABLE mytable (id CHAR(3)) ENGINE = MYISAM');
} }
public function testCreateTableSupportsCharType2() public function testCreateTableSupportsCharType2()
{ {
$name = 'mytable'; $name = 'mytable';
$fields = array('id' => array('type' => 'char')); $fields = array('id' => array('type' => 'char'));
$options = array('type' => 'MYISAM'); $options = array('type' => 'MYISAM');
$this->export->createTable($name, $fields, $options); $this->export->createTable($name, $fields, $options);
$this->assertEqual($this->adapter->pop(), 'CREATE TABLE mytable (id CHAR(255)) ENGINE = MYISAM'); $this->assertEqual($this->adapter->pop(), 'CREATE TABLE mytable (id CHAR(255)) ENGINE = MYISAM');
} }
public function testCreateTableSupportsVarcharType() public function testCreateTableSupportsVarcharType()
{ {
$name = 'mytable'; $name = 'mytable';
$fields = array('id' => array('type' => 'varchar', 'length' => '100')); $fields = array('id' => array('type' => 'varchar', 'length' => '100'));
$options = array('type' => 'MYISAM'); $options = array('type' => 'MYISAM');
$this->export->createTable($name, $fields, $options); $this->export->createTable($name, $fields, $options);
$this->assertEqual($this->adapter->pop(), 'CREATE TABLE mytable (id VARCHAR(100)) ENGINE = MYISAM'); $this->assertEqual($this->adapter->pop(), 'CREATE TABLE mytable (id VARCHAR(100)) ENGINE = MYISAM');
} }
public function testCreateTableSupportsIntegerType() public function testCreateTableSupportsIntegerType()
{ {
$name = 'mytable'; $name = 'mytable';
$fields = array('id' => array('type' => 'integer', 'length' => '10')); $fields = array('id' => array('type' => 'integer', 'length' => '10'));
$options = array('type' => 'MYISAM'); $options = array('type' => 'MYISAM');
$this->export->createTable($name, $fields, $options); $this->export->createTable($name, $fields, $options);
$this->assertEqual($this->adapter->pop(), 'CREATE TABLE mytable (id BIGINT) ENGINE = MYISAM'); $this->assertEqual($this->adapter->pop(), 'CREATE TABLE mytable (id BIGINT) ENGINE = MYISAM');
} }
public function testCreateTableSupportsBlobType() public function testCreateTableSupportsBlobType()
{ {
$name = 'mytable'; $name = 'mytable';
$fields = array('content' => array('type' => 'blob')); $fields = array('content' => array('type' => 'blob'));
$options = array('type' => 'MYISAM'); $options = array('type' => 'MYISAM');
$this->export->createTable($name, $fields, $options); $this->export->createTable($name, $fields, $options);
$this->assertEqual($this->adapter->pop(), 'CREATE TABLE mytable (content LONGBLOB) ENGINE = MYISAM'); $this->assertEqual($this->adapter->pop(), 'CREATE TABLE mytable (content LONGBLOB) ENGINE = MYISAM');
} }
public function testCreateTableSupportsBlobType2() public function testCreateTableSupportsBlobType2()
{ {
$name = 'mytable'; $name = 'mytable';
$fields = array('content' => array('type' => 'blob', 'length' => 2000)); $fields = array('content' => array('type' => 'blob', 'length' => 2000));
$options = array('type' => 'MYISAM'); $options = array('type' => 'MYISAM');
$this->export->createTable($name, $fields, $options); $this->export->createTable($name, $fields, $options);
$this->assertEqual($this->adapter->pop(), 'CREATE TABLE mytable (content BLOB) ENGINE = MYISAM'); $this->assertEqual($this->adapter->pop(), 'CREATE TABLE mytable (content BLOB) ENGINE = MYISAM');
} }
public function testCreateTableSupportsBooleanType() public function testCreateTableSupportsBooleanType()
{ {
$name = 'mytable'; $name = 'mytable';
$fields = array('id' => array('type' => 'boolean')); $fields = array('id' => array('type' => 'boolean'));
$options = array('type' => 'MYISAM'); $options = array('type' => 'MYISAM');
$this->export->createTable($name, $fields, $options); $this->export->createTable($name, $fields, $options);
$this->assertEqual($this->adapter->pop(), 'CREATE TABLE mytable (id TINYINT(1)) ENGINE = MYISAM'); $this->assertEqual($this->adapter->pop(), 'CREATE TABLE mytable (id TINYINT(1)) ENGINE = MYISAM');
} }
public function testCreateTableSupportsForeignKeys() public function testCreateTableSupportsForeignKeys()
{ {
$name = 'mytable'; $name = 'mytable';
$fields = array('id' => array('type' => 'boolean', 'primary' => true), $fields = array('id' => array('type' => 'boolean', 'primary' => true),
'foreignKey' => array('type' => 'integer') 'foreignKey' => array('type' => 'integer')
); );
$options = array('type' => 'INNODB', $options = array('type' => 'INNODB',
'foreignKeys' => array(array('local' => 'foreignKey', 'foreignKeys' => array(array('local' => 'foreignKey',
'foreign' => 'id', 'foreign' => 'id',
'foreignTable' => 'sometable')) 'foreignTable' => 'sometable'))
); );
$sql = $this->export->createTableSql($name, $fields, $options); $sql = $this->export->createTableSql($name, $fields, $options);
$this->assertEqual($sql[0], 'CREATE TABLE mytable (id TINYINT(1), foreignKey INT, INDEX foreignKey_idx (foreignKey)) ENGINE = INNODB'); $this->assertEqual($sql[0], 'CREATE TABLE mytable (id TINYINT(1), foreignKey INT, INDEX foreignKey_idx (foreignKey)) ENGINE = INNODB');
$this->assertEqual($sql[1], 'ALTER TABLE mytable ADD CONSTRAINT FOREIGN KEY (foreignKey) REFERENCES sometable(id)'); $this->assertEqual($sql[1], 'ALTER TABLE mytable ADD CONSTRAINT FOREIGN KEY (foreignKey) REFERENCES sometable(id)');
} }
public function testCreateTableDoesNotAutoAddIndexesWhenIndexForFkFieldAlreadyExists() public function testCreateTableDoesNotAutoAddIndexesWhenIndexForFkFieldAlreadyExists()
{ {
$name = 'mytable'; $name = 'mytable';
$fields = array('id' => array('type' => 'boolean', 'primary' => true), $fields = array('id' => array('type' => 'boolean', 'primary' => true),
'foreignKey' => array('type' => 'integer') 'foreignKey' => array('type' => 'integer')
); );
$options = array('type' => 'INNODB', $options = array('type' => 'INNODB',
'foreignKeys' => array(array('local' => 'foreignKey', 'foreignKeys' => array(array('local' => 'foreignKey',
'foreign' => 'id', 'foreign' => 'id',
'foreignTable' => 'sometable')), 'foreignTable' => 'sometable')),
'indexes' => array('myindex' => array('fields' => array('foreignKey' => array()))), 'indexes' => array('myindex' => array('fields' => array('foreignKey'))),
); );
$sql = $this->export->createTableSql($name, $fields, $options); $sql = $this->export->createTableSql($name, $fields, $options);
$this->assertEqual($sql[0], 'CREATE TABLE mytable (id TINYINT(1), foreignKey INT, INDEX myindex_idx (foreignKey)) ENGINE = INNODB');
$this->assertEqual($sql[0], 'CREATE TABLE mytable (id TINYINT(1), foreignKey INT, INDEX myindex_idx (foreignKey)) ENGINE = INNODB'); $this->assertEqual($sql[1], 'ALTER TABLE mytable ADD CONSTRAINT FOREIGN KEY (foreignKey) REFERENCES sometable(id)');
$this->assertEqual($sql[1], 'ALTER TABLE mytable ADD CONSTRAINT FOREIGN KEY (foreignKey) REFERENCES sometable(id)'); }
} public function testCreateDatabaseExecutesSql()
public function testCreateDatabaseExecutesSql() {
{ $this->export->createDatabase('db');
$this->export->createDatabase('db');
$this->assertEqual($this->adapter->pop(), 'CREATE DATABASE db');
$this->assertEqual($this->adapter->pop(), 'CREATE DATABASE db'); }
} public function testDropDatabaseExecutesSql()
public function testDropDatabaseExecutesSql() {
{ $this->export->dropDatabase('db');
$this->export->dropDatabase('db');
$this->assertEqual($this->adapter->pop(), 'DROP DATABASE db');
$this->assertEqual($this->adapter->pop(), 'DROP DATABASE db'); }
}
public function testDropIndexExecutesSql()
public function testDropIndexExecutesSql() {
{ $this->export->dropIndex('sometable', 'relevancy');
$this->export->dropIndex('sometable', 'relevancy');
$this->assertEqual($this->adapter->pop(), 'DROP INDEX relevancy_idx ON sometable');
$this->assertEqual($this->adapter->pop(), 'DROP INDEX relevancy_idx ON sometable'); }
} public function testUnknownIndexSortingAttributeThrowsException()
public function testUnknownIndexSortingAttributeThrowsException() {
{ $fields = array('id' => array('sorting' => 'ASC'),
$fields = array('id' => array('sorting' => 'ASC'), 'name' => array('sorting' => 'unknown'));
'name' => array('sorting' => 'unknown'));
try {
try { $this->export->getIndexFieldDeclarationList($fields);
$this->export->getIndexFieldDeclarationList($fields); $this->fail();
$this->fail(); } catch(Doctrine_Export_Exception $e) {
} catch(Doctrine_Export_Exception $e) { $this->pass();
$this->pass(); }
} }
} public function testIndexDeclarationsSupportSortingAndLengthAttributes()
public function testIndexDeclarationsSupportSortingAndLengthAttributes() {
{ $fields = array('id' => array('sorting' => 'ASC', 'length' => 10),
$fields = array('id' => array('sorting' => 'ASC', 'length' => 10), 'name' => array('sorting' => 'DESC', 'length' => 1));
'name' => array('sorting' => 'DESC', 'length' => 1));
$this->assertEqual($this->export->getIndexFieldDeclarationList($fields), 'id(10) ASC, name(1) DESC');
$this->assertEqual($this->export->getIndexFieldDeclarationList($fields), 'id(10) ASC, name(1) DESC'); }
} public function testCreateTableSupportsIndexesWithCustomSorting()
public function testCreateTableSupportsIndexesWithCustomSorting() {
{ $fields = array('id' => array('type' => 'integer', 'unsigned' => 1, 'autoincrement' => true, 'unique' => true),
$fields = array('id' => array('type' => 'integer', 'unsigned' => 1, 'autoincrement' => true, 'unique' => true), 'name' => array('type' => 'string', 'length' => 4),
'name' => array('type' => 'string', 'length' => 4), );
);
$options = array('primary' => array('id'),
$options = array('primary' => array('id'), 'indexes' => array('myindex' => array(
'indexes' => array('myindex' => array( 'fields' => array(
'fields' => array( 'id' => array('sorting' => 'ASC'),
'id' => array('sorting' => 'ASC'), 'name' => array('sorting' => 'DESC')
'name' => array('sorting' => 'DESC') )
) ))
)) );
);
$this->export->createTable('sometable', $fields, $options);
$this->export->createTable('sometable', $fields, $options);
$this->assertEqual($this->adapter->pop(), 'CREATE TABLE sometable (id INT UNSIGNED AUTO_INCREMENT, name VARCHAR(4), INDEX myindex_idx (id ASC, name DESC), PRIMARY KEY(id)) ENGINE = INNODB');
$this->assertEqual($this->adapter->pop(), 'CREATE TABLE sometable (id INT UNSIGNED AUTO_INCREMENT, name VARCHAR(4), INDEX myindex_idx (id ASC, name DESC), PRIMARY KEY(id)) ENGINE = INNODB'); }
} public function testCreateTableSupportsFulltextIndexes()
public function testCreateTableSupportsFulltextIndexes() {
{ $fields = array('id' => array('type' => 'integer', 'unsigned' => 1, 'autoincrement' => true, 'unique' => true),
$fields = array('id' => array('type' => 'integer', 'unsigned' => 1, 'autoincrement' => true, 'unique' => true), 'content' => array('type' => 'string', 'length' => 4),
'content' => array('type' => 'string', 'length' => 4), );
);
$options = array('primary' => array('id'),
$options = array('primary' => array('id'), 'indexes' => array('myindex' => array(
'indexes' => array('myindex' => array( 'fields' => array(
'fields' => array( 'content' => array('sorting' => 'DESC')
'content' => array('sorting' => 'DESC') ),
), 'type' => 'fulltext',
'type' => 'fulltext', )),
)), 'type' => 'MYISAM',
'type' => 'MYISAM', );
);
$this->export->createTable('sometable', $fields, $options);
$this->export->createTable('sometable', $fields, $options);
$this->assertEqual($this->adapter->pop(), 'CREATE TABLE sometable (id INT UNSIGNED AUTO_INCREMENT, content VARCHAR(4), FULLTEXT INDEX myindex_idx (content DESC), PRIMARY KEY(id)) ENGINE = MYISAM');
$this->assertEqual($this->adapter->pop(), 'CREATE TABLE sometable (id INT UNSIGNED AUTO_INCREMENT, content VARCHAR(4), FULLTEXT INDEX myindex_idx (content DESC), PRIMARY KEY(id)) ENGINE = MYISAM'); }
} }
}

View File

@ -1,41 +1,41 @@
<?php <?php
class Cms_CategoryLanguages extends Doctrine_Record class Cms_CategoryLanguages extends Doctrine_Record
{ {
public function setUp() public function setUp()
{ {
$this->setAttribute(Doctrine::ATTR_COLL_KEY, 'language_id'); $this->setAttribute(Doctrine::ATTR_COLL_KEY, 'language_id');
$this->hasOne('Cms_Category as category', array('local' => 'category_id', 'foreign' => 'id', 'onDelete' => 'CASCADE')); $this->hasOne('Cms_Category as category', array('local' => 'category_id', 'foreign' => 'id', 'onDelete' => 'CASCADE'));
} }
public function setTableDefinition() public function setTableDefinition()
{ {
$this->hasColumn('name', 'string',256); $this->hasColumn('name', 'string',256);
$this->hasColumn('category_id', 'integer',11); $this->hasColumn('category_id', 'integer',11);
$this->hasColumn('language_id', 'integer',11); $this->hasColumn('language_id', 'integer',11);
$this->option('collate', 'utf8_unicode_ci'); $this->option('collate', 'utf8_unicode_ci');
$this->option('charset', 'utf8'); $this->option('charset', 'utf8');
$this->option('type', 'INNODB'); $this->option('type', 'INNODB');
$this->index('index_category', array('fields' => 'category_id')); $this->index('index_category', array('fields' => array('category_id')));
$this->index('index_language', array('fields' => 'language_id')); $this->index('index_language', array('fields' => array('language_id')));
} }
} }
class Cms_Category extends Doctrine_Record class Cms_Category extends Doctrine_Record
{ {
public function setUp() public function setUp()
{ {
$this->ownsMany('Cms_CategoryLanguages as langs', array('local' => 'id', 'foreign' => 'category_id')); $this->ownsMany('Cms_CategoryLanguages as langs', array('local' => 'id', 'foreign' => 'category_id'));
} }
public function setTableDefinition() public function setTableDefinition()
{ {
$this->hasColumn('created', 'timestamp'); $this->hasColumn('created', 'timestamp');
$this->hasColumn('parent', 'integer', 11); $this->hasColumn('parent', 'integer', 11);
$this->hasColumn('position', 'integer', 3); $this->hasColumn('position', 'integer', 3);
$this->hasColumn('active', 'integer', 11); $this->hasColumn('active', 'integer', 11);
$this->option('collate', 'utf8_unicode_ci'); $this->option('collate', 'utf8_unicode_ci');
$this->option('charset', 'utf8'); $this->option('charset', 'utf8');
$this->option('type', 'INNODB'); $this->option('type', 'INNODB');
$this->index('index_parent', array('fields' => 'parent')); $this->index('index_parent', array('fields' => array('parent')));
} }
} }