#****************************************************************************
#  ##   ##         #####   #####  ##     **       NoSQL RDBMS - istable     *
#  ###  ##        ####### ####### ##     **        $Revision: 2.1.2 $       *
#  #### ##        ###     ##   ## ##     ************************************
#  #######  ####  #####   ##   ## ##     **      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.                                *
#****************************************************************************
#
#  Checks that a file is a valid NoSQL table.
#
#  This NoSQL operator reads a file from STDIN and returns an exit
#  code equal 0 if the file is a valid table, or 255 otherwise.
#  If option '-n' is specified (together with option 'v'), then the failing
#  row No.(s) will not include the header, i.e. it will be the failing
#  row No. - 2.
#
#
#  Usage: nosql istable [-v|--verbose] [-n|--no-header] < table
#
########################################################################

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

BEGIN \
{
  NULL = ""; FS = OFS = "\t";

  # Handle command-line switches.
  split( __nosql_args, args, " " )

  while ( args[++i] != NULL )
  {
	if ( args[i] == "-v" || args[i] == "--verbose" ) verbose = 1
	else if ( args[i] == "-n" || args[i] == "--no-header" ) no_hdr = 1
  }
}

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

# Column names.
NR == 1 \
{
  num_cols = NF

  # Check the column name line.
  if ( $0 !~ /^[A-Za-z0-9\t_ ]+$/ )
  {
	if ( verbose )
	  print "nosql istable: invalid characters in column names" > "/dev/stderr"

	errors = 1
	exit 255
  }

  # Check individual column names.
  for ( i = 1; i <= NF; i++ )
  {
	if ( $i !~ /^[A-Za-z]/ )
	{
	  if ( verbose )
		print "nosql istable: invalid column name '" $i "'" > "/dev/stderr"

	  errors = 1
	  exit 255
	}
  }
}

# Dashline.
NR == 2 \
{
  if ( NF != num_cols )
  {
	if ( verbose )
	  print "nosql istable: dashes do not match column heads" > "/dev/stderr"

	errors = 1
	exit 255
  }
  if ( $0 !~ /^[-\t]+$/ )
  {
	if ( verbose )
	  print "nosql istable: dashline is missing" > "/dev/stderr"

	errors = 1
	exit 255
  }
}

NR > 2 \
{
  # Empty rows in a one-column table are ok.
  if ( $0 ~ /^$/ && num_cols == 1 ) next

  if ( NF != num_cols )
  {
	if ( verbose )
	{
	  if ( no_hdr ) nr = NR - 2
	  else nr = NR

	  print "nosql islist: bad No. of fields at line " nr > "/dev/stderr"
	}

	errors = 1
	exit 255
  }
}

END \
{
  if ( NR == 0 ) errors = 1
  if ( verbose )
  {
	if( errors ) print "nosql istable: table not ok" > "/dev/stderr"
	else print "nosql istable: table ok" > "/dev/stderr"
  }
}

