L'ensemble des scripts et bibliothèques bash utilisés pour maintenir l'infrastructure du Tetalab. Ce socle Bash est une version légère et adaptée du socle Bash essentiellement développé par Emmanuel Confrère, éminent DBA Calédonien.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

266 lines
14 KiB

##----------------------------------------------------------------------------
## Script : esql.lib
## Module Puppet : gnc-script_database_dtsi
## Auteur : Emmanuel Confrere
## Date : 10-02-2016
## Version : 8.0.7-0
## Objet : Cette fonction permet l execution d une requete sur un serveur de base de donnees
##
## Fonction : esql [NomVariable] [Connexion]
##
## Detail : Cette fonction permet l execution d une requete sur un serveur de base de donnees
## La requete est passe a travers la variable d environement ESQL_SQLSTMT.
## Cette fonction s appuis sur les executables psql et sqlplus. Les client de ces
## editeurs doivent donc a minima etre installer.
## La fonction est appelle depuis le shell ou depuis un script de la facon suivante
## esql <VAR> <CNX>
##
## Note : l ordre des parametres n a pas d importance et sont tout deux optionnel.
##
## Le type de base est determine soit par la variable d environement NC_EXPL_DBEDITEUR
## soit par la forme du parametre <CNX>. Ce parametre reconnais le format suivant
## <editeur>:<compte>/<mdp>@<Alias>|@<host:port>//<base>
##
## Ex. cpt/mdp@host:port//base
## cpt/mdp
## cpt/mdp@Alias ( @ est equivalent a //base pour Postgres )
## cpt/mdp//base ( // est equivalent a @Alias pour Oracle)
## /sys ( connexion "/ as sysdba" pour Oracle et "postgres" pour Postgres )
## /sys//base ( pour Postgres se connecte a la base "base" sous le compte "postgres". Ignore par oracle)
##
## Chacune de ces formes peut etre precede par l editeur de la base...
## Ex. oracle:cpt/mdp@Alias
## postgres:/sys
##
## Note : Prefixer par l editeur est necessaire pour interoger une base distante.
## Si l editeur n est pas specifier alors la variable NC_EXPL_DBEDITEUR seras utilisee
## pour determiner l executable a utiliser. La variable NC_EXPL_DBEDITEUR est initialise
## par /opt/expl/conf/shell-env/profile_socle_database.env
##
## Le resultat de la requete est envoye sur la sortie standard ou dans la variable <VAR>
## si cette derniere est renseignee. Si plusieur enragistrement sont
## retourne par la requete la variable <VAR> seras un tableau.
##
## Si aucun parametre de connexion n est fourni (<CNX> est null) alors
## une connxion par defaut sur la base local est utilise
##
## Par defaut la connexion a un serveur Postgres se fait avec le compte postgres
## et si la base n est pas specifier on se connectre a la base postgres.
## Sur un serveur Oracle la connexion se fait par defaut via un compte externe "/"
## sur la base courante defini par la librairie "base".
##
## Si aucune erreur n est releve cette fontion retourne le code de sortie 0.
##
## IMPORTANT : Cette fonction utilise le disque virtuel /dev/shm pour construire les tableaux
##
# ----------------------------------------------------------------------------
# Mise a jour :
# 8.0.7-0 - 10-02-2016 - Emmanuel Confrere - Integration au socle DTSI via Puppet
##----------------------------------------------------------------------------
function esql
{
local VAR_DB=""
local VAR_RES=$1
local VAR_CPT=$2
local VAR_TMP=""
local VAR_CNX=""
local VAR_SES=""
local VAR_LIGNE=""
local VAR_I=1
local PVF=${ESQL_SQLSTMT:${#ESQL_SQLSTMT}-1:1}
local VAR_TMP=""
local VAR_MDP=""
local VAR_CPT2=""
local VAR_ERR=0
local VAR_HOST=""
local VAR_PORT=""
local VAR_BASE=""
fct_message -debug 0 "<lib:esql> ## ---------------------- esql.lib sql submit -------------------- ##"
# -- On controle si l ordre SQL fini bien par ";", le cas echeans on ajoute ce caractere...
[ "${PVF}" = "/" -o "${PVF}" = ";" ] && PVF="" || PVF=";"
# -- On identifie une eventuelle chaine de connexion sur le premier argument
# -- si c est c est le cas, soit il y eu inversion des arguments, soit il n y a pas de nom de variable passe en argument
# -- Si dessous on echange les arguments dans tous les cas ...
if [ `expr match "${VAR_RES}" ".*/.*@.*$"` -ne 0 -o `expr match "${VAR_RES}" ".*/.*$"` -ne 0 -o `expr match "${VAR_RES}" "[a-z,A-Z][a-z,A-Z]*:.*$"` -ne 0 ]
then
VAR_TMP="${VAR_RES}"
VAR_RES="${VAR_CPT}"
VAR_CPT="${VAR_TMP}"
fct_message -debug 0 "<lib:esql> Echange des parametres d entree"
fi
# -- identification de l editeur a partir du format de la chaine de connection
if [ `expr match "${VAR_CPT}" "[a-z]*:"` -ne 0 ]
then
VAR_DB=`echo ${VAR_CPT}|cut -d ":" -f1`
VAR_CPT=`echo ${VAR_CPT}|sed 's/[^:]*:\(.*$\)/\1/'`
else
VAR_DB=${NC_EXPL_DBEDITEUR}
fi
# -- Construction de la chaine de connexion en fontion de l editeur (VAR_CNX) et de la forme du parametre VAR_CPT
case "${VAR_DB}" in
"oracle" ) fct_message -debug 0 "<lib:esql> Connexion a une base Oracle"
if [ -z "${VAR_CPT}" ]
then
VAR_MDP="Aucun"
VAR_CPT2="/"
VAR_CNX="/"
VAR_SES="alter session set current_schema = zzsmai_adm;"
fct_message -debug 2 "<lib:esql> <1> Chaine de connexion (VAR_CNX) : ${VAR_CNX}"
fct_message -debug 2 "<lib:esql> <1> Schema courant (VAR_SES) : ${VAR_SES}"
elif [ "${VAR_CPT}" = "/sys" ]
then
VAR_MDP="Aucun"
VAR_CPT2="/ as sysdba"
VAR_CNX="/ as sysdba"
fct_message -debug 2 "<lib:esql> <2> Chaine de connexion (VAR_CNX) : ${VAR_CNX}"
elif [ `expr match "${VAR_CPT}" "/sys//.*$"` -ne 0 ]
then
fct_message "<lib:esql> format de connexion non supporte (VAR_CPT=${VAR_CPT})"
return 2
elif [ `expr match "${VAR_CPT}" ".*/.*@.*:[0-9][0-9]*//.*$"` -ne 0 ]
then
VAR_BASE=`echo "${VAR_CPT}"|sed 's#.*/.*@.*:[0-9][0-9]*//\(.*\)$#\1#'`
VAR_HOST=`echo "${VAR_CPT}"|sed 's#.*/.*@\(.*\):[0-9][0-9]*//.*$#\1#'`
VAR_PORT=`echo "${VAR_CPT}"|sed 's#.*/.*@.*:\([0-9][0-9]*\)//.*$#\1#'`
VAR_CPT2=`echo "${VAR_CPT}"|sed 's#\(.*\)/.*@.*:[0-9][0-9]*//.*$#\1#'`
VAR_MDP=`echo "${VAR_CPT}"|sed 's#.*/\(.*\)@.*:[0-9][0-9]*//.*$#\1#'`
VAR_CNX="${VAR_CPT2}/${VAR_MDP}@${VAR_HOST}:${VAR_PORT}/${VAR_BASE}"
fct_message -debug 2 "<lib:esql> <3> Chaine de connexion (VAR_CNX) : ${VAR_CNX}"
elif [ `expr match "${VAR_CPT}" ".*/.*@.*$"` -ne 0 ]
then
VAR_HOST=`echo "${VAR_CPT}"|sed 's#.*/.*@\(.*\)$#\1#'`
VAR_CPT2=`echo "${VAR_CPT}"|sed 's#\(.*\)/.*@.*$#\1#'`
VAR_MDP=`echo "${VAR_CPT}"|sed 's#.*/\(.*\)@.*$#\1#'`
VAR_CNX="${VAR_CPT2}/${VAR_MDP}@${VAR_HOST}"
fct_message -debug 2 "<lib:esql> <4> Chaine de connexion (VAR_CNX) : ${VAR_CNX}"
elif [ `expr match "${VAR_CPT}" ".*/.*//.*$"` -ne 0 ]
then
VAR_HOST=`echo "${VAR_CPT}"|sed 's#.*/.*//\(.*\)$#\1#'`
VAR_CPT2=`echo "${VAR_CPT}"|sed 's#\(.*\)/.*//.*$#\1#'`
VAR_MDP=`echo "${VAR_CPT}"|sed 's#.*/\(.*\)//.*$#\1#'`
VAR_CNX="${VAR_CPT2}/${VAR_MDP}@${VAR_HOST}"
fct_message -debug 2 "<lib:esql> <5> Chaine de connexion (VAR_CNX) : ${VAR_CNX}"
elif [ `expr match "${VAR_CPT}" ".*/.*$"` -ne 0 ]
then
VAR_CPT2=`echo "${VAR_CPT}"|sed 's#\(.*\)/.*$#\1#'`
VAR_MDP=`echo "${VAR_CPT}"|sed 's#.*/\(.*\)$#\1#'`
VAR_CNX="${VAR_CPT2}/${VAR_MDP}"
fct_message -debug 2 "<lib:esql> <6> Chaine de connexion (VAR_CNX) : ${VAR_CNX}"
else
fct_message "<lib:esql> Chaine de connexion non reconnue"
return 2
fi ;;
"postgres" ) fct_message -debug 0 "<lib:esql> Connexion a une base Postgres"
if [ -z "${VAR_CPT}" -o "${VAR_CPT}" = "/sys" ]
then
VAR_CPT2="postgres"
VAR_MDP="aucun"
VAR_CNX="postgres://"
fct_message -debug 2 "<lib:esql> <7> Chaine de connexion (VAR_CNX) : ${VAR_CNX}"
elif [ `expr match "${VAR_CPT}" "/sys//.*$"` -ne 0 ]
then
VAR_BASE=`echo "${VAR_CPT}"|sed 's#^/sys//\(.*\)$#\1#'`
VAR_CPT2="postgres"
VAR_MDP="aucun"
VAR_CNX="postgres:///${VAR_BASE}"
fct_message -debug 2 "<lib:esql> <8> Chaine de connexion (VAR_CNX) : ${VAR_CNX}"
elif [ `expr match "${VAR_CPT}" ".*/.*@.*:[0-9][0-9]*//.*$"` -ne 0 ]
then
VAR_BASE=`echo "${VAR_CPT}"|sed 's#.*/.*@.*:[0-9][0-9]*//\(.*\)$#\1#'`
VAR_HOST=`echo "${VAR_CPT}"|sed 's#.*/.*@\(.*\):[0-9][0-9]*//.*$#\1#'`
VAR_PORT=`echo "${VAR_CPT}"|sed 's#.*/.*@.*:\([0-9][0-9]*\)//.*$#\1#'`
VAR_CPT2=`echo "${VAR_CPT}"|sed 's#\(.*\)/.*@.*:[0-9][0-9]*//.*$#\1#'`
VAR_MDP=`echo "${VAR_CPT}"|sed 's#.*/\(.*\)@.*:[0-9][0-9]*//.*$#\1#'`
VAR_CNX="postgres://${VAR_CPT2}:${VAR_MDP}@${VAR_HOST}:${VAR_PORT}/${VAR_BASE}"
fct_message -debug 2 "<lib:esql> <9> Chaine de connexion (VAR_CNX) : ${VAR_CNX}"
elif [ `expr match "${VAR_CPT}" ".*/.*@.*$"` -ne 0 ]
then
VAR_BASE=`echo "${VAR_CPT}"|sed 's#.*/.*@\(.*\)$#\1#'`
VAR_CPT2=`echo "${VAR_CPT}"|sed 's#\(.*\)/.*@.*$#\1#'`
VAR_MDP=`echo "${VAR_CPT}"|sed 's#.*/\(.*\)@.*$#\1#'`
VAR_CNX="postgres://${VAR_CPT2}:${VAR_MDP}@localhost/${VAR_BASE}"
fct_message -debug 2 "<lib:esql> <10> Chaine de connexion (VAR_CNX) : ${VAR_CNX}"
elif [ `expr match "${VAR_CPT}" ".*/.*//.*$"` -ne 0 ]
then
VAR_BASE=`echo "${VAR_CPT}"|sed 's#.*/.*//\(.*\)$#\1#'`
VAR_CPT2=`echo "${VAR_CPT}"|sed 's#\(.*\)/.*//.*$#\1#'`
VAR_MDP=`echo "${VAR_CPT}"|sed 's#.*/\(.*\)//.*$#\1#'`
VAR_CNX="postgres://${VAR_CPT2}:${VAR_MDP}@localhost/${VAR_BASE}"
fct_message -debug 2 "<lib:esql> <11> Chaine de connexion (VAR_CNX) : ${VAR_CNX}"
elif [ `expr match "${VAR_CPT}" ".*/.*$"` -ne 0 ]
then
VAR_BASE=`echo "${VAR_CPT}"|sed 's#\(.*\)/.*$#\1#'`
VAR_CPT2=${VAR_BASE}
VAR_MDP=`echo "${VAR_CPT}"|sed 's#.*/\(.*\)$#\1#'`
VAR_CNX="postgres://${VAR_CPT2}:${VAR_MDP}@localhost/${VAR_BASE}"
fct_message -debug 2 "<lib:esql> <12> Chaine de connexion (VAR_CNX) : ${VAR_CNX}"
else
fct_message "<lib:esql> Chaine de connexion non reconnue"
return 2
fi ;;
* ) fct_message "<lib:esql> Editeur inconnu : ${VAR_DB}"
return 3 ;;
esac
if [ -n "${ESQL_SQLSTMT}" ]
then
fct_message -debug 0 "<lib:esql> Compte de soumission : ${VAR_CPT2}"
fct_message -debug 3 "<lib:esql> Mot de passe : ${VAR_MDP}"
fct_message -debug 0 "<lib:esql> ${ESQL_SQLSTMT}${PVF}"
case "${VAR_DB}" in
"oracle" ) VAR_TMP=`sqlplus -s ${VAR_CNX} << EndSQL
whenever sqlerror exit 100 rollback;
whenever oserror exit 101 rollback;
set head off pages 0 feed off echo off lines 2048 trim on verify off;
${VAR_SES}
${ESQL_SQLSTMT}${PVF}
EndSQL`
VAR_ERR=$? ;;
"postgres" ) VAR_TMP=`psql -t -q -F "|" -A ${VAR_CNX} << EndSQL
${ESQL_SQLSTMT}${PVF}
EndSQL`
VAR_ERR=$? ;;
esac
if [ ${VAR_ERR} -ne 0 ]
then
export ESQL_NUMROWS=0
[ -n "${SH_SESSION_ID}" ] && fct_message -debug 0 "<lib:esql> ${VAR_TMP}" || echo "${VAR_TMP}"
return 1
else
[ -z "${VAR_TMP}" ] && ESQL_NUMROWS=0 || ESQL_NUMROWS=`echo "${VAR_TMP}"|wc -l`
fct_message -debug 0 "<lib:esql> ESQL_NUMROWS=${ESQL_NUMROWS}"
export ESQL_NUMROWS
fct_message -debug 2 "<lib:esql> ## ---------------------- esql.lib result set -------------------- ##"
if [ -n "${VAR_RES}" ]
then
eval unset ${VAR_RES}
[ ${ESQL_NUMROWS} -eq 0 ] && eval ${VAR_RES}=""
[ ${ESQL_NUMROWS} -eq 1 ] && eval ${VAR_RES}=\"${VAR_TMP}\"
[ ${ESQL_NUMROWS} -eq 1 -a -n "${SH_SESSION_ID}" ] && fct_message -debug 2 "<lib:esql> ${VAR_TMP}"
if [ ${ESQL_NUMROWS} -gt 1 ]
then
VAR_I=0
echo "${VAR_TMP}" > /dev/shm/sql$$.tmp
while read VAR_LIGNE
do
VAR_LIGNE=`echo ${VAR_LIGNE}|sed 's/ */ /g'`
[ -n "${SH_SESSION_ID}" ] && fct_message -debug 2 "<lib:esql> ${VAR_LIGNE}"
eval ${VAR_RES}[${VAR_I}]=\"${VAR_LIGNE}\"
(( VAR_I++ ))
done < /dev/shm/sql$$.tmp
rm -f /dev/shm/sql$$.tmp
fi
else
[ ${ESQL_NUMROWS} -ne 0 ] && echo "${VAR_TMP}"
fi
fct_message -debug 0 "<lib:esql> ## --------------------------------------------------------------- ##"
fi
fi
return 0
}
typeset -Ffx esql