158 lines
4.9 KiB
Bash
Executable File
158 lines
4.9 KiB
Bash
Executable File
#!/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
|
|
-T, --truncate
|
|
Vider la table avant d'effectuer le chargement"
|
|
}
|
|
|
|
source "$(dirname "$0")/ulib/ulib" &&
|
|
urequire DEFAULTS awk ||
|
|
exit 1
|
|
|
|
host=
|
|
port=
|
|
user=
|
|
password=--NOT-SET--
|
|
configs=()
|
|
profile=
|
|
input=
|
|
skip_lines=
|
|
truncate=
|
|
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= \
|
|
-T,--truncate truncate=1 \
|
|
@ 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"
|
|
|
|
if [ -n "$input" -a "$input" != "-" ]; then
|
|
[ -f "$input" ] || die "$input: fichier introuvable"
|
|
fi
|
|
|
|
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
|
|
|
|
[ -n "$truncate" ] && truncate="truncate table \`$table\`;"
|
|
loadcsv="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);"
|
|
|
|
mysqlargs=(
|
|
${host:+-h "$host"} ${port:+-P "$port"}
|
|
${user:+-u "$user"} ${database:+-D "$database"}
|
|
)
|
|
[ "$password" != "--NOT-SET--" ] && mysqlargs=("${mysqlargs[@]}" -p"$password")
|
|
mysqlargs=("${mysqlargs[@]}"
|
|
"$truncate$loadcsv"
|
|
--
|
|
--local-infile=1
|
|
)
|
|
|
|
exec "$scriptdir/mysqlcsv" "${mysqlargs[@]}" "$@"
|