Commit 58b04271 authored by Bertrand Gauthier's avatar Bertrand Gauthier
Browse files

Doc pour développeur : ajout du support d'une autre plateforme de bdd

parent 01246fca
Loading
Loading
Loading
Loading
+194 −0
Original line number Diff line number Diff line
@@ -527,3 +527,197 @@ Exemple de CRON appliqué à l'application Zebu.
# Du lundi au vendredi, entre 6h00 et 19h45, toutes les 15 minutes
*/15 6-19 * * 1-5   root    /usr/bin/php /var/www/zebu-back/public/index.php run import --all 1> /tmp/zebu-cron.log 2>&1
```




Ajouter le support d'une autre plateforme de base de données (pour développeur)
-------------------------------------------------------------------------------

Imaginons que l'on veuille ajouter la possibilité d'importer/synchroniser vers la plateforme de base de données
destination MySQL.

- Ajouter dans le fichier `config/module.config.php` la config permettant d'associer la bonne classe de "code generator"
  à chaque classe de plateforme de base de données MySQL connue de Doctrine :

```php
return [
    'import' => [
        'code_generators' => [
            \Doctrine\DBAL\Platforms\MySqlPlatform::class   => \UnicaenDbImport\CodeGenerator\MySQL\CodeGenerator::class,
            \Doctrine\DBAL\Platforms\MySQL57Platform::class => \UnicaenDbImport\CodeGenerator\MySQL\CodeGenerator::class,
            \Doctrine\DBAL\Platforms\MySQL80Platform::class => \UnicaenDbImport\CodeGenerator\MySQL\CodeGenerator::class,
        ],
        //...
    ],
    //...
];
```

- Créer un répertoire `src/UnicaenDbImport/CodeGenerator/MySQL` dans lequel on va créer les fichiers/classes 
  suivants :

```
.
├── CodeGeneratorFactory.php
├── CodeGenerator.php
├── Helper
│   ├── DiffViewHelper.php
│   ├── SynchroLogHelper.php
│   ├── TableHelper.php
│   └── TableValidationHelper.php
└── MySQLCommonsTrait.php
```

- La classe `CodeGenerator` doit *obligatoirement* :
  - hériter de la classe abstraite `\UnicaenDbImport\CodeGenerator\CodeGenerator` ;
  - instancier dans le constructeur ses propres versions MySQL des "helper" de génération de code (`MySQLTableHelper`, etc.)

Exemple :

```php
namespace UnicaenDbImport\CodeGenerator\MySQL;

use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Platforms\PostgreSqlPlatform;
use UnicaenDbImport\CodeGenerator\MySQL\Helper\DiffViewHelper as MySQLDiffViewHelper;
use UnicaenDbImport\CodeGenerator\MySQL\Helper\SynchroLogHelper as MySQLSynchroLogHelper;
use UnicaenDbImport\CodeGenerator\MySQL\Helper\TableValidationHelper as MySQLTableValidationHelper;
use UnicaenDbImport\CodeGenerator\MySQL\Helper\TableHelper as MySQLTableHelper;

/**
 * Version MySQL.
 */
class CodeGenerator extends \UnicaenDbImport\CodeGenerator\CodeGenerator
{
    /**
     * @var PostgreSqlPlatform
     */
    protected $platform;

    /**
     * @var MySQLTableHelper
     */
    protected $tableHelper;

    /**
     * @var MySQLTableValidationHelper
     */
    protected $tableValidationHelper;

    /**
     * @var MySQLDiffViewHelper
     */
    protected $diffViewHelper;

    /**
     * @var MySQLSynchroLogHelper
     */
    protected $synchroLogHelper;

    /**
     * CodeGenerator constructor.
     *
     * @param AbstractPlatform $platform
     */
    public function __construct(AbstractPlatform $platform)
    {
        parent::__construct($platform);

        $this->tableHelper = new MySQLTableHelper($this->platform);
        $this->tableValidationHelper = new MySQLTableValidationHelper($this->platform);
        $this->diffViewHelper = new MySQLDiffViewHelper($this->platform);
        $this->synchroLogHelper = new MySQLSynchroLogHelper($this->platform);
    }
    
    //...
```

- Sa factory `CodeGeneratorFactory` doit *obligatoirement* :
  - injecter dans le "code generator" une instance de la plateforme correspondant à la base de données destination.
  
    *NB: l'instance de la plateforme de base de données injectée ici est utilisée pour générer du SQL compris par 
    la base de données destination. Si aucune classe de platforme ne correspond exactement à la version de la base 
    de données destination, prenez la générique (`MySqlPlatform` dans notre exemple)*

Exemple :

```php
namespace UnicaenDbImport\CodeGenerator\MySQL;

use Doctrine\DBAL\Platforms\MySqlPlatform;
use Interop\Container\ContainerInterface;
use UnicaenDbImport\CodeGenerator\MySQL\CodeGenerator as MySQLCodeGenerator;

class CodeGeneratorFactory
{
    /**
     * @param ContainerInterface $container
     * @return CodeGenerator
     */
    public function __invoke(ContainerInterface $container)
    {
        return new MySQLCodeGenerator(new MySqlPlatform());
    }
}
```


- La classe de "helper" de génération de code `Helper\DiffViewHelper` doit :
  - *obligatoirement* hériter de la classe abstraite `\UnicaenDbImport\CodeGenerator\Helper\DiffViewHelper` ;
  - *obligatoirement* définir les méthodes nom implémentée par la classe mère ;
  - *si besoin* redéfinir les méthodes de la classe mère qui ne génèrerait pas du code SQL valide pour la
    plateforme de base de données concernée.

Exemple :

```php
namespace UnicaenDbImport\CodeGenerator\MySQL\Helper;

use Doctrine\DBAL\Platforms\MySqlPlatform;
use UnicaenDbImport\Domain\Operation;

class DiffViewHelper extends \UnicaenDbImport\CodeGenerator\Helper\DiffViewHelper
{
    /**
     * @var MySqlPlatform
     */
    protected $platform;

    /**
     * {@inheritDoc}
     */
    protected function generateViewDeletionSQLSnippet($destinationTable)
    {
        $name = $this->generateViewName($destinationTable);

        return "DROP VIEW IF EXISTS $name";
    }
  
    //...
```


- Mêmes principes pour les autres classes `Helper\SynchroLogHelper`, `Helper\TableHelper`, `Helper\TableValidationHelper`.


- Du fait que les classes `CodeGenerator` et `*Helper` hérite déjà chacune d'une classe, un trait `MySQLCommonsTrait` 
  peut être utile pour partager des des éléments de génération de SQL utilisables dans toutes ces classes.
  
Exemple pour la plateforme PostgreSQL :

```php
namespace UnicaenDbImport\CodeGenerator\PostgreSQL;

trait PostgreSQLCommonsTrait
{
    /**
     * @param string $argument
     * @return string
     */
    protected function getQuoteLiteralFunctionCallSQLSnippet($argument)
    {
        return 'quote_literal(' . $argument . ')';
    }
}
```