#!/bin/ash
# *********************************************************************
#  Written by and copyright Carlo Strozzi <carlos@linux.it>.
#
#  edittable: NoSQL trivial table editor. Requires a vi(1)-compatible
#	      full-screen editor.
#  Copyright (C) 1998-2001 Carlo Strozzi <carlos@linux.it>
#
#  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.
#
#  2001-03-24 Beta Code
#  2001-04-06 Removed record-level locking facilities.
#  2001-05-25 Switched to lockfile(1) for table-locking
#  2001-05-26 Fixed unsupported 'if !' of early ash(1) versions.
#  2001-06-20 Better naming convention for temporary files.
#  2001-08-05 Added option '--list'.
#
# *********************************************************************

# $Id$

#
# Function section
#

#
# Main program.
#

if [ "$1" = "-l" ] || [ "$1" = "--list" ]
then
   edit_format=list
   shift
fi

if [ $# != 1 ]
then
   echo 'Usage: edittable [-l|--list] 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.

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

# 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 $tbl_file.lock"
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
   tabletolist < $tbl_file > $edit_tmp
else
   cp $tbl_file $edit_tmp
fi

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

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

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

   if [ "$2" = "" ]
   then
      break
   else
      offset=$2
      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 | sorttable > $tbl_tmp
else
   sorttable < $edit_tmp > $tbl_tmp
fi

mv $tbl_tmp $tbl_file || exit 1

#
# End of program.
#
