#!/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", 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
