#!/bin/sh
#
############################################################################
#
# MODULE:       v.db.renamecol
# AUTHOR(S):    Markus Neteler
# PURPOSE:      interface to db.execute to drop a column from the 
#               attribute table connected to a given vector map
#               - Based on v.db.dropcol
#               - with special trick for SQLite and DBF (here the new col is 
#                 added/values copied/old col deleted)
# COPYRIGHT:    (C) 2007 by the GRASS Development Team
#
#               This program is free software under the GNU General Public
#               License (>=v2). Read the file COPYING that comes with GRASS
#               for details.
#
# TODO: MySQL untested
#############################################################################


#%Module
#%  description: Renames a column in the attribute table connected to a given vector map.
#%  keywords: vector, database, attribute table
#%End
#%option
#% key: map
#% type: string
#% gisprompt: old,vector,vector
#% key_desc : name
#% description: Vector map for which to rename attribute column
#% required : yes
#%end
#%option
#% key: layer
#% gisprompt:  old_layer,layer,layer
#% description: Layer where to rename column
#% answer: 1
#% required : no
#%end
#%option
#% key: column
#% type: string
#% description: Old and new name of the column (old,new)
#% required : yes
#% key_desc: old_name,new_name
#% multiple: no
#%end

if [ -z "$GISBASE" ] ; then
    echo 'You must be in GRASS GIS to run this program' >&2
    exit 1
fi

# save command line
if [ "$1" != "@ARGS_PARSED@" ] ; then
    CMDLINE=`basename "$0"`
    for arg in "$@" ; do
        CMDLINE="$CMDLINE \"$arg\""
    done
    export CMDLINE
    exec g.parser "$0" "$@"
fi

PROG=`basename "$0"`

# what to do in case of user break:
exitprocedure()
{
   g.message -e 'User break!'
   exit 1
}
# shell check for user break (signal list: trap -l)
trap "exitprocedure" 2 3 15

error()
{
   g.message -e 'Cannot continue (problem renaming column)'
   exit 1
}

### setup enviro vars ###
eval `g.gisenv`
: ${GISBASE?} ${GISDBASE?} ${LOCATION_NAME?} ${MAPSET?}
# does map exist in CURRENT mapset?
eval `g.findfile element=vector file="$GIS_OPT_MAP" mapset="$MAPSET"`
if [ ! "$file" ] ; then
   g.message -e  "Vector map <$GIS_OPT_MAP> not found in current mapset"
   exit 1
fi

table=`v.db.connect -gl map="$GIS_OPT_MAP" fs="|" layer="$GIS_OPT_LAYER" | cut -f2 -d'|'`
if [ -z "$table" ] ; then
   g.message -e 'There is no table connected to the input vector map! Cannot rename any column'
   exit 1
fi

keycol=`v.db.connect -gl map="$GIS_OPT_MAP" fs="|" layer="$GIS_OPT_LAYER" | cut -f3 -d'|'`
database="`v.db.connect -gl map="$GIS_OPT_MAP" fs='|' layer=$GIS_OPT_LAYER | cut -f4 -d'|'`"
driver=`v.db.connect -gl map="$GIS_OPT_MAP" fs="|" layer="$GIS_OPT_LAYER" | cut -f5 -d'|'`
oldcol="`echo $GIS_OPT_COLUMN | cut -d',' -f1`"
newcol="`echo $GIS_OPT_COLUMN | cut -d',' -f2`"

if [ "$driver" = "dbf" ] ; then
  NAMELEN=`echo "$newcol" | wc -c`
  #max DBF column name length is 10, but wc counts echo's \n char so we test for 11.
  #  'echo -n' (output as string, ie with no newline) is apparently not portable.
  if [ "$NAMELEN" -gt 11 ] ; then
   g.message -e "Column name <$newcol> too long. The DBF driver supports column names\
    not longer than 10 characters"
   exit 1
  fi
fi

if [ "$oldcol" = "$keycol" ] ; then
   g.message -e "Cannot rename column <$oldcol> as it is needed to keep table <$table>\
     connected to the input vector map"
   exit 1
fi

# old col there?
v.info --quiet -c map="$GIS_OPT_MAP" layer=$GIS_OPT_LAYER | cut -d'|' -f1,2 | grep "|${oldcol}$" 2>&1 >/dev/null
if [ $? -ne 0 ] ; then
   g.message -e "Column <$oldcol> not found in table"
   exit 1
fi

# describe old col
oldcoltype="`db.describe -c table="${table}" database="${database}" driver=$driver | grep -w "$oldcol" | cut -d':' -f3`"
oldcollength=`db.describe -c table="${table}" database="${database}" driver=$driver | grep -w "$oldcol" | cut -d':' -f4`

# some tricks
if [ "$driver" = "sqlite" -o "$driver" = "dbf" ] ; then

	if [ "$oldcoltype" = "CHARACTER" ] ; then
	    v.db.addcol map="$GIS_OPT_MAP" layer=$GIS_OPT_LAYER col="$newcol varchar($oldcollength)" || error
	else
	    v.db.addcol map="$GIS_OPT_MAP" layer=$GIS_OPT_LAYER col="$newcol $oldcoltype" || error
	fi
	echo "UPDATE $table SET $newcol=$oldcol" | db.execute database="${database}" driver=${driver}
	v.db.dropcol map="$GIS_OPT_MAP" layer=$GIS_OPT_LAYER col=$oldcol
else
	echo "ALTER TABLE $table RENAME $oldcol TO $newcol" | db.execute database="${database}" driver=${driver} || error
fi


# write cmd history:
v.support map="${GIS_OPT_MAP}" cmdhist="${CMDLINE}"

exit 0
