#!/bin/ash
# *********************************************************************
# edittable: NoSQL trivial table editor. Requires a vi(1)-compatible
#	     full-screen editor.
# Copyright (c) 1998,1999,2000,2001,2002,2003 Carlo Strozzi
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# *********************************************************************
# $Id: edittable,v 1.4 2003/10/09 10:53:30 carlo Exp $

# Get local settings and apply defaults.
: ${NOSQL_INSTALL:=/usr/local/nosql}

tab="	"			# Warning: this must be a physical TAB!

while [ $# -gt 0 ]
do
   case $1 in
	-l|--list)		edit_format=list ;;
	-L|--no-lock)		no_lock=1 ;;
	-a|--add-record)	add_rec=1 ;;
	-h|--help)
	     grep -v '^#' $NOSQL_INSTALL/help/edittable.txt
	     exit 0
	;;
	-*) ;;				# Skip unknown options.
	*) args="$args $1" ;;
   esac
   shift
done

set - $args

if [ $# != 1 ]
then
   echo 'Usage: edittable [options] tablename' >&2
   exit 1
fi

tbl_path=$1

out_dir=`dirname $tbl_path`

cd $out_dir
if [ $? -ne 0 ]
then
   echo Could not access directory "'$out_dir'" >&2
   exit 1
fi

tbl_file=`basename $tbl_path`

# Lock the target table before doing anything.

if [ "$no_lock" != 1 ]
then
   lockfile -r0 $tbl_file.lock 2>/dev/null

   if [ $? -ne 0 ]
   then
      echo edittable: unable to lock "'$tbl_file'" for write >&2
      exit 1
   fi
   trap_list="$tbl_file.lock"
fi

# We must create the work files in the same directory as the
# target table for 'mv' to work as desired.

edit_tmp=`mktemp ./$tbl_file.XXXXXX` || exit $?
tbl_tmp=`mktemp ./$tbl_file.XXXXXX` || exit $?

# Set-up trapping on signals.
trap_list="$edit_tmp $tbl_tmp $trap_list"
trap "rm -f $trap_list; trap 0; exit 0" 0 1 2 3 15

istable < $tbl_file
if [ $? -ne 0 ]
then
   echo edittable: file "'$tbl_file'" is not a valid table >&2
   exit 1
fi

if [ "$edit_format" = list ]
then
   if [ -n "$add_rec" ]
   then
      addrow < $tbl_file | tabletolist > $edit_tmp
   else
      tabletolist < $tbl_file > $edit_tmp
   fi
else
   if [ -n "$add_rec" ]
   then
      addrow --highlight < $tbl_file | tabletordb > $edit_tmp
   else
      tabletordb < $tbl_file > $edit_tmp
   fi
fi

[ "$EDITOR" = "" ] && EDITOR=vi
editor=$EDITOR

[ $EDITOR = vi ] && [ -n "$add_rec" ] && offset=+

while :
do
   if [ $EDITOR = vi ]
   then
      $editor $offset $edit_tmp
   else
      $editor $edit_tmp
   fi

   set --
   if [ "$edit_format" = list ]
   then
      plus=0
      set - `islist --verbose --edit < $edit_tmp`
   else
      plus=2
      set - `rdbtotable < $edit_tmp | istable --verbose --edit`
   fi

   if [ "$2" = "" ]
   then
      break
   else
      offset=+`expr $2 + $plus`
      echo ''
      echo 'What shall I do ?'
      echo ''
      echo '1) Re-edit the table'
      echo '2) Quit without saving the changes'
      echo '3) Commit the changes anyway'
      printf '\n=> '

      # Read one line from the terminal.
      read edit_action

      [ "$edit_action" = "" ] && edit_action=2

      case $edit_action in
         1) continue ;;
         2) exit 4 ;;
         3) break ;;
      esac
   fi
done

# Keep the table sorted on the key column.
if [ "$edit_format" = list ]
then
   listtotable < $edit_tmp | filter -- sort "-t$tab" +0 -1 > $tbl_tmp
else
   rdbtotable < $edit_tmp | filter -- sort "-t$tab" +0 -1 > $tbl_tmp
fi

old_mode=`filemode $tbl_file`
[ $? -eq 0 ] || exit 1

chmod $old_mode $tbl_tmp || exit $?

mv $tbl_tmp $tbl_file || exit $?

# End of program.
