#!/bin/bash
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8

function display_help() {
    uecho "$scriptname: Charger une table MySQL avec un fichier csv

USAGE
    $scriptname [db.]table [fields...] [-- mysql options]

db      est le nom de la base de données
table   est le nom de la table à charger
fields  est la liste des colonnes. Si cette valeur est spécifiée, il faudra
        peut-être utiliser l'option -s pour ignorer le cas échéant la ligne des
        en-têtes dans le fichier en entrée. Sinon, les colonnes à utiliser sont
        calculées à partir du fichier en entrée.

Dans les données en entrées, qui doivent être en UTF8, les conversions suivantes
sont effectuées:

    \\0 --> NUL
    \\b --> backspace
    \\n --> newline
    \\r --> carriage return
    \\t --> tab
    \\Z --> Ctrl+Z
    \\N --> NULL

OPTIONS
    -h host
    -P port
    -u user
    -ppassword
        Informations de connexion à la base de données
    -C CONFIG
        Prendre les informations de connexion depuis le fichier spécifié.
        Le fichier doit être de la forme
            host=HOST.TLD
            #post=3306
            user=USER
            password=PASS
            #dbtable=DB.TABLE
            #fields=(FIELDS...)
            # Il est possible aussi de spécifier DB et TABLE séparément:
            #database=DB
            #table=TABLE
        Les variables port, dbtable et fields sont facultatives.
        Les valeurs définies dans ce fichier sont prioritaires par rapport à
        celles qui auraient été spécifiées sur la ligne de commande.
        Utiliser password=--NOT-SET-- s'il faut se connecter sans mot de passe
        Cette option peut être utilisée plusieurs fois, auquel cas les fichiers
        sont chargés dans l'ordre.
    --profile PROFILE
        La variable \$PROFILE est définie avec la valeur spécifiée avant de
        sourcer les fichiers de configuration. Cela permet d'avoir des fichiers
        de configuration qui calculent dynamiquement les paramètres en fonction
        de la valeur du profil.
    -f INPUT
        Fichier en entrée. Ne pas spécifier cette option ou utiliser '-' pour
        lire depuis l'entrée standard.
    -s NBLINES
        Nombre de lignes à sauter dans le fichier en entrée"
}

source "$(dirname "$0")/ulib/ulib" &&
urequire DEFAULTS awk ||
exit 1

host=
port=
user=
password=--NOT-SET--
configs=()
profile=
input=
skip_lines=
parse_opts "${PRETTYOPTS[@]}" \
    --help '$exit_with display_help' \
    -h:,-H:,--host: host= \
    -P:,--port: port= \
    -u:,--user: user= \
    -p::,--passwd:,--password: password= \
    -C:,--config: configs \
    -f:,--input: input= \
    -s:,--skip-lines: skip_lines= \
    @ args -- "$@" && set -- "${args[@]}" || die "$args"

dbtable="$1"; shift
fields=()
while [ "$#" -gt 0 -a "$1" != "--" ]; do
    fields=("${fields[@]}" "$1")
    shift
done
[ "$1" == "--" ] && shift

splitname "$dbtable" database table
if [ -z "$table" ]; then
    table="$database"
    database=
fi

if [ -n "${configs[*]}" ]; then
    PROFILE="$profile"
    array_fix_paths configs
    for config in "${configs[@]}"; do
        [ -f "$config" ] || die "Fichier introuvable: $config"
        source "$(abspath "$config")"
    done
fi
[ -n "$table" ] || die "Vous devez spécifier la table dans laquelle se fera l'importation"

isnum "$skip_lines" || skip_lines=0

if [ -n "${fields[*]}" ]; then
    # nous savons quels champs utiliser
    cfields="$(array_join fields ,)"
    if [ -z "$input" -o "$input" == "-" ]; then
        ac_set_tmpfile input
        awkcsv -s "$skip_lines" -k "$cfields" >"$input"
    else
        ac_set_tmpfile tmpinput
        <"$input" awkcsv -s "$skip_lines" -k "$cfields" >"$tmpinput"
        input="$tmpinput"
    fi
else
    # les champs seront calculés à partir de l'entrée
    if [ -z "$input" -o "$input" == "-" ]; then
        ac_set_tmpfile input
        cat >"$input"
    fi
    array_split fields "$(awkcsv -s "$skip_lines" -e '{ print array_join(HEADERS, ","); exit }' <"$input")" ","
    cfields="$(array_join fields ,)"
    skip_lines=$(($skip_lines + 1))
fi

mysqlargs=(
    ${host:+-h "$host"} ${port:+-P "$port"}
    ${user:+-u "$user"}
)
[ "$password" != "--NOT-SET--" ] && mysqlargs=("${mysqlargs[@]}" -p"$password")
mysqlargs=("${mysqlargs[@]}"
    "$database"
    "load data local infile '$input' into table \`$table\` character set 'utf8' fields terminated by ',' optionally enclosed by '\\\"' escaped by '\\\\' lines terminated by '\\n' starting by '' ignore $skip_lines lines ($cfields);"
    --
    --local-infile=1
)

exec "$scriptdir/mysqlcsv" "${mysqlargs[@]}" "$@"