##---------------------------------------------------------------------------- ## 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 ## ## 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 . Ce parametre reconnais le format suivant ## :/@|@// ## ## 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 ## si cette derniere est renseignee. Si plusieur enragistrement sont ## retourne par la requete la variable seras un tableau. ## ## Si aucun parametre de connexion n est fourni ( 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 " ## ---------------------- 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 " Echange des parametre 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 " 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 " <1> Chaine de connexion (VAR_CNX) : ${VAR_CNX}" fct_message -debug 2 " <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 " <2> Chaine de connexion (VAR_CNX) : ${VAR_CNX}" elif [ `expr match "${VAR_CPT}" "/sys//.*$"` -ne 0 ] then fct_message " 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 " <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 " <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 " <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 " <6> Chaine de connexion (VAR_CNX) : ${VAR_CNX}" else fct_message " Chaine de connexion non reconnu" return 2 fi ;; "postgres" ) fct_message -debug 0 " 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 " <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 " <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 " <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 " <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 " <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 " <12> Chaine de connexion (VAR_CNX) : ${VAR_CNX}" else fct_message " Chaine de connexion non reconnu" return 2 fi ;; * ) fct_message " Editeur inconnu : ${VAR_DB}" return 3 ;; esac if [ -n "${ESQL_SQLSTMT}" ] then fct_message -debug 0 " Compte de soumission : ${VAR_CPT2}" fct_message -debug 3 " Mot de passe : ${VAR_MDP}" fct_message -debug 0 " ${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 " ${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 " ESQL_NUMROWS=${ESQL_NUMROWS}" export ESQL_NUMROWS fct_message -debug 2 " ## ---------------------- 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 " ${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 " ${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 " ## --------------------------------------------------------------- ##" fi fi return 0 } typeset -Ffx esql