badge Dotclear 2.36

Avant la version 2.36 de Dotclear, l'accès à la base de données se faisait par l'appel App::con(); mais d'un point de vu technique cet appel passait par une fonction intermediaire directement dans la pile de services du Container principal, fonctionnel mais pas vraiment joli et surtout trop strict et rigide. C'est pourquoi la version 2.36 de Dotclear introduit un nouveau service du core nommé db() qui fait le lien entre Dotclear et les drivers de base de données. De ce fait, l'appel qui se faisait par App::con() devient App::db()->con(), plus long et donc moins sexy, mais cela va permettre de travailler et d'améliorer les drivers de base de données beaucoup plus facilement.

//App::con()->openCursor('xyz');
App::db()->con()->openCursor('xyz);

Bien entendu l'écriture App::con() est dépréciée mais reste fonctionnelle encore pour quelques siècles.

Ce changement a permis dès la version 2.36 de proposer d'autres drivers de base de données et d'améliorer le processus d'installation.

Le nouveau service App::db()

Le coeur de l'application Dotclear embarque donc un nouveau service qui va permettre de faire le lien entre les drivers de base de données et le reste de Dotclear.

Il est identifié comme suit dans le container :

  • Identifiant du service : Dotclear\Core\DatabaseInterface
  • Classe par défaut : Dotclear\Core\Database
  • Methode du service : App::db()

Son interface montre ses méthodes :

  • App::db()->con() : l'accès à la base de données
  • App::db()->newCon() : Une instance isolé de l'accès à une base de données
  • App::db()->structure() : l'accès à la gestion de structure de base de données
  • App::db()->combo() : liste des drivers utilisables (sert dans le process d'installation Dotclear)
interface DatabaseInterface
{
    /**
     * Get dabatase connection handler instance.
     *
     * This connection instance uses parameters from config service.
     */
    public function con(): ConnectionInterface;

    /**
     * Get new dabatase connection handler instance.
     *
     * @param   string  $driver         Driver name
     * @param   string  $host           Database hostname
     * @param   string  $database       Database name
     * @param   string  $user           User ID
     * @param   string  $password       Password
     * @param   bool    $persistent     Persistent connection
     * @param   string  $prefix         Database tables prefix
     */
    public function newCon(
        string $driver, 
        string $host, 
        string $database, 
        string $user = '', 
        string $password = '', 
        bool $persistent = false, 
        string $prefix = ''
    ): ConnectionInterface;

    /**
     * Get database structure handler.
     *
     * The handler uses current connexion.
     * Each call to this method MUST return a new instance.
     *
     * @return  Structure   The database structure handler
     */
    public function structure(): Structure;

    /**
     * Get combo of available database drivers.
     *
     * @return  array<string, string>   The drivers name/driver pairs
     */
    public function combo(): array;
}

Cette classe est récente et va surement évoluer dans les versions à venir.

Le gestionnaire de connexion App::db()->con()

Une fois le driver choisi et inscrit dans le fichier de configuration de Dotclear, ses méthodes sont accessibles depuis l'application dans App::db()->con(). 
Un driver est généralement constitué d'une classe principale qui étend une classe d'abstraction qui étend elle même une interface. Le driver fournit également une classe de gestion de Schema. Toutes ces classes sont disponibles à divers endroits de Dotclear :

  • Les classes d'abstraction sont dans Dotclear\Database,
  • Les interfaces dans Dotclear\Interface\Database
  • Les drivers dans Dotclear\Schema\Database
  • Les drivers sont ajoutés à un container dédié
  • Les drivers vérifient l'installation avant d'être proposés

Une nouvelle méthode fait sont appartition dans le gestionnaire de connexion (driver), afin de tester que les conditions requises à son utilisation sont présentes. Sa définition est visible dans l'interface :

/**
 * Check driver requirements.
 *
 * This method MUST throw a DatabaseException if driver can not be used.
 * This method does NOT say a SGBD is installed but only PHP supports it.
 *
 * @since   2.36
 *
 * @throws  \Dotclear\Exception\DatabaseException   if condition does not meet driver requirements
 */
public static function precondition(): void;

Les drivers PDO

PDO est une extension de PHP signifiant PHP Data Objects, c'est une interface d'abstraction de l'accès à des bases de données, en d'autre termes cela doit simplifier l'accès à differents types de base de données depuis une application comme Dotclear. Jusqu'à la version 2.36 Dotclear n'utilisait PDO que pour la connexion à des bases de donnée Sqlite, depuis la version 2.36 il est possible de se connecter à des bases Mysql et PostgreSql à travers les drivers PDO. Les drivers de Dotclear utilisant PDO ne sont pour l'instant que des passerelles de connexion, toutes les fonctionnalités de PDO ne sont pas exploitées, Dotclear ayant déjà son propre système de préparation de requêtes.

Par défaut sur les sytèmes Linux, PHP embarque l'extension PDO avec le pilote pour Sqlite, si ce n'est pas le cas, le site de PHP fournira un peu d'aide à l'installation plus complète de PDO.

Le cas Sqlite

Le driver Sqlite de Dotclear était déjà basé sur PDO, il a simplement été renommé pour correspondre aux autres drivers. Il n'y a rien besoin de modifier, Dotclear se charge de comprendre que si vous avez définie le driver à "sqlite" cela veut dire qu'il faut utiliser "pdosqlite". 

Les drivers livrés avec Dotclear

  • mysqli : Mysql avec les fonctions mysqli_* de PHP
  • mysqlimb4 : Idem avec le support utf8-mb4
  • pgsql : PostgreSql avec les classes PgSql de PHP
  • pdosqlite : Sqlite sous PDO
  • pdomysql : Mysql sous PDO
  • pdomysqlmb4 : Mysql sous PDO avec support utf8-mb4
  • pdopgsql : PostgreSql sous PDO

Lors de l'installation de Dotclear tous les drivers ayant un support dans la version installée de PHP seront proposés pour définir la connexion à la base de données.

Utiliser un driver PDO sur une installation existante

Si votre système embarque les composants PDO pour votre base de données, il est possible de passer sur les drivers PDO simplement en mettant à jour le fichier config.php, il faut remplacer la définiton de DC_DBDRIVER par le nouveau driver. Et l'inverse est également vrai. Voici les equivalents :

  • mysqli <=> pdomysql
  • mysqlimb4 <=> pdomysqlmb4
  • sqlite <=> pdosqlite
  • pgsql <=> pdopgsql
// define('DC_DBDRIVER', 'mysqli');
define('DC_DBDRIVER', 'pdomysql');

Auncune recommandation ici, rien ne vous oblige aujourd'hui à changer, ce ne sont que des drivers qui permettent le lien entre Dotclear et votre base de données et ils sont tous maintenus pour le moment.

Créer un driver

Pour l'exemple on va prendre un driver utilisant PDO. L'extension PDO de PHP n'est pas magique, chaque type de base de données à ses propres lois et chaque type est diffèrent. Néanmoins Dotclear propose un classe d'abstraction pour simplifier la création d'un driver de base de données utilisant PDO. Par exemple, si vous souhaiter commencer un driver pour MsSql voici ce à quoi ça pourrait ressembler.

On ajoute notre service au container des drivers de base de données et on crée notre classe de service :

<php

namespace /MySpace/PdoMsSql;

use Dotclear\Database\AbstractPdoHandler;
use Dotclear\Helper\Container\Container;
use Dotclear\Helper\Conttainer\Factories;

Factories::addService('database', 'pdomssql', PdoMsSql::class);

class PdoMsSql extends AbstractPdoHandler
{
    public const HANDLER_NAME   = 'MsSql (PDO)';
    public const HANDLER_DRIVER = 'pdomssql';
    public const HANDLER_SYNTAX = 'mssql';
    public const HANDLER_PDO    = 'sqlsrv';

    // ...
}

Il faut ensuite modifier toutes les methodes qui demandent un ajustement par rapport au language MsSql et lui adjoindre un classe de Schema. Bon courage.

 

Il y aurait beaucoup à dire sur cette partie mais ce serait bien trop long. Les très rares personnes qui souhaiteraient créer leur propre driver de base de données sont sans aucun doute assez callées pour comprendre le code de Dotclear.