Browse Source

Add support for tinytext, mediumtext and longtext

Yves P 10 years ago
parent
commit
2784faf8d4

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

@@ -116,6 +116,8 @@ class MysqlSchema extends BaseSchema
             return ['type' => 'string', 'length' => $length];
         }
         if (strpos($col, 'text') !== false) {
+            $lengthName = substr($col, 0, -4);
+            $length = isset(Table::$columnLengths[$lengthName]) ? Table::$columnLengths[$lengthName] : null;
             return ['type' => 'text', 'length' => $length];
         }
         if (strpos($col, 'blob') !== false || $col === 'binary') {
@@ -289,7 +291,6 @@ class MysqlSchema extends BaseSchema
             'binary' => ' LONGBLOB',
             'float' => ' FLOAT',
             'decimal' => ' DECIMAL',
-            'text' => ' TEXT',
             'date' => ' DATE',
             'time' => ' TIME',
             'datetime' => ' DATETIME',
@@ -298,6 +299,7 @@ class MysqlSchema extends BaseSchema
         ];
         $specialMap = [
             'string' => true,
+            'text' => true,
         ];
         if (isset($typeMap[$data['type']])) {
             $out .= $typeMap[$data['type']];
@@ -310,6 +312,19 @@ class MysqlSchema extends BaseSchema
                         $data['length'] = 255;
                     }
                     break;
+                case 'text':
+                    $isKnownLength = in_array($data['length'], Table::$columnLengths);
+                    if (empty($data['length']) || !$isKnownLength) {
+                        $out .= ' TEXT';
+                        break;
+                    }
+
+                    if ($isKnownLength) {
+                        $length = array_search($data['length'], Table::$columnLengths);
+                        $out .= ' ' . strtoupper($length) . 'TEXT';
+                    }
+
+                    break;
             }
         }
         $hasLength = ['integer', 'string'];

+ 5 - 2
src/Database/Schema/PostgresSchema.php

@@ -334,7 +334,6 @@ class PostgresSchema extends BaseSchema
             'binary' => ' BYTEA',
             'float' => ' FLOAT',
             'decimal' => ' DECIMAL',
-            'text' => ' TEXT',
             'date' => ' DATE',
             'time' => ' TIME',
             'datetime' => ' TIMESTAMP',
@@ -355,7 +354,11 @@ class PostgresSchema extends BaseSchema
             $out .= $type;
         }
 
-        if ($data['type'] === 'string') {
+        if ($data['type'] === 'text' && $data['length'] !== Table::LENGTH_TINY) {
+            $out .= ' TEXT';
+        }
+
+        if ($data['type'] === 'string' || ($data['type'] === 'text' && $data['length'] === Table::LENGTH_TINY)) {
             $isFixed = !empty($data['fixed']);
             $type = ' VARCHAR';
             if ($isFixed) {

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

@@ -245,22 +245,16 @@ class SqliteSchema extends BaseSchema
         $data = $table->column($name);
         $typeMap = [
             'uuid' => ' CHAR(36)',
-            'string' => ' VARCHAR',
-            'integer' => ' INTEGER',
             'biginteger' => ' BIGINT',
             'boolean' => ' BOOLEAN',
             'binary' => ' BLOB',
             'float' => ' FLOAT',
             'decimal' => ' DECIMAL',
-            'text' => ' TEXT',
             'date' => ' DATE',
             'time' => ' TIME',
             'datetime' => ' DATETIME',
             'timestamp' => ' TIMESTAMP',
         ];
-        if (!isset($typeMap[$data['type']])) {
-            throw new Exception(sprintf('Unknown column type for "%s"', $name));
-        }
 
         $out = $this->_driver->quoteIdentifier($name);
         $hasUnsigned = ['biginteger', 'integer', 'float', 'decimal'];
@@ -272,14 +266,30 @@ class SqliteSchema extends BaseSchema
                 $out .= ' UNSIGNED';
             }
         }
-        $out .= $typeMap[$data['type']];
 
-        $hasLength = ['integer', 'string'];
-        if (in_array($data['type'], $hasLength, true) && isset($data['length'])) {
-            if ($data['type'] !== 'integer' || [$name] !== (array)$table->primaryKey()) {
+        if (isset($typeMap[$data['type']])) {
+            $out .= $typeMap[$data['type']];
+        }
+
+        if ($data['type'] === 'text' && $data['length'] !== Table::LENGTH_TINY) {
+            $out .= ' TEXT';
+        }
+
+        if ($data['type'] === 'string' || ($data['type'] === 'text' && $data['length'] === Table::LENGTH_TINY)) {
+            $out .= ' VARCHAR';
+
+            if (isset($data['length'])) {
+                $out .= '(' . (int)$data['length'] . ')';
+            }
+        }
+
+        if ($data['type'] === 'integer') {
+            $out .= ' INTEGER';
+            if (isset($data['length']) && [$name] !== (array)$table->primaryKey()) {
                 $out .= '(' . (int)$data['length'] . ')';
             }
         }
+
         $hasPrecision = ['float', 'decimal'];
         if (in_array($data['type'], $hasPrecision, true) &&
             (isset($data['length']) || isset($data['precision']))

+ 5 - 2
src/Database/Schema/SqlserverSchema.php

@@ -305,7 +305,6 @@ class SqlserverSchema extends BaseSchema
             'binary' => ' VARBINARY(MAX)',
             'float' => ' FLOAT',
             'decimal' => ' DECIMAL',
-            'text' => ' NVARCHAR(MAX)',
             'date' => ' DATE',
             'time' => ' TIME',
             'datetime' => ' DATETIME',
@@ -324,7 +323,11 @@ class SqlserverSchema extends BaseSchema
             }
         }
 
-        if ($data['type'] === 'string') {
+        if ($data['type'] === 'text' && $data['length'] !== Table::LENGTH_TINY) {
+            $out .= ' NVARCHAR(MAX)';
+        }
+
+        if ($data['type'] === 'string' || ($data['type'] === 'text' && $data['length'] === Table::LENGTH_TINY)) {
             $type = ' NVARCHAR';
 
             if (!empty($data['fixed'])) {

+ 28 - 0
src/Database/Schema/Table.php

@@ -82,6 +82,34 @@ class Table
     protected $_temporary = false;
 
     /**
+     * Column length when using a `tiny` text column type
+     *
+     * @var int
+     */
+    const LENGTH_TINY = 255;
+
+    /**
+     * Column length when using a `medium` text column type
+     *
+     * @var int
+     */
+    const LENGTH_MEDIUM = 16777215;
+
+    /**
+     * Column length when using a `long` text column type
+     *
+     * @var int
+     */
+    const LENGTH_LONG = 4294967295;
+
+    public static $columnLengths = [
+        'tiny' => self::LENGTH_TINY,
+        'medium' => self::LENGTH_MEDIUM,
+        'long' => self::LENGTH_LONG
+    ];
+
+
+    /**
      * The valid keys that can be used in a column
      * definition.
      *

+ 5 - 3
tests/Fixture/TagsFixture.php

@@ -14,6 +14,7 @@
  */
 namespace Cake\Test\Fixture;
 
+use Cake\Database\Schema\Table;
 use Cake\TestSuite\Fixture\TestFixture;
 
 /**
@@ -31,6 +32,7 @@ class TagsFixture extends TestFixture
     public $fields = [
         'id' => ['type' => 'integer', 'null' => false],
         'name' => ['type' => 'string', 'null' => false],
+        'description' => ['type' => 'text', 'length' => Table::LENGTH_MEDIUM],
         '_constraints' => ['primary' => ['type' => 'primary', 'columns' => ['id']]]
     ];
 
@@ -40,8 +42,8 @@ class TagsFixture extends TestFixture
      * @var array
      */
     public $records = [
-        ['name' => 'tag1'],
-        ['name' => 'tag2'],
-        ['name' => 'tag3']
+        ['name' => 'tag1', 'description' => 'A big description'],
+        ['name' => 'tag2', 'description' => 'Another big description'],
+        ['name' => 'tag3', 'description' => 'Yet another one']
     ];
 }

+ 25 - 2
tests/TestCase/Database/Schema/MysqlSchemaTest.php

@@ -100,7 +100,15 @@ class MysqlSchemaTest extends TestCase
             ],
             [
                 'TINYTEXT',
-                ['type' => 'text', 'length' => null]
+                ['type' => 'text', 'length' => 255]
+            ],
+            [
+                'MEDIUMTEXT',
+                ['type' => 'text', 'length' => 16777215]
+            ],
+            [
+                'LONGTEXT',
+                ['type' => 'text', 'length' => 4294967295]
             ],
             [
                 'BLOB',
@@ -150,7 +158,7 @@ class MysqlSchemaTest extends TestCase
     }
 
     /**
-     * Test parsing MySQL column types form field description.
+     * Test parsing MySQL column types from field description.
      *
      * @dataProvider convertColumnProvider
      * @return void
@@ -466,6 +474,21 @@ SQL;
                 ['type' => 'text', 'null' => false],
                 '`body` TEXT NOT NULL'
             ],
+            [
+                'body',
+                ['type' => 'text', 'length' => Table::LENGTH_TINY, 'null' => false],
+                '`body` TINYTEXT NOT NULL'
+            ],
+            [
+                'body',
+                ['type' => 'text', 'length' => Table::LENGTH_MEDIUM, 'null' => false],
+                '`body` MEDIUMTEXT NOT NULL'
+            ],
+            [
+                'body',
+                ['type' => 'text', 'length' => Table::LENGTH_LONG, 'null' => false],
+                '`body` LONGTEXT NOT NULL'
+            ],
             // Integers
             [
                 'post_id',

+ 16 - 0
tests/TestCase/Database/Schema/PostgresSchemaTest.php

@@ -16,6 +16,7 @@ namespace Cake\Test\TestCase\Database\Schema;
 
 use Cake\Core\Configure;
 use Cake\Database\Schema\Collection as SchemaCollection;
+use Cake\Database\Schema\MysqlSchema;
 use Cake\Database\Schema\PostgresSchema;
 use Cake\Database\Schema\Table;
 use Cake\Datasource\ConnectionManager;
@@ -628,6 +629,21 @@ SQL;
                 ['type' => 'text', 'null' => false],
                 '"body" TEXT NOT NULL'
             ],
+            [
+                'body',
+                ['type' => 'text', 'length' => Table::LENGTH_TINY, 'null' => false],
+                '"body" VARCHAR(' . Table::LENGTH_TINY . ') NOT NULL'
+            ],
+            [
+                'body',
+                ['type' => 'text', 'length' => Table::LENGTH_MEDIUM, 'null' => false],
+                '"body" TEXT NOT NULL'
+            ],
+            [
+                'body',
+                ['type' => 'text', 'length' => Table::LENGTH_LONG, 'null' => false],
+                '"body" TEXT NOT NULL'
+            ],
             // Integers
             [
                 'post_id',

+ 15 - 0
tests/TestCase/Database/Schema/SqliteSchemaTest.php

@@ -454,6 +454,21 @@ SQL;
                 ['type' => 'text', 'null' => false],
                 '"body" TEXT NOT NULL'
             ],
+            [
+                'body',
+                ['type' => 'text', 'length' => Table::LENGTH_TINY, 'null' => false],
+                '"body" VARCHAR(' . Table::LENGTH_TINY . ') NOT NULL'
+            ],
+            [
+                'body',
+                ['type' => 'text', 'length' => Table::LENGTH_MEDIUM, 'null' => false],
+                '"body" TEXT NOT NULL'
+            ],
+            [
+                'body',
+                ['type' => 'text', 'length' => Table::LENGTH_LONG, 'null' => false],
+                '"body" TEXT NOT NULL'
+            ],
             // Integers
             [
                 'post_id',

+ 15 - 0
tests/TestCase/Database/Schema/SqlserverSchemaTest.php

@@ -487,6 +487,21 @@ SQL;
                 ['type' => 'text', 'null' => false],
                 '[body] NVARCHAR(MAX) NOT NULL'
             ],
+            [
+                'body',
+                ['type' => 'text', 'length' => Table::LENGTH_TINY, 'null' => false],
+                '[body] NVARCHAR(' . Table::LENGTH_TINY . ') NOT NULL'
+            ],
+            [
+                'body',
+                ['type' => 'text', 'length' => Table::LENGTH_MEDIUM, 'null' => false],
+                '[body] NVARCHAR(MAX) NOT NULL'
+            ],
+            [
+                'body',
+                ['type' => 'text', 'length' => Table::LENGTH_LONG, 'null' => false],
+                '[body] NVARCHAR(MAX) NOT NULL'
+            ],
             // Integers
             [
                 'post_id',

+ 24 - 12
tests/TestCase/ORM/QueryTest.php

@@ -569,12 +569,14 @@ class QueryTest extends TestCase
                     [
                         'id' => 1,
                         'name' => 'tag1',
-                        '_joinData' => ['article_id' => 1, 'tag_id' => 1]
+                        '_joinData' => ['article_id' => 1, 'tag_id' => 1],
+                        'description' => 'A big description'
                     ],
                     [
                         'id' => 2,
                         'name' => 'tag2',
-                        '_joinData' => ['article_id' => 1, 'tag_id' => 2]
+                        '_joinData' => ['article_id' => 1, 'tag_id' => 2],
+                        'description' => 'Another big description'
                     ]
                 ]
             ],
@@ -588,12 +590,14 @@ class QueryTest extends TestCase
                     [
                         'id' => 1,
                         'name' => 'tag1',
-                        '_joinData' => ['article_id' => 2, 'tag_id' => 1]
+                        '_joinData' => ['article_id' => 2, 'tag_id' => 1],
+                        'description' => 'A big description'
                     ],
                     [
                         'id' => 3,
                         'name' => 'tag3',
-                        '_joinData' => ['article_id' => 2, 'tag_id' => 3]
+                        '_joinData' => ['article_id' => 2, 'tag_id' => 3],
+                        'description' => 'Yet another one'
                     ]
                 ]
             ],
@@ -631,7 +635,8 @@ class QueryTest extends TestCase
                     [
                         'id' => 3,
                         'name' => 'tag3',
-                        '_joinData' => ['article_id' => 2, 'tag_id' => 3]
+                        '_joinData' => ['article_id' => 2, 'tag_id' => 3],
+                        'description' => 'Yet another one'
                     ]
                 ]
             ],
@@ -745,6 +750,7 @@ class QueryTest extends TestCase
                     'Tags' => [
                         'id' => 3,
                         'name' => 'tag3',
+                        'description' => 'Yet another one',
                     ],
                     'ArticlesTags' => ['article_id' => 2, 'tag_id' => 3]
                 ]
@@ -770,6 +776,7 @@ class QueryTest extends TestCase
                     'Tags' => [
                         'id' => 2,
                         'name' => 'tag2',
+                        'description' => 'Another big description',
                     ],
                     'ArticlesTags' => ['article_id' => 1, 'tag_id' => 2]
                 ]
@@ -806,6 +813,7 @@ class QueryTest extends TestCase
                     'tags' => [
                         'id' => 2,
                         'name' => 'tag2',
+                        'description' => 'Another big description',
                     ],
                     'articles' => [
                         'id' => 1,
@@ -815,9 +823,9 @@ class QueryTest extends TestCase
                         'published' => 'Y'
                     ],
                     'ArticlesTags' => [
-                            'article_id' => 1,
-                            'tag_id' => 2
-                        ]
+                        'article_id' => 1,
+                        'tag_id' => 2
+                    ]
                 ]
             ]
         ];
@@ -1259,14 +1267,16 @@ class QueryTest extends TestCase
         $expected = [
             'id' => 1,
             'name' => 'tag1',
-            '_joinData' => ['article_id' => 1, 'tag_id' => 1]
+            '_joinData' => ['article_id' => 1, 'tag_id' => 1],
+            'description' => 'A big description',
         ];
         $this->assertEquals($expected, $first->tags[0]->toArray());
 
         $expected = [
             'id' => 2,
             'name' => 'tag2',
-            '_joinData' => ['article_id' => 1, 'tag_id' => 2]
+            '_joinData' => ['article_id' => 1, 'tag_id' => 2],
+            'description' => 'Another big description'
         ];
         $this->assertEquals($expected, $first->tags[1]->toArray());
     }
@@ -1310,14 +1320,16 @@ class QueryTest extends TestCase
         $expected = [
             'id' => 1,
             'name' => 'tag1',
-            '_joinData' => ['article_id' => 1, 'tag_id' => 1]
+            '_joinData' => ['article_id' => 1, 'tag_id' => 1],
+            'description' => 'A big description',
         ];
         $this->assertEquals($expected, $first->tags[0]->toArray());
 
         $expected = [
             'id' => 2,
             'name' => 'tag2',
-            '_joinData' => ['article_id' => 1, 'tag_id' => 2]
+            '_joinData' => ['article_id' => 1, 'tag_id' => 2],
+            'description' => 'Another big description'
         ];
         $this->assertEquals($expected, $first->tags[1]->toArray());
     }

+ 2 - 1
tests/TestCase/ORM/TableTest.php

@@ -3869,7 +3869,8 @@ class TableTest extends TestCase
         ], $options);
 
         $newTag = new \TestApp\Model\Entity\Tag([
-            'name' => 'Foo'
+            'name' => 'Foo',
+            'description' => 'Foo desc'
         ], $source);
         $tags[] = new \TestApp\Model\Entity\Tag([
             'id' => 3