Browse Source

Fix for inconsistency for JSON type field between mysql and sqlite (#17713)

Krzysiek 1 year ago
parent
commit
529a7f76a0

+ 5 - 0
src/Database/Schema/SqliteSchemaDialect.php

@@ -141,6 +141,11 @@ class SqliteSchemaDialect extends SchemaDialect
         if (in_array($col, $datetimeTypes)) {
             return ['type' => $col, 'length' => null];
         }
+
+        if (str_contains($col, 'json') && !str_contains($col, 'jsonb')) {
+            return ['type' => TableSchemaInterface::TYPE_JSON, 'length' => null];
+        }
+
         if (in_array($col, TableSchemaInterface::GEOSPATIAL_TYPES)) {
             // TODO how can srid be preserved? It doesn't come back
             // in the output of show full columns from ...

+ 25 - 0
tests/TestCase/Database/Driver/SqliteTest.php

@@ -16,6 +16,7 @@ declare(strict_types=1);
  */
 namespace Cake\Test\TestCase\Database\Driver;
 
+use Cake\Core\Configure;
 use Cake\Database\Connection;
 use Cake\Database\Driver\Sqlite;
 use Cake\Database\DriverFeatureEnum;
@@ -220,6 +221,30 @@ class SqliteTest extends TestCase
     }
 
     /**
+     * Test of Inconsistency for JSON type field between mysql and sqlite
+     *
+     * @return void
+     */
+
+    public function testJSON(): void
+    {
+        Configure::write('ORM.mapJsonTypeForSqlite', true);
+        $connection = ConnectionManager::get('test');
+        $this->skipIf(!($connection->getDriver() instanceof Sqlite));
+        assert($connection instanceof Connection);
+
+        $connection->execute('CREATE TABLE json_test (id INTEGER PRIMARY KEY, data JSON_TEXT);');
+        $table = $this->getTableLocator()->get('json_test');
+
+        $data = ['foo' => 'bar', 'baz' => 1, 'qux' => ['a', 'b', 'c' => true]];
+        $entity = $table->newEntity(['data' => $data]);
+        $table->save($entity);
+        $result = $table->find()->first();
+        $this->assertEquals($data, $result->data);
+        Configure::write('ORM.mapJsonTypeForSqlite', false);
+    }
+
+    /**
      * Tests identifier quoting
      */
     public function testQuoteIdentifier(): void