1698 lines
		
	
	
		
			57 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1698 lines
		
	
	
		
			57 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
#!/bin/bash
 | 
						|
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
 | 
						|
source "$(dirname -- "$0")/lib/ulib/ulib" || exit 1
 | 
						|
urequire DEFAULTS install
 | 
						|
 | 
						|
function display_help() {
 | 
						|
    uecho "$scriptname: gérer les mises à jour sur une base de données
 | 
						|
 | 
						|
Les mises à jours sont dans un répertoire UPDATEDIR, qui contient un répertoire
 | 
						|
pour chaque base de données à gérer. Ces répertoires sont des DATABASEDIR. Les
 | 
						|
fichiers sql peuvent être placés dans le répertoire UPDATEDIR pour les mises à
 | 
						|
jour administratives, ou dans DATABASEDIR pour les mises à jour de la base de
 | 
						|
données.
 | 
						|
 | 
						|
Les fichiers sql peuvent contenir dans les premières lignes du fichier un tag
 | 
						|
@sqlmig sous forme de commentaire. On peut avoir:
 | 
						|
-- @sqlmig drop
 | 
						|
    identifie une suite de requêtes à exécuter pour supprimer la base de données
 | 
						|
    et recommencer à zéro
 | 
						|
-- @sqlmig create
 | 
						|
    identifie une suite de requêtes à exécuter pour créer la base de données.
 | 
						|
-- @sqlmig admin
 | 
						|
    identifie une mise à jour administrative. Les fichiers situés dans UPADTEDIR
 | 
						|
    sont automatiquement considérés comme des mises à jour administratives même
 | 
						|
    en l'absence de ce tag.
 | 
						|
 | 
						|
Les mises à jour administratives sont exécutées avec les paramètres du fichier
 | 
						|
my.cnf (resp. ora.conf) et sont typiquement utilisées pour créer les comptes
 | 
						|
utilisateurs pour la connexion à la base de données et leur attribuer des droits
 | 
						|
d'accès. Ces mises à jour sont exécutées sans sélectionner une base de données
 | 
						|
en particulier.
 | 
						|
 | 
						|
Les mises à jour utilisateurs sont exécutées avec les paramètres du fichier
 | 
						|
my.cnf (resp. ora.conf) augmenté du fichier my-DBNAME.cnf (res. ora-DBNAME.conf)
 | 
						|
Elles sont exécutées avec la base de données concernée sélectionnée.
 | 
						|
 | 
						|
Il y a deux modes d'exécution: prod ou devel. En mode prod, la suppression de
 | 
						|
base de données est interdite. De plus, tous les fichiers de mise à jour de la
 | 
						|
forme *.devel.sql sont ignorés. Cela permet de fignoler une mise à jour sans
 | 
						|
risquer de l'exécuter en production.
 | 
						|
 | 
						|
Les fichiers de la forme maint-*.sql sont ignorés sauf s'ils sont explicitement
 | 
						|
sélectionnés avec l'option -f ce qui permet de suivre les opérations de
 | 
						|
maintenance faites sur la base de données.
 | 
						|
 | 
						|
USAGE
 | 
						|
    $scriptname [options]
 | 
						|
 | 
						|
OPTIONS
 | 
						|
    -g, --admin-defaults-file ADMINDEFAULTS
 | 
						|
        Spécifier un fichier de configuration à utiliser pour se connecter à la
 | 
						|
        base de données pour les opérations de maintenance comme la création ou
 | 
						|
        la suppression de la base de données.
 | 
						|
        * Dans le mode MySQL, ce fichier est chargé en plus du fichier par
 | 
						|
          défaut my.cnf
 | 
						|
        * Dans le mode Oracle, ce fichier est chargé en plus du fichier par
 | 
						|
          défaut ora.conf.
 | 
						|
    -C, --defaults-file USERDEFAULTS
 | 
						|
        Spécifier un fichier de configuration à utiliser pour se connecter à la
 | 
						|
        base de données pour les opérations de mise à jour.
 | 
						|
        * Dans le mode MySQL, ce fichier est chargé en plus du fichier par
 | 
						|
          défaut my-DATABASE.cnf
 | 
						|
        * Dans le mode Oracle, ce fichier est chargé en plus du fichier par
 | 
						|
          défaut ora-DATABASE.conf.
 | 
						|
    -u, --user USER
 | 
						|
    -p, --password PASSWORD
 | 
						|
    -h, --host HOST
 | 
						|
    --port PORT
 | 
						|
    --socket SOCKET
 | 
						|
    --character-set CHARSET
 | 
						|
    -s, --oracle-sid ORACLE_SID
 | 
						|
    --nls-lang NLS_LANG
 | 
						|
        Spécifier les valeurs pour la connexion à la base de données. Les
 | 
						|
        options --host, --port et --socket ne sont valides que pour MySQL. Ces
 | 
						|
        valeurs remplacent les valeurs par défaut chargées depuis my.cnf
 | 
						|
        Les options --sid et --nls-lang ne sont valides que pour Oracle. Ces
 | 
						|
        valeurs remplacent les valeurs par défaut chargées depuis ora.conf
 | 
						|
    --suffix SUFFIX
 | 
						|
        Lors de la connexion à la base de données, toujours ajouter le suffixe
 | 
						|
        spécifié au nom de la base de données. Cette valeur peut être spécifiée
 | 
						|
        dans la section [sqlmig] du fichier my.cnf ou avec la variable SUFFIX
 | 
						|
        pour ora.conf
 | 
						|
    --csv2sql
 | 
						|
        Convertir les fichiers CSV en SQL. C'est la valeur par défaut. Ce
 | 
						|
        paramètre peut être spécifié dans my.cnf sous la forme
 | 
						|
            [sqlmig]
 | 
						|
            csv2sql=1
 | 
						|
        ou dans ora.conf
 | 
						|
            CSV2SQL=1
 | 
						|
        Pour le moment, cette conversion n'est supportée que pour MySQL. Tous
 | 
						|
        les fichiers de la forme [NUM]TABLE[-data].csv sont transformés en une
 | 
						|
        suite d'insertion dans la table TABLE. Une variante insère les données
 | 
						|
        dans la table après l'avoir vidée avec 'truncate table'. Les fichiers
 | 
						|
        doivent être de la forme [NUM]TABLE-data_truncate.csv
 | 
						|
    --csv-null VALUE
 | 
						|
        Lors de la conversion des fichiers .csv en .sql, considérer que VALUE
 | 
						|
        représente la valeur NULL. Par défaut, utiliser la chaine vide
 | 
						|
    --csv-null-empty
 | 
						|
    --csv-null-mysql
 | 
						|
    --csv-null-upper
 | 
						|
        Aliases pour --csv-null '', --csv-null '\\N' et --csv-null NULL respectivement
 | 
						|
    --no-csv2sql
 | 
						|
        Ne pas convertir les fichiers CSV en SQL. Ce paramètre peut être
 | 
						|
        spécifié dans my.cnf sous la forme
 | 
						|
            [sqlmig]
 | 
						|
            csv2sql=0
 | 
						|
        ou dans ora.conf
 | 
						|
            CSV2SQL=0
 | 
						|
    --load-data DEFAULT|LOCAL|SERVER
 | 
						|
        Si l'option --no-csv2sql est activée, spécifier le type de chargement
 | 
						|
        effectué pour les fichiers CSV.
 | 
						|
        * Avec LOCAL (la valeur par défaut), la directive 'load data local' est
 | 
						|
          utilisée. Cependant les erreurs éventuelles sont ignorées parce que le
 | 
						|
          serveur n'a pas de moyen pour arrêter la transmission des informations
 | 
						|
          par le client.
 | 
						|
        * Avec SERVER, la directive 'load data' est utilisée. Les erreurs
 | 
						|
          éventuelles sont affichées et arrêtent l'importation des données. Par
 | 
						|
          contre, le fichier doit être accessible par le serveur MySQL puisque
 | 
						|
          les données sont chargées directement par le serveur.
 | 
						|
          NB: avec MariaDB sur systemd, l'accès à /home, /root et /run/user est
 | 
						|
          désactivé par défaut. Pour pouvoir utiliser ce mode avec des fichiers
 | 
						|
          de l'utilisateur, il faut lancer ces commandes:
 | 
						|
              [ \$(id -u) == 0 ] && sudo= || sudo=sudo
 | 
						|
              \$sudo mkdir -p /etc/systemd/system/mariadb.service.d
 | 
						|
              \$sudo tee /etc/systemd/system/mariadb.service.d/dontprotecthome.conf <<<\$'[Service]\nProtectHome=false'
 | 
						|
              \$sudo systemctl daemon-reload
 | 
						|
        * Avec DEFAULT, utiliser SERVER si on communique avec le serveur MySQL
 | 
						|
          local (c'est à dire si host n'est pas spécifié ou vaut 127.*, ::1 ou
 | 
						|
          localhost). Sinon, utiliser LOCAL
 | 
						|
    --profile PROFILE
 | 
						|
    -P, --prod
 | 
						|
    -T, --test
 | 
						|
        Activer le profil spécifié. Les options -P et -T sont des aliases pour
 | 
						|
        les options --profile prod et --profile test respectivement.
 | 
						|
        Quand un profil est activé, les fichiers de configuration par défaut
 | 
						|
        deviennent respectivement \$PROFILE-my.cnf et \$PROFILE-ora.conf au lieu
 | 
						|
        de my.cnf et ora.conf. De plus, ces fichiers sont aussi recherchés dans
 | 
						|
        le répertoire /etc/sqlmig, en fonction du mode: en mode production, on
 | 
						|
        cherche d'abord dans /etc/sqlmig. En mode développement, on cherche
 | 
						|
        d'abord dans le répertoire local.
 | 
						|
 | 
						|
    --mysql
 | 
						|
    --oracle
 | 
						|
        Spécifier le type de base de données à gérer. Par défaut, on gère une
 | 
						|
        base de type mysql.
 | 
						|
        Avec le type oracle, il faut adapter la lecture de cette documentation:
 | 
						|
        à chaque fois que l'on parle de base de données, il s'agit en réalité de
 | 
						|
        gérer un utilisateur. La connexion à la base de données proprement dite
 | 
						|
        est configurée dans le fichier ora.conf
 | 
						|
    -0, --init
 | 
						|
        Créer les fichiers initiaux pour gérer une base de données. Cette option
 | 
						|
        est utilisée pour le développement
 | 
						|
    -e, --export DESTUPDATEDIR
 | 
						|
        Exporter les définitions de bases de données et mises à jour du
 | 
						|
        répertoire courant vers le répertoire DESTUPDATEDIR
 | 
						|
    -c, --connect
 | 
						|
        Se connecter avec le client natif (mysql ou sqlplus) sur la base de
 | 
						|
        données courante.
 | 
						|
    -r, --restore-test
 | 
						|
        Restaurer une sauvegarde d'une base de production sur la test. Cette
 | 
						|
        option n'est (actuellement) supportée que pour MySQL.
 | 
						|
        L'argument attendu est un fichier de sauvegarde DATABASE.sql[.gz]
 | 
						|
        effectué avec la commande
 | 
						|
            mysqldump --databases --add-drop-database DATABASE
 | 
						|
        Dans le fichier spécifié, on remplace toutes les occurences de DATABASE
 | 
						|
        par DATABASE_test, ensuite on lance (re)création de la base de données
 | 
						|
            mysql <DATABASE_test.sql
 | 
						|
    --update-all
 | 
						|
        Mettre à jour la base de données. C'est l'option par défaut
 | 
						|
    -t, --updatedir UPDATEDIR
 | 
						|
        Spécifier le répertoire qui contient les répertoires de mises à jour
 | 
						|
        pour chaque base de données.
 | 
						|
    -d, --databasedir DATABASEDIR
 | 
						|
        Spécifier le répertoire qui contient les mises à jour à appliquer pour
 | 
						|
        une base de données spécifique. Le nom de la base de données à gérer est
 | 
						|
        déterminé à partir du nom du répertoire. Si cette option n'est pas
 | 
						|
        spécifiée, tous les répertoires de base de données de UPDATEDIR sont
 | 
						|
        considérés.
 | 
						|
    -b, --database DATABASE
 | 
						|
        Spécifier le nom de la base de données. En principe le nom de la base de
 | 
						|
        données est calculé à partir du nom du répertoire DATABASEDIR. Cette
 | 
						|
        option peut être utilisée par exemple pour créer une base de test à
 | 
						|
        partir des définitions d'une base de prod.
 | 
						|
        Notez que le suffixe spécifié avec l'option --suffix est toujours
 | 
						|
        rajouté au nom de la base de données.
 | 
						|
    -f, --update-one UPDATES...
 | 
						|
        Forcer l'application des mises à jour spécifiées. Ne pas mettre à jour
 | 
						|
        l'état des mises à jour installées.
 | 
						|
        Important: Avec cette option, tout se passe comme si les seuls fichiers
 | 
						|
        existant sont ceux spécifiés. Par exemple, quel que soit l'ordre dans
 | 
						|
        lequel les fichiers sont spécifiés, ils sont évalués dans l'ordre
 | 
						|
        alphanumérique et sont ignorés s'ils n'ont pas l'extension .sql
 | 
						|
 | 
						|
    -n, --fake
 | 
						|
        Ne pas faire les mises à jour, afficher simplement ce qui serait fait
 | 
						|
    --force, --continue-on-error
 | 
						|
        Ne pas s'arrêter en cas d'erreur de mise à jour
 | 
						|
    --no-data-csv
 | 
						|
        Ne pas procéder à la conversion des fichiers CSV en SQL
 | 
						|
    --force-data-csv
 | 
						|
        Forcer la conversion des fichiers CSV en SQL. Par défaut, la conversion
 | 
						|
        n'est faite que si le fichier csv est plus récent que le fichier sql
 | 
						|
        correspondant.
 | 
						|
    --devel-mode
 | 
						|
        Activer le mode développement. Ce mode est automatiquement activé si
 | 
						|
        l'utilisateur courant n'est pas root. La suppression des bases de
 | 
						|
        données n'est autorisée qu'en mode développement
 | 
						|
    -Z, --recreate
 | 
						|
        Supprimer la base de données puis la recréer et appliquer les mises à
 | 
						|
        jour.
 | 
						|
    --drop-only
 | 
						|
        Supprimer la base de données uniquement. Ne pas la recréer.
 | 
						|
    --create-only
 | 
						|
        Créer la base de données uniquement. Ne pas appliquer les mises à jour"
 | 
						|
}
 | 
						|
 | 
						|
function mconf_get() {
 | 
						|
    local cnf="$1" section="$2" name="$3"
 | 
						|
    awkrun <"$cnf" section="$section" name="$name" '
 | 
						|
    BEGIN { in_section = 0 }
 | 
						|
    !in_section && $0 == "[" section "]" { in_section = 1; next }
 | 
						|
    in_section && $0 == "[" section "]" { in_section = 0; next }
 | 
						|
    in_section && $0 ~ "^" name " *=" {
 | 
						|
        gsub(/^[^=]*= */, "")
 | 
						|
        print
 | 
						|
        exit
 | 
						|
    }
 | 
						|
    '
 | 
						|
}
 | 
						|
 | 
						|
function __check_devel_dir() {
 | 
						|
    # $1 = P (le préfixe)
 | 
						|
    # parentdir et cwd doivent être définis. initialiser le cas échéant la
 | 
						|
    # variable updatedir
 | 
						|
    local updatedir dbdir
 | 
						|
    if [ "${parentdir%/$1}" != "$parentdir" ]; then
 | 
						|
        # On est dans un répertoire de la forme P/$1/DB, autosélectioner P/$1
 | 
						|
        upvar updatedir "$parentdir"
 | 
						|
        upvar dbdir "$cwd"
 | 
						|
        return 0
 | 
						|
    elif [ "${cwd%/$1}" != "$cwd" ]; then
 | 
						|
        # On est dans un répertoire de la forme P/$1, autosélectioner P/$1
 | 
						|
        upvar updatedir "$cwd"
 | 
						|
        return 0
 | 
						|
    elif [ -d "$cwd/$1" ]; then
 | 
						|
        # On est dans un répertoire P tel que P/$1 existe, autosélectioner P/$1
 | 
						|
        upvar updatedir "$cwd/$1"
 | 
						|
        return 0
 | 
						|
    fi
 | 
						|
    return 1
 | 
						|
}
 | 
						|
function __check_mysql_prod_dir() {
 | 
						|
    # parentdir et cwd doivent être définis
 | 
						|
    local dir updatedir dbdir
 | 
						|
    if [ "${parentdir%/updates}" != "$parentdir" ]; then
 | 
						|
        # Si on est dans un répertoire de la forme P/updates/DB, alors
 | 
						|
        # sélectioner P/updates si P contient le marqueur .mysqld-update
 | 
						|
        dir="$parentdir"
 | 
						|
        dbdir="$cwd"
 | 
						|
    elif [ -d "$cwd/updates" ]; then
 | 
						|
        # Si on est dans un répertoire P tel que P/updates existe, alors
 | 
						|
        # sélectioner P/updates si P contient le marqueur .mysqld-update
 | 
						|
        dir="$cwd/updates"
 | 
						|
    fi
 | 
						|
    if [ -n "$dir" -a -f "$(dirname -- "$dir")/.mysqld-update" ]; then
 | 
						|
        upvar updatedir "$dir"
 | 
						|
        [ -n "$dbdir" ] && upvar dbdir "$dbdir"
 | 
						|
        return 0
 | 
						|
    fi
 | 
						|
    return 1
 | 
						|
}
 | 
						|
 | 
						|
function find_mysqldupdatedir() {
 | 
						|
    # en commençant à partir du répertoire $1 qui vaut par défaut le répertoire
 | 
						|
    # courant, chercher un répertoire contenant le fichier témoin .mysqld-update
 | 
						|
    local dir="$1" origdir
 | 
						|
    [ -n "$dir" ] || dir="$(pwd)"
 | 
						|
    setx dir=abspath "$dir"
 | 
						|
    origdir="$dir"
 | 
						|
 | 
						|
    while true; do
 | 
						|
        if [ -f "$dir/.mysqld-update" ]; then
 | 
						|
            echo "$dir"
 | 
						|
            return 0
 | 
						|
        fi
 | 
						|
        if [ -z "$dir" -o "$dir" == / -o "$dir" == "$HOME" ]; then
 | 
						|
            echo "$origdir"
 | 
						|
            return 1
 | 
						|
        fi
 | 
						|
        setx dir=dirname -- "$dir"
 | 
						|
    done
 | 
						|
}
 | 
						|
function check_mysqldupdatedir() {
 | 
						|
    local exportdir="$1"
 | 
						|
    [ -f "$exportdir/.mysqld-update" ] || die "$(ppath "$exportdir"): n'est pas un répertoire mysqld-update"
 | 
						|
}
 | 
						|
 | 
						|
function have_tag() {
 | 
						|
    # tester si le fichier $2 a le tag "@sqlmig $1"
 | 
						|
    <"$2" awk '{print; if ($0 == "") exit}' | quietgrep '^--  *@sqlmig  *'"$1"' *$'
 | 
						|
}
 | 
						|
 | 
						|
function abort_on_error() {
 | 
						|
    [ -z "$force" ] && die "$@"
 | 
						|
}
 | 
						|
 | 
						|
function ensure_dbtype() {
 | 
						|
    local dir="$1" type="$2"
 | 
						|
    if [ "$type" == auto ]; then
 | 
						|
        if [ -f "$dir/my.cnf" ]; then
 | 
						|
            dbtype=mysql
 | 
						|
        elif [ -f "$dir/ora.conf" ]; then
 | 
						|
            dbtype=oracle
 | 
						|
        else
 | 
						|
            die "Vous devez spécifier le type --mysql ou --oracle"
 | 
						|
        fi
 | 
						|
    else
 | 
						|
        dbtype="$type"
 | 
						|
    fi
 | 
						|
}
 | 
						|
function ensure_dbmode() {
 | 
						|
    local dbtype="$1" mode="$2"
 | 
						|
    if [ "$mode" == auto ]; then
 | 
						|
        local profile_mode
 | 
						|
        if [ -n "$profile" ]; then
 | 
						|
            profile_mode="${profile}_PROFILE_MODE"
 | 
						|
            profile_mode="${!profile_mode}"
 | 
						|
        fi
 | 
						|
        if [ -n "$profile_mode" ]; then
 | 
						|
            dbmode="$profile_mode"
 | 
						|
        elif [ "$dbtype" == mysql ]; then
 | 
						|
            is_root && dbmode=prod || dbmode=devel
 | 
						|
        else
 | 
						|
            dbmode=prod
 | 
						|
        fi
 | 
						|
    else
 | 
						|
        dbmode="$mode"
 | 
						|
    fi
 | 
						|
}
 | 
						|
 | 
						|
function set_dbdirs() {
 | 
						|
    if [ -n "$dbdir" ]; then
 | 
						|
        dbdirs=("$dbdir")
 | 
						|
    elif [ -z "$updatedir" ]; then
 | 
						|
        array_lsfiles files . "*.sql"
 | 
						|
        if [ ${#files[*]} -gt 0 ]; then
 | 
						|
            enote "Autosélection répertoire courant"
 | 
						|
            dbdir="$cwd"
 | 
						|
            dbdirs=("$dbdir")
 | 
						|
        else
 | 
						|
            die "Vous devez spécifier l'option -b"
 | 
						|
        fi
 | 
						|
    elif [ -n "$dbname" ]; then
 | 
						|
        dbdirs=("$updatedir/$dbname")
 | 
						|
    else
 | 
						|
        array_lsdirs dbdirs "$updatedir"
 | 
						|
    fi
 | 
						|
 | 
						|
    if [ -n "$dbname" -a ${#dbdirs[*]} -gt 1 ]; then
 | 
						|
        die "Avec l'option -n, une seule base de données doit être spécifiée"
 | 
						|
    fi
 | 
						|
}
 | 
						|
 | 
						|
function fix_csv2sql() {
 | 
						|
    if [ -z "$csv2sql" ]; then
 | 
						|
        # valeur par défaut
 | 
						|
        csv2sql=1
 | 
						|
    elif is_yes "$csv2sql"; then
 | 
						|
        csv2sql=1
 | 
						|
    elif is_no "$csv2sql"; then
 | 
						|
        csv2sql=0
 | 
						|
    fi
 | 
						|
}
 | 
						|
function fix_csv_null() {
 | 
						|
    # si csv_null a une valeur vide, c'est déjà la valeur par défaut
 | 
						|
    case "$csv_null" in
 | 
						|
    empty) csv_null=;;
 | 
						|
    mysql) csv_null='\N';;
 | 
						|
    upper) csv_null=NULL;;
 | 
						|
    esac
 | 
						|
}
 | 
						|
function fix_load_data() {
 | 
						|
    if [ -z "$load_data" ]; then
 | 
						|
        # valeur par défaut
 | 
						|
        load_data=local
 | 
						|
    else
 | 
						|
        case "${load_data,,}" in
 | 
						|
        default|d*) load_data=default;;
 | 
						|
        local|l*) load_data=local;;
 | 
						|
        server|s*) load_data=server;;
 | 
						|
        esac
 | 
						|
    fi
 | 
						|
    if [ "$load_data" == default ]; then
 | 
						|
        case "$host" in
 | 
						|
        ""|localhost|127.*|::1) load_data=server;;
 | 
						|
        *) load_data=local;;
 | 
						|
        esac
 | 
						|
    fi
 | 
						|
}
 | 
						|
 | 
						|
function get_csvinfo() {
 | 
						|
    # afficher les informations sur un fichier csv: nom de la table, et s'il
 | 
						|
    # faut faire un truncate
 | 
						|
    local csvname="$(basename -- "$1")"
 | 
						|
    local script='{
 | 
						|
  truncate = ($0 ~ /-data_truncate(.devel)?.csv$/)? "1": ""
 | 
						|
  sub(/^.*\//, "")
 | 
						|
  sub(/^(([A-Z][-.A-Z0-9]*[0-9]-?)|([0-9][-.0-9]*-?))/, "")
 | 
						|
  sub(/\.csv$/, "")
 | 
						|
  sub(/\.devel$/, "")
 | 
						|
  sub(/-data(_[a-z]+*)?$/, "")
 | 
						|
  print "truncate=" truncate
 | 
						|
  gsub(/'\''/, "'\'\\\\\'\''")
 | 
						|
  print "table='\''" $0 "'\''"
 | 
						|
}'
 | 
						|
    awk "$script" <<<"$csvname"
 | 
						|
}
 | 
						|
 | 
						|
################################################################################
 | 
						|
# MySQL
 | 
						|
 | 
						|
function get_mysql_admindb() { echo "sqlmig_admin_db_"; }
 | 
						|
function get_mysql_admintb() { echo "sqlmig_updates_"; }
 | 
						|
function get_mysql_usertb() { echo "${1}_updates_"; }
 | 
						|
 | 
						|
function mysql_ve() {
 | 
						|
    #local r; set -x #DEBUG
 | 
						|
    mysql "${@:3}" ${2:+-D "$2"} ${1:+-e "$1"}
 | 
						|
    #r=$?; set +x; return $r #DEBUG
 | 
						|
}
 | 
						|
function mysql_user_ve() {
 | 
						|
    mysql_ve "$1" "$dbname" "${userargs[@]}" "${mysqlargs[@]}" "${@:2}"
 | 
						|
}
 | 
						|
function mysql_user_qe() {
 | 
						|
    if show_debug; then mysql_user_ve "$@"
 | 
						|
    elif show_verbose; then mysql_user_ve "$@" >/dev/null
 | 
						|
    else mysql_user_ve "$@" >&/dev/null
 | 
						|
    fi
 | 
						|
}
 | 
						|
function mysql_admin_ve() {
 | 
						|
    mysql_ve "$1" "$2" "${adminargs[@]}" "${mysqlargs[@]}" "${@:3}"
 | 
						|
}
 | 
						|
function mysql_admin_qe() {
 | 
						|
    if show_debug; then mysql_admin_ve "$@"
 | 
						|
    elif show_verbose; then mysql_admin_ve "$@" >/dev/null
 | 
						|
    else mysql_admin_ve "$@" >&/dev/null
 | 
						|
    fi
 | 
						|
}
 | 
						|
function mysql_tbconf() {
 | 
						|
    [ -n "$fake" ] && return
 | 
						|
 | 
						|
    # s'assurer que la table des mises à jour existe
 | 
						|
    local dbname="$1" tb="$2"
 | 
						|
 | 
						|
    if [ -z "$dbname" ]; then
 | 
						|
        # admin
 | 
						|
        setx dbname=get_mysql_admindb
 | 
						|
        if ! mysql_admin_qe "select 1" "$dbname"; then
 | 
						|
            mysql_admin_qe "create database $dbname"
 | 
						|
        fi
 | 
						|
        [ -n "$tb" ] || setx tb=get_mysql_admintb "$dbname"
 | 
						|
        if ! mysql_admin_qe "select count(*) from $tb" "$dbname"; then
 | 
						|
            mysql_admin_qe "create table $tb (
 | 
						|
 name varchar(128) not null primary key
 | 
						|
,tem_done int(1)
 | 
						|
,date_start datetime
 | 
						|
,date_done datetime
 | 
						|
)" "$dbname" || die "create table $tb"
 | 
						|
        fi
 | 
						|
    else
 | 
						|
        # user
 | 
						|
        [ -n "$tb" ] || setx tb=get_mysql_usertb "$dbname"
 | 
						|
        if ! mysql_user_qe "select count(*) from $tb"; then
 | 
						|
            mysql_user_qe "create table $tb (
 | 
						|
 name varchar(128) not null primary key
 | 
						|
,tem_done int(1)
 | 
						|
,date_start datetime
 | 
						|
,date_done datetime
 | 
						|
)" || die "create table $tb"
 | 
						|
        fi
 | 
						|
    fi
 | 
						|
}
 | 
						|
function mysql_get_done() {
 | 
						|
    local name="$1" dbname="$2" tb="$3"
 | 
						|
    if [ -z "$dbname" ]; then
 | 
						|
        # admin
 | 
						|
        setx dbname=get_mysql_admindb
 | 
						|
        [ -n "$tb" ] || setx tb=get_mysql_admintb "$dbname"
 | 
						|
        mysql_admin_ve "select name from $tb where name = '$name' and tem_done = 1" "$dbname" -N
 | 
						|
    else
 | 
						|
        # user
 | 
						|
        [ -n "$tb" ] || setx tb=get_mysql_usertb "$dbname"
 | 
						|
        mysql_user_ve "select name from $tb where name = '$name' and tem_done = 1" -N
 | 
						|
    fi
 | 
						|
}
 | 
						|
function mysql_before_update() {
 | 
						|
    local dbname="$1" tb="$2"
 | 
						|
    if [ -z "$dbname" ]; then
 | 
						|
        # admin
 | 
						|
        setx dbname=get_mysql_admindb
 | 
						|
        [ -n "$tb" ] || setx tb=get_mysql_admintb "$dbname"
 | 
						|
        mysql_admin_ve "insert into $tb (name, tem_done, date_start) values ('$name', 0, sysdate()) on duplicate key update tem_done = 0, date_start = sysdate(), date_done = null" "$dbname"
 | 
						|
    else
 | 
						|
        # user
 | 
						|
        [ -n "$tb" ] || setx tb=get_mysql_usertb "$dbname"
 | 
						|
        mysql_user_ve "insert into $tb (name, tem_done, date_start) values ('$name', 0, sysdate()) on duplicate key update tem_done = 0, date_start = sysdate(), date_done = null"
 | 
						|
    fi
 | 
						|
}
 | 
						|
function mysql_after_update() {
 | 
						|
    local dbname="$1" tb="$2"
 | 
						|
    if [ -z "$dbname" ]; then
 | 
						|
        # admin
 | 
						|
        setx dbname=get_mysql_admindb
 | 
						|
        [ -n "$tb" ] || setx tb=get_mysql_admintb "$dbname"
 | 
						|
        mysql_admin_ve "update $tb set tem_done = 1, date_done = sysdate() where name = '$name'" "$dbname"
 | 
						|
    else
 | 
						|
        # user
 | 
						|
        [ -n "$tb" ] || setx tb=get_mysql_usertb "$dbname"
 | 
						|
        mysql_user_ve "update $tb set tem_done = 1, date_done = sysdate() where name = '$name'"
 | 
						|
    fi
 | 
						|
}
 | 
						|
 | 
						|
function mysql_get_defaults() {
 | 
						|
    local dir="$1"
 | 
						|
    if [ -n "$profile" ]; then
 | 
						|
        if [ "$dbmode" == devel ]; then
 | 
						|
            if [ -f "$dir/${profile}-my.cnf" ]; then
 | 
						|
                echo "$dir/${profile}-my.cnf"; return
 | 
						|
            elif [ -f "$PROFILEDIR/${profile}-my.cnf" ]; then
 | 
						|
                echo "$PROFILEDIR/${profile}-my.cnf"; return
 | 
						|
            fi
 | 
						|
        else
 | 
						|
            if [ -f "$PROFILEDIR/${profile}-my.cnf" ]; then
 | 
						|
                echo "$PROFILEDIR/${profile}-my.cnf"; return
 | 
						|
            elif [ -f "$dir/${profile}-my.cnf" ]; then
 | 
						|
                echo "$dir/${profile}-my.cnf"; return
 | 
						|
            fi
 | 
						|
        fi
 | 
						|
    fi
 | 
						|
    echo "$dir/my.cnf"
 | 
						|
}
 | 
						|
function mysql_set_adminargs() {
 | 
						|
    local dir="$1" defaults
 | 
						|
    adminargs=()
 | 
						|
    setx defaults=mysql_get_defaults "$dir"
 | 
						|
    if [ -f "$defaults" ]; then
 | 
						|
        array_add adminargs --defaults-file="$defaults"
 | 
						|
        if [ -n "$admindefaults" ]; then
 | 
						|
            array_add adminargs --defaults-extra-file="$admindefaults"
 | 
						|
        fi
 | 
						|
    elif [ -n "$admindefaults" ]; then
 | 
						|
        array_add adminargs --defaults-file="$admindefaults"
 | 
						|
    fi
 | 
						|
    [ ${#adminargs[*]} -gt 0 ] || array_add adminargs --default-character-set utf8
 | 
						|
}
 | 
						|
function mysql__mconf_get() {
 | 
						|
    local defaults="$1" tmp
 | 
						|
    if [ -n "$set_suffix" ]; then
 | 
						|
        setx tmp=mconf_get "$defaults" sqlmig suffix
 | 
						|
        [ -n "$tmp" ] && suffix="$tmp"
 | 
						|
    fi
 | 
						|
    if [ -n "$set_csv2sql" ]; then
 | 
						|
        setx tmp=mconf_get "$defaults" sqlmig csv2sql
 | 
						|
        [ -n "$tmp" ] && {
 | 
						|
            csv2sql="$tmp"
 | 
						|
            fix_csv2sql
 | 
						|
        }
 | 
						|
    fi
 | 
						|
    if [ -n "$set_csv_null" ]; then
 | 
						|
        setx tmp=mconf_get "$defaults" sqlmig csv_null
 | 
						|
        [ -n "$tmp" ] && {
 | 
						|
            csv_null="$tmp"
 | 
						|
            fix_csv_null
 | 
						|
        }
 | 
						|
    fi
 | 
						|
    if [ -n "$set_load_data" ]; then
 | 
						|
        if [ -z "$host" ]; then
 | 
						|
            # load_data==default requière host
 | 
						|
            setx host=mconf_get "$defaults" client host
 | 
						|
        fi
 | 
						|
        setx tmp=mconf_get "$defaults" sqlmig load-data
 | 
						|
        [ -n "$tmp" ] && {
 | 
						|
            load_data="$tmp"
 | 
						|
            fix_load_data
 | 
						|
        }
 | 
						|
    fi
 | 
						|
}
 | 
						|
function mysql_set_userargs() {
 | 
						|
    local dir="$1" dbname="$2" defaults
 | 
						|
    local set_suffix set_csv2sql set_csv_null set_load_data
 | 
						|
    userargs=()
 | 
						|
    setx defaults=mysql_get_defaults "$dir"
 | 
						|
    [ -z "$suffix" ] && set_suffix=1
 | 
						|
    [ -z "$csv2sql" ] && set_csv2sql=1
 | 
						|
    [ -z "$csv_null" ] && set_csv_null=1
 | 
						|
    [ -z "$load_data" ] && set_load_data=1
 | 
						|
    if [ -f "$defaults" ]; then
 | 
						|
        array_add userargs --defaults-file="$defaults"
 | 
						|
        mysql__mconf_get "$defaults"
 | 
						|
        if [ -n "$userdefaults" ]; then
 | 
						|
            array_add userargs --defaults-extra-file="$userdefaults"
 | 
						|
            mysql__mconf_get "$userdefaults"
 | 
						|
        elif [ -f "$dir/my-${dbname}.cnf" ]; then
 | 
						|
            array_add userargs --defaults-extra-file="$dir/my-${dbname}.cnf"
 | 
						|
            mysql__mconf_get "$dir/my-${dbname}.cnf"
 | 
						|
        fi
 | 
						|
    elif [ -n "$userdefaults" ]; then
 | 
						|
        array_add userargs --defaults-file="$userdefaults"
 | 
						|
        mysql__mconf_get "$userdefaults"
 | 
						|
    elif [ -f "$dir/my-${dbname}.cnf" ]; then
 | 
						|
        array_add userargs --defaults-file="$dir/my-${dbname}.cnf"
 | 
						|
        mysql__mconf_get "$dir/my-${dbname}.cnf"
 | 
						|
    fi
 | 
						|
    [ ${#userargs[*]} -gt 0 ] || array_add userargs --default-character-set utf8
 | 
						|
    # initialiser les valeurs par défaut
 | 
						|
    fix_csv2sql
 | 
						|
    fix_csv_null
 | 
						|
    fix_load_data
 | 
						|
}
 | 
						|
function mysql_set_mysqlargs() {
 | 
						|
    mysqlargs=()
 | 
						|
    [ -n "$user" ] && array_add mysqlargs -u "$user"
 | 
						|
    [ -n "$pwset" ] && array_add mysqlargs -p"$password"
 | 
						|
    [ -n "$host" ] && array_add mysqlargs -h "$host"
 | 
						|
    [ -n "$port" ] && array_add mysqlargs -P "$port"
 | 
						|
    [ -n "$socket" ] && array_add mysqlargs -S "$socket"
 | 
						|
    [ -n "$charset" ] && array_add mysqlargs --default-character-set "$charset"
 | 
						|
    [ -n "$force" ] && array_add mysqlargs -f
 | 
						|
    array_add mysqlargs -B
 | 
						|
}
 | 
						|
MYSQL_ADMIN_CONF_DONE=
 | 
						|
function mysql_admin_update() {
 | 
						|
    local name="$1" update="$2" updateone="$3" done
 | 
						|
    if [ -z "$updateone" ]; then
 | 
						|
        if [ -z "$MYSQL_ADMIN_CONF_DONE" ]; then
 | 
						|
            MYSQL_ADMIN_CONF_DONE=1
 | 
						|
            mysql_tbconf
 | 
						|
        fi
 | 
						|
        if ! setx done=mysql_get_done "$name"; then
 | 
						|
            [ -n "$fake" ] || die
 | 
						|
        fi
 | 
						|
        [ -n "$done" ] && return
 | 
						|
    fi
 | 
						|
 | 
						|
    estep "$name"
 | 
						|
    [ -n "$fake" ] && return
 | 
						|
 | 
						|
    if [ -z "$updateone" ]; then
 | 
						|
        mysql_before_update || die
 | 
						|
    fi
 | 
						|
    cat "$update" | mysql_admin_ve || abort_on_error
 | 
						|
    if [ -z "$updateone" ]; then
 | 
						|
        mysql_after_update || die
 | 
						|
    fi
 | 
						|
}
 | 
						|
function mysql_user_update() {
 | 
						|
    local name="$1" update="$2" dbname="$3" updateone="$4" done
 | 
						|
    if [ -z "$updateone" ]; then
 | 
						|
        if ! setx done=mysql_get_done "$name" "$dbname"; then
 | 
						|
            [ -n "$fake" ] || die
 | 
						|
        fi
 | 
						|
        [ -n "$done" ] && return
 | 
						|
    fi
 | 
						|
 | 
						|
    estep "$name"
 | 
						|
    [ -n "$fake" ] && return
 | 
						|
 | 
						|
    if [ -z "$updateone" ]; then
 | 
						|
        mysql_before_update "$dbname" || die
 | 
						|
    fi
 | 
						|
    if [[ "$update" == *.sql ]]; then
 | 
						|
        # SQL
 | 
						|
        cat "$update" | mysql_user_ve || abort_on_error
 | 
						|
    else
 | 
						|
        # CSV
 | 
						|
        local truncate table local sql
 | 
						|
        eval "$(get_csvinfo "$update")"
 | 
						|
        [ -n "$truncate" ] && sql="truncate table $table;"
 | 
						|
        [ "$load_data" == local ] && local=1 || local=
 | 
						|
        sql="${sql}load data${local:+ local} infile '$update' into table \`$table\`
 | 
						|
 character set 'utf8'
 | 
						|
 fields terminated by ','
 | 
						|
 optionally enclosed by '\\\"'
 | 
						|
 escaped by '\\\\'
 | 
						|
 lines terminated by '\\n'
 | 
						|
 starting by ''
 | 
						|
 ignore 1 lines
 | 
						|
 ($(<"$update" awk '{ print; exit }'));"
 | 
						|
        echo "$sql" | mysql_user_ve || abort_on_error
 | 
						|
    fi
 | 
						|
    if [ -z "$updateone" ]; then
 | 
						|
        mysql_after_update "$dbname" || die
 | 
						|
    fi
 | 
						|
}
 | 
						|
 | 
						|
################################################################################
 | 
						|
# Oracle
 | 
						|
 | 
						|
function get_oracle_admindb() { echo "sqlmig_admin_db_"; }
 | 
						|
function get_oracle_admintb() { echo "sqlmig_updates_"; }
 | 
						|
function get_oracle_usertb() { echo "${1}_updates_"; }
 | 
						|
 | 
						|
function oracle_sqlplus() {
 | 
						|
    # lancer sqlplus sans affichage superflu, et spooler vers $SQLMIGLOG
 | 
						|
    #local r; set -x #DEBUG
 | 
						|
    echo "\
 | 
						|
set pagesize 0
 | 
						|
set feedback off
 | 
						|
set linesize 8192
 | 
						|
set tab off
 | 
						|
whenever oserror exit failure
 | 
						|
whenever sqlerror exit sql.sqlcode
 | 
						|
spool '$SQLMIGLOG' append" >"$OPDIR/login.sql"
 | 
						|
    local connect="$1@$ORACLE_SID" sysdba="$2"; shift; shift
 | 
						|
    ORACLE_PATH="$OPDIR" sqlplus -S "$connect" ${sysdba:+as sysdba} "$@"
 | 
						|
    #r=$?; set +x; return $r #DEBUG
 | 
						|
}
 | 
						|
function qe() {
 | 
						|
    # lancer la commande $@: si elle retourne un code d'erreur, afficher le
 | 
						|
    # résultat de la commande sur stderr si on est en mode verbeux, sinon ne
 | 
						|
    # rien afficher
 | 
						|
    local r output
 | 
						|
    output="$("$@")"; r=$?
 | 
						|
    if [ ${#output} -gt 0 ]; then
 | 
						|
        show_verbose && echo "$output" 1>&2
 | 
						|
    fi
 | 
						|
    return $r
 | 
						|
}
 | 
						|
 | 
						|
function oracle_admin_query() {
 | 
						|
    # lancer sqlplus avec la connexion admin
 | 
						|
    oracle_sqlplus "$ADMINCONNECT" "$ADMINDBA" "$@"
 | 
						|
}
 | 
						|
function oracle_admin_ve() {
 | 
						|
    # lancer une requête admin, ne pas masquer le résultat
 | 
						|
    if [ $# -gt 0 ]; then
 | 
						|
        show_debug && edebug "query: $*"
 | 
						|
        oracle_admin_query <<<"$*"
 | 
						|
    else
 | 
						|
        oracle_admin_query
 | 
						|
    fi
 | 
						|
}
 | 
						|
function oracle_admin_qe() {
 | 
						|
    # lancer une requête admin en masquant le résultat
 | 
						|
    if [ $# -gt 0 ]; then
 | 
						|
        show_debug && edebug "query: $*"
 | 
						|
        qe oracle_admin_query <<<"$*"
 | 
						|
    else
 | 
						|
        qe oracle_admin_query
 | 
						|
    fi
 | 
						|
}
 | 
						|
function oracle_admin_ne() {
 | 
						|
    # lancer une requête admin et retourner vrai si elle affiche un résultat
 | 
						|
    if [ $# -gt 0 ]; then
 | 
						|
        show_debug && edebug "query: $*"
 | 
						|
        [ -n "$(oracle_admin_query <<<"$*")" ]
 | 
						|
    else
 | 
						|
        [ -n "$(oracle_admin_query)" ]
 | 
						|
    fi
 | 
						|
}
 | 
						|
function oracle_admin_have_user() {
 | 
						|
    # tester en mode admin si le user $1 existe
 | 
						|
    oracle_admin_ne "select username from all_users where username = '${1^^}';"
 | 
						|
}
 | 
						|
function oracle_admin_have_table() {
 | 
						|
    # tester en mode admin si le table $1 existe (avec éventuellement le owner $2)
 | 
						|
    local sql="select table_name from all_tables where table_name = '${1^^}'"
 | 
						|
    [ -n "$2" ] && sql="$sql and owner = '${2^^}'"
 | 
						|
    oracle_admin_ne "$sql;"
 | 
						|
}
 | 
						|
 | 
						|
function oracle_user_query() {
 | 
						|
    # lancer sqlplus avec la connexion user
 | 
						|
    oracle_sqlplus "$USERCONNECT" "$USERDBA" "$@"
 | 
						|
}
 | 
						|
function oracle_user_ve() {
 | 
						|
    # lancer une requête user, ne pas masquer le résultat
 | 
						|
    if [ $# -gt 0 ]; then
 | 
						|
        show_debug && edebug "query: $*"
 | 
						|
        oracle_user_query <<<"$*"
 | 
						|
    else
 | 
						|
        oracle_user_query
 | 
						|
    fi
 | 
						|
}
 | 
						|
function oracle_user_qe() {
 | 
						|
    # lancer une requête user en masquant le résultat
 | 
						|
    if [ $# -gt 0 ]; then
 | 
						|
        show_debug && edebug "query: $*"
 | 
						|
        qe oracle_user_query <<<"$*"
 | 
						|
    else
 | 
						|
        qe oracle_user_query
 | 
						|
    fi
 | 
						|
}
 | 
						|
function oracle_user_ne() {
 | 
						|
    # lancer une requête user et retourner vrai si elle affiche un résultat
 | 
						|
    if [ $# -gt 0 ]; then
 | 
						|
        show_debug && edebug "query: $*"
 | 
						|
        [ -n "$(oracle_user_query <<<"$*")" ]
 | 
						|
    else
 | 
						|
        [ -n "$(oracle_user_query)" ]
 | 
						|
    fi
 | 
						|
}
 | 
						|
function oracle_user_have_user() {
 | 
						|
    # tester en mode user si le user $1 existe
 | 
						|
    oracle_user_ne "select username from all_users where username = '${1^^}';"
 | 
						|
}
 | 
						|
function oracle_user_have_table() {
 | 
						|
    # tester en mode user si le table $1 existe (avec éventuellement le owner $2)
 | 
						|
    local sql="select table_name from all_tables where table_name = '${1^^}'"
 | 
						|
    [ -n "$2" ] && sql="$sql and owner = '${2^^}'"
 | 
						|
    oracle_user_ne "$sql;"
 | 
						|
}
 | 
						|
 | 
						|
function oracle_tbconf() {
 | 
						|
    [ -n "$fake" ] && return
 | 
						|
 | 
						|
    # s'assurer que la table des mises à jour existe
 | 
						|
    local dbname="$1" tb="$2"
 | 
						|
    if [ -z "$dbname" ]; then
 | 
						|
        # admin
 | 
						|
        setx dbname=get_oracle_admindb
 | 
						|
        #if ! oracle_admin_have_user "$dbname"; then
 | 
						|
        #    oracle_admin_ve "create user $dbname; grant connect to $dbname;"
 | 
						|
        #fi
 | 
						|
        [ -n "$tb" ] || setx tb=get_oracle_admintb "$dbname"
 | 
						|
        local owner="${ADMINCONNECT%%/*}"
 | 
						|
        [ -n "owner" ] || owner=system
 | 
						|
        if ! oracle_admin_have_table "$tb" "$owner"; then
 | 
						|
            oracle_admin_ve "create table $tb (
 | 
						|
 name varchar(128) not null primary key
 | 
						|
,tem_done number(1)
 | 
						|
,date_start timestamp
 | 
						|
,date_done timestamp
 | 
						|
);" || die "create table $tb"
 | 
						|
        fi
 | 
						|
    else
 | 
						|
        # user
 | 
						|
        [ -n "$tb" ] || setx tb=get_oracle_usertb "$dbname"
 | 
						|
        local owner="${USERCONNECT%%/*}"
 | 
						|
        [ -n "owner" ] || owner=system
 | 
						|
        if ! oracle_user_have_table "$tb" "$owner"; then
 | 
						|
            oracle_user_ve "create table $tb (
 | 
						|
 name varchar(128) not null primary key
 | 
						|
,tem_done number(1)
 | 
						|
,date_start timestamp
 | 
						|
,date_done timestamp
 | 
						|
);" || die "create table $tb"
 | 
						|
        fi
 | 
						|
    fi
 | 
						|
}
 | 
						|
function oracle_get_done() {
 | 
						|
    # afficher le nom d'une mise à jour si elle a été appliquée
 | 
						|
    local name="$1" dbname="$2" tb="$3"
 | 
						|
    if [ -z "$dbname" ]; then
 | 
						|
        # admin
 | 
						|
        setx dbname=get_oracle_admindb
 | 
						|
        [ -n "$tb" ] || setx tb=get_oracle_admintb "$dbname"
 | 
						|
        oracle_admin_ve "select name from $tb where name = '$name' and tem_done = 1;"
 | 
						|
    else
 | 
						|
        # user
 | 
						|
        [ -n "$tb" ] || setx tb=get_oracle_usertb "$dbname"
 | 
						|
        oracle_user_ve "select name from $tb where name = '$name' and tem_done = 1;"
 | 
						|
    fi
 | 
						|
}
 | 
						|
function oracle_before_update() {
 | 
						|
    # préparer l'exécution d'une mise à jour
 | 
						|
    local dbname="$1" tb="$2"
 | 
						|
    if [ -z "$dbname" ]; then
 | 
						|
        # admin
 | 
						|
        setx dbname=get_oracle_admindb
 | 
						|
        [ -n "$tb" ] || setx tb=get_oracle_admintb "$dbname"
 | 
						|
        oracle_admin_ve "\
 | 
						|
merge into $tb d
 | 
						|
using (select '$name' name from dual) s
 | 
						|
on (d.name = s.name)
 | 
						|
when matched then update set d.tem_done = 0, d.date_start = sysdate, d.date_done = null
 | 
						|
when not matched then insert (name, tem_done, date_start) values ('$name', 0, sysdate);
 | 
						|
commit;"
 | 
						|
    else
 | 
						|
        # user
 | 
						|
        [ -n "$tb" ] || setx tb=get_oracle_usertb "$dbname"
 | 
						|
        oracle_user_ve "\
 | 
						|
merge into $tb d
 | 
						|
using (select '$name' name from dual) s
 | 
						|
on (d.name = s.name)
 | 
						|
when matched then update set d.tem_done = 0, d.date_start = sysdate, d.date_done = null
 | 
						|
when not matched then insert (name, tem_done, date_start) values ('$name', 0, sysdate);
 | 
						|
commit;"
 | 
						|
    fi
 | 
						|
}
 | 
						|
function oracle_after_update() {
 | 
						|
    # valider l'exécution d'une mise à jour
 | 
						|
    local dbname="$1" tb="$2"
 | 
						|
    if [ -z "$dbname" ]; then
 | 
						|
        # admin
 | 
						|
        setx dbname=get_oracle_admindb
 | 
						|
        [ -n "$tb" ] || setx tb=get_oracle_admintb "$dbname"
 | 
						|
        oracle_admin_ve "\
 | 
						|
update $tb set tem_done = 1, date_done = sysdate where name = '$name';
 | 
						|
commit;"
 | 
						|
    else
 | 
						|
        # user
 | 
						|
        [ -n "$tb" ] || setx tb=get_oracle_usertb "$dbname"
 | 
						|
        oracle_user_ve "\
 | 
						|
update $tb set tem_done = 1, date_done = sysdate where name = '$name';
 | 
						|
commit;"
 | 
						|
    fi
 | 
						|
}
 | 
						|
 | 
						|
function oracle_ensure_opdir() {
 | 
						|
    if [ -z "$OPDIR" ]; then
 | 
						|
        ac_set_tmpdir OPDIR
 | 
						|
        >"$SQLMIGLOG"
 | 
						|
    fi
 | 
						|
}
 | 
						|
function oracle_get_defaults() {
 | 
						|
    local dir="$1"
 | 
						|
    if [ -n "$profile" ]; then
 | 
						|
        if [ "$dbmode" == devel ]; then
 | 
						|
            if [ -f "$dir/${profile}-ora.conf" ]; then
 | 
						|
                echo "$dir/${profile}-ora.conf"; return
 | 
						|
            elif [ -f "$PROFILEDIR/${profile}-ora.conf" ]; then
 | 
						|
                echo "$PROFILEDIR/${profile}-ora.conf"; return
 | 
						|
            fi
 | 
						|
        else
 | 
						|
            if [ -f "$PROFILEDIR/${profile}-ora.conf" ]; then
 | 
						|
                echo "$PROFILEDIR/${profile}-ora.conf"; return
 | 
						|
            elif [ -f "$dir/${profile}-ora.conf" ]; then
 | 
						|
                echo "$dir/${profile}-ora.conf"; return
 | 
						|
            fi
 | 
						|
        fi
 | 
						|
    fi
 | 
						|
    echo "$dir/ora.conf"
 | 
						|
}
 | 
						|
function oracle_source_adminconf() {
 | 
						|
    local dir="$1"
 | 
						|
    unset ORACLE_SID NLS_LANG ADMINCONNECT USERCONNECT SQLMIGLOG
 | 
						|
    setx defaults=oracle_get_defaults "$dir"
 | 
						|
    [ -f "$defaults" ] && source "$defaults"
 | 
						|
    [ -n "$admindefaults" ] && {
 | 
						|
        source "$admindefaults" || die
 | 
						|
    }
 | 
						|
    [ -n "$oracle_sid" ] && ORACLE_SID="$oracle_sid"
 | 
						|
    [ -n "$nls_lang" ] && NLS_LANG="$nls_lang"
 | 
						|
    export ORACLE_SID NLS_LANG
 | 
						|
    if [ -n "$ADMINCONNECT" ]; then
 | 
						|
        ADMINDBA=
 | 
						|
    else
 | 
						|
        ADMINCONNECT=/
 | 
						|
        ADMINDBA=1
 | 
						|
    fi
 | 
						|
    [ -n "$SQLMIGLOG" ] || SQLMIGLOG="/tmp/sqlmig-${ORACLE_SID}-${dbname}.log"
 | 
						|
}
 | 
						|
function oracle_source_userconf() {
 | 
						|
    local dir="$1" dbname="$2"
 | 
						|
    unset ORACLE_SID NLS_LANG ADMINCONNECT USERCONNECT SQLMIGLOG SUFFIX CSV2SQL CSV_NULL
 | 
						|
    setx defaults=oracle_get_defaults "$dir"
 | 
						|
    [ -f "$defaults" ] && source "$defaults"
 | 
						|
    [ -f "$dir/ora-${dbname}.conf" ] && source "$dir/ora-${dbname}.conf"
 | 
						|
    [ -n "$userdefaults" ] && {
 | 
						|
        source "$userdefaults" || die
 | 
						|
    }
 | 
						|
    [ -n "$oracle_sid" ] && ORACLE_SID="$oracle_sid"
 | 
						|
    [ -n "$nls_lang" ] && NLS_LANG="$nls_lang"
 | 
						|
    export ORACLE_SID NLS_LANG
 | 
						|
    if [ -n "$ADMINCONNECT" ]; then
 | 
						|
        ADMINDBA=
 | 
						|
    else
 | 
						|
        ADMINCONNECT=/
 | 
						|
        ADMINDBA=1
 | 
						|
    fi
 | 
						|
    if [ -n "$USERCONNECT" ]; then
 | 
						|
        USERDBA=
 | 
						|
    else
 | 
						|
        USERCONNECT=/
 | 
						|
        USERDBA=1
 | 
						|
    fi
 | 
						|
    [ -n "$SQLMIGLOG" ] || SQLMIGLOG="/tmp/sqlmig-${ORACLE_SID}-${dbname}.log"
 | 
						|
    [ -z "$suffix" ] && suffix="$SUFFIX"
 | 
						|
    [ -z "$csv2sql" ] && csv2sql="$CSV2SQL"
 | 
						|
    [ -z "$csv_null" ] && csv_null="$CSV_NULL"
 | 
						|
    fix_csv2sql
 | 
						|
    fix_csv_null
 | 
						|
}
 | 
						|
ORACLE_ADMIN_CONF_DONE=
 | 
						|
function oracle_admin_update() {
 | 
						|
    local name="$1" update="$2" updateone="$3" done
 | 
						|
    if [ -z "$updateone" ]; then
 | 
						|
        if [ -z "$ORACLE_ADMIN_CONF_DONE" ]; then
 | 
						|
            ORACLE_ADMIN_CONF_DONE=
 | 
						|
            oracle_tbconf
 | 
						|
        fi
 | 
						|
        setx done=oracle_get_done "$name" || die
 | 
						|
        [ -n "$done" ] && return
 | 
						|
    fi
 | 
						|
 | 
						|
    estep "$name"
 | 
						|
    [ -n "$fake" ] && return
 | 
						|
 | 
						|
    if [ -z "$updateone" ]; then
 | 
						|
        oracle_before_update || die
 | 
						|
    fi
 | 
						|
    cat "$update" | oracle_admin_ve || abort_on_error
 | 
						|
    if [ -z "$updateone" ]; then
 | 
						|
        oracle_after_update || die
 | 
						|
    fi
 | 
						|
}
 | 
						|
function oracle_user_update() {
 | 
						|
    local name="$1" update="$2" dbname="$3" updateone="$4" done
 | 
						|
    if [ -z "$updateone" ]; then
 | 
						|
        setx done=oracle_get_done "$name" "$dbname" || die
 | 
						|
        [ -n "$done" ] && return
 | 
						|
    fi
 | 
						|
 | 
						|
    estep "$name"
 | 
						|
    [ -n "$fake" ] && return
 | 
						|
 | 
						|
    if [ -z "$updateone" ]; then
 | 
						|
        oracle_before_update "$dbname" || die
 | 
						|
    fi
 | 
						|
    cat "$update" | oracle_user_ve || abort_on_error
 | 
						|
    if [ -z "$updateone" ]; then
 | 
						|
        oracle_after_update "$dbname" || die
 | 
						|
    fi
 | 
						|
}
 | 
						|
 | 
						|
################################################################################
 | 
						|
 | 
						|
MODE=auto
 | 
						|
PROFILEDIR=/etc/sqlmig
 | 
						|
prod_PROFILE_MODE=prod
 | 
						|
test_PROFILE_MODE=devel
 | 
						|
set_defaults sqlmig
 | 
						|
 | 
						|
admindefaults=
 | 
						|
userdefaults=
 | 
						|
user=
 | 
						|
password=
 | 
						|
pwset=
 | 
						|
host=
 | 
						|
port=
 | 
						|
socket=
 | 
						|
charset=
 | 
						|
oracle_sid=
 | 
						|
nls_lang=
 | 
						|
suffix=
 | 
						|
csv2sql=
 | 
						|
csv_null=
 | 
						|
load_data=
 | 
						|
profile=
 | 
						|
type=auto
 | 
						|
action=update
 | 
						|
updatedir=
 | 
						|
exportdir=
 | 
						|
dbdir=
 | 
						|
dbname=
 | 
						|
updateone=
 | 
						|
force=
 | 
						|
data_csv=auto
 | 
						|
mode="$MODE"
 | 
						|
drop=
 | 
						|
drop_only=
 | 
						|
create_only=
 | 
						|
args=(
 | 
						|
    --help '$exit_with display_help'
 | 
						|
    -g:,--admin-defaults-file: admindefaults=
 | 
						|
    -C:,--defaults-file: userdefaults=
 | 
						|
    -u:,--user: user=
 | 
						|
    -p:,--password: '$set@ password; pwset=1'
 | 
						|
    -h:,--host: host=
 | 
						|
    --port: port=
 | 
						|
    --socket: socket=
 | 
						|
    --character-set: charset=
 | 
						|
    -s:,--oracle-sid: oracle_sid=
 | 
						|
    --nls-lang: nls_lang=
 | 
						|
    --suffix: suffix=
 | 
						|
    --csv2sql csv2sql=1
 | 
						|
    --csv-null: csv_null=
 | 
						|
    --csv-null-empty csv_null=empty
 | 
						|
    --csv-null-mysql csv_null='\N'
 | 
						|
    --csv-null-upper csv_null=NULL
 | 
						|
    --no-csv2sql csv2sql=0
 | 
						|
    --load-data: load_data=
 | 
						|
    --profile: profile=
 | 
						|
    -P,--prod profile=prod
 | 
						|
    -T,--test profile=test
 | 
						|
    --mysql type=mysql
 | 
						|
    --oracle type=oracle
 | 
						|
    -0,--init action=init
 | 
						|
    -e:,--export: '$action=export; set@ exportdir'
 | 
						|
    -c,--connect action=connect
 | 
						|
    -r,--restore-test action=restore_test
 | 
						|
    --update-all action=update
 | 
						|
    -t:,--updatedir: updatedir=
 | 
						|
    -d:,--databasedir: dbdir=
 | 
						|
    -b:,--database: dbname=
 | 
						|
    -f,--update-one updateone=1
 | 
						|
    -n,--fake fake=1
 | 
						|
    --force,--continue-on-error force=1
 | 
						|
    --no-data-csv data_csv=
 | 
						|
    --force-data-csv data_csv=force
 | 
						|
    --prod-mode-dangerous mode=prod
 | 
						|
    --devel-mode mode=devel
 | 
						|
    -Z,--recreate drop=1
 | 
						|
    --drop-only '$drop=1; drop_only=1'
 | 
						|
    --create-only create_only=1
 | 
						|
)
 | 
						|
parse_args "$@"; set -- "${args[@]}"
 | 
						|
 | 
						|
setx cwd=pwd
 | 
						|
if [ -z "$dbdir" -a -z "$updatedir" ]; then
 | 
						|
    setx parentdir=dirname -- "$cwd"
 | 
						|
    if __check_devel_dir src/main/resources/database; then
 | 
						|
        enote "Autosélection src/main/resources/database/"
 | 
						|
    elif __check_devel_dir config/sqlmig; then
 | 
						|
        enote "Autosélection config/sqlmig/"
 | 
						|
    elif __check_devel_dir support/database; then
 | 
						|
        enote "Autosélection support/database/"
 | 
						|
    elif __check_devel_dir database; then
 | 
						|
        enote "Autosélection database/"
 | 
						|
    elif __check_mysql_prod_dir; then
 | 
						|
        [ "$type" == auto ] && type=mysql
 | 
						|
    fi
 | 
						|
fi
 | 
						|
 | 
						|
[ -n "$updatedir" ] && setx updatedir=abspath "$updatedir"
 | 
						|
[ -n "$dbdir" ] && setx dbdir=abspath "$dbdir"
 | 
						|
 | 
						|
################################################################################
 | 
						|
if [ "$action" == init ]; then
 | 
						|
    [ -n "$dbdir" -a -z "$dbname" ] && setx dbname=basename "$dbdir"
 | 
						|
    [ -n "$dbname" ] || dbname="$1"
 | 
						|
    read_value ${dbname:+-i} "Entrez le nom de la base de données" dbname "$dbname"
 | 
						|
 | 
						|
    if [ -z "$dbdir" -a -n "$updatedir" ]; then
 | 
						|
        dbdir="$updatedir/$dbname"
 | 
						|
    elif [ -z "$dbdir" ]; then
 | 
						|
        dbdir="$dbname"
 | 
						|
    fi
 | 
						|
    read_value ${dbdir:+-i} "Entrez le répertoire dans lequel créer les définitions" dbdir "$dbdir"
 | 
						|
    setx dbdir=abspath "$dbdir"
 | 
						|
 | 
						|
    ask_yesno "Voulez-vous créer les fichiers initiaux pour la base de données $dbname dans le répertoire $(ppath "$dbdir")?" O || die
 | 
						|
 | 
						|
    estep "Création du répertoire $dbdir"
 | 
						|
    [ -d "$dbdir" ] || mkdir -p "$dbdir" || die
 | 
						|
 | 
						|
    [ "$type" == auto ] && type=mysql
 | 
						|
 | 
						|
    if [ "$type" == mysql ]; then
 | 
						|
        if [ ! -f "$dbdir/00dropdb.sql" ]; then
 | 
						|
            estep "00dropdb.sql"
 | 
						|
            echo >"$dbdir/00dropdb.sql" "\
 | 
						|
-- -*- coding: utf-8 mode: sql -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
 | 
						|
-- @sqlmig drop
 | 
						|
 | 
						|
drop database if exists @@database@@;"
 | 
						|
        fi
 | 
						|
 | 
						|
        if [ ! -f "$dbdir/01createdb.sql" ]; then
 | 
						|
            estep "01createdb.sql"
 | 
						|
            echo >"$dbdir/01createdb.sql" "\
 | 
						|
-- -*- coding: utf-8 mode: sql -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
 | 
						|
-- @sqlmig create
 | 
						|
 | 
						|
create database @@database@@;"
 | 
						|
        fi
 | 
						|
 | 
						|
        if [ ! -f "$dbdir/02grants.sql" ]; then
 | 
						|
            estep "02grants.sql"
 | 
						|
            echo >"$dbdir/02grants.sql" "\
 | 
						|
-- -*- coding: utf-8 mode: sql -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
 | 
						|
-- @sqlmig admin
 | 
						|
 | 
						|
create user '$dbname' identified by '$dbname';
 | 
						|
grant all privileges on $dbname.* to '$dbname';"
 | 
						|
        fi
 | 
						|
 | 
						|
        if [ ! -f "$dbdir/my.cnf" ]; then
 | 
						|
            estep "my.cnf"
 | 
						|
            echo >"$dbdir/my.cnf" "\
 | 
						|
# Paramètres de connexion par défaut
 | 
						|
[client]
 | 
						|
#user=
 | 
						|
#password=
 | 
						|
#host=localhost
 | 
						|
#port=3306
 | 
						|
#socket=/var/run/mysqld/mysqld.sock
 | 
						|
 | 
						|
[mysql]
 | 
						|
default-character-set=utf8
 | 
						|
 | 
						|
[sqlmig]
 | 
						|
#suffix="
 | 
						|
        fi
 | 
						|
 | 
						|
        if [ ! -f "$dbdir/my-${dbname}.cnf" ]; then
 | 
						|
            estep "my-${dbname}.cnf"
 | 
						|
            echo >"$dbdir/my-${dbname}.cnf" "\
 | 
						|
# Paramètres de connexion pour $dbname
 | 
						|
[client]
 | 
						|
#user=
 | 
						|
#password=
 | 
						|
 | 
						|
[sqlmig]
 | 
						|
#csv2sql=0
 | 
						|
csv_null=
 | 
						|
#load-data=default"
 | 
						|
       fi
 | 
						|
 | 
						|
    elif [ "$type" == oracle ]; then
 | 
						|
        if [ ! -f "$dbdir/00dropuser.sql" ]; then
 | 
						|
            estep "00dropuser.sql"
 | 
						|
            echo >"$dbdir/00dropuser.sql" "\
 | 
						|
-- -*- coding: utf-8 mode: sql -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
 | 
						|
-- @sqlmig drop
 | 
						|
 | 
						|
drop user $dbname cascade;"
 | 
						|
        fi
 | 
						|
 | 
						|
        if [ ! -f "$dbdir/01createuser.sql" ]; then
 | 
						|
            estep "01createuser.sql"
 | 
						|
            echo >"$dbdir/01createuser.sql" "\
 | 
						|
-- -*- coding: utf-8 mode: sql -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
 | 
						|
-- @sqlmig create
 | 
						|
 | 
						|
create user $dbname identified by \"$dbname\";
 | 
						|
grant connect to $dbname;
 | 
						|
grant resource to $dbname;"
 | 
						|
        fi
 | 
						|
 | 
						|
        if [ ! -f "$dbdir/ora.conf" ]; then
 | 
						|
            estep "ora.conf"
 | 
						|
            echo >"$dbdir/ora.conf" "\
 | 
						|
# Paramètres de connexion par défaut
 | 
						|
ORACLE_SID=orcl
 | 
						|
NLS_LANG=FRENCH_FRANCE.AL32UTF8
 | 
						|
#NLS_LANG=AMERICAN_AMERICA.AL32UTF8
 | 
						|
# paramètres de connexion pour les mises à jour administratives
 | 
						|
# si aucune valeur n'est spécifiée, la valeur effective est '/ as sysdba' mais
 | 
						|
# cela requière que la mise à jour soit faite avec une connexion locale.
 | 
						|
ADMINCONNECT=
 | 
						|
# paramètres de connexion pour les mises à jour utilisateur
 | 
						|
USERCONNECT=$dbname/password
 | 
						|
# logs des mises à jour
 | 
						|
SQLMIGLOG=\"/tmp/sqlmig-\${ORACLE_SID}-${dbname}.log\"
 | 
						|
# divers
 | 
						|
#SUFFIX=
 | 
						|
#CSV2SQL=0
 | 
						|
CSV_NULL="
 | 
						|
        fi
 | 
						|
 | 
						|
    else
 | 
						|
        die "BUG: $type: type non implémenté"
 | 
						|
    fi
 | 
						|
 | 
						|
    exit 0
 | 
						|
 | 
						|
################################################################################
 | 
						|
elif [ "$action" == export ]; then
 | 
						|
    [ -n "$exportdir" ] || setx exportdir=find_mysqldupdatedir
 | 
						|
    check_mysqldupdatedir "$exportdir"
 | 
						|
    setx exportdir=abspath "$exportdir/updates"
 | 
						|
 | 
						|
    if [ -n "$dbdir" ]; then
 | 
						|
        dbdirs=("$dbdir")
 | 
						|
    elif [ -z "$updatedir" ]; then
 | 
						|
        array_lsfiles files . "*.sql" "*my.cnf" "my-*.cnf" "*ora.conf" "ora-*.conf"
 | 
						|
        if [ ${#files[*]} -gt 0 ]; then
 | 
						|
            enote "Autosélection répertoire courant"
 | 
						|
            dbdir="$cwd"
 | 
						|
            dbdirs=("$dbdir")
 | 
						|
        else
 | 
						|
            die "Vous devez spécifier l'option -b"
 | 
						|
        fi
 | 
						|
    elif [ -n "$dbname" ]; then
 | 
						|
        dbdirs=("$updatedir/$dbname")
 | 
						|
    else
 | 
						|
        array_lsdirs dbdirs "$updatedir"
 | 
						|
    fi
 | 
						|
 | 
						|
    for dbdir in "${dbdirs[@]}"; do
 | 
						|
        setx dbname=basename -- "$dbdir"
 | 
						|
        # TEMPLATE.d est spécial dans mysqld-update: il faut l'ignorer
 | 
						|
        [ "$dbname" != TEMPLATE.d ] || continue
 | 
						|
 | 
						|
        etitled "$dbname"
 | 
						|
        destdir="$exportdir/$dbname"
 | 
						|
        array_lsfiles updates "$dbdir"
 | 
						|
        for update in "${updates[@]}"; do
 | 
						|
            [ -d "$destdir" ] || mkdir -p "$destdir"
 | 
						|
            [[ "$update" == "*.devel.sql" ]] && continue
 | 
						|
            copy_update "$update" "$destdir"
 | 
						|
        done
 | 
						|
        eend; eclearp
 | 
						|
    done
 | 
						|
 | 
						|
    exit 0
 | 
						|
 | 
						|
################################################################################
 | 
						|
elif [ "$action" == connect ]; then
 | 
						|
    set_dbdirs
 | 
						|
 | 
						|
    force_dbname="$dbname"
 | 
						|
    force_suffix="$suffix"
 | 
						|
    for dbdir in "${dbdirs[@]}"; do
 | 
						|
        dbname="$force_dbname"
 | 
						|
        [ -n "$dbname" ] || setx dbname=basename "$dbdir"
 | 
						|
        suffix="$force_suffix"
 | 
						|
        etitle "$dbname"
 | 
						|
 | 
						|
        ensure_dbtype "$dbdir" "$type"
 | 
						|
        ensure_dbmode "$dbtype" "$mode"
 | 
						|
 | 
						|
        if [ "$dbtype" == mysql ]; then
 | 
						|
            # construire les paramètres pour mysql
 | 
						|
            mysql_set_userargs "$dbdir" "$dbname"
 | 
						|
            mysql_set_mysqlargs
 | 
						|
 | 
						|
            if [ -n "$suffix" ]; then
 | 
						|
                estepi "Suffixe: $dbname --> $dbname$suffix"
 | 
						|
                dbname="$dbname$suffix"
 | 
						|
            fi
 | 
						|
 | 
						|
            array_del mysqlargs -B # désactiver le mode batch
 | 
						|
            mysql "${userargs[@]}" "${mysqlargs[@]}" -D "$dbname"
 | 
						|
 | 
						|
        elif [ "$dbtype" == oracle ]; then
 | 
						|
            # lire les paramètres
 | 
						|
            oracle_source_userconf "$dbdir" "$dbname"
 | 
						|
            oracle_ensure_opdir
 | 
						|
 | 
						|
            if [ -n "$suffix" ]; then
 | 
						|
                estepi "Suffixe: $dbname --> $dbname$suffix"
 | 
						|
                dbname="$dbname$suffix"
 | 
						|
            fi
 | 
						|
 | 
						|
            sqlplus "$USERCONNECT@$ORACLE_SID" ${USERDBA:+as sysdba} "$@"
 | 
						|
 | 
						|
        else
 | 
						|
            die "BUG: $dbtype: type non implémenté"
 | 
						|
        fi
 | 
						|
 | 
						|
        eend
 | 
						|
    done
 | 
						|
    exit 0
 | 
						|
 | 
						|
################################################################################
 | 
						|
elif [ "$action" == restore_test ]; then
 | 
						|
    set_dbdirs
 | 
						|
 | 
						|
    if [ ${#dbdirs[*]} -gt 1 ]; then
 | 
						|
        die "Avec --restore-test, une seule base de données doit être spécifiée"
 | 
						|
    fi
 | 
						|
 | 
						|
    dbdir="${dbdirs[0]}"
 | 
						|
    [ -n "$dbname" ] || setx dbname=basename "$dbdir"
 | 
						|
 | 
						|
    etitle "$dbname"
 | 
						|
 | 
						|
    ensure_dbtype "$dbdir" "$type"
 | 
						|
    ensure_dbmode "$dbtype" "$mode"
 | 
						|
 | 
						|
    [ "$dbtype" == mysql ] || die "Seule les bases de type MySQL sont supportées"
 | 
						|
 | 
						|
    # construire les paramètres pour mysql
 | 
						|
    mysql_set_userargs "$dbdir" "$dbname"
 | 
						|
    mysql_set_mysqlargs
 | 
						|
 | 
						|
    if [ -n "$suffix" ]; then
 | 
						|
        estepi "Suffixe: $dbname --> $dbname$suffix"
 | 
						|
        dbname="$dbname$suffix"
 | 
						|
    fi
 | 
						|
 | 
						|
    dump="$1"
 | 
						|
    [ -n "$dump" ] || die "Vous devez spécifier le fichier de dump"
 | 
						|
    [ -f "$dump" ] || die "$dump: fichier de dump introuvable"
 | 
						|
 | 
						|
    ac_set_tmpdir tmpdir
 | 
						|
    if [[ "$dump" == *.gz ]]; then
 | 
						|
        gzip -dc "$dump" >"$tmpdir/prod.sql"
 | 
						|
    elif [[ "$dump" == *.sql ]]; then
 | 
						|
        cat "$dump" >"$tmpdir/prod.sql"
 | 
						|
    else
 | 
						|
        die "$dump: n'est pas un fichier sql"
 | 
						|
    fi
 | 
						|
    dump="$tmpdir/prod.sql"
 | 
						|
 | 
						|
    pname="$dbname"
 | 
						|
    tname="${dbname}_test"
 | 
						|
    sed <"$tmpdir/prod.sql" >"$tmpdir/test.sql" "\
 | 
						|
s/\`$pname\`/\`$tname\`/g
 | 
						|
s/\`${pname}_updates_\`/\`${tname}_updates_\`/g"
 | 
						|
 | 
						|
    enote "Vous allez restaurer un fichier de sauvegarde de le base $pname vers la base $tname"
 | 
						|
    ask_yesno "Voulez-vous continuer?" X || die
 | 
						|
 | 
						|
    array_del mysqlargs -B # désactiver le mode batch
 | 
						|
    mysql "${userargs[@]}" "${mysqlargs[@]}" <"$tmpdir/test.sql"
 | 
						|
    ac_clean "$tmpdir"
 | 
						|
 | 
						|
    exit 0
 | 
						|
 | 
						|
################################################################################
 | 
						|
elif [ "$action" != update ]; then
 | 
						|
    die "BUG: $action: action non implémentée"
 | 
						|
fi
 | 
						|
 | 
						|
################################################################################
 | 
						|
# update
 | 
						|
 | 
						|
set_dbdirs
 | 
						|
if [ -n "$updateone" ]; then
 | 
						|
    updatefiles=()
 | 
						|
    for updatefile in "$@"; do
 | 
						|
        array_add updatefiles "$(abspath "$updatefile")"
 | 
						|
    done
 | 
						|
fi
 | 
						|
function should_update() {
 | 
						|
    local update="$1" name
 | 
						|
    setx name=basename "$update"
 | 
						|
    if [ -n "$updateone" ]; then
 | 
						|
        # prendre tous les fichiers sélectionnés par -f
 | 
						|
        array_contains updatefiles "$update"
 | 
						|
        return $?
 | 
						|
    elif [ "${name#maint-}" != "$name" ]; then
 | 
						|
        # ignorer les opérations de maintenance par défaut
 | 
						|
        return 1
 | 
						|
    elif [ "$dbmode" != devel -a "${name%.devel.*}" != "$name" ]; then
 | 
						|
        # si on est en mode autre que devel, le nom ne doit pas se terminer
 | 
						|
        # par .devel.*
 | 
						|
        return 1
 | 
						|
    fi
 | 
						|
    return 0
 | 
						|
}
 | 
						|
 | 
						|
# répertoire temporaire pour Oracle
 | 
						|
OPDIR=
 | 
						|
 | 
						|
if [ -n "$updatedir" ]; then
 | 
						|
    ## mises à jour administratives
 | 
						|
    array_lsfiles updates "$updatedir" "*.sql"
 | 
						|
    if [ ${#updates[*]} -gt 0 ]; then
 | 
						|
        ensure_dbtype "$updatedir" "$type"
 | 
						|
        ensure_dbmode "$dbtype" "$mode"
 | 
						|
        if [ "$dbtype" == mysql ]; then
 | 
						|
            # construire les paramètres pour mysql
 | 
						|
            mysql_set_adminargs "$updatedir"
 | 
						|
            mysql_set_mysqlargs
 | 
						|
 | 
						|
            # Mises à jour
 | 
						|
            etitled "Mises à jour admin"
 | 
						|
            for update in "${updates[@]}"; do
 | 
						|
                should_update "$update" || continue
 | 
						|
                mysql_admin_update "${update#$updatedir/}" "$update" "$updateone"
 | 
						|
            done
 | 
						|
            eend; eclearp
 | 
						|
 | 
						|
        elif [ "$dbtype" == oracle ]; then
 | 
						|
            # lire les paramètres
 | 
						|
            oracle_source_adminconf "$updatedir"
 | 
						|
            oracle_ensure_opdir
 | 
						|
 | 
						|
            # Mises à jour
 | 
						|
            etitled "Mises à jour"
 | 
						|
            for update in "${updates[@]}"; do
 | 
						|
                should_update "$update" || continue
 | 
						|
                oracle_admin_update "${update#$updatedir/}" "$update" "$updateone"
 | 
						|
            done
 | 
						|
            eend; eclearp
 | 
						|
        fi
 | 
						|
    fi
 | 
						|
fi
 | 
						|
 | 
						|
## mises à jour utilisateur
 | 
						|
force_dbname="$dbname"
 | 
						|
force_suffix="$suffix"
 | 
						|
for dbdir in "${dbdirs[@]}"; do
 | 
						|
    dbname="$force_dbname"
 | 
						|
    [ -n "$dbname" ] || setx dbname=basename "$dbdir"
 | 
						|
    suffix="$force_suffix"
 | 
						|
    etitle "$dbname"
 | 
						|
 | 
						|
    ensure_dbtype "$dbdir" "$type"
 | 
						|
    ensure_dbmode "$dbtype" "$mode"
 | 
						|
 | 
						|
    ############################################################################
 | 
						|
    if [ "$dbtype" == mysql ]; then
 | 
						|
        # construire les paramètres pour mysql
 | 
						|
        mysql_set_adminargs "$dbdir"
 | 
						|
        mysql_set_userargs "$dbdir" "$dbname"
 | 
						|
        mysql_set_mysqlargs
 | 
						|
 | 
						|
        if is_yes "$csv2sql" && [ -n "$data_csv" ]; then
 | 
						|
            # Conversion csv --> sql
 | 
						|
            array_lsfiles csvs "$dbdir" "*.csv"
 | 
						|
 | 
						|
            etitled "Conversion"
 | 
						|
            for csv in "${csvs[@]}"; do
 | 
						|
                setx csvname=basename -- "$csv"
 | 
						|
                sql="${csv%.csv}.sql"
 | 
						|
                if [ "$data_csv" != force ]; then
 | 
						|
                    testnewer "$csv" "$sql" || continue
 | 
						|
                fi
 | 
						|
 | 
						|
                estep "$csvname --> ${csvname%.csv}.sql"
 | 
						|
                eval "$(get_csvinfo "$csvname")"
 | 
						|
                mysqlloadcsv_args=(
 | 
						|
                    ${truncate:+-T}
 | 
						|
                    -Z "$csv_null"
 | 
						|
                    --prefix "-- -*- coding: utf-8 mode: sql -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8"
 | 
						|
                    -nIf "$csv" "$table"
 | 
						|
                )
 | 
						|
                "$scriptdir/mysqlloadcsv" "${mysqlloadcsv_args[@]}" >"$sql"
 | 
						|
            done
 | 
						|
            eend; eclearp
 | 
						|
        fi
 | 
						|
 | 
						|
        # lister les mises à jour disponibles
 | 
						|
        drops=()
 | 
						|
        creates=()
 | 
						|
        updates=()
 | 
						|
        have_csv=
 | 
						|
        array_lsfiles files "$dbdir" "*.sql" "*.csv"
 | 
						|
        for file in "${files[@]}"; do
 | 
						|
            if [[ "$file" == *.sql ]]; then
 | 
						|
                if have_tag drop "$file"; then
 | 
						|
                    array_add drops "$file"
 | 
						|
                elif have_tag create "$file"; then
 | 
						|
                    array_add creates "$file"
 | 
						|
                else
 | 
						|
                    array_add updates "$file"
 | 
						|
                fi
 | 
						|
            elif [ ! -f "${file%.csv}.sql" ]; then
 | 
						|
                # n'ajouter le CSV que si le fichier SQL correspondant n'existe pas
 | 
						|
                array_add updates "$file"
 | 
						|
                have_csv=1
 | 
						|
            fi
 | 
						|
        done
 | 
						|
 | 
						|
        if [ -n "$suffix" ]; then
 | 
						|
            estepi "Suffixe: $dbname --> $dbname$suffix"
 | 
						|
            dbname="$dbname$suffix"
 | 
						|
        fi
 | 
						|
        if is_no "$csv2sql" && [ -n "$have_csv" ]; then
 | 
						|
            estepi "Chargement des fichiers CSV avec la méthode $load_data"
 | 
						|
        fi
 | 
						|
 | 
						|
        # Suppression
 | 
						|
        if [ -n "$drop" ]; then
 | 
						|
            [ "$dbmode" == devel ] || die "La suppression de base de données n'est pas autorisée en mode production"
 | 
						|
            etitle "Suppression"
 | 
						|
            if ! ask_yesno "Etes-vous sûr de vouloir supprimer la base de données $dbname?" X; then
 | 
						|
                ewarn "Suppression annulée, les autres opérations ne seront pas effectuées"
 | 
						|
                eend; continue
 | 
						|
            fi
 | 
						|
            for drop in "${drops[@]}"; do
 | 
						|
                should_update "$update" || continue
 | 
						|
                setx name=basename "$drop"
 | 
						|
                estep "$name"
 | 
						|
                [ -n "$fake" ] && continue
 | 
						|
 | 
						|
                sed "s/@@database@@/$dbname/g" "$drop" | mysql_admin_qe || abort_on_error "drop: $name"
 | 
						|
            done
 | 
						|
            eend
 | 
						|
            [ -n "$drop_only" ] && { eend; continue; }
 | 
						|
        fi
 | 
						|
 | 
						|
        # Création
 | 
						|
        if ! mysql_admin_qe "select 1" "$dbname"; then
 | 
						|
            etitled "Création"
 | 
						|
            for create in "${creates[@]}"; do
 | 
						|
                should_update "$update" || continue
 | 
						|
                setx name=basename "$create"
 | 
						|
                estep "$name"
 | 
						|
                [ -n "$fake" ] && continue
 | 
						|
 | 
						|
                sed "s/@@database@@/$dbname/g" "$create" | mysql_admin_qe || abort_on_error "create: $name"
 | 
						|
            done
 | 
						|
            eend; eclearp
 | 
						|
        fi
 | 
						|
        [ -n "$create_only" ] && { eend; continue; }
 | 
						|
 | 
						|
        # Mises à jour
 | 
						|
        etitled "Mises à jour"
 | 
						|
        mysql_tbconf "$dbname"
 | 
						|
        for update in "${updates[@]}"; do
 | 
						|
            should_update "$update" || continue
 | 
						|
            if [[ "$update" == *.sql ]]; then
 | 
						|
                # fichier SQL
 | 
						|
                if have_tag admin "$update"; then
 | 
						|
                    [ -n "$updatedir" ] && name="${update#$updatedir/}" || name="${update#$dbdir/}"
 | 
						|
                    mysql_admin_update "$name" "$update" "$updateone"
 | 
						|
                else
 | 
						|
                    mysql_user_update "${update#$dbdir/}" "$update" "$dbname" "$updateone"
 | 
						|
                fi
 | 
						|
            elif is_no "$csv2sql"; then
 | 
						|
                # fichier CSV, ne les traiter que si on est en mode --no-csv2sql
 | 
						|
                mysql_user_update "${update#$dbdir/}" "$update" "$dbname" "$updateone"
 | 
						|
            fi
 | 
						|
        done
 | 
						|
        eend; eclearp
 | 
						|
 | 
						|
    ############################################################################
 | 
						|
    elif [ "$dbtype" == oracle ]; then
 | 
						|
        [ -n "$OPDIR" ] || ac_set_tmpdir OPDIR
 | 
						|
 | 
						|
        # lire les paramètres
 | 
						|
        oracle_source_userconf "$dbdir" "$dbname"
 | 
						|
        oracle_ensure_opdir
 | 
						|
 | 
						|
        # lister les mises à jour disponibles
 | 
						|
        drops=()
 | 
						|
        creates=()
 | 
						|
        updates=()
 | 
						|
        have_csv=
 | 
						|
        array_lsfiles files "$dbdir" "*.sql" "*.csv"
 | 
						|
        for file in "${files[@]}"; do
 | 
						|
            if [[ "$file" == *.sql ]]; then
 | 
						|
                if have_tag drop "$file"; then
 | 
						|
                    array_add drops "$file"
 | 
						|
                elif have_tag create "$file"; then
 | 
						|
                    array_add creates "$file"
 | 
						|
                else
 | 
						|
                    array_add updates "$file"
 | 
						|
                fi
 | 
						|
            elif [ ! -f "${file%.csv}.sql" ]; then
 | 
						|
                # n'ajouter le CSV que si le fichier SQL correspondant n'existe pas
 | 
						|
                array_add updates "$file"
 | 
						|
                have_csv=1
 | 
						|
            fi
 | 
						|
        done
 | 
						|
 | 
						|
        if [ -n "$suffix" ]; then
 | 
						|
            estepi "Suffixe: $dbname --> $dbname$suffix"
 | 
						|
            dbname="$dbname$suffix"
 | 
						|
        fi
 | 
						|
 | 
						|
        # Suppression
 | 
						|
        if [ -n "$drop" ]; then
 | 
						|
            [ "$dbmode" == devel ] || die "La suppression de user n'est pas autorisée en mode production"
 | 
						|
            etitle "Suppression"
 | 
						|
            if ! ask_yesno "Etes-vous sûr de vouloir supprimer le user $dbname?" X; then
 | 
						|
                ewarn "Suppression annulée, les autres opérations ne seront pas effectuées"
 | 
						|
                eend; continue
 | 
						|
            fi
 | 
						|
            for drop in "${drops[@]}"; do
 | 
						|
                should_update "$update" || continue
 | 
						|
                setx name=basename "$drop"
 | 
						|
                estep "$name"
 | 
						|
                [ -n "$fake" ] && continue
 | 
						|
 | 
						|
                sed "s/@@database@@/$dbname/g" "$drop" | oracle_admin_ve || abort_on_error "drop: $name"
 | 
						|
            done
 | 
						|
            eend
 | 
						|
            [ -n "$drop_only" ] && { eend; continue; }
 | 
						|
        fi
 | 
						|
 | 
						|
        # Création
 | 
						|
        if ! oracle_admin_have_user "$dbname"; then
 | 
						|
            etitled "Création"
 | 
						|
            for create in "${creates[@]}"; do
 | 
						|
                should_update "$update" || continue
 | 
						|
                setx name=basename "$create"
 | 
						|
                estep "$name"
 | 
						|
                [ -n "$fake" ] && continue
 | 
						|
 | 
						|
                sed "s/@@database@@/$dbname/g" "$create" | oracle_admin_ve || abort_on_error "create: $name"
 | 
						|
            done
 | 
						|
            eend; eclearp
 | 
						|
        fi
 | 
						|
        [ -n "$create_only" ] && { eend; continue; }
 | 
						|
 | 
						|
        # Mises à jour
 | 
						|
        etitled "Mises à jour"
 | 
						|
        oracle_tbconf "$dbname"
 | 
						|
        for update in "${updates[@]}"; do
 | 
						|
            should_update "$update" || continue
 | 
						|
            if [[ "$update" == *.sql ]]; then
 | 
						|
                # fichier SQL
 | 
						|
                if have_tag admin "$update"; then
 | 
						|
                    [ -n "$updatedir" ] && name="${update#$updatedir/}" || name="${update#$dbdir/}"
 | 
						|
                    oracle_admin_update "$name" "$update" "$updateone"
 | 
						|
                else
 | 
						|
                    oracle_user_update "${update#$dbdir/}" "$update" "$dbname" "$updateone"
 | 
						|
                fi
 | 
						|
            fi
 | 
						|
        done
 | 
						|
        eend; eclearp
 | 
						|
 | 
						|
    ############################################################################
 | 
						|
    else
 | 
						|
        die "BUG: $dbtype: type non implémenté"
 | 
						|
    fi
 | 
						|
 | 
						|
    eend
 | 
						|
done
 |