#!/usr/bin/perl
#
# $Header: /Users/claude/fuzz/lib/Genezzo/RCS/genexp.pl,v 7.5 2006/05/19 07:29:34 claude Exp claude $
#
# copyright (c) 2005, 2006 Jeffrey I Cohen, all rights reserved, worldwide
#
#
#use strict;
use Genezzo::GenDBI;
use Genezzo::Havok::SQLScalar;
use Data::Dumper;
use Getopt::Long;
use Pod::Usage;
use strict;
use warnings;
=head1 NAME
B<genexp.pl> - Genezzo database exporter
=head1 SYNOPSIS
B<genexp> [options]
Options:
-help brief help message
-man full documentation
-gnz_home supply a directory for the gnz_home
-version print version information
-define key=val define a configuration parameter
=head1 OPTIONS
=over 8
=item B<-help>
Print a brief help message and exits.
=item B<-man>
Prints the manual page and exits.
=item B<-gnz_home>
Supply the location for the gnz_home installation. If
specified, it overrides the GNZ_HOME environment variable.
=item B<-version>
Print version information.
=item B<-define> key=value
If initializing a new database, define a configuration
parameter.
=back
=head1 DESCRIPTION
Genezzo is an extensible, persistent datastore that uses a subset of
SQL. The genexp tool lets users export their existing schema as a SQL
script. Running the script will recreate and repopulate the tables.
=head2 Environment
GNZ_HOME: If the user does not specify a gnz_home directory using
the B<'-gnz_home'> option, Genezzo stores dictionary and table
information in the location specified by this variable. If
GNZ_HOME is undefined, the default location is $HOME/gnz_home.
=head1 TODO
=over 4
=item move most methods to separate .pm file
=item need to distinguish "dictionary" havok routines vs
post-dictionary havok tables
=back
=head1 AUTHORS
Copyright (c) 2005, 2006 Jeffrey I Cohen. All rights reserved.
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 2 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Address bug reports and comments to: jcohen@genezzo.com
For more information, please visit the Genezzo homepage
at L<http://www.genezzo.com>
=cut
our $GZERR = sub {
my %args = (@_);
return
unless (exists($args{msg}));
my $warn = 0;
if (exists($args{severity}))
{
my $sev = uc($args{severity});
$sev = 'WARNING'
if ($sev =~ m/warn/i);
# don't print 'INFO' prefix
if ($args{severity} !~ m/info/i)
{
printf ("%s: ", $sev);
$warn = 1;
}
else
{
if (exists($args{no_info}))
{
# don't print info if no_info set...
return;
}
}
}
print $args{msg};
# add a newline if necessary
print "\n" unless $args{msg}=~/\n$/;
# carp $args{msg}
# if (warnings::enabled() && $warn);
};
my $glob_gnz_home;
my $glob_id;
my $glob_defs;
sub setinit
{
$glob_gnz_home = shift;
$glob_defs = shift;
}
BEGIN {
my $man = 0;
my $help = 0;
my $verzion = 0;
my $gnz_home = '';
my %defs = (); # list of --define key=value
GetOptions(
'help|?' => \$help, man => \$man,
version => \$verzion,
'gnz_home=s' => \$gnz_home,
'define=s' => \%defs)
or pod2usage(2);
$glob_id = "genexp.pl - Genezzo Version $Genezzo::GenDBI::VERSION - $Genezzo::GenDBI::RELSTATUS $Genezzo::GenDBI::RELDATE\n\n";
if ($verzion)
{
my $bigmsg =
Genezzo::GenDBI::getversionstring(
$Genezzo::GenDBI::VERSION,
$Genezzo::GenDBI::RELSTATUS,
$Genezzo::GenDBI::RELDATE,
1);
pod2usage(-exitstatus => 0, -verbose => 0,
-msg => $bigmsg
);
}
pod2usage(-msg => $glob_id, -exitstatus => 1) if $help;
pod2usage(-msg => $glob_id, -exitstatus => 0, -verbose => 2) if $man;
setinit($gnz_home, \%defs);
# print "loading...\n" ;
}
my $dbh = Genezzo::GenDBI->new(exe => $0,
gnz_home => $glob_gnz_home,
defs => $glob_defs,
GZERR => $GZERR
);
unless (defined($dbh))
{
my $initmsg =
"export failed -- no installation found at $glob_gnz_home\n";
pod2usage(-exitstatus => 2, -verbose => 0,
-msg => $glob_id . $initmsg
);
# Note: exit takes zero for success, 1 for failure
exit (1);
}
my $stat = 0;
{
unless($dbh->do("startup"))
{
$stat = 1;
last;
}
my $sth;
$sth =
$dbh->prepare("select pref_value from _pref1 where pref_key=\'export_start_tid\'");
$sth->execute();
my @lastfetch = $sth->fetchrow_array();
my $last_dict_tid;
if (scalar(@lastfetch))
{
$last_dict_tid = ($lastfetch[0]);
}
$sth =
$dbh->prepare("select tid, tname from _tab1 where tid > $last_dict_tid and object_type='TABLE'");
# print $sth->execute(), " rows \n";
$sth->execute();
my @tabs;
while (1)
{
my @ggg = $sth->fetchrow_array();
# print Dumper (@ggg), "\n";
last
unless (scalar(@ggg));
push @tabs, [@ggg];
}
# print Dumper(@tabs), "\n";
# get all tables with tid > cons1_cols
for my $tabi (@tabs)
{
my $tid = $tabi->[0];
my $sql =
"select colidx, colname, coltype, tid, tname from _col1 where tid = $tid";
$sth =
$dbh->prepare($sql);
# print $sth->execute(), " rows \n";
$sth->execute();
my @cols = ();
while (1)
{
my @ggg = $sth->fetchrow_array();
# print Dumper (@ggg), "\n";
last
unless (scalar(@ggg));
my $colidx = shift @ggg;
$cols[$colidx] = [@ggg];
}
print "ct $tabi->[1] ";
for my $coli (@cols)
{
print $coli->[0],"=",$coli->[1]," "
if (defined($coli));
}
print "\n";
}
for my $tabi (@tabs)
{
my $tname = $tabi->[1];
my $tid = $tabi->[0];
my $sql =
"select colidx, colname, coltype, tid, tname from _col1 where tid = $tid";
$sth =
$dbh->prepare($sql);
# print $sth->execute(), " rows \n";
$sth->execute();
my @cols = ();
while (1)
{
my @ggg = $sth->fetchrow_array();
# print Dumper (@ggg), "\n";
last
unless (scalar(@ggg));
my $colidx = shift @ggg;
$cols[$colidx] = [@ggg];
}
$sql =
"select * from $tname ";
$sth =
$dbh->prepare($sql);
# print $sth->execute(), " rows \n";
$sth->execute();
while (1)
{
my $firsttime;
my @fff = $sth->fetchrow_array();
my @ggg = @fff;
# print Dumper (@ggg), "\n";
last
unless (scalar(@ggg));
print "insert into $tname values(";
$firsttime = 1;
for my $colcnt (1..scalar(@fff))
{
print ", "
unless $firsttime;
if (defined($fff[$colcnt-1]))
{
my $outi = $ggg[$colcnt-1];
# print "'",$outi,"'";
if ($outi =~ m/([^A-Za-z0-9])+/)
{
print "unquurl(\'", sql_func_quurl2($outi),"\')";
}
else
{
print "\'",$outi,"\'";
}
}
else
{
print "NULL";
}
$firsttime = 0
}
print ");\n";
}
}
$sth =
$dbh->prepare("select cons_name, cons_type, tid, check_text,check2 from cons1");
# print $sth->execute(), " rows \n";
$sth->execute();
while (1)
{
my @ggg = $sth->fetchrow_array();
last
unless (scalar(@ggg));
# print Dumper (@ggg), "\n";
my ($c_name, $c_type, $tid, $c_text, $check2) = @ggg;
$c_name = undef
if ($c_name =~ m/^SYS_/);
if ($c_type =~ m/(IK|PK|UQ)/)
{
my ($i_name, $iid) = split(":", $c_text, 2);
next
unless ($iid > $last_dict_tid);
my @iinfo = get_index_info($dbh, $tid, $iid);
my $tname = get_tname_by_tid($dbh, $tid);
if ($c_type =~ m/IK/)
{
my $iname = shift(@iinfo);
print "CREATE INDEX $iname on ";
print "$tname (";
}
if ($c_type =~ m/PK|UQ/)
{
my $iname = shift(@iinfo);
print "ALTER TABLE $tname ADD ";
print "CONSTRAINT $c_name "
if (defined($c_name));
my $tt1 = ($c_type =~ m/UQ/) ? "UNIQUE (" : "PRIMARY KEY (";
print $tt1;
}
print join(", ", @iinfo);
print ");\n";
}
else
{
if ($c_type =~ m/(CK)/)
{
my $tname = get_tname_by_tid($dbh, $tid);
print "ALTER TABLE $tname ADD " ;
print "CONSTRAINT $c_name "
if (defined($c_name));
print "CHECK ($check2);\n";
}
}
} # end while 1
}
sub get_tname_by_tid
{
my ($dbh, $tid) = @_;
my $sth;
$sth =
$dbh->prepare("select tname from _tab1 where tid = $tid");
$sth->execute();
my @lastfetch = $sth->fetchrow_array();
return undef
unless scalar(@lastfetch);
my $tname = $lastfetch[0];
return $tname;
}
sub get_cname_by_idx
{
my ($dbh, $tid, $col_idx) = @_;
# print "d2 ",Dumper ([$tid, $col_idx]), "\n";
my $sth;
$sth =
$dbh->prepare(
"select colname from _col1 where tid = $tid and colidx = $col_idx");
$sth->execute();
my @lastfetch = $sth->fetchrow_array();
return undef
unless scalar(@lastfetch);
my $cname = $lastfetch[0];
return $cname;
}
sub get_index_info
{
my ($dbh, $tid, $iid) = @_;
my $sth;
$sth =
$dbh->prepare("select iname from ind1 where iid = $iid");
$sth->execute();
my @lastfetch = $sth->fetchrow_array();
return undef
unless scalar(@lastfetch);
my $iname = $lastfetch[0];
$sth =
$dbh->prepare("select colidx, posn from ind1_cols where iid = $iid and tid = $tid");
$sth->execute();
my @cols;
@lastfetch = $sth->fetchrow_array();
while (scalar(@lastfetch))
{
my ($cidx, $iposn) = @lastfetch;
# print "d1 ", Dumper (@lastfetch), "\n";
my $cname = get_cname_by_idx($dbh, $tid, $cidx);
return undef
unless (defined($cname));
$cols[$iposn] = $cname;
@lastfetch = $sth->fetchrow_array();
}
return undef
unless scalar(@cols);
$cols[0] = $iname;
return @cols;
}
exit($stat)