#!/bin/bash
#
# CLX Database maintenance program
#
# Last change DL6RAI: Sun Nov 12 04:03:51 GMT 2000


PROG=`basename $0`
HOME=/usr/local/clx
export HOME
. $HOME/.profile
CONFIG=$HOME/config/clx_par
LANG=C ; export LANG
N=0
PSQL="psql -d clx_db"
PROMPT="-->"
ECHO=":"

# If we ever need to decide version number
# PG_VERSION=`$PSQL -c "$CMD" | awk '/PostgreSQL/ {print$2}'`
# PG_VERSION=`echo $PG_VERSION | tr -d '.'`
# $ECHO "PG_VERSION: $PG_VERSION"

exit_gracefully() {
	$HOME/tools/clx_watchdog -q on
}

#
# Turn the CLX watchdog off in case something takes a long time but
# set a trap to turn it back on on exit or when this program is
# terminated with kill or kill -3.
#
$HOME/tools/clx_watchdog -q off
trap exit_gracefully EXIT TERM QUIT

#
# If we are called from usr_mng then the prompt contains
# our callsign, else it's our user id
#
PARENT=`/bin/ps ax | /usr/bin/awk -v ppid=$PPID '{if ($1 == ppid) {print $5}}'`
if [ "$PARENT" = "usc_mng" ]
then
	MYCALL=$1 ; shift
else
	MYCALL=`whoami`
fi

#
# Set some default values
#
ANNLIMIT=30
MAILLIMIT=90
LOGLIMIT=20
USLIMIT=120
DXLIMIT=100
QSLFILE="/usr/local/clx/tmp/sdx_qsl.ful"
VHFFILE="/usr/local/clx/tmp/vhf.dbf"
IOTAFILE="/usr/local/clx/tmp/iota.data"
BATCHCOMMANDS="1b 1f 2a 2b 4c 4d 5a 5b 6b 6d 7i 3b v q"


#
# Process command line switch
#
if [ "$1" = "-v" ]
then
	ECHO="echo + "
	shift
fi

#
# Find out if we are in batch mode or interactive
#
if [ "$1" ]
then
	# Batch mode
	MODE="batch"
	ECHO="echo + "
else
	# interactive mode
	MODE="interactive"
fi

#
# Now try to read values from the config file
#
if [ -f $CONFIG ]
then
	for i in MAILLIMIT LOGLIMIT USLIMIT DXLIMIT QSLFILE BATCHCOMMANDS \
		ANNLIMIT VHFFILE IOTAFILE
	do
		T=`grep -i "^$i:" $CONFIG | perl -ne 's/^.+://i; 
					      s/[#].*$//; 
                                              s/^\s+//; 
                                              s/\s+$//; 
                                              print $_;'`
		if [ "$T" ]
		then
			eval $i=$T
			if [ "$MODE" = "batch" ]
			then
				echo "setting $i=$T from clx_par"
			fi
		fi
	done
fi



#
# Main program loop
#

while [ "$N" != "99" -a "$N" != "" ]
do

CMD="\\q"

if [ "$MODE" = "batch" ]
then
	if [ "$1" = "batch" ]
	then
		set -- $BATCHCOMMANDS
	fi
	N=$1
	NOW=`/bin/date '+%X %Z'`
	echo -e "\n\n($PROG $NOW) $PROMPT $N"
	shift
else
	echo -ne "($PROG:$MYCALL) $PROMPT "
	read N
fi

case $N in

	"h") cat <<!

CLX Database maintenance program, main menu

 1 -- DX Table related functions
 2 -- WWV Table related functions
 3 -- Statistical functions
 4 -- Modify user records
 5 -- User log related functions
 6 -- Mailbox related functions
 7 -- QSL table related functions
 8 -- Other database table functions
 9 -- General functions
 q -- Exit

!
	;;

	"1")	cat <<!

DX Table related functions

1a -- Select any DX spots sorted by call
1b -- Delete dummy DX spots like "CQ, DX, DE" etc.
1c -- Select any DX spots sorted by logger
1d -- Delete specific OID from dx_data
1e -- Delete DX spots older than $DXLIMIT days (trims the dx_data table).
1f -- Delete any DX spots in the future
1g -- Delete any Announcements older than $ANNLIMIT days
 q -- Exit

!

	;;

	"1a")	echo -ne "prefix (enter for any prefix): "
		read PFX
		DX="dx_call,dx_dati,dx_freq,log_a,oid from dx_data"
		CMD="select $DX where dx_call~'^"$PFX"' order by dx_call;"
                $ECHO $CMD
		$PSQL -c "$CMD"
	;;

        "1b")	CMD="delete from dx_data where dx_call~'^.$|^..$|\\\?|^[a-z/]*$'"
                $ECHO $CMD
		$PSQL -c "$CMD"
	;;

	"1c")	echo -ne "logger (enter for any call): "
		read LOGGER
		DX="dx_call,dx_dati,dx_freq,log_a,oid from dx_data"
		CMD="select $DX where log_a~'^"$LOGGER"' order by dx_dati;"
                $ECHO $CMD
		$PSQL -c "$CMD"
	;;

	"1d")	echo -ne "OID-List (Enter to abort): "
		read OID
		if [ "$OID" ]
                then
			for i in $OID
			do
				CMD="delete from dx_data where oid=$i;"
	                	$ECHO $CMD
				$PSQL -c "$CMD"
			done
		fi
	;;

	"1e")	A="dx_dati<timemi('now','@${DXLIMIT} days')"
		CMD="delete from dx_data where $A;"
                $ECHO $CMD
		$PSQL -c "$CMD"
	;;

	"1f")	CMD="delete from dx_data where dx_dati > 'now';"
                $ECHO $CMD
		$PSQL -c "$CMD"
	;;

	"1g")	A="ann_dati<timemi('now','@${ANNLIMIT} days')"
		CMD="delete from ann_data where $A;"
		$ECHO $CMD
		$PSQL -c "$CMD"
	;;

	"2")	cat <<!

WWV Table related functions

2a -- Delete any WWV spots in the future
2b -- Delete duplicate and un-timely WWV spots
 q -- Exit

!
	;;

	"2a")	CMD="delete from wwv_data where wwv_date > 'now';"
                $ECHO $CMD
                $PSQL -c "$CMD"

	;;

	"2b")	CMD="UPDATE wwv_data 
			SET wwv_hour=int2(int4(trunc(float8(wwv_hour/3)*3))) 
			WHERE wwv_hour!=int2(int4(trunc(float8(wwv_hour/3)*3)))"
		$ECHO $CMD
		$PSQL -c "$CMD"
		CMD="DELETE from wwv_data WHERE (wwv_hour>21 OR wwv_hour<0)"
		$ECHO $CMD
		$PSQL -c "$CMD"
		# CMD="CREATE TABLE oids (to_delete oid, unique(to_delete))"
		CMD="CREATE TABLE oids (to_delete oid)"
		$ECHO $CMD
		$PSQL -c "$CMD"
		CMD="INSERT INTO oids
			 SELECT a.oid AS to_delete
			 FROM wwv_data a, wwv_data b
			     WHERE a.wwv_date=b.wwv_date
			     AND a.wwv_hour=b.wwv_hour
			     AND a.wwv_a=b.wwv_a
			     AND a.wwv_k=b.wwv_k
			     AND a.oid>b.oid"
		$ECHO $CMD
		$PSQL -c "$CMD"
		CMD="DELETE FROM wwv_data WHERE oids.to_delete=wwv_data.oid"
		$ECHO $CMD
		$PSQL -c "$CMD"
		CMD="DROP TABLE oids"
		$ECHO $CMD
		$PSQL -c "$CMD"
	;;

	"3")	cat <<!

Statistical functions

3a -- Show number of DX records in last 60 minutes, 24 hours and 7 days
3b -- Show number of records in DX, ANN, User Tables
3c -- Show number of DX records in the last 7 days (day by day)
 q -- Exit

!
	;;

	"3a")	echo "Record Counts for dx_data table:"
		echo ""
		for i in "60 minutes" "3 hours" "24 hours" "7 days"
		do
			A="dx_dati>=timemi('now','@${i}')"
			CMD="select count(*) from dx_data where $A;"
			$ECHO $CMD
			count=`$PSQL -Aqtc "$CMD"`
			printf "%20s: %6d\n" "Last $i" $count
		done
		echo ""
	;;

	"3b")	echo "Record Counts for some CLX tables:"
		for i in dx_data wwv_data ann_data qsl_mng us_data \
			us_log ml_file
		do
			CMD="select count(*) from $i;"
			$ECHO $CMD
			count=`$PSQL -Aqtc "$CMD"`
			printf "%12s: %6d\n" $i $count
		done
	;;

	"3c")	echo "Number of DX Spots over the last 7 days:"
		echo ""
		for i in 7 6 5 4 3 2 1 0
		do
			D=`/bin/date '+%b %d xxx %Y GMT' -d "$i days ago"`
			D1=`echo $D | sed "s/xxx/00:00:00/"`
			D2=`echo $D | sed "s/xxx/23:59:59/"`
			A="dx_dati <?> mktinterval('$D1','$D2')"
			CMD="select count(*) from dx_data where $A"
			$ECHO $CMD
			count=`$PSQL -Aqtc "$CMD"`
			printf "%s - %s : %6d\n" "$D1" "$D2" $count
		done
		echo ""
	;;

	"4")	cat <<!

Modify user records

4a -- Show a specific user record (full)
4b -- Delete specific OID from us_data
4c -- Show all users with special rights
4d -- Show users with "bye" or "quit" in login script
4e -- Show duplicate user records in us_data
4f -- Delete duplicate home node records in us_uhn
4g -- Delete duplicate user records in us_data
 q -- Exit

!
	;;

	"4a")	echo -ne "callsign: "
		read CALL
		CMD="select *,oid from us_data where us_call~'^"$CALL"';"
		$ECHO $CMD
		$PSQL -x -c "$CMD"
	;;

	"4b")	echo -ne "OID-List (Enter to abort): "
		read OID
		if [ "$OID" ]
                then
			for i in $OID
			do
				CMD="delete from us_data where oid=$i;"
				$ECHO $CMD
				$PSQL -c "$CMD"
			done
		fi
	;;

	"4c")	CMD="select us_call,us_name,us_qth,us_perm from us_data where us_perm>0;"
		$ECHO $CMD
		$PSQL -c "$CMD"
	;;

	"4d") 	CMD="find $HOME/box/batch/start ..."
		$ECHO $CMD
		find $HOME/box/batch/start -type f -exec \
			egrep -l "^[ ]*[bq]" {} \;
	;;

	"4e")	A="a.us_call,a.us_name,a.f_login,a.oid"
		CMD="select $A from us_data a, us_data b
			where a.us_call=b.us_call and a.oid!=b.oid
			order by a.f_login;"
		$ECHO $CMD
		$PSQL -c "$CMD"
	;;

	"4f")	CMD="CREATE TABLE oids (to_delete oid)"
		$ECHO $CMD
		$PSQL -c "$CMD"
                CMD="INSERT INTO oids 
                         SELECT a.oid AS to_delete 
                             FROM us_uhn a, us_uhn b 
                             WHERE a.us_call=b.us_call AND a.oid>b.oid;
                     SELECT count(*) from oids;
                     DELETE FROM us_uhn WHERE oids.to_delete=us_uhn.oid;"
		$ECHO $CMD
		$PSQL -c "$CMD"
                CMD="DROP TABLE oids;"
		$ECHO $CMD
		$PSQL -c "$CMD"
	;;

	"4g")	CMD="CREATE TABLE oids (to_delete oid)"
		$ECHO $CMD
		$PSQL -c "$CMD"
                CMD="INSERT INTO oids 
                         SELECT a.oid AS to_delete 
                             FROM us_data a, us_data b 
                             WHERE a.us_call=b.us_call AND a.oid>b.oid;
                     SELECT count(*) from oids;
                     DELETE FROM us_data WHERE oids.to_delete=us_data.oid;"
		$ECHO $CMD
		$PSQL -c "$CMD"
                CMD="DROP TABLE oids;"
		$ECHO $CMD
		$PSQL -c "$CMD"
	;;

	"5")	cat <<!

User log related functions

5a -- Delete entries from us_data with no login for $USLIMIT days and us_perms=0
5b -- purge entries older than $LOGLIMIT days from us_log
 q -- Exit

!
	;;

	"5a")	A="l_login<timemi('now','@${USLIMIT} days') and us_perm=0"
		CMD="delete from us_data where $A;"
		$ECHO $CMD
		$PSQL -c "$CMD"
	;;

	"5b")	A="log_time<timemi('now','@${LOGLIMIT} days')"
		CMD="delete from us_log where $A;"
		$ECHO $CMD
		$PSQL -qtc "$CMD"
	;;


	"6")	cat <<!

Mailbox related functions

6a -- Delete mail messages older than $MAILLIMIT days
6b -- Check mailbox consistency
6c -- Cleanup forwarding queues
6d -- Move mails to/from forwarding queue (sync with home node)
 q -- Exit

!

	;;

	"6a")	A="f_thema='mail' and 
			f_date<timemi('now','@${MAILLIMIT} days')"
		CMD="delete from ml_file where $A;"
		$ECHO $CMD
		$PSQL -c "$CMD"
		CMD="$HOME/tools/mbx_chk -q"
		$ECHO $CMD
		$CMD
	;;

	"6b")	CMD="$HOME/tools/mbx_chk -q"
		$ECHO $CMD
		$CMD
	;;

	"6c")	echo "Existing (non-empty) forwarding queues:"
		PWD=`pwd`
		cd $HOME/box/iclb
		j=0
		for i in `/bin/ls` 
		do 
			c="`ls $i | wc -l`"
			if [ $c -gt 0 ]
			then 
				printf "%10s: %3d messages\n" $i $c
				j=`expr $j + 1`
			fi
		done
	
		if [ $j -gt 0 ]
		then
			echo -ne "Forwarding queue(s) to be deleted (Enter to abort): "
			read QUEUE
			if [ "$QUEUE" ]
			then
				~/tools/rm_fwd $QUEUE
			fi
		else
			echo "All forwarding queues are empty."
		fi
		cd $PWD
	;;

	"6d")	CMD="$HOME/tools/do_fwd"
		$ECHO $CMD
		$CMD
	;;


	"7")	cat <<!

QSL table related functions

7a -- Delete all QSL records that were not entered by users
7b -- Delete specific OID from QSL database
7c -- Read in QSL records from $QSLFILE
7d -- Find any duplicate info from QSL database
7e -- Count records in QSL database
7f -- Search the QSL database
7g -- Find QSL records that were entered by users
7h -- Extract QSL info from whole dx_data table
7i -- Extract QSL info from dx_data table 30 days back
 q -- Exit

!
	;;

	"7a")	A="cll_auth ISNULL"
		CMD="delete from qsl_mng where $A;"
                $ECHO $CMD
		$PSQL -qtc "$CMD"
	;;
	"7b")	echo -ne "OID-List (Enter to abort): "
		read OID
		if [ "$OID" ]
                then
			for i in $OID
			do
				CMD="delete from qsl_mng where oid=$i;"
				$ECHO $CMD
				$PSQL -c "$CMD"
			done
		fi
	;;
	"7c")	if [ -e $QSLFILE ]
		then
			CMD="$HOME/tools/read_ak1a -t qsl $QSLFILE"
			$ECHO "++ $CMD"
			$CMD
		else
			echo "$QSLFILE does not exist."
		fi
	;;
	"7d")	A="a.stn_call,a.stn_mng,a.oid,a.add_time,a.a_comm"
		CMD="select $A from qsl_mng a, qsl_mng b
			where a.stn_call=b.stn_call 
			AND a.stn_mng=b.stn_mng
			and a.oid!=b.oid
			order by a.add_time;"
		$ECHO $CMD
		$PSQL -c "$CMD"
	;;
	"7e")	CMD="select count(*) from qsl_mng;"
                $ECHO $CMD
		c=`$PSQL -qtc "$CMD"`
		echo "The QSL database contains $c records."
	;;
	"7f")	echo -ne "callsign: "
		read CALL
		CMD="select stn_call,stn_mng,a_comm,oid from qsl_mng 
			where stn_call='$CALL' 
			or stn_mng='$CALL';"
		$ECHO $CMD
		$PSQL -x -c "$CMD"
	;;
	"7g")	A="cll_auth NOTNULL"
		CMD="select stn_call,stn_mng,inf_auth,add_time,cll_auth, oid
			from qsl_mng where $A;"
                $ECHO $CMD
		$PSQL -qtc "$CMD"
	;;

	"7h")	~/tools/extract_qsl_info -q
	;;

	"7i")	~/tools/extract_qsl_info -q -d 30
	;;

	"8")	cat <<!

Other database table functions

8a -- Read in new VHF database from $VHFFILE
8b -- Extract locator data to mail to DL8EBW
8c -- Read in new IOTA database from $IOTAFILE

!
	;;

	"8a")
		if [ -e "$VHFFILE" ]
		then
			CMD="$HOME/tools/read_ak1a -t vhf -c $VHFFILE"
			$ECHO "++ $CMD"
			$CMD
		else
			echo "$VHFFILE does not exist."
		fi
	;;

	"8b")	~/tools/extract_locators
	;;

	"8c")
		if [ -e "$IOTAFILE" ]
		then
			CMD="$HOME/tools/read_ak1a -t iota -c $IOTAFILE"
			$ECHO "++ $CMD"
			$CMD
		else
			echo "$IOTAFILE does not exist."
		fi
	;;

	"9")	cat <<!
General functions

 u -- Show Uptime
 a -- Update ar_band table from $HOME/config/ar_band.cd
 b -- Backup database to $HOME/backup
 r -- Restore database from $HOME/backup
 c -- Clean database (backup + drop + create + restore)
 v -- Run VACUUM manually
 i -- drop and re-create indexes
 q -- Exit
 
!
	;;

	"u")	CMD="select 'now'::datetime - datetime(sys_dat.l_start);"
		$PSQL -qtc "$CMD"
	;;

	"a")	CMD="drop table ar_band"
		$ECHO $CMD
		$PSQL -c "$CMD"
		$PSQL < ~/db/ar_band.cl
		$PSQL < ~/config/ar_band.cd
	;;

	"b")	if [ $MODE = "interactive" ]
		then
			echo -ne "Backup Database to $HOME/backup - are you sure? (y/n) >"
			read X
		fi
		if [ "$X" = "y" -o "$MODE" = "batch" ]
		then
			CMD="$HOME/tools/bup_db -s"
			$ECHO $CMD
			$CMD
		fi
	;;

	"c")	if [ $MODE = "interactive" ]
		then
			echo -ne "Clean Database - are you sure? (y/n) >"
			read X
		fi
		if [ "$X" = "y" -o "$MODE" = "batch" ]
		then
			CMD="$HOME/tools/bup_db -s"
			$ECHO $CMD
			$CMD
			CMD="$HOME/tools/clx_db"
			$ECHO $CMD
			$CMD
			$CMD="tr -d '[\01-\10,\013-\037]' < dx_data > dx_data.new"
			$ECHO $CMD
			$CMD
			CMD="mv dx_data dx_data.old; mv dx_data.new dx_data"
			$ECHO $CMD
			$CMD
			CMD="$HOME/tools/bup_db -r"
			$ECHO $CMD
			$CMD
			CMD="$HOME/tools/clx_idx"
			$ECHO $CMD
			$CMD
		fi
	;;

	"r")	if [ $MODE = "interactive" ]
		then
			echo -ne "Restore Database from $HOME/backup - are you sure? (y/n) >"
			read X
		fi
		if [ "$X" = "y" -o "$MODE" = "batch" ]
		then
			CMD="$HOME/tools/bup_db -r"
			$ECHO $CMD
			$CMD
		fi
	;;

	"v")
		CMD="select relname from pg_class where relname ~ '.*tmp*'"
		LIST=`$PSQL -qtc "$CMD"`
		for i in $LIST
		do
			CMD="drop table $i"
                	$ECHO $CMD
			$PSQL -c "$CMD"
		done
		CMD="vacuum"
		$PSQL -c "$CMD"
	;;

	"i")	~/tools/clx_idx
	;;

	"99")	
		exit_gracefully
	;;

	"q")	N=99
	;;
 
 	"*")	echo "unknown option $N"
 		
 	;;
esac

done
