From 01a3e06326491a519f64e7d5c9f0daa5dfda78ae Mon Sep 17 00:00:00 2001 From: jackbravo Date: Sun, 30 Sep 2007 01:17:49 +0000 Subject: [PATCH] Fixed some identifier quoting on sqlite, mysql and pgsql. Added some tests too --- lib/Doctrine/Export.php | 2 +- lib/Doctrine/Export/Mysql.php | 13 ++++++---- lib/Doctrine/Export/Pgsql.php | 4 ++- lib/Doctrine/Export/Sqlite.php | 12 +++++---- tests/Export/MysqlTestCase.php | 45 ++++++++++++++++++++++++++++++++ tests/Export/PgsqlTestCase.php | 46 +++++++++++++++++++++++++++++++++ tests/Export/SqliteTestCase.php | 39 ++++++++++++++++++++++++++++ 7 files changed, 149 insertions(+), 12 deletions(-) diff --git a/lib/Doctrine/Export.php b/lib/Doctrine/Export.php index 161008a56..c1213d379 100644 --- a/lib/Doctrine/Export.php +++ b/lib/Doctrine/Export.php @@ -920,7 +920,7 @@ class Doctrine_Export extends Doctrine_Connection_Module $sql .= implode(', ', array_map(array($this->conn, 'quoteIdentifier'), $definition['local'])) . ') REFERENCES ' - . $definition['foreignTable'] . '(' + . $this->conn->quoteIdentifier($definition['foreignTable']) . '(' . implode(', ', array_map(array($this->conn, 'quoteIdentifier'), $definition['foreign'])) . ')'; return $sql; diff --git a/lib/Doctrine/Export/Mysql.php b/lib/Doctrine/Export/Mysql.php index 5b0672728..680738d50 100644 --- a/lib/Doctrine/Export/Mysql.php +++ b/lib/Doctrine/Export/Mysql.php @@ -134,7 +134,9 @@ class Doctrine_Export_Mysql extends Doctrine_Export // attach all primary keys if (isset($options['primary']) && ! empty($options['primary'])) { - $queryFields .= ', PRIMARY KEY(' . implode(', ', array_values($options['primary'])) . ')'; + $keyColumns = array_values($options['primary']); + $keyColumns = array_map(array($this->conn, 'quoteIdentifier'), $keyColumns); + $queryFields .= ', PRIMARY KEY(' . implode(', ', $keyColumns) . ')'; } $query = 'CREATE TABLE ' . $this->conn->quoteIdentifier($name, true) . ' (' . $queryFields . ')'; @@ -470,6 +472,7 @@ class Doctrine_Export_Mysql extends Doctrine_Export { $table = $table; $name = $this->conn->getIndexName($name); + $name = $this->conn->quoteIdentifier($name); $type = ''; if (isset($definition['type'])) { switch (strtolower($definition['type'])) { @@ -523,7 +526,7 @@ class Doctrine_Export_Mysql extends Doctrine_Export */ public function getIndexDeclaration($name, array $definition) { - $name = $this->conn->quoteIdentifier($name); + $name = $this->conn->formatter->getIndexName($name); $type = ''; if (isset($definition['type'])) { switch (strtolower($definition['type'])) { @@ -543,7 +546,7 @@ class Doctrine_Export_Mysql extends Doctrine_Export $definition['fields'] = array($definition['fields']); } - $query = $type . 'INDEX ' . $this->conn->formatter->getIndexName($name); + $query = $type . 'INDEX ' . $this->conn->quoteIdentifier($name); $query .= ' (' . $this->getIndexFieldDeclarationList($definition['fields']) . ')'; @@ -561,7 +564,7 @@ class Doctrine_Export_Mysql extends Doctrine_Export $declFields = array(); foreach ($fields as $fieldName => $field) { - $fieldString = $fieldName; + $fieldString = $this->conn->quoteIdentifier($fieldName); if (is_array($field)) { if (isset($field['length'])) { @@ -580,7 +583,7 @@ class Doctrine_Export_Mysql extends Doctrine_Export } } } else { - $fieldString = $field; + $fieldString = $this->conn->quoteIdentifier($field); } $declFields[] = $fieldString; } diff --git a/lib/Doctrine/Export/Pgsql.php b/lib/Doctrine/Export/Pgsql.php index a6a59efba..ef8328c17 100644 --- a/lib/Doctrine/Export/Pgsql.php +++ b/lib/Doctrine/Export/Pgsql.php @@ -305,7 +305,9 @@ class Doctrine_Export_Pgsql extends Doctrine_Export if (isset($options['primary']) && ! empty($options['primary'])) { - $queryFields .= ', PRIMARY KEY(' . implode(', ', array_values($options['primary'])) . ')'; + $keyColumns = array_values($options['primary']); + $keyColumns = array_map(array($this->conn, 'quoteIdentifier'), $keyColumns); + $queryFields .= ', PRIMARY KEY(' . implode(', ', $keyColumns) . ')'; } $query = 'CREATE TABLE ' . $this->conn->quoteIdentifier($name, true) . ' (' . $queryFields . ')'; diff --git a/lib/Doctrine/Export/Sqlite.php b/lib/Doctrine/Export/Sqlite.php index 02e0e35ab..3d908cf55 100644 --- a/lib/Doctrine/Export/Sqlite.php +++ b/lib/Doctrine/Export/Sqlite.php @@ -87,8 +87,8 @@ class Doctrine_Export_Sqlite extends Doctrine_Export */ public function createIndexSql($table, $name, array $definition) { - $table = $this->conn->quoteIdentifier($table, true); $name = $this->conn->formatter->getIndexName($name); + $name = $this->conn->quoteIdentifier($name); $query = 'CREATE INDEX ' . $name . ' ON ' . $table; $query .= ' (' . $this->getIndexFieldDeclarationList($definition['fields']) . ')'; @@ -106,7 +106,7 @@ class Doctrine_Export_Sqlite extends Doctrine_Export $declFields = array(); foreach ($fields as $fieldName => $field) { - $fieldString = $fieldName; + $fieldString = $this->conn->quoteIdentifier($fieldName); if (is_array($field)) { if (isset($field['sorting'])) { @@ -121,7 +121,7 @@ class Doctrine_Export_Sqlite extends Doctrine_Export } } } else { - $fieldString = $field; + $fieldString = $this->conn->quoteIdentifier($field); } $declFields[] = $fieldString; } @@ -176,7 +176,9 @@ class Doctrine_Export_Sqlite extends Doctrine_Export } if ( ! $autoinc && isset($options['primary']) && ! empty($options['primary'])) { - $queryFields.= ', PRIMARY KEY('.implode(', ', array_values($options['primary'])).')'; + $keyColumns = array_values($options['primary']); + $keyColumns = array_map(array($this->conn, 'quoteIdentifier'), $keyColumns); + $queryFields.= ', PRIMARY KEY('.implode(', ', $keyColumns).')'; } $name = $this->conn->quoteIdentifier($name, true); @@ -406,4 +408,4 @@ class Doctrine_Export_Sqlite extends Doctrine_Export return 'ALTER TABLE ' . $name . ' ' . $query; } -} \ No newline at end of file +} diff --git a/tests/Export/MysqlTestCase.php b/tests/Export/MysqlTestCase.php index 5583bf959..50a643886 100644 --- a/tests/Export/MysqlTestCase.php +++ b/tests/Export/MysqlTestCase.php @@ -189,6 +189,51 @@ class Doctrine_Export_Mysql_TestCase extends Doctrine_UnitTestCase $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)'); } + public function testForeignKeyIdentifierQuoting() + { + $this->conn->setAttribute(Doctrine::ATTR_QUOTE_IDENTIFIER, true); + + $name = 'mytable'; + + $fields = array('id' => array('type' => 'boolean', 'primary' => true), + 'foreignKey' => array('type' => 'integer') + ); + $options = array('type' => 'INNODB', + 'foreignKeys' => array(array('local' => 'foreignKey', + 'foreign' => 'id', + 'foreignTable' => 'sometable')) + ); + + + $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[1], 'ALTER TABLE `mytable` ADD CONSTRAINT FOREIGN KEY (`foreignKey`) REFERENCES `sometable`(`id`)'); + + $this->conn->setAttribute(Doctrine::ATTR_QUOTE_IDENTIFIER, false); + } + public function testIndexIdentifierQuoting() + { + $this->conn->setAttribute(Doctrine::ATTR_QUOTE_IDENTIFIER, true); + + $fields = array('id' => array('type' => 'integer', 'unsigned' => 1, 'autoincrement' => true, 'unique' => true), + 'name' => array('type' => 'string', 'length' => 4), + ); + + $options = array('primary' => array('id'), + 'indexes' => array('myindex' => array('fields' => array('id', 'name'))) + ); + + $this->export->createTable('sometable', $fields, $options); + + //this was the old line, but it looks like the table is created first + //and then the index so i replaced it with the ones below + //$this->assertEqual($var, 'CREATE TABLE sometable (id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(4), INDEX myindex (id, name))'); + + $this->assertEqual($this->adapter->pop(), 'CREATE TABLE `sometable` (`id` INT UNSIGNED AUTO_INCREMENT, `name` VARCHAR(4), INDEX `myindex_idx` (`id`, `name`), PRIMARY KEY(`id`)) ENGINE = INNODB'); + + $this->conn->setAttribute(Doctrine::ATTR_QUOTE_IDENTIFIER, false); + } public function testCreateTableDoesNotAutoAddIndexesWhenIndexForFkFieldAlreadyExists() { $name = 'mytable'; diff --git a/tests/Export/PgsqlTestCase.php b/tests/Export/PgsqlTestCase.php index b1d4d21c1..dbaf37fc3 100644 --- a/tests/Export/PgsqlTestCase.php +++ b/tests/Export/PgsqlTestCase.php @@ -54,6 +54,52 @@ class Doctrine_Export_Pgsql_TestCase extends Doctrine_UnitTestCase $this->assertEqual($this->adapter->pop(), 'CREATE TABLE mytable (id SERIAL, PRIMARY KEY(id))'); } + public function testQuoteAutoincPks() + { + $this->conn->setAttribute(Doctrine::ATTR_QUOTE_IDENTIFIER, true); + + $name = 'mytable'; + + $fields = array('id' => array('type' => 'integer', 'unsigned' => 1, 'autoincrement' => true)); + $options = array('primary' => array('id')); + + $this->export->createTable($name, $fields, $options); + + $this->assertEqual($this->adapter->pop(), 'CREATE TABLE "mytable" ("id" SERIAL, PRIMARY KEY("id"))'); + + $name = 'mytable'; + $fields = array('name' => array('type' => 'char', 'length' => 10), + 'type' => array('type' => 'integer', 'length' => 3)); + + $options = array('primary' => array('name', 'type')); + $this->export->createTable($name, $fields, $options); + + $this->assertEqual($this->adapter->pop(), 'CREATE TABLE "mytable" ("name" CHAR(10), "type" INT, PRIMARY KEY("name", "type"))'); + + $this->conn->setAttribute(Doctrine::ATTR_QUOTE_IDENTIFIER, false); + } + public function testForeignKeyIdentifierQuoting() + { + $this->conn->setAttribute(Doctrine::ATTR_QUOTE_IDENTIFIER, true); + + $name = 'mytable'; + + $fields = array('id' => array('type' => 'boolean', 'primary' => true), + 'foreignKey' => array('type' => 'integer') + ); + $options = array('foreignKeys' => array(array('local' => 'foreignKey', + 'foreign' => 'id', + 'foreignTable' => 'sometable')) + ); + + + $sql = $this->export->createTableSql($name, $fields, $options); + + $this->assertEqual($sql[0], 'CREATE TABLE "mytable" ("id" BOOLEAN, "foreignKey" INT)'); + $this->assertEqual($sql[1], 'ALTER TABLE "mytable" ADD FOREIGN KEY ("foreignKey") REFERENCES "sometable"("id") NOT DEFERRABLE INITIALLY IMMEDIATE'); + + $this->conn->setAttribute(Doctrine::ATTR_QUOTE_IDENTIFIER, false); + } public function testCreateTableSupportsDefaultAttribute() { $name = 'mytable'; diff --git a/tests/Export/SqliteTestCase.php b/tests/Export/SqliteTestCase.php index 9daf3522b..1851868e4 100644 --- a/tests/Export/SqliteTestCase.php +++ b/tests/Export/SqliteTestCase.php @@ -103,6 +103,45 @@ class Doctrine_Export_Sqlite_TestCase extends Doctrine_UnitTestCase $this->assertEqual($this->adapter->pop(), 'CREATE TABLE sometable (id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(4))'); } + public function testIdentifierQuoting() + { + $this->conn->setAttribute(Doctrine::ATTR_QUOTE_IDENTIFIER, true); + + $fields = array('id' => array('type' => 'integer', 'unsigned' => 1, 'autoincrement' => true, 'unique' => true), + 'name' => array('type' => 'string', 'length' => 4), + ); + + $options = array('primary' => array('id'), + 'indexes' => array('myindex' => array('fields' => array('id', 'name'))) + ); + + $this->export->createTable('sometable', $fields, $options); + + //this was the old line, but it looks like the table is created first + //and then the index so i replaced it with the ones below + //$this->assertEqual($var, 'CREATE TABLE sometable (id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(4), INDEX myindex (id, name))'); + + $this->assertEqual($this->adapter->pop(),'CREATE INDEX "myindex_idx" ON "sometable" ("id", "name")'); + + $this->assertEqual($this->adapter->pop(), 'CREATE TABLE "sometable" ("id" INTEGER PRIMARY KEY AUTOINCREMENT, "name" VARCHAR(4))'); + + $this->conn->setAttribute(Doctrine::ATTR_QUOTE_IDENTIFIER, false); + } + public function testQuoteMultiplePks() + { + $this->conn->setAttribute(Doctrine::ATTR_QUOTE_IDENTIFIER, true); + + $name = 'mytable'; + $fields = array('name' => array('type' => 'char', 'length' => 10), + 'type' => array('type' => 'integer', 'length' => 3)); + + $options = array('primary' => array('name', 'type')); + $this->export->createTable($name, $fields, $options); + + $this->assertEqual($this->adapter->pop(), 'CREATE TABLE "mytable" ("name" CHAR(10), "type" INTEGER, PRIMARY KEY("name", "type"))'); + + $this->conn->setAttribute(Doctrine::ATTR_QUOTE_IDENTIFIER, false); + } public function testUnknownIndexSortingAttributeThrowsException() { $fields = array('id' => array('sorting' => 'ASC'),