Browse Source

Added a new JsonType class.

Postgres and Mysql already support json data, so it make sense to
support this in cake as well
Jose Lorenzo Rodriguez 10 years ago
parent
commit
cd5fee1a85
3 changed files with 182 additions and 0 deletions
  1. 1 0
      src/Database/Type.php
  2. 81 0
      src/Database/Type/JsonType.php
  3. 100 0
      tests/TestCase/Database/Type/JsonTypeTest.php

+ 1 - 0
src/Database/Type.php

@@ -40,6 +40,7 @@ class Type
         'decimal' => 'Cake\Database\Type\FloatType',
         'float' => 'Cake\Database\Type\FloatType',
         'integer' => 'Cake\Database\Type\IntegerType',
+        'json' => 'Cake\Database\Type\JsonType',
         'string' => 'Cake\Database\Type\StringType',
         'text' => 'Cake\Database\Type\StringType',
         'time' => 'Cake\Database\Type\TimeType',

+ 81 - 0
src/Database/Type/JsonType.php

@@ -0,0 +1,81 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * For full copyright and license information, please see the LICENSE.txt
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link          http://cakephp.org CakePHP(tm) Project
+ * @since         3.3.0
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
+ */
+namespace Cake\Database\Type;
+
+use Cake\Database\Driver;
+use Cake\Database\Type;
+use InvalidArgumentException;
+use JsonSerializable;
+use PDO;
+
+/**
+ * Json type converter.
+ *
+ * Use to convert json data between PHP and the database types.
+ */
+class JsonType extends Type
+{
+
+    /**
+     * Convert a value data into a json string
+     *
+     * @param mixed $value The value to convert.
+     * @param \Cake\Database\Driver $driver The driver instance to convert with.
+     * @return string|null
+     */
+    public function toDatabase($value, Driver $driver)
+    {
+        if (is_resource($value)) {
+            throw new InvalidArgumentException('Cannot convert a resource value to JSON');
+        }
+
+        return json_encode($value);
+    }
+
+    /**
+     * Convert string values to PHP strings.
+     *
+     * @param mixed $value The value to convert.
+     * @param \Cake\Database\Driver $driver The driver instance to convert with.
+     * @return string|null|array
+     */
+    public function toPHP($value, Driver $driver)
+    {
+        return json_decode($value, true);
+    }
+
+    /**
+     * Get the correct PDO binding type for string data.
+     *
+     * @param mixed $value The value being bound.
+     * @param \Cake\Database\Driver $driver The driver.
+     * @return int
+     */
+    public function toStatement($value, Driver $driver)
+    {
+        return PDO::PARAM_STR;
+    }
+
+    /**
+     * Marshalls request data into PHP strings.
+     *
+     * @param mixed $value The value to convert.
+     * @return mixed Converted value.
+     */
+    public function marshal($value)
+    {
+        return $value;
+    }
+}

+ 100 - 0
tests/TestCase/Database/Type/JsonTypeTest.php

@@ -0,0 +1,100 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * For full copyright and license information, please see the LICENSE.txt
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link          http://cakephp.org CakePHP(tm) Project
+ * @since         3.3.0
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
+ */
+namespace Cake\Test\TestCase\Database\Type;
+
+use Cake\Database\Type;
+use Cake\TestSuite\TestCase;
+use PDO;
+
+/**
+ * Test for the String type.
+ */
+class JsonTypeTest extends TestCase
+{
+
+    /**
+     * Setup
+     *
+     * @return void
+     */
+    public function setUp()
+    {
+        parent::setUp();
+        $this->type = Type::build('json');
+        $this->driver = $this->getMock('Cake\Database\Driver');
+    }
+
+    /**
+     * Test toPHP
+     *
+     * @return void
+     */
+    public function testToPHP()
+    {
+        $this->assertNull($this->type->toPHP(null, $this->driver));
+        $this->assertSame('word', $this->type->toPHP(json_encode('word'), $this->driver));
+        $this->assertSame(2.123, $this->type->toPHP(json_encode(2.123), $this->driver));
+    }
+
+    /**
+     * Test converting to database format
+     *
+     * @return void
+     */
+    public function testToDatabase()
+    {
+        $this->assertSame('null', $this->type->toDatabase(null, $this->driver));
+        $this->assertSame(json_encode('word'), $this->type->toDatabase('word', $this->driver));
+        $this->assertSame(json_encode(2.123), $this->type->toDatabase(2.123, $this->driver));
+        $this->assertSame(json_encode(['a' => 'b']), $this->type->toDatabase(['a' => 'b'], $this->driver));
+    }
+
+    /**
+     * Tests that passing an invalid value will throw an exception
+     *
+     * @expectedException InvalidArgumentException
+     * @return void
+     */
+    public function testToDatabaseInvalid()
+    {
+        $value = fopen(__FILE__, 'r');
+        $this->type->toDatabase($value, $this->driver);
+    }
+
+    /**
+     * Test marshalling
+     *
+     * @return void
+     */
+    public function testMarshal()
+    {
+        $this->assertNull($this->type->marshal(null));
+        $this->assertSame('word', $this->type->marshal('word'));
+        $this->assertSame(2.123, $this->type->marshal(2.123));
+        $this->assertSame([1, 2, 3], $this->type->marshal([1, 2, 3]));
+        $this->assertSame(['a' => 1, 2, 3], $this->type->marshal(['a' => 1, 2, 3]));
+    }
+
+    /**
+     * Test that the PDO binding type is correct.
+     *
+     * @return void
+     */
+    public function testToStatement()
+    {
+        $this->assertEquals(PDO::PARAM_STR, $this->type->toStatement('', $this->driver));
+    }
+}
+