5   Le Repository

5.1   Au sujet du Repository

Le Repository va faire le lien entre votre objet entité et votre base de données, par l’intermédiaire de l’objet Query.

Il est aussi responsable d’initialiser les Metadata qui concernent votre entité afin de savoir comment mapper votre objet en base de données.

5.2   Création des Metadata

Comme un exemple est plus parlant qu’un long discours :

use CCMBenchmark\Ting\Repository\Repository;
use CCMBenchmark\Ting\Serializer\SerializerFactoryInterface;
use CCMBenchmark\Ting\Repository\MetadataInitializer;

class SampleRepository extends Repository implements MetadataInitializer
{
    public static function initMetadata(SerializerFactoryInterface $serializerFactory, array $options = [])
    {
        $metadata = new Metadata($serializerFactory);

        $metadata->setEntity(Sample\Model\City::class);
        $metadata->setConnectionName('main');
        $metadata->setDatabase('world');
        $metadata->setTable('t_city_cit');

        $metadata
            ->addField([
                'primary'       => true,
                'autoincrement' => true,
                'fieldName'     => 'id',
                'columnName'    => 'cit_id',
                'type'          => 'int'
            ])
            ->addField([
                'fieldName'  => 'name',
                'columnName' => 'cit_name',
                'type'       => 'string'
            ])
            ->addField([
                'fieldName'  => 'capitalCity',
                'columnName' => 'capital_city',
                'type'       => 'bool',
                'getter'     => 'isCapitalCity',
                'setter'     => 'capitalCityIs'
            ]);

        return $metadata
    }
Quelques précisions :
  • fieldName correspond au nom de la propriété de votre entité
  • columnName correspond au nom de la colonne dans votre base de données
  • type correspond au type de votre variable avec comme valeurs possibles :
    • int
    • double
    • string
    • bool
    • datetime
    • json

Les types bool, datetime et json sont un peu particuliers, car il s’agit de types considérés complexes et qui acceptent donc d’être sérializés/désérializés via les options du serializer

Note

Disponible uniquement à partir de la version 3.2

  • getter permet de redéfinir le nom du getter (par defaut, le getter est getFieldName)
  • setter permet de redéfinir le nom du setter (par defaut, le setter est setFieldName)

Note

Disponible uniquement à partir de la version 3.4 avec le driver Pgsql

  • sequenceName permet de préciser le nom de la séquence à utiliser pour récupérer la valeur de l’autoincrément

5.3   Le Serializer

5.3.1   Au sujet du serializer

La serialisation est l’opération qui permet de passer d’une donnée PHP vers une donnée au format SGBD. La déserialisation est l’opération inverse.

Le serializer permet de gérer les types complexes tels que les types suivants bool, datetime et json.

Le type booléen est considéré comme un type complexe, car la façon de le stocker en base est différent selon chaque SGBD :
  • CCMBenchmark\Ting\Driver\Pgsql\Serializer\Boolean
  • CCMBenchmark\Ting\Driver\Mysqli\Serializer\Boolean

Le type datetime est considéré comme complexe car il permet de transformer un objet DateTime dans un format compréhensible pour le SGBD.

Le type json est complexe car il permet de transformer un tableau de données en chaîne de caractère compréhensible par le SGBD.

5.3.2   Configuration du serializer

Le serializer peut être configurer via la clé serializer_options

addField([
    'fieldName'          => 'tags',
    'columnName'         => 'tags_name',
    'type'               => 'json',
    'serializer_options' => [
        'unserialize' => ['assoc' => true]
    ]
]);

Je vous invite à regarder le code source de chaque Serializer pour voir les configurations possibles.

5.3.3   Ecrire un serializer

Vous pouvez écrire vos propres serializers et les injecter dans la définition du repository via la clé serializer.

Le serializer doit implémenter l’interface CCMBenchmark\Ting\Serializer\SerializeInterface et/ou CCMBenchmark\Ting\Serializer\UnserializeInterface. Si l’on souhaite implémenter les 2 interfaces, on préfèrera utiliser CCMBenchmark\Ting\Serializer\SerializerInterface

L’interface CCMBenchmark\Ting\Serializer\SerializeInterface permet de transformer une valeur en donnée stockable en base de donnée. L’interface CCMBenchmark\Ting\Serializer\UnserializeInterface permet de faire l’opération inverse.

addField([
    'fieldName'  => 'tags',
    'columnName' => 'tags_name',
    'type'       => 'json',
    'serializer' => Bouh\Awesome\Serializer::class
]);

5.4   QueryBuilder

On peut avoir besoin de chaîner des requêtes, un QueryBuilder est adapté pour ce cas. Ting le fourni via aura/sqlquery.

$repository->getQueryBuilder(Repository::QUERY_SELECT);

ou

$repository->getQueryBuilder(Repository::QUERY_INSERT);

ou

$repository->getQueryBuilder(Repository::QUERY_UPDATE);

ou

$repository->getQueryBuilder(Repository::QUERY_DELETE);

Documentation disponible sur https://github.com/auraphp/Aura.SqlQuery

5.5   Requêtes

Le Repository fournit plusieurs méthodes afin de faciliter les requêtes simples.

5.5.1   Trouver un objet par clé primaire

$repository->get(3)

5.5.2   Tous les objets

$repository->getAll()

5.5.3   Un objet d’après une ou plusieurs propriété(s) du modèle

$repository->getOneBy(['propertyName' => 'Sylvain']);

5.5.4   Une collection d’objet d’après une ou plusieurs propriété(s) du modèle

$repository->getBy(['propertyName' => 'Sylvain']);