Skip to content

Commit 937fb0e

Browse files
authored
Merge pull request #8012 from MolbioUnige/issue/7906
Custom data type suggestion
2 parents 01643f8 + 3d3fd47 commit 937fb0e

File tree

1 file changed

+30
-17
lines changed

1 file changed

+30
-17
lines changed

en/orm/database-basics.rst

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -540,40 +540,39 @@ implement the following methods:
540540
* ``marshal``: Marshals flat data into PHP objects.
541541

542542
To fulfill the basic interface, extend :php:class:`Cake\\Database\\Type`.
543-
For example if we wanted to add a JSON type, we could make the following type
543+
For example if we wanted to add a PointMutation type, we could make the following type
544544
class::
545545

546-
// in src/Database/Type/JsonType.php
546+
// in src/Database/Type/PointMutationType.php
547547

548548
namespace App\Database\Type;
549549

550550
use Cake\Database\Driver;
551551
use Cake\Database\Type\BaseType;
552552
use PDO;
553553

554-
class JsonType extends BaseType
554+
class PointMutationType extends BaseType
555555
{
556556
public function toPHP(mixed $value, Driver $driver): mixed
557557
{
558558
if ($value === null) {
559559
return null;
560560
}
561561

562-
return json_decode($value, true);
563-
}
562+
return $this->pmDecode($valu
564563

565564
public function marshal(mixed $value): mixed
566565
{
567566
if (is_array($value) || $value === null) {
568567
return $value;
569568
}
570569

571-
return json_decode($value, true);
570+
return $this->pmDecode($value);
572571
}
573572

574573
public function toDatabase(mixed $value, Driver $driver): mixed
575574
{
576-
return json_encode($value);
575+
return sprintf('%d%s>%s', $value['position'], $value['from'], $value['to']);
577576
}
578577

579578
public function toStatement(mixed $value, Driver $driver): int
@@ -584,6 +583,19 @@ class::
584583

585584
return PDO::PARAM_STR;
586585
}
586+
587+
protected function pmDecode(mixed $value): mixed
588+
{
589+
if (preg_match('/^(\d+)([a-zA-Z])>([a-zA-Z])$/', $value, $matches)) {
590+
return [
591+
'position' => (int) $matches[1],
592+
'from' => $matches[2],
593+
'to' => $matches[3]
594+
];
595+
}
596+
597+
return null;
598+
}
587599
}
588600

589601
By default the ``toStatement()`` method will treat values as strings which will
@@ -597,7 +609,8 @@ the type mapping. During our application bootstrap we should do the following::
597609

598610
use Cake\Database\TypeFactory;
599611

600-
TypeFactory::map('json', \App\Database\Type\JsonType::class);
612+
TypeFactory::map('point_mutation', \App\Database\Type\PointMutationType:class);
613+
601614

602615
We then have two ways to use our datatype in our models.
603616

@@ -606,27 +619,27 @@ We then have two ways to use our datatype in our models.
606619
and define the SQL column type and reflection logic.
607620

608621
Overwriting the reflected schema with our custom type will enable CakePHP's
609-
database layer to automatically convert JSON data when creating queries. In your
610-
Table's :ref:`initialize() method <saving-complex-types>` add the
622+
database layer to automatically convert PointMutation data when creating queries. In your
623+
Table's :ref:`getSchema() method <saving-complex-types>` add the
624+
611625
following::
612626

613627
class WidgetsTable extends Table
614628
{
615629
public function initialize(array $config): void
616630
{
617-
parent::initialize($config);
631+
return parent::getSchema()->setColumnType('mutation', 'point_mutation');
618632

619-
$this->getSchema()->setColumnType('widget_prefs', 'json');
620633
}
621634
}
622635

623636
Implementing ``ColumnSchemaAwareInterface`` gives you more control over
624637
custom datatypes. This avoids overwriting schema definitions if your
625638
datatype has an unambiguous SQL column definition. For example, we could have
626-
our JSON type be used anytime a ``TEXT`` column with a specific comment is
639+
our PointMutation type be used anytime a ``TEXT`` column with a specific comment is
627640
used::
628641

629-
// in src/Database/Type/JsonType.php
642+
// in src/Database/Type/PointMutationType.php
630643

631644
namespace App\Database\Type;
632645

@@ -636,7 +649,7 @@ used::
636649
use Cake\Database\Schema\TableSchemaInterface;
637650
use PDO;
638651

639-
class JsonType extends BaseType
652+
class PointMutationType extends BaseType
640653
implements ColumnSchemaAwareInterface
641654
{
642655
// other methods from earlier
@@ -691,8 +704,8 @@ no value for the current database driver:
691704
Mapping Custom Datatypes to SQL Expressions
692705
-------------------------------------------
693706

694-
The previous example maps a custom datatype for a 'json' column type which is
695-
easily represented as a string in a SQL statement. Complex SQL data
707+
The previous example maps a custom datatype for a 'point_mutation' column type
708+
which is easily represented as a string in a SQL statement. Complex SQL data
696709
types cannot be represented as strings/integers in SQL queries. When working
697710
with these datatypes your Type class needs to implement the
698711
``Cake\Database\Type\ExpressionTypeInterface`` interface. This interface lets

0 commit comments

Comments
 (0)