Browse Source

Make the foreign key constraints columns references resolution DRY

Also uses the assertQuotedQuery method in the TableTest class
Yves P 10 years ago
parent
commit
0aea497e2d

+ 18 - 0
src/Database/Schema/BaseSchema.php

@@ -90,6 +90,24 @@ abstract class BaseSchema
     }
 
     /**
+     * Convert foreign key constraints references to a valid
+     * stringified list
+     *
+     * @param string|array $references The referenced columns of a foreign key constraint statement
+     * @return string
+     */
+    protected function _convertFkColumnsReference($references) {
+        if (is_string($references)) {
+            return $this->_driver->quoteIdentifier($references);
+        }
+
+        return implode(', ', array_map(
+            [$this->_driver, 'quoteIdentifier'],
+            $references
+        ));
+    }
+
+    /**
      * Generate the SQL to drop a table.
      *
      * @param \Cake\Database\Schema\Table $table Table instance

+ 1 - 10
src/Database/Schema/MysqlSchema.php

@@ -418,20 +418,11 @@ class MysqlSchema extends BaseSchema
             }
         }
         if ($data['type'] === Table::CONSTRAINT_FOREIGN) {
-            if (!is_array($data['references'][1])) {
-                $data['references'][1] = [$data['references'][1]];
-            }
-
-            $columnsReference = array_map(
-                [$this->_driver, 'quoteIdentifier'],
-                $data['references'][1]
-            );
-
             return $prefix . sprintf(
                 ' FOREIGN KEY (%s) REFERENCES %s (%s) ON UPDATE %s ON DELETE %s',
                 implode(', ', $columns),
                 $this->_driver->quoteIdentifier($data['references'][0]),
-                implode(', ', $columnsReference),
+                $this->_convertFkColumnsReference($data['references'][1]),
                 $this->_foreignOnClause($data['update']),
                 $this->_foreignOnClause($data['delete'])
             );

+ 1 - 10
src/Database/Schema/PostgresSchema.php

@@ -463,20 +463,11 @@ class PostgresSchema extends BaseSchema
             $data['columns']
         );
         if ($data['type'] === Table::CONSTRAINT_FOREIGN) {
-            if (!is_array($data['references'][1])) {
-                $data['references'][1] = [$data['references'][1]];
-            }
-
-            $columnsReference = array_map(
-                [$this->_driver, 'quoteIdentifier'],
-                $data['references'][1]
-            );
-
             return $prefix . sprintf(
                 ' FOREIGN KEY (%s) REFERENCES %s (%s) ON UPDATE %s ON DELETE %s DEFERRABLE INITIALLY IMMEDIATE',
                 implode(', ', $columns),
                 $this->_driver->quoteIdentifier($data['references'][0]),
-                implode(', ', $columnsReference),
+                $this->_convertFkColumnsReference($data['references'][1]),
                 $this->_foreignOnClause($data['update']),
                 $this->_foreignOnClause($data['delete'])
             );

+ 1 - 10
src/Database/Schema/SqliteSchema.php

@@ -332,19 +332,10 @@ class SqliteSchema extends BaseSchema
         if ($data['type'] === Table::CONSTRAINT_FOREIGN) {
             $type = 'FOREIGN KEY';
 
-            if (!is_array($data['references'][1])) {
-                $data['references'][1] = [$data['references'][1]];
-            }
-
-            $columnsReference = array_map(
-                [$this->_driver, 'quoteIdentifier'],
-                $data['references'][1]
-            );
-
             $clause = sprintf(
                 ' REFERENCES %s (%s) ON UPDATE %s ON DELETE %s',
                 $this->_driver->quoteIdentifier($data['references'][0]),
-                implode(', ', $columnsReference),
+                $this->_convertFkColumnsReference($data['references'][1]),
                 $this->_foreignOnClause($data['update']),
                 $this->_foreignOnClause($data['delete'])
             );

+ 1 - 10
src/Database/Schema/SqlserverSchema.php

@@ -415,20 +415,11 @@ class SqlserverSchema extends BaseSchema
             $data['columns']
         );
         if ($data['type'] === Table::CONSTRAINT_FOREIGN) {
-            if (!is_array($data['references'][1])) {
-                $data['references'][1] = [$data['references'][1]];
-            }
-
-            $columnsReference = array_map(
-                [$this->_driver, 'quoteIdentifier'],
-                $data['references'][1]
-            );
-
             return $prefix . sprintf(
                 ' FOREIGN KEY (%s) REFERENCES %s (%s) ON UPDATE %s ON DELETE %s',
                 implode(', ', $columns),
                 $this->_driver->quoteIdentifier($data['references'][0]),
-                implode(', ', $columnsReference),
+                $this->_convertFkColumnsReference($data['references'][1]),
                 $this->_foreignOnClause($data['update']),
                 $this->_foreignOnClause($data['delete'])
             );

+ 3 - 4
tests/TestCase/Database/Schema/TableTest.php

@@ -436,11 +436,10 @@ class TableTest extends TestCase
 
         $this->assertEquals($expected, $compositeConstraint);
 
-        $expectedSubstring = '#CONSTRAINT <product_id_fk> FOREIGN KEY \(<product_id>, <product_category>\)' .
-            ' REFERENCES <products> \(<id>, <category>\)#';
-        $expectedSubstring = str_replace(['<', '>'], ['[`"\[]', '[`"\]]'], $expectedSubstring);
+        $expectedSubstring = 'CONSTRAINT <product_id_fk> FOREIGN KEY \(<product_id>, <product_category>\)' .
+            ' REFERENCES <products> \(<id>, <category>\)';
 
-        $this->assertRegExp($expectedSubstring, $table->schema()->createSql(ConnectionManager::get('default'))[0]);
+        $this->assertQuotedQuery($expectedSubstring, $table->schema()->createSql(ConnectionManager::get('default'))[0]);
     }
 
     /**