Hooks for SQLite with support for communication between hooks

This commit is contained in:
Sebastian Gniazdowski 2018-05-19 12:25:47 +02:00
parent 07f17e0399
commit 3bef2e801c
3 changed files with 95 additions and 10 deletions

View file

@ -18,9 +18,64 @@ function -zflai_run_log {
# No way around the 1 second waiting, e.g. SQLite
# can respond not enough fast for -t 0, but as it
# is done in background process, it's not a drama
#
# $1 - label for log message
# $2 - timeout value (>=0)
# $3 - where to store fetched text/array (default: REPLY/reply)
# $4 - preprocess the captured output, possible values are:
# - get-tokens - get words delimeted by white space, put them into $3 array
# - get-tokens-nl - as above, but return as \n-joined string (into $3)
# - whitespace-collapse - returns text (not array) in which consecutive
# white spaces are replaced by single space; replaces also tabs with space
# - copy - no ingerention into the captured text
function -zflai_coproc_error_fetch {
local __iobuf
IFS='' read -r -t ${2:-1} -p __iobuf && { [[ "$__iobuf" = Error* ]] && builtin print -r "$1: $__iobuf" >>! "$LOG_FILE"; }
local __label="${1:-zflai}" __tout="${2:-1}" __var_name="$3" __preproc="${4:-copy}"
local __iobuf __outbuf="" __retval=1 __tab=$'\t' __nl=$'\n'
local -a __arr
repeat 3; do
IFS='' read -r -t "$__tout" -p __iobuf && {
if [[ "$__iobuf" = Error* ]]; then
builtin print -r -- "$__label: $__iobuf" >>! "$LOG_FILE"
else
__outbuf+="$__iobuf$__nl"
__retval=0
fi
}
__tout=0
done
if (( !retval )); then
[[ -z "$__var_name" ]] && { __var_name="REPLY"; [[ "$__preproc" = "get-tokens" ]] && __var_name="reply"; }
case "$__preproc" in
get-tokens)
__outbuf="${__outbuf//($__tab|$__nl)/ }"
__arr=( "${(s: :)__outbuf}" )
;;
get-tokens-nl)
__outbuf="${__outbuf//($__tab|$__nl)/ }"
__arr=( "${(s: :)__outbuf}" )
__outbuf="${(F)__arr}"
;;
whitespace-collapse)
__outbuf="${__outbuf//$__tab/ }"
__outbuf="${__outbuf//[ ]##/ }"
;;
*) # copy
;;
esac
if [[ "$__preproc" = "get-tokens" ]]; then
: "${(PA)__var_name::=${__arr[@]}}"
else
: "${(P)__var_name::=$__outbuf}"
fi
fi
return "$__retval"
}
emulate -LR zsh -o extendedglob -o typesetsilent -o warncreateglobal

View file

@ -9,21 +9,35 @@ setopt localtraps
[[ "$ZFLAI_LIBS_SOURCED" != "1" ]] && source "${ZFLAI_SRC_DIR}/zflai_lib.zsh"
local __db="$1" __table="$2" __array="$3[@]"
local __db="$1" __table="$2" __array="$3[@]" __table_resolved="$4"
local __db_dir="${DB_DEFS[${__db}_<access>_path]%/}" __db_file="${DB_DEFS[${__db}_<access>_file]}"
local __iobuf __it __it2 __sql __vn __val __ts
local __iobuf __it __it2 __sql __vn __val __ts __tab=$'\t' __nl=$'\n'
local -a __arr
integer __have_table_def=0
local __table_def_param_name
local __table_resolved
-zflai_resolve "$__table" __table_resolved
trap "builtin print -p \".exit\"" EXIT
coproc 2>&1 sqlite3
builtin print -p '.prompt "" ""'
builtin print -p ".open ${__db_dir}/${__db_file}"
builtin print -r -p '.prompt "" ""'
builtin print -r -p ".open ${__db_dir}/${__db_file}"
local -a __hook_arr_out
[[ -n "${DB_DEFS[${__db}_<hooks>_on_open]}" ]] && {
builtin print -r -p -- "${${DB_DEFS[${__db}_<hooks>_on_open]#(\!|@|\#)}//(#m)${~_xchg_pat_}/${_xchg_map_[$MATCH]}}"
if [[ "${DB_DEFS[${__db}_<hooks>_on_open]}" = (\!|\#)* ]]; then
-zflai_coproc_error_fetch SQLite 1 '__hook_arr_out[1]' ${${${(M)DB_DEFS[${__db}_<hooks>_on_open]#\!}:+get-tokens-nl}:-whitespace-collapse}
elif [[ "${DB_DEFS[${__db}_<hooks>_on_open]}" = @* ]]; then
-zflai_coproc_error_fetch SQLite 1 __hook_arr_out "get-tokens"
fi
}
[[ -n "${DB_DEFS[${__db}_<hooks>_on_open_sh]}" ]] && (
builtin cd -q "${DB_DEFS[${__db}_<access>_path]}" && \
() { eval "${DB_DEFS[${__db}_<hooks>_on_open_sh]//(#m)${~_xchg_pat_}/${_xchg_map_[$MATCH]}}"; } "${__hook_arr_out[@]}"
)
# Search for definition of the target table
-zflai_get_abstract_table_for "$__db" "$__table" "tspec_" __table_def_param_name __have_table_def || \
@ -81,4 +95,20 @@ for __it in "${(P)__array}"; do
fi
done
__hook_arr_out=()
[[ -n "${DB_DEFS[${__db}_<hooks>_on_close]}" ]] && {
builtin print -r -p -- "${${DB_DEFS[${__db}_<hooks>_on_close]#(\!|@|\#)}//(#m)${~_xchg_pat_}/${_xchg_map_[$MATCH]}}"
if [[ "${DB_DEFS[${__db}_<hooks>_on_close]}" = (\!|\#)* ]]; then
-zflai_coproc_error_fetch SQLite 1 '__hook_arr_out[1]' ${${${(M)DB_DEFS[${__db}_<hooks>_on_close]#\!}:+get-tokens-nl}:-whitespace-collapse}
elif [[ "${DB_DEFS[${__db}_<hooks>_on_close]}" = @* ]]; then
-zflai_coproc_error_fetch SQLite 1 __hook_arr_out "get-tokens"
fi
}
[[ -n "${DB_DEFS[${__db}_<hooks>_on_close_sh]}" ]] && (
builtin cd -q "${DB_DEFS[${__db}_<access>_path]}" && \
() { eval "${DB_DEFS[${__db}_<hooks>_on_close_sh]//(#m)${~_xchg_pat_}/${_xchg_map_[$MATCH]}}"; } "${__hook_arr_out[@]}"
)
# vim:ft=zsh:et

View file

@ -71,7 +71,7 @@ for (( idx=1; idx <= priv_arr_index; ++ idx )); do
[[ "$db_string" = [[:space:]]# ]] && { print "ERROR: didn't find db_string for $priv_arr_name"; continue; }
if [[ "${DB_DEFS[${sel_db}_<access>_engine]}" = "sqlite3" ]]; then
-zflai_sqlite_store "$sel_db" "$sel_table" "$priv_arr_name"
-zflai_sqlite_store "$sel_db" "$sel_table" "$priv_arr_name" "$sel_table_resolved"
elif [[ "${DB_DEFS[${sel_db}_<access>_engine]}" = "file" ]]; then
-zflai_file_store "$sel_db" "$sel_table" "$priv_arr_name" "$sel_table_resolved"
elif [[ "${DB_DEFS[${sel_db}_<access>_engine]}" = "elastic-search" ]]; then