#!/usr/bin/perl

=pod

=head1	NAME

B<Create_Pipeline>

Create a Conductor pipeline table set in a MySQL database.

=head1	SYNOPSIS

Create_Pipeline | Create_[E<lt>B<catalog>E<gt>.]E<lt>B<pipeline>E<gt>
[-Catalog E<lt>B<catalog>E<gt>[.E<lt>B<pipeline>E<gt>]]
[[-Pipeline] [E<lt>B<catalog>E<gt>.]E<lt>B<pipeline>E<gt>]

=head1	OPTIONS AND ARGUMENTS

Both a catalog and pipeline name are required. Either or both may be
specified in the command name, the -Catalog name or the -Pipeline name
arguments. A name containing a period character ('.') is split into a
catalog name from the part preceeding the period and a pipeline name from
the part following the period. If the command name contains an underbar
character ('_') that is followed by a non-zero length word that is not
"Pipeline" then that word is taken to be the pipeline name (or
catalog.pipeline if it contains a period). A name without a period is the
pipeline name unless it occurs with the -Catalog argument in which case
it is the catalog name.

=over

=item	-Catalog E<lt>B<catalog>E<gt>[.E<lt>B<pipeline>E<gt>]

The name of the database catalog where the pipeline tables are to be
created. The catalog name may be qualified by the E<lt>B<pipeline>E<gt>
name, following a '.' delimiter. Default: The E<lt>B<catalog>E<gt> name
in the -Pipeline name or command name, if present, in that order.

=item	[-Pipeline] [E<lt>B<catalog>E<gt>.]E<lt>B<pipeline>E<gt>

The prefix name of the pipline tables. The pipeline name may be qualified
by the E<lt>B<catalog>E<gt> name, preceeding a '.' delimiter. Default:
The E<lt>B<pipeline>E<gt> name in the  -Catalog name or command name, if
present, in that order. Note: A command line argument that is not
preceeded by a switch (with a '-' prefix) is treated as if it was
preceeded by the -Pipeline switch.

=item	-Help

The man page for this procedure is listed.

=back

=head1	DESCRIPTION

A pair of pipeline tables will be created in the database catalog. The
mysql command line utility will be used to do this. The catalog (a.k.a.
"database") will be created if it does not exist. Then the pipeline
tables will be created in the catalog if they do not already exist. Note
that existing tables are never replaced or modified; if an existing table
with the expected pipeline name does not have the expected field
definitions these will not be changed.

The E<lt>B<pipeline>E<gt>_Sources table will contain the following fields:

    Field Name          Field Type
    ------------------  ---------------------------------------------
    Source_Number       INT UNSIGNED NOT NULL AUTO_INCREMENT
                            PRIMARY KEY
    Source_Pathname     TEXT NOT NULL
    Source_ID           VARCHAR(64) BINARY
    Conductor_ID        VARCHAR(64)
    Status              TEXT
    Log_Pathname        TEXT
    Last_Update         TIMESTAMP

The E<lt>B<pipeline>E<gt>_Procedures table will contain the following fields:

    Field Name          Field Type
    ------------------  ----------------------------------------------
    Sequence            FLOAT NOT NULL PRIMARY KEY
    Description         TEXT
    Command_Line        TEXT NOT NULL
    Success_Status      TEXT
    Success_Message     TEXT
    Time_Limit          TEXT
    On_Failure          TEXT
    Last_Update         TIMESTAMP

Both tables will be TYPE InnoDB.

=head1	Exit Status

=over

=item	E<48> - Success

The database table insert(s) completed successfully.

=item	E<49> - Bad command line syntax

A command line syntax usage message will be provided.

=item	E<50> - Create failed

There was a problem creating the database tables. This usually means
that the user does not have the required database permissions to
create the catalog and/or tables.

=back

=head1	Author

Bradford Castalia, UA/PIRL

=head1	Copyright

Copyright (C) 2004-2012 Arizona Board of Regents on behalf of the
Planetary Image Research Laboratory, Lunar and Planetary Laboratory at
the University of Arizona.

This file is part of the PIRL Java Packages.

The PIRL Java Packages are free software; you can redistribute them
and/or modify them under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.

The PIRL Java Packages are distributed in the hope that they will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.

=head1	Version

1.14 2012/04/16 06:04:10

=cut

#	PIRL CVS ID: Create_Pipeline,v 1.14 2012/04/16 06:04:10 castalia Exp
#===============================================================================
$CVS_ID = 'Create_Pipeline (1.14 2012/04/16 06:04:10)';

($Command_Name = $0) =~ s|.*/(\w+)$|$1|;
print "$CVS_ID\n";


#	Database client for submitting SQL statements.
@SQL_Tool			= ('mysql', '-e');

$Sources_Fields			= q(
    (
    Source_Number       INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
    Source_Pathname     TEXT NOT NULL,
    Source_ID           VARCHAR(64) BINARY,
    Conductor_ID        VARCHAR(64),
    Status              TEXT,
    Log_Pathname        TEXT,
    Last_Update         TIMESTAMP
    )
    TYPE=InnoDB
);

$Procedures_Fields		= q(
    (
    Sequence            FLOAT NOT NULL PRIMARY KEY,
    Description         TEXT,
    Command_Line        TEXT NOT NULL,
    Success_Status      TEXT,
    Success_Message     TEXT,
    Time_Limit          TEXT,
    On_Failure          TEXT,
    Last_Update         TIMESTAMP
    )
    TYPE=InnoDB
);

#	Exit status values:
$SUCCESS				= 0;
$BAD_SYNTAX				= 1;
$CREATE_FAILED			= 2;

#-------------------------------------------------------------------------------
#	Command line arguments:

use Pod::Usage;

while ($option = shift @ARGV)
	{
	if ($option =~ /^-[Pp]/)
		{
		#	Pipeline.
		if (! @ARGV || $ARGV[0] =~ /^-/)
			{
			Missing_Pipeline:
			pod2usage
				(
				-message => "$Command_Name: Missing pipeline name.\n",
				-verbose => 0,
				-exitval => BAD_SYNTAX
				);
			}
		$option = shift @ARGV;
		Pipeline_Name:
		$Pipeline = $option
			unless ($Pipeline = pipeline_name ($option));

		#	Check for catalog name.
		$Catalog = catalog_name ($option)
			unless $Catalog;
		next;
		}
	if ($option =~ /^-[Cc]/)
		{
		#	Catalog.
		if (! @ARGV || $ARGV[0] =~ /^-/)
			{
			Missing_Catalog:
			pod2usage
				(
				-message => "$Command_Name: Missing database catalog name.\n",
				-verbose => 0,
				-exitval => $BAD_SYNTAX
				);
			}
		$Catalog = $option
			unless ($Catalog = catalog_name ($option = shift @ARGV));

		#	Check for pipeline name.
		$Pipeline = pipeline_name ($option)
			unless $Pipeline;
		next;
		}

	#	Help.
	pod2usage
		(
		-verbose => 2,
		-exitval => 0
		)
		if ($option =~ /^-[Hh]/);

	pod2usage
		(
		-message => "$Command_Name: Unknown option \"$option\"\n",
		-verbose => 0,
		-exitval => $BAD_SYNTAX
		)
		if ($option =~ /^-/);

	goto Pipeline_Name;
	}

#	Ensure that both a catalog and pipeline name were provided.

if (! $Pipeline)
	{
	#	Check the command name for the pipeline name.
	($Create, $pipeline) = split (/_/, $Command_Name, 2);
	goto Missing_Pipeline
		if ($pipeline eq "Pipeline" ||
			$pipeline eq "");
	$Pipeline = $pipeline
		if (! ($Pipeline = pipeline_name ($pipeline)));

	#	Check for catalog name.
	$Catalog = catalog_name ($pipeline)
		if (! $Catalog);
	}

goto Missing_Catalog
	if (! $Catalog);


#-------------------------------------------------------------------------------
#	Catalog

print
	"==> Creating the $Catalog database catalog,\n",
	"    if it doesn't already exist.\n";
&Database_Operation ("CREATE DATABASE IF NOT EXISTS $Catalog");

#-------------------------------------------------------------------------------
#	Sources table

print
	"==> Creating the ${Catalog}.${Pipeline}_Sources table,\n",
	"    if it doesn't already exist,\n",
	"    with fields -",
	$Sources_Fields;

&Database_Operation
	("CREATE TABLE IF NOT EXISTS $Catalog.$Pipeline"."_Sources $Sources_Fields");

#-------------------------------------------------------------------------------
#	Procedures table

print
	"==> Creating the ${Catalog}.${Pipeline}_Procedures table,\n",
	"    if it doesn't already exist,\n",
	"    with fields -",
	$Procedures_Fields;

&Database_Operation
	("CREATE TABLE IF NOT EXISTS $Catalog.$Pipeline"."_Procedures $Procedures_Fields");


exit (0);

#-------------------------------------------------------------------------------

sub catalog_name
{
my ($name) = @_;
return (($index = index ($name, '.')) > 0) ?
	substr ($name, 0, $index) : undef;
}


sub pipeline_name
{
my ($name) = @_;
return (($index = index ($name, '.')) >= 0 && $index < (length ($name) - 1)) ?
	substr ($name, $index + 1) : undef;
}


sub Database_Operation {

my ($SQL_statement) = @_;
#	Replace NL and tabs and compress down whitespace.
$SQL_statement =~ tr/\n\t /   /s;
#	Trim off leading and trailing whitespace.
$SQL_statement =~ s|^\s*(.*?)\s*$|$1|;
push @SQL_Tool, $SQL_statement;
print "++> Database_Operation:\n@SQL_Tool\n"
	if ($Verbose > 1);

$Exit_Status = system @SQL_Tool;
if ($Exit_Status == -1)
	{
	print STDERR
		"$Command_Name: The command could not be executed!\n";
		"@SQL_Tool\n";
	exit ($CREATE_FAILED);
	}
if ($Exit_Status >> 8)
	{
	print STDERR
		"$Command_Name: The command failed - exit status $Exit_Status.\n",
		"  You may not have the database privileges to do this.\n",
		"@SQL_Tool\n";
	exit ($CREATE_FAILED);
	}

pop @SQL_Tool;
return $Exit_Status;
}
