prepare for later
[jackhill/mal.git] / plsql / wrap.sh
CommitLineData
97df14cd
JM
1#!/bin/bash
2
3RL_HISTORY_FILE=${HOME}/.mal-history
4SKIP_INIT="${SKIP_INIT:-}"
5
b88bb764
JM
6ORACLE_LOGON=${ORACLE_LOGON:-system/oracle}
7SQLPLUS="sqlplus -S ${ORACLE_LOGON}"
97df14cd 8
06951f55
JM
9FILE_PID=
10cleanup() {
11 trap - TERM QUIT INT EXIT
10cc781f 12 #echo cleanup: ${FILE_PID}
06951f55
JM
13 [ "${FILE_PID}" ] && kill ${FILE_PID}
14}
15trap "cleanup" TERM QUIT INT EXIT
16
17
97df14cd
JM
18# Load the SQL code
19if [ -z "${SKIP_INIT}" ]; then
20 out=$(echo "" | ${SQLPLUS} @$1)
21 if echo "${out}" | grep -vs "^No errors.$" \
22 | grep -si error >/dev/null; then
23 #if echo "${out}" | grep -si error >/dev/null; then
24 echo "${out}"
25 exit 1
26 fi
27fi
28
29# open I/O streams
02936b42 30echo -e "BEGIN io.open(0); io.open(1); END;\n/" \
97df14cd
JM
31 | ${SQLPLUS} >/dev/null
32
33# Stream from table to stdout
34(
35while true; do
02936b42 36 out="$(echo "SELECT io.read(1) FROM dual;" \
97df14cd 37 | ${SQLPLUS} 2>/dev/null)" || break
02936b42 38 #echo "out: [${out}] (${#out})"
97df14cd
JM
39 echo "${out}"
40done
41) &
8119e744 42STDOUT_PID=$!
97df14cd
JM
43
44# Perform readline input into stream table when requested
45(
46[ -r ${RL_HISTORY_FILE} ] && history -r ${RL_HISTORY_FILE}
47while true; do
02936b42 48 prompt=$(echo "SELECT io.wait_rl_prompt(0) FROM dual;" \
97df14cd
JM
49 | ${SQLPLUS} 2>/dev/null) || break
50 # Prompt is returned single-quoted because sqlplus trims trailing
51 # whitespace. Remove the single quotes from the beginning and end:
52 prompt=${prompt%\'}
53 prompt=${prompt#\'}
54 #echo "prompt: [${prompt}]"
55
56 IFS= read -u 0 -r -e -p "${prompt}" line || break
57 if [ "${line}" ]; then
58 history -s -- "${line}" # add to history
59 history -a ${RL_HISTORY_FILE} # save history to file
60 fi
61
62 # Escape (double) single quotes per SQL norm
63 line=${line//\'/\'\'}
64 #echo "line: [${line}]"
02936b42 65 ( echo -n "BEGIN io.writeline('${line}', 0); END;";
9fc524f1 66 echo -en "\n/" ) \
97df14cd
JM
67 | ${SQLPLUS} >/dev/null || break
68done
8119e744 69echo -e "BEGIN io.close(0); END;\n/" \
97df14cd
JM
70 | ${SQLPLUS} > /dev/null
71) <&0 >&1 &
72
06951f55
JM
73
74# File read if requested
75(
76while true; do
77 files="$(echo "SELECT path FROM file_io WHERE in_or_out = 'in';" \
78 | ${SQLPLUS} 2>/dev/null \
79 | grep -v "^no rows selected")" || break
80 for f in ${files}; do
02936b42 81 if [ ! -r ${f} ]; then
10cc781f 82 echo "UPDATE file_io SET error = 'Cannot read ''${f}''' WHERE path = '${f}' AND in_or_out = 'in';" \
06951f55 83 | ${SQLPLUS} >/dev/null
02936b42 84 continue;
06951f55 85 fi
02936b42
JM
86 IFS= read -rd '' content < "${f}"
87 # sqlplus limits lines to 2499 characters so split the update
88 # into chunks of the file ORed together over multiple lines
89 query="UPDATE file_io SET data = TO_CLOB('')"
90 while [ -n "${content}" ]; do
91 chunk="${content:0:2000}"
92 content="${content:${#chunk}}"
93 chunk="${chunk//\'/\'\'}"
94 chunk="${chunk//$'\n'/\\n}"
95 query="${query}"$'\n'" || TO_CLOB('${chunk}')"
96 done
97 query="${query}"$'\n'" WHERE path = '${f}' AND in_or_out = 'in';"
98 echo "${query}" | ${SQLPLUS} > /dev/null
99 #echo "file read: ${f}: ${?}"
06951f55
JM
100 done
101 sleep 1
102done
103) &
104FILE_PID=$!
105
97df14cd
JM
106res=0
107shift
108if [ $# -gt 0 ]; then
109 # If there are command line arguments then run a command and exit
110 args=$(for a in "$@"; do echo -n "\"$a\" "; done)
10cc781f
JM
111 echo -e "SELECT mal.MAIN('(${args})') FROM dual;" \
112 | ${SQLPLUS} > /dev/null
97df14cd
JM
113 res=$?
114else
115 # Start main loop in the background
10cc781f
JM
116 echo "SELECT mal.MAIN() FROM dual;" \
117 | ${SQLPLUS} > /dev/null
97df14cd
JM
118 res=$?
119fi
8119e744
JM
120# Wait for output to flush
121wait ${STDOUT_PID}
97df14cd 122exit ${res}