#!/usr/bin/perl
use strict;
use warnings;
use Getopt::Long::Descriptive qw/describe_options prog_name/;
use SQL::Tree;

my ( $opt, $usage ) = describe_options(
    prog_name . ' <options>',
    [ 'dbtype=s', "database type [SQLite|Pg]",         { required => 1 } ],
    [ 'drop',     "issue DROP statements [optional]" ],
    [ 'table=s',  "the table name",                    { required => 1 } ],
    [ 'pk=s',     "the primary key column of <table>", { required => 1 } ],
    [
        'pktype=s',
        "the SQL column type of 'pk' and 'parent'",
        { required => 1 }
    ],
    [ 'parent=s', "the parent column of <table>", { required => 1 } ],
    [ 'path=s',   "the path column of <table> [optional]" ],
    [
        'path_from=s', "the colum from which path will be calculated [optional]"
    ],
    [ 'order=s', "the order column of <table> [optional]" ],
    [],

    #    [ 'verbose|v',  "print extra stuff"            ],
    [ 'help', "print usage message and exit" ],
);

print( $usage->text ), exit 2 if $opt->{help};

my %args = map { $_ => $opt->{$_} } qw/
  dbtype drop table pk pktype parent path path_from order
  /;

if ( $opt->{dbtype} =~ m/(SQLite)|(Pg)/ ) {
    my $prog_name = prog_name;
    my $date      = scalar gmtime;
    my $dbtype    = $opt->{dbtype};

    print qq[
-- --------------------------------------------------------------------
-- A hierarchical data (tree) implementation using triggers
-- inside the database as described here:
--
--   http://www.depesz.com/index.php/2008/04/11/my-take-on-trees-in-sql/
--
-- Generated by $prog_name on $date for $dbtype
-- --------------------------------------------------------------------
];
    print join( "\n\n", SQL::Tree::generate_sql_tree(%args) );

}
else {
    print STDERR prog_name . ": dbtype must be SQLite or Pg\n";
    exit 2;
}

__END__


=head1 NAME

sqltree - hierarchical data (tree) implementation in SQL

=head1 SYNOPSIS

  sqltree OPTIONS

=head1 DESCRIPTION

B<sqltree> generates the SQL for a herarchical data (tree)
implementation using triggers, as described here:

    http://www.depesz.com/index.php/2008/04/11/my-take-on-trees-in-sql/

This implementation relies on a previously-defined table containing:

=over 4

=item * a single primary key column

=item * a parent column that references the
primary key

=item * a column to hold path data [optional]

=back

Several triggers are added to this previously-defined table, which
update a new table holding in-depth tree information.

Output from B<sqltree> can usually be piped directly to the "sqlite3"
or "psql" command line tools.

=head1 OPTIONS

=over 4

=item --dbtype

Must be 'SQLite' or 'Pg'. Patches for other database systems are
welcome.

=item --drop

[optional] Generate DROP TABLE/TRIGGER statements preceeding the rest
of the output.

=item --table

The name of the (existing) table holding the hierarchical data. The
additional tree table will be called "table_tree".

=item --pk

The primary key of the (existing) table holding the hierarchical data.

=item --parent

The parent column of the (existing) table holding the hierarchical
data.

=item --pktype

The SQL column type of the (existing) primary key and parent columns.

=item --path

[optional] The (existing) column into which the tree path will be
automatically calculated. This column should be defined as TEXT or
VARCHAR, and should be UNIQUE.

=item --path_from

[optional] When --path is given this option identifies the (existing)
column from which path names will be built.

=cut
item --order

The (existing) column containing the object ordering information
[optional].

=back

=head1 SEE ALSO

L<SQL::Tree>(3p), The SQLite "foreign_key" pragma.

=head1 BUGS

At the moment global ordering is not implemented, but is in the works.

=head1 AUTHOR

Mark Lawrence E<lt>nomad@null.netE<gt>

=head1 COPYRIGHT AND LICENSE

Copyright (C) 2010 Mark Lawrence E<lt>nomad@null.netE<gt>

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 3 of the License, or (at your
option) any later version.

=cut
