Commit e3c5e6f1 authored by Laurent Lecluse's avatar Laurent Lecluse
Browse files

doc

parent 7437d557
Loading
Loading
Loading
Loading
Loading
+178 −13
Original line number Diff line number Diff line
# BddAdmin

Outil d'administration de bases de données Postgresql et Oracle
**L'outil déclaratif et a-versionné pour maîtriser vos schémas et données de bases de données
(Oracle & PostgreSQL).**

## Fonctionnalités principales :
- Crée une DDL à partir d'une base de données
- Met à jour les objets d'une base de données à partir d'une DDL
- Permet de générer des DIFF en SQL entre deux bases, 2 DDL ou entre une DDL et une base de données
- Permet de constituer un jeu de données pour la mise à jour des données
- Pour les opérations de migrations complexes, un système de scripts qui se lancent sur déclencheur permettant de faire les manipulations nécessaires sur les données
- Système de copie / sauvegarde / restauration de base de données
BddAdmin élimine la complexité des migrations SQL manuelles. Décrivez l'état désiré de votre base
(schéma ET données) dans des fichiers de configuration, et BddAdmin calcule et exécute automatiquement
les différences. Idéal pour les déploiements fiables, le travail en équipe et la synchronisation de données.

[Changelog ici](CHANGELOG.md)
🚀 **Fini les scripts de migration séquentiels. Adoptez la gestion par état désiré.**

## Prérequis
- PHP 8.2
- Drivers Bdd installés, en fonction du SGBD visé (OCI8, PDO, etc)
> **Pourquoi "A-Versionné" ?** Parce que vous ne versionnez plus des scripts (`V1__ajout_table.sql`), mais
> l'état final de votre base : la DDL. L'outil est **agnostique de la version précédente** et recalcule
> toujours le chemin le plus efficace pour atteindre l'état cible, garantissant résilience et réparabilité.

| Phase du Projet              | Problème avec les Migrations Standard                                                                                                                             | Ce que BddAdmin Résout                                                                                                                                    |
|:-----------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------|
| **Développement en équipe**  | Le fameux "sur ma machine ça marche". Les branches créent des conflits de schéma, le partage des évolutions est manuel.                                           | **État désiré partagé** : `git pull` + `bddadmin:update` aligne immédiatement la base de dev sur l'état du dépôt. Fin des divergences.                    |
| **Recette / Pré-production** | La base de recette dérive. On doit rejouer N migrations depuis le début, avec des risques d'échec sur des données réelles.                                        | **Synchronisation idempotente** : Un `update` recalcule et applique la diff depuis n'importe quel état, **répare** les écarts.                            |
| **Production**               | Un échec à la migration #47 laisse la base dans un état inconnu. Le rollback est souvent aussi risqué.                                                            | **Résilience & Réparation** : BddAdmin est conçu pour détecter et corriger les écarts. Relancer `update` après un échec partiel est une stratégie valide. |
| **Maintenance long terme**   | La pile de fichiers de migration (V1 à V538) devient un "dette de migration". Modifier une table créée il y a 3 ans nécessite de comprendre l'historique complet. | **Simplicité déclarative** : Vous voyez l'état *actuel* de la table dans un seul fichier. La modification est locale et sans héritage.                    |

[Documentation](doc/doc.md)
 No newline at end of file
---

## 🧠 **Public Cible**

* **Tech Leads / Architectes** qui voient la dette technique et les risques opérationnels monter.
* **DevOps / Ingénieurs de production** qui en ont marre des rollbacks de migration à 3h du matin.
* **Équipes sur des applications métier critiques** avec des cycles de vie longs (>5 ans) et des schémas complexes.
* **Éditeurs de logiciels** qui doivent déployer la même base sur des dizaines d'instances clientes différentes et
  hétérogènes.

---

## ✨ Fonctionnalités Phares

### 🏗️ **Gestion Déclarative du modèle de données (DDL)**

* **Synchro Bidirectionnelle** : Générez une DDL depuis une base existante, ou appliquez une DDL pour mettre à jour une
  base. Tout est réversible.
* **Diff Intelligent** : Calculez les différences entre deux bases, deux DDL, ou une DDL et une base. Visualisez ce qui
  va changer.
* **Support Complet** : Gère les tables, vues, séquences, index, contraintes, fonctions, procédures, packages et
  triggers.
* **Résilience en Production** : Des mécanismes avancés permettent des migrations complexes (comme l'ajout progressif d'
  une colonne `NOT NULL`)
  sans interruption de service.

### 📊 **Synchronisation Intelligente des Données**

* **Merge Automatique** : Fournissez un jeu de données préformaté. BddAdmin calcule et exécute les **INSERT, UPDATE et
  DELETE nécessaires** pour synchroniser la base.
* **Filtres & Règles Métier** : Contrôlez finement quelles données sont synchronisées grâce à un système de filtres
  configurables.
* **Historisation & Restauration** : Activez l'historisation des lignes sur une colonne dédiée et restaurez des états
  antérieurs des données en une commande.

### ⚙️ **Pour les Équipes et la Production**

* **Scripts de Migration Conditionnels** : Déclenchez automatiquement des scripts PHP personnalisés lors de changements
  spécifiques (ex: après l'ajout d'une colonne, transformer les données existantes).
* **Copie & Sauvegarde** : Dupliquez facilement des environnements (prod -> dev) ou créez des sauvegardes contextuelles.
* **Multi-SGBD** : Une seule base de code pour gérer vos bases **PostgreSQL** et **Oracle**.

---

## 🏁 Commencer en 2 Minutes

### Installation avec Composer

Utilisation du repository Unicaen requise :

1. Ajoutez ceci à la section "repositories" de votre composer.json

```json
{
    "type": "composer",
    "url" : "https://gest.unicaen.fr/packagist"
}
```

2. Ajoutez ceci à la section "require"

```json
"unicaen/bddadmin": "^1.7"
```

### Comment instancier BddAdmin

Voici un script rapide vous permettant d'instancier un nouvel objet Bdd

```php
use Unicaen\BddAdmin\Bdd;

/* Paramètres d'accès à votre BDD */
$config = [
        'driver'   => 'Postgresql', // Postgresql ou Oracle
        'host'     => '*********',  // IP ou nom DNS
        'port'     => 5432,         // port, à adapter
        'dbname'   => '*********',  // Nom de votre base de données
        'username' => '*********',  // Utilisateur
        'password' => '*********',  // Mot de passe
];

$bdd = new Bdd($config);

$bdd->setOptions([
    /* Facultatif, permet de spécifier une fois pour toutes le répertoire où sera renseignée la DDL de votre BDD */
    Bdd::OPTION_DDL_DIR => getcwd() . '/data/ddl',

    /* Facultatif, spécifie le répertoire où seront stockés vos scripts de migration si vous en avez */
    Bdd::OPTION_MIGRATION_DIR => getcwd() . '/admin/migration/',

    /* Facultatif, permet de personnaliser l'ordonnancement des colonnes dans les tables */
    Bdd::OPTION_COLUMNS_POSITIONS_FILE => getcwd() . '/data/ddl_columns_pos.php',
]);

// première requête pour tester, à personnaliser selon votre modèle de données
$data = $bdd->select('select * from annee');

var_dump($data);
```

### Premiers cas d'utilisation

#### Faire un diff depuis la DDL vers la BDD

```php

// Récupération du schéma de référence, issu du répertoire spécifié via l'option Bdd::OPTION_DDL_DIR
// note : le répertoire peut aussi être passé directement en argument de getRefDdl
$ddl = $bdd->getRefDdl();

// On fait un DIFF et on le convertit en SQL
$sql = $bdd->diff($ddl)->toScript();

// Et si on veut faire un diff avec une autre BDD, pour comparer la bdd de prod avec cette de dév:
// /** @var $bddProd \Unicaen\BddAdmin\Bdd */
// /** @var $bddDev \Unicaen\BddAdmin\Bdd */
// $sql = $bddProd->diff($bddDev)->toScript();

echo $sql;
```

#### Mise à jour d'une DDL à partir de la base de données

```php
/* Filtres éventuels pour éviter de faire figurer dans la DDL des objets d'utilité locale */
$filters = [];

// On calcule la DDL depuis la BDD
$ddl = $bdd->getDdl($filters);

// Enregistrement du schéma de référence, vers le répertoire spécifié via l'option Bdd::OPTION_DDL_DIR
// note : le répertoire peut aussi être passé directement en argument de saveToDir
$ddl->saveToDir();
```

#### Mise à jour de la base de données à partir d'une DDL

```php
// Récupération du schéma de référence, issu du répertoire spécifié via l'option Bdd::OPTION_DDL_DIR
// note : le répertoire peut aussi être passé directement en argument de getRefDdl
$ref = $bdd->getRefDdl();

// Filtre pour l'appliquer les modifications que pour la DDL et ne supprime pas les objets autres
// C'est facultatif, à activer selon contexte
$filters = $ref->makeFilters();

// On met à jour la BDD
$bdd->alter($ref, $filters);
```

---

## 📚 Documentation

- **[📖 Guide Complet](doc/doc.md)** – Tout savoir sur la configuration, les commandes et les concepts avancés.

---

## 🛡️ Prérequis

- PHP 8.2 ou supérieur (testé avec 8.3, 8.4)
- Extensions PHP pour le SGBD cible (ex: `pdo_pgsql`, `oci8`)
 No newline at end of file
+7 −8
Original line number Diff line number Diff line
@@ -25,8 +25,8 @@ Voici ses fonctionnalités :

### Depuis Laminas

BddAdmin est un module Laminas.
Il faut donc l'utiliser par ce biais.
BddAdmin propose un module pour Laminas.
Vous pouvez donc l'utiliser par ce biais.

Comme pour les autres bibliothèques Unicaen,
copier/coller les fichiers config/*.php.dist et les adapter.
@@ -34,7 +34,7 @@ copier/coller les fichiers config/*.php.dist et les adapter.
Ajouter 'Unicaen\BddAdmin', à la liste de vos mosules dans votre application.

Pour y accéder :
Un BddAwareTrait permet d'injecter ses accesseurs.
Un [BddAwareTrait](../src/BddAwareTrait.php) permet d'injecter ses accesseurs.
Dans la Factory de votre classe, ajouter :
$service->setBdd($container->get(Unicaen\BddAdmin\Bdd::class));

@@ -46,7 +46,7 @@ $service->setBdd($container->get(Unicaen\BddAdmin\Bdd::class));
Ce mode peut servir si on utilise la bibliothèque hors Laminas.
Il peut aussi servir si vous voulez accéder à une autre BDD.

Voici comment instancier un nouvel objet Bdd
Voici comment instancier un nouvel objet [Bdd](../src/Bdd.php)

```php
use Unicaen\BddAdmin\Bdd;
@@ -70,10 +70,10 @@ application.

## Utilisation des commandes standard

Les commandes ne sont disponibles que si vous utilisez BddAdmin avec son module Laminas.

BddAdmin possède une facade CLI avec des commandes Symphony accessibles.

Avec le module Laminas, elles sont accessibles si vous avez installé Laminas/Cli.

La liste est accessible via la commande

./vendor/bin/laminas list
@@ -178,4 +178,3 @@ $bdd->majSequences();

Cette opération est réalisée automatiquement lorsque vous mettez à jour le jeu de données de votre base à l'aide
du `DataUpdater`.
 No newline at end of file

doc/console/clear.md

0 → 100644
+47 −0
Original line number Diff line number Diff line
# bddadmin:clear

Vide complètement une base de données en supprimant tous ses objets.

## 📋 Description

La commande clear permet de vider l'intégralité d'une base de données cible. Elle supprime tous les objets (tables, vues, séquences, fonctions, schémas, etc.) de la base de données spécifiée dans la configuration.

    ⚠️ **Avertissement critique** : Cette opération est **destructive et irréversible**. Elle doit être utilisée avec une extrême prudence, en particulier sur les bases de données de production.

## 🎯 Cas d'utilisation typiques

- **Environnements de test et développement** : Réinitialiser une base à un état vierge avant d'exécuter des tests ou des scénarios spécifiques.

- **Nettoyage après des tests** : Effacer toutes les données et structures créées pendant des sessions de test.

- **Préparation d'une nouvelle installation** : S'assurer qu'une base est complètement vide avant d'appliquer une nouvelle DDL.

- **Scénarios CI/CD** : Dans des pipelines d'intégration continue où une base propre est nécessaire pour chaque exécution.

## 📝 Utilisation

Syntaxe de base
```bash
php bin/console bddadmin:clear
```

La commande s'appuie sur la méthode drop() qui implémente la logique de suppression en respectant l'ordre des dépendances et en gérant les spécificités de chaque SGBD (Oracle, PostgreSQL).

## Ce qui est supprimé

La méthode drop() de BddAdmin est conçue pour supprimer tous les objets de la base, dans l'ordre approprié pour respecter les dépendances :

1. Contraintes de clé étrangère
2. Tables
3. Vues
4. Séquences
5. Fonctions et procédures
6. Schémas personnalisés
7. Types personnalisés

## Bonnes pratiques

- Toujours avoir une sauvegarde avant d'utiliser clear sur une base importante.
- Utiliser en environnement contrôlé : Réservez cette commande aux environnements de développement et de test.
- Vérifier la connexion : Assurez-vous d'être connecté à la bonne base de données.
- Documenter son utilisation : Notez quand et pourquoi cette commande est utilisée dans vos processus.
 No newline at end of file
+164 −0
Original line number Diff line number Diff line
# bddadmin:copy-from

Copie la structure et les données d'une base de données source vers la base de données cible courante.

## 📋 Description

La commande copy-from permet de copier le contenu d'une base de données source (configuration définie) vers la base de
données cible actuellement configurée. Cette opération est utile pour dupliquer des environnements ou synchroniser des
bases.

    ⚠️ **Avertissement critique** : Cette opération est **destructive et irréversible**. La base de données courante sera complètement vidée. Elle doit être utilisée avec une extrême prudence, en particulier sur les bases de données de production.

## 🎯 Cas d'utilisation typiques

- **Duplication d'environnement** : Copier une base de production vers un environnement de développement ou de test

- **Initialisation** : Peupler une nouvelle base à partir d'un modèle existant

- **Synchronisation** : Mettre à jour une base avec le contenu d'une autre (avec des limitations)

## 📝 Utilisation

Syntaxe de base

```bash

php bin/console bddadmin:copy-from [source]

```

# Arguments

| Argument | Description                                              | Obligatoire |
|----------|----------------------------------------------------------|-------------|
| `source` | Nom de la connexion source définie dans la configuration | Non         |

    🔎 Si `source` n'est pas spécifié, alors la commande se bornera à lister les sources disponibles, sans rien faire d'autre.

### Exemples d'exécution

```bash

# Liste les sources disponibles (déclarées en config)

php bin/console bddadmin:copy-from

# En spécifiant directement la source

php bin/console bddadmin:copy-from production_db

```

## 🔍 Comportement détaillé

## ⚙️ Configuration requise

### Connexions multiples
Plusieurs connexions doivent être configurées :

```php
return [
    'unicaen-bddadmin' => [    
        'connection' => [
            'dev_db' => [
                'driver'   => 'Postgresql',
                'host'     => 'localhost',
                'port'     => 5432,
                'dbname'   => 'dev_db',
                'user'     => 'dev_db_user',
                'password' => 'secret',
            ],
            
            'staging_db' => [
                'driver'   => 'Postgresql',
                'host'     => 'localhost',
                'port'     => 5432,
                'dbname'   => 'staging_db',
                'user'     => 'staging_db_user',
                'password' => 'secret',
            ],
            'test_db' => [
               'driver'   => 'Postgresql',
                'host'     => 'localhost',
                'port'     => 5432,
                'dbname'   => 'test_db',
                'user'     => 'test_db_user',
                'password' => 'secret',
            ],
        ],    
        'current_connection' => 'dev_db',
    ];
];
```

### Processus d'exécution

1. **Vérification des connexions disponibles** : La commande récupère la liste des bases de données configurées (autres que la cible).
2. **Sélection de la source** :
    - Si l'argument source est fourni, il est utilisé directement
    - Sinon, une liste des sources disponibles est présentée à l'utilisateur
3. **Exécution de la copie** : Appel de la méthode copy($source) sur l'objet Bdd.

### Mécanisme de copie

La méthode copy() implémentée dans la classe Bdd gère :

* La copie de la structure (DDL) si nécessaire
* La copie des données selon des règles prédéfinies
* La préservation des dépendances et contraintes

    
## ⚙️ Prérequis de configuration
Fichier de configuration des connexions

Pour que la commande fonctionne, plusieurs connexions doivent être définies dans le fichier de configuration :
yaml

# unicaen-bddadmin/connection.yml (ou équivalent)

connections:
main_db:           # Connexion principale (cible par défaut)
driver: Postgresql
host: localhost
dbname: application
user: app_user
password: secret

backup_db:         # Source possible
driver: Postgresql
host: backup-server
dbname: backup
user: backup_user
password: backup_secret

test_db:           # Autre source possible
driver: Postgresql
host: 127.0.0.1
dbname: test_application
user: test_user
password: test_secret

## ⚠️ Limitations et considérations

### Compatibilité des SGBD

La copie entre différents types de SGBD (ex: PostgreSQL → Oracle) est impossible.

### Performances

Pour les bases volumineuses, l'opération peut prendre du temps. Il est recommandé de :
* Vérifier l'espace disque disponible
* Privilégier les heures creuses pour les bases de production
* Surveiller la consommation mémoire

### Copie depuis une base de production

**⚠️ AVERTISSEMENT - COPIE DE BASES ACTIVES**

La commande `copy-from` copie les données d'une base source **qui peut être en cours de modification**. 

Pour garantir l'intégrité des données copiées :

1.  **Privilégiez les sources inertes** : Utilisez une sauvegarde (`backup`) ou une réplique dédiée comme source, jamais la base de production principale.
2.  **Planifiez une fenêtre de maintenance** : Si vous devez absolument copier depuis la production, faites-le pendant une période de faible activité ou de maintenance planifiée.
 No newline at end of file

doc/console/copy-to.md

0 → 100644
+102 −0
Original line number Diff line number Diff line
# bddadmin:copy-to

Copie la structure et les données de la base de données **courante** (source) vers une base de données **destination** configurée.

## 📋 Description

La commande `copy-to` est l'opération inverse de `copy-from`. Elle copie le contenu de la base de données **actuellement configurée comme cible** vers une autre base de données configurée (la destination). C'est utile pour déployer un état connu vers un autre environnement.

## 🎯 Cas d'utilisation typiques

- **Déploiement** : Propager l'état d'une base de développement vers une base de recette ou pré-production
- **Sauvegarde vers un secondaire** : Créer une copie de la base principale sur un serveur secondaire
- **Migration de schéma** : Tester l'application d'une nouvelle DDL sur une copie avant de l'appliquer en production
- **Création d'environnements de test** : Dupliquer l'état actuel vers une base dédiée aux tests

## 📝 Utilisation

### Syntaxe de base
```bash
php bin/console bddadmin:copy-to [destination]
```

### Arguments
| Argument | Description | Obligatoire |
|----------|-------------|-------------|
| `destination` | Nom de la connexion de destination définie dans la configuration | Non |

    🔎 Si `destination` n'est pas spécifié, alors la commande se bornera à lister les destinations disponibles, sans rien faire d'autre.

### Exemples d'exécution
```bash
# Avec sélection interactive de la destination
php bin/console bddadmin:copy-to

# En spécifiant directement la destination
php bin/console bddadmin:copy-to recette_db

# Vers un environnement de backup
php bin/console bddadmin:copy-to backup_server
```

## 🔍 Comportement détaillé

### Processus d'exécution
1. **Vérification des connexions disponibles** : Récupère la liste des bases de données disponibles.
2. **Sélection de la destination** :
    - Si l'argument `destination` est fourni, il est utilisé directement
    - Sinon, une liste des destinations potentielles est présentée à l'utilisateur
3. **Exécution de la copie** : Appel de la méthode `copyTo($destination)` sur l'objet `Bdd`.

## ⚙️ Configuration requise

### Connexions multiples
Plusieurs connexions doivent être configurées :

```php
return [
    'unicaen-bddadmin' => [    
        'connection' => [
            'dev_db' => [
                'driver'   => 'Postgresql',
                'host'     => 'localhost',
                'port'     => 5432,
                'dbname'   => 'dev_db',
                'user'     => 'dev_db_user',
                'password' => 'secret',
            ],
            
            'staging_db' => [
                'driver'   => 'Postgresql',
                'host'     => 'localhost',
                'port'     => 5432,
                'dbname'   => 'staging_db',
                'user'     => 'staging_db_user',
                'password' => 'secret',
            ],
            'test_db' => [
               'driver'   => 'Postgresql',
                'host'     => 'localhost',
                'port'     => 5432,
                'dbname'   => 'test_db',
                'user'     => 'test_db_user',
                'password' => 'secret',
            ],
        ],    
        'current_connection' => 'dev_db',
    ];
];
```

## ⚠️ Avertissements importants

### Écrasement de données

**La copie écrase totalement la base de destination.**: la destination sera complètement vidée avant la copie.

### Cohérence transactionnelle
Comme pour `copy-from`, si la base **source** (celle courante) est en cours de modification pendant la copie, des incohérences peuvent apparaître dans la destination.

### Compatibilité
- Les SGBD source et destination doivent être de même type (PostgreSQL → PostgreSQL)
- Les versions doivent être compatibles
 No newline at end of file
Loading