Browse Source

Fix autoIncrement reflection in SQLServer

SQLServer was not correctly reflecting the identity-ness of a column. We
cannot get this information from INFORMATION_SCHEMA so we'll use other
SQLServer specific catalog views.
Mark Story 11 years ago
parent
commit
4912fc207d

+ 18 - 11
src/Database/Schema/SqlserverSchema.php

@@ -42,15 +42,20 @@ class SqlserverSchema extends BaseSchema
      */
     public function describeColumnSql($tableName, $config)
     {
-        $sql = "SELECT DISTINCT TABLE_SCHEMA AS [schema], COLUMN_NAME AS [name], DATA_TYPE AS [type],
-            IS_NULLABLE AS [null], COLUMN_DEFAULT AS [default],
-            CHARACTER_MAXIMUM_LENGTH AS [char_length],
-            NUMERIC_PRECISION AS [precision],
-            NUMERIC_SCALE AS [scale],
-            '' AS [comment], ORDINAL_POSITION AS [ordinal_position]
-        FROM INFORMATION_SCHEMA.COLUMNS
-        WHERE TABLE_NAME = ? AND TABLE_SCHEMA = ?
-        ORDER BY ordinal_position";
+        $sql = "SELECT DISTINCT
+            AC.name AS [name],
+            TY.name AS [type],
+            AC.max_length AS [char_length],
+            AC.precision AS [precision],
+            AC.scale AS [scale],
+            AC.is_identity AS [autoincrement],
+            AC.is_nullable AS [null],
+            OBJECT_DEFINITION(AC.default_object_id) AS [default]
+            FROM sys.[tables] T
+            INNER JOIN sys.[schemas] S ON S.[schema_id] = T.[schema_id]
+            INNER JOIN sys.[all_columns] AC ON T.[object_id] = AC.[object_id]
+            INNER JOIN sys.[types] TY ON TY.[user_type_id] = AC.[user_type_id]
+            WHERE T.[name] = ? AND S.[name] = ?";
 
         $schema = empty($config['schema']) ? static::DEFAULT_SCHEMA_NAME : $config['schema'];
         return [$sql, [$tableName, $schema]];
@@ -146,13 +151,15 @@ class SqlserverSchema extends BaseSchema
         if (!empty($row['default'])) {
             $row['default'] = trim($row['default'], '()');
         }
-
+        if (!empty($row['autoincrement'])) {
+            $field['autoIncrement'] = true;
+        }
         if ($field['type'] === 'boolean') {
             $row['default'] = (int)$row['default'];
         }
 
         $field += [
-            'null' => $row['null'] === 'YES' ? true : false,
+            'null' => $row['null'] === '1' ? true : false,
             'default' => $row['default'],
         ];
         $table->addColumn($row['name'], $field);

+ 28 - 1
tests/TestCase/Database/Schema/SqlserverSchemaTest.php

@@ -243,7 +243,7 @@ SQL;
         $field = [
             'name' => 'field',
             'type' => $type,
-            'null' => 'YES',
+            'null' => '1',
             'default' => 'Default value',
             'char_length' => $length,
             'precision' => $precision,
@@ -365,6 +365,33 @@ SQL;
     }
 
     /**
+     * Test describing a table with postgres and composite keys
+     *
+     * @return void
+     */
+    public function testDescribeTableCompositeKey()
+    {
+        $this->_needsConnection();
+        $connection = ConnectionManager::get('test');
+        $sql = <<<SQL
+CREATE TABLE schema_composite (
+    [id] INTEGER IDENTITY(1, 1),
+    [site_id] INTEGER NOT NULL,
+    [name] VARCHAR(255),
+    PRIMARY KEY([id], [site_id])
+);
+SQL;
+        $connection->execute($sql);
+        $schema = new SchemaCollection($connection);
+        $result = $schema->describe('schema_composite');
+        $connection->execute('DROP TABLE schema_composite');
+
+        $this->assertEquals(['id', 'site_id'], $result->primaryKey());
+        $this->assertNull($result->column('site_id')['autoIncrement'], 'site_id should not be autoincrement');
+        $this->assertTrue($result->column('id')['autoIncrement'], 'id should be autoincrement');
+    }
+
+    /**
      * Test that describe accepts tablenames containing `schema.table`.
      *
      * @return void