#****************************************************************************
#  ##   ##         #####   #####  ##     **        NoSQL RDBMS - sort       *
#  ###  ##        ####### ####### ##     **      $Revision: 2.1 $			*
#  #### ##        ###     ##   ## ##     ************************************
#  #######  ####  #####   ##   ## ##     **      Carlo Strozzi (c) 1998     *
#  ####### ######   ##### ## # ## ##     ************************************
#  ## #### ##  ##     ### ##  ### ##     **           Written by            *
#  ##  ### ###### ####### ######  ###### **          Carlo Strozzi          *
#  ##   ##  ####   #####   #### # ###### **     e-mail: carlos@linux.it     *
#****************************************************************************
#   NoSQL RDBMS, Copyright (C) 1998 Carlo Strozzi.                          *
#   This program comes with ABSOLUTELY NO WARRANTY; for details             *
#   refer to the GNU General Public License.                                *
#****************************************************************************
#
#  Sorts a table.
#
#  Sorts a table on one or more columns. Additional sort(1) options
#  that can be specified on the command line are '-cbdfinru'. See sort(1)
#  for more info on what each option means.
#  If no sort columns are specified, then the input table is sorted on 
#  entire rows.
#
#  This NoSQL operator reads a table from STDIN and writes an
#  table to STDOUT.
#
########################################################################

########################################################################
# BEGIN block
########################################################################

BEGIN \
{
  NULL = ""; FS = OFS = "\t";
  split( __nosql_args, args, " " )

  while ( args[++i] != NULL )
  {
	# Test for the debug flag first.
	if ( args[i] == "-x" || args[i] == "--debug" )
	{
	  debug = 1
	  continue
	}

	# Separate sort(1) options from column names.
	if ( substr( args[i],1,1 ) == "-" )
	{
	  sub( /^-/, "", args[i] )		# Remove leading hyphen.
	  sort_args = sort_args args[i]
	}
	else command_cols[++j] = args[i]
  }

  command_cols[0] = j
}

########################################################################
# Main loop
########################################################################

# Column names and positions.
NR == 1 \
{
  while ( ++p <= NF )
  {
	# Make sure we pick the first occurrence of duplicated column
	# names (it may happen after a join).
	if ( P[$p] == NULL ) { P[$p] = p; N[p] = $p }
  }

  # Remove forbidden sort options.
  gsub( /[^cbdfinru]/, NULL, sort_args )
  # Add leading '-'
  if ( sort_args != NULL ) sort_args = "-" sort_args

  # Add list of columns, excluding the invalid ones.
  for ( i = 1; i <= command_cols[0]; i++ )
  {
    if ( P[ command_cols[i] ] != NULL )
	{
	  # Avoid passing duplicated fields to sort(1).
	  if ( ! done[ command_cols[i] ] )
	  {
		# Build the +POS1 -POS2 directions for sort(1).
	    sort_fields = sort_fields " +" P[ command_cols[i] ] - 1
	    sort_fields = sort_fields " -" P[ command_cols[i] ]
	    done[ command_cols[i] ] = 1
	  }
	}
  }

  sort_cmd = "sort -t \"\011\" " sort_args " " sort_fields

  # Print header and dashline.
  print; gsub( /[^\t]/, "-" ); print;

  # Make sure the header is printed before calling sort(1).
  fflush(); next
}

# Dashline
NR == 2 { if ( debug ) print sort_cmd > "/dev/stderr" ; next }

# Table body.
{ print |sort_cmd }

