Author: spadkins
Date: Thu Mar 26 06:19:36 2009
New Revision: 12633

Modified:
   p5ee/trunk/App-Repository/Makefile.PL
   p5ee/trunk/App-Repository/bin/dash
   p5ee/trunk/App-Repository/lib/App/Repository/DBI.pm
   p5ee/trunk/App-Repository/lib/App/Repository/Oracle.pm

Log:
initial version of dash

Modified: p5ee/trunk/App-Repository/Makefile.PL
==============================================================================
--- p5ee/trunk/App-Repository/Makefile.PL       (original)
+++ p5ee/trunk/App-Repository/Makefile.PL       Thu Mar 26 06:19:36 2009
@@ -9,6 +9,7 @@
 
 my @programs = (
     "bin/dbget",
+    "bin/dash",
 );
 
 %opts = (

Modified: p5ee/trunk/App-Repository/bin/dash
==============================================================================
--- p5ee/trunk/App-Repository/bin/dash  (original)
+++ p5ee/trunk/App-Repository/bin/dash  Thu Mar 26 06:19:36 2009
@@ -1,339 +1,65 @@
 #!/usr/bin/perl -w
 
-use Date::Format;
+use strict;
 
 use App::Options (
-    options => [ qw(dbhost dbname dbuser dbpass repository table params 
columns headings compact decimals subtotal_columns totals
-                    distinct cache_skip cache_refresh silent) ],
+    #options => [ qw(dbhost dbname dbuser dbpass repository table params 
columns headings compact decimals subtotal_columns totals
+    #                distinct cache_skip cache_refresh silent) ],
+    options => [ qw(dbhost dbname dbuser dbpass dbschema repository silent) ],
     option => {
         repository => {
             default => "default",
-            description => "Name of the repository to get the rows from",
-        },
-        table => {
-            description => "Table name (i.e. --table=customer)",
-        },
-        params => {
-            description => "List of params (var=value pairs) (i.e. 
--params=\"last_name=Jones|first_name=Mike\")",
-        },
-        columns => {
-            description => "List of columns (comma-separated list) (i.e. 
--columns=first_name,last_name)",
-        },
-        headings => {
-            description => "List of heading abbreviations (comma-separated) 
(i.e. --headings=first,last)",
-        },
-        compact => {
-            description => "Trim titles to make compact table",
-        },
-        decimals => {
-            description => "Number of decimal places to print on floats",
-            default => "2",
-        },
-        subtotal_columns => {
-            description => "Print sub-totals at the end",
-        },
-        totals => {
-            description => "Print totals at the end",
-        },
-        cache_skip => {
-            description => "Skip any cached values for the table",
-        },
-        cache_refresh => {
-            description => "Skip any cached values for the table but save the 
results in the cache",
-        },
-        distinct => {
-            description => "Select only distinct rows",
+            description => "Name of the repository to operate on",
         },
+        #table => {
+        #    description => "Table name (i.e. --table=customer)",
+        #},
+        #params => {
+        #    description => "List of params (var=value pairs) (i.e. 
--params=\"last_name=Jones|first_name=Mike\")",
+        #},
+        #columns => {
+        #    description => "List of columns (comma-separated list) (i.e. 
--columns=first_name,last_name)",
+        #},
+        #headings => {
+        #    description => "List of heading abbreviations (comma-separated) 
(i.e. --headings=first,last)",
+        #},
+        #compact => {
+        #    description => "Trim titles to make compact table",
+        #},
+        #decimals => {
+        #    description => "Number of decimal places to print on floats",
+        #    default => "2",
+        #},
+        #subtotal_columns => {
+        #    description => "Print sub-totals at the end",
+        #},
+        #totals => {
+        #    description => "Print totals at the end",
+        #},
+        #cache_skip => {
+        #    description => "Skip any cached values for the table",
+        #},
+        #cache_refresh => {
+        #    description => "Skip any cached values for the table but save the 
results in the cache",
+        #},
+        #distinct => {
+        #    description => "Select only distinct rows",
+        #},
+        #log_level => {
+        #    description => "Do not emit log messages normally created by 
App-Repository",
+        #    default => 0,
+        #},
         silent => {
-            default => 0,
             description => "Do not emit prompts or other messages (useful 
during scripted use)",
         },
     },
 );
 
-use App;
-use strict;
-
-my $LOADED_TERM_READLINE = 0;
-my $term = undef;
-
-$| = 1;  # autoflush stdout
+use App::RepositoryShell;
 
 {
-    my $context  = App->context();
-    my $options  = $context->{options};
-    &init($options);
-    my $silent   = $options->{silent};
-    my $done = 0;
-    my ($command, $command_entry);
-    my $prompt = "dash";
-    while (!$done) {
-        $command_entry = &get_command_entry($prompt, $options);
-        $command = &get_command_from_command_entry($command_entry);
-        if (!$command) {
-            #print "I didn't understand that.\n";
-            #print "Please try 'help' for help on the available commands and 
their use\n";
-        }
-        elsif ($command eq "help" || $command eq "?") {
-            &show_help($command_entry);
-        }
-        elsif ($command eq "repository") {
-            &set_repository($command_entry);
-        }
-        elsif ($command eq "select") {
-            &show_select($command_entry);
-        }
-        elsif ($command eq "exit") {
-            $done = 1;
-        }
-        else {
-            print "I don't know the '$command' command.\n";
-            print "Please try 'help' for help on the available commands and 
their use\n";
-        }
-    }
-    print "Goodbye\n" if (!$silent);
-}
-
-sub init {
-    my ($options) = @_;
-    eval { use Term::ReadLine; };
-    if ($@) {
-        $LOADED_TERM_READLINE = 0;
-    }
-    else {
-        $LOADED_TERM_READLINE = 1;
-        $term = Term::ReadLine->new($options->{app});
-    }
-}
-
-sub get_command_entry {
-    my ($prompt, $options) = @_;
-    my ($command_entry);
-    if ($LOADED_TERM_READLINE) {
-        $command_entry = &get_command_entry_readline($prompt, $options);
-    }
-    else {
-        $command_entry = &get_command_entry_std($prompt, $options);
-    }
-    return($command_entry);
-}
-
-sub get_command_entry_std {
-    my ($prompt, $options) = @_;
-    print "$prompt> " if (!$options->{silent});
-    my $command_entry = <STDIN>;
-    return($command_entry);
-}
-
-sub get_command_entry_readline {
-    my ($prompt, $options) = @_;
-    my $readline_prompt = $options->{silent} ? "" : "$prompt> ";
-    my $command_entry = $term->readline($readline_prompt);
-    return($command_entry);
-}
-
-sub get_command_from_command_entry {
-    my ($command_entry) = @_;
-    my ($command);
-    if ($command_entry =~ /^([a-zA-Z_\?]+)/) {
-        $command = $1;
-    }
-    return($command);
-}
-
-sub show_help {
-    my ($command_entry) = @_;
-    print "============================================================\n";
-    print "COMMANDS:\n";
-    print "============================================================\n";
-    print "help - [synonym: ?] show this list of commands\n";
-    print "exit - quit the program\n";
-}
-
-sub set_repository {
-    my ($command_entry) = @_;
-}
-
-sub show_select {
-    my ($command_entry) = @_;
-    my $context  = App->context();
-    my $db       = $context->repository($App::options{repository});
-    my $rows = $db->_do($command_entry);
-    foreach my $row (@$rows) {
-        print "ROW:[", join("|", @$row), "]\n";
-    }
-}
-
-sub foo {
-    my $context  = App->context();
-    my $db       = $context->repository($App::options{repository});
-    my $table    = $App::options{table};
-    my ($columns, $params, $headings, $get_options, $cache_rows);
-    if ($table && $App::options{hashkey}) {
-        my $hashkey = $App::options{hashkey};
-        my $table_def = $db->get_table_def($table);
-        my $cache_name = $table_def->{cache_name};
-        if ($cache_name) {
-            my $cache = $context->shared_datastore($cache_name);
-            my $ref = $cache->get_ref($hashkey);
-            if (!$ref) {
-                warn "Nothing in the [$cache_name] cache for table [$table] 
with hashkey [$hashkey]\n";
-            }
-            else {
-                ($table, $params, $columns, $cache_rows, $get_options) = @$ref;
-                $get_options->{cache_skip} = 1;
-                print $db->dump([$table, $params, $columns, $get_options]);
-            }
-        }
-        else {
-            warn "cache_name option is not set on table $table";
-        }
-    }
-    else {
-        if ($App::options{columns}) {
-            $columns  = [ split(/,/, $App::options{columns}) ];
-        }
-        else {
-            $columns  = $db->_get_default_columns($table);
-        }
-        die "Must supply the --params option\n" if (! defined 
$App::options{params});
-        $params   = { split(/[=>\|]+/, $App::options{params}) };
-        $headings = $App::options{headings} ? [ split(/,/, 
$App::options{headings}) ] : [];
-        $get_options = { extend_columns => 1 };
-    }
-    $get_options->{distinct} = 1 if ($App::options{distinct});
-    $get_options->{cache_skip} = 1 if ($App::options{cache_skip});
-    $get_options->{cache_refresh} = 1 if ($App::options{cache_refresh});
-    my $rows     = $db->get_rows($table, $params, $columns, $get_options);
-    my ($subtotal_rows, $total_rows);
-    if ($App::options{subtotal_columns}) {
-        my $subtotal_columns = [ split(/,/, $App::options{subtotal_columns}) ];
-        $subtotal_rows = $db->summarize_rows($table, $rows, $columns, 
$subtotal_columns);
-    }
-    if ($App::options{totals}) {
-        $total_rows = $db->summarize_rows($table, $rows, $columns);
-    }
-    if ($subtotal_rows) {
-        push(@$rows, @$subtotal_rows);
-    }
-    if ($total_rows) {
-        push(@$rows, @$total_rows);
-    }
-    my $formats  = [];
-    &print_table($rows, $columns, $formats, { compact => 
$App::options{compact}, headings => $headings });
-}
-
-sub print_table {
-    &App::sub_entry if ($App::trace);
-    my ($rows, $columns, $formats, $options) = @_;
-    my ($row, $r, $c, $elem, $format, $len, $f, $heading);
-    my (@autoformat);
-    my $headings = $options->{headings};
-
-    # compute the number of columns as the max columns of any row
-    my $max_columns = 0;
-    for ($r = 0; $r <= $#$rows; $r++) {
-        $row = $rows->[$r];
-        if ($max_columns < $#$row + 1) {
-            $max_columns = $#$row + 1;
-        }
-    }
-
-    # compute automatic sprintf formats
-    for ($c = 0; $c < $max_columns; $c++) {
-
-        if (! defined $autoformat[$c]) {
-            $autoformat[$c] = {
-                max_length => 0,
-                type => 2,        # 0=string, 1=float, 2=integer
-                min => undef,
-                max => undef,
-            };
-        }
-        $f = $autoformat[$c];
-
-        # set the length of the column by the length of its heading
-        $heading = ($headings && $headings->[$c]) ? $headings->[$c] : "";
-        if ($heading) { 
-            $len = length($heading);
-            if ($len > $f->{max_length}) {
-                $f->{max_length} = $len;
-            }
-        }
-        elsif (! $options->{compact}) { 
-            $len = length($columns->[$c]);
-            if ($len > $f->{max_length}) {
-                $f->{max_length} = $len;
-            }
-        }
-
-        for ($r = 0; $r <= $#$rows; $r++) {
-            $row = $rows->[$r];
-            if ($c <= $#$row && defined $row->[$c]) {
-                $elem = $row->[$c];
-                $len = length($elem);
-                if ($elem =~ /^-?[0-9]*\.[0-9]+$/) {  # float
-                    $len = length(sprintf("%.$App::options{decimals}f",$elem));
-                    $f->{type} = 1 if ($f->{type} > 1);
-                    if (!defined $f->{min} || $elem < $f->{min}) {
-                        $f->{min} = $elem;
-                    }
-                    if (!defined $f->{max} || $elem < $f->{max}) {
-                        $f->{max} = $elem;
-                    }
-                }
-                elsif ($elem =~ /^-?[0-9]+$/) { # integer
-                    if (!defined $f->{min} || $elem < $f->{min}) {
-                        $f->{min} = $elem;
-                    }
-                    if (!defined $f->{max} || $elem < $f->{max}) {
-                        $f->{max} = $elem;
-                    }
-                }
-                else {
-                    $f->{type} = 0;
-                }
-                $f->{max_length} = $len if ($len > $f->{max_length});
-            }
-        }
-        &determine_sprintf_fmt($f);
-    }
-    for ($c = 0; $c <= $#$columns; $c++) {
-        $format = $autoformat[$c]->{title_fmt} || "%s";
-        print " " if ($c > 0);
-        $heading = ($headings && $headings->[$c]) ? $headings->[$c] : 
$columns->[$c];
-        printf($format, $heading);
-    }
-    print "\n";
-    for ($r = 0; $r <= $#$rows; $r++) {
-        $row = $rows->[$r];
-        for ($c = 0; $c <= $#$row; $c++) {
-            $format = $autoformat[$c]->{fmt} || "%s";
-            print " " if ($c > 0);
-            printf($format, $row->[$c]);
-        }
-        print "\n";
-    }
-    &App::sub_exit() if ($App::trace);
-}
-
-sub determine_sprintf_fmt {
-    &App::sub_entry if ($App::trace);
-    my ($f) = @_;
-    my ($width, $int_len, $fract_len);
-    if ($f->{type} == 1) {     # float
-        $f->{title_fmt} = "%$f->{max_length}.$f->{max_length}s";
-        $f->{fmt} = "%$f->{max_length}.$App::options{decimals}f";
-    }
-    elsif ($f->{type} == 2) {  # integer
-        $f->{title_fmt} = "%$f->{max_length}.$f->{max_length}s";
-        $f->{fmt} = "%$f->{max_length}d";
-    }
-    else {                     # string
-        $f->{title_fmt} = "%-$f->{max_length}.$f->{max_length}s";
-        $f->{fmt} = "%-$f->{max_length}s";
-    }
-    &App::sub_exit($f->{fmt}) if ($App::trace);
+    my $shell = App::RepositoryShell->new();
+    $shell->run();
 }
 
 exit (0);

Modified: p5ee/trunk/App-Repository/lib/App/Repository/DBI.pm
==============================================================================
--- p5ee/trunk/App-Repository/lib/App/Repository/DBI.pm (original)
+++ p5ee/trunk/App-Repository/lib/App/Repository/DBI.pm Thu Mar 26 06:19:36 2009
@@ -2470,7 +2470,7 @@
 
 sub _do {
     &App::sub_entry if ($App::trace);
-    my ($self, $sql) = @_;
+    my ($self, $sql, $options) = @_;
     $self->{error} = "";
     $self->{sql} = $sql;
     my $dbh = $self->{dbh};
@@ -2494,7 +2494,12 @@
         while ($continue) {
             eval {
                 if ($sql =~ /^select/i) {
-                    $retval = $dbh->selectall_arrayref($sql);
+                    if ($options->{columns}) {
+                        $retval = $self->_selectall_arrayref($sql, $options);
+                    }
+                    else {
+                        $retval = $dbh->selectall_arrayref($sql);
+                    }
                 }
                 else {
                     $retval = $dbh->do($sql)+0; # turn "0E0" into plain old "0"
@@ -2544,6 +2549,33 @@
     $retval;
 }
 
+sub _selectall_arrayref {
+    &App::sub_entry if ($App::trace);
+    my ($self, $sql, $options, $attr, @bind) = @_;
+    my $dbh = $self->{dbh};
+    my $sth = (ref $sql) ? $sql : $dbh->prepare($sql, $attr)
+        or return;
+    $sth->execute(@bind) || return;
+
+    my $columns = $options->{columns};
+    if ($columns && ref($columns) eq "ARRAY") {
+        my $sth_columns = $sth->{NAME_lc};
+        @$columns = @{$sth->{NAME_lc}};
+    }
+
+    my $slice = $attr->{Slice}; # typically undef, else hash or array ref
+    if (!$slice and $slice=$attr->{Columns}) {
+        if (ref $slice eq 'ARRAY') { # map col idx to perl array idx
+            $slice = [ @{$attr->{Columns}} ];   # take a copy
+            for (@$slice) { $_-- }
+        }
+    }
+    my $rows = $sth->fetchall_arrayref($slice, my $MaxRows = $attr->{MaxRows});
+    $sth->finish if defined $MaxRows;
+    &App::sub_exit($rows) if ($App::trace);
+    return $rows;
+}
+
 #############################################################################
 # begin_work()
 #############################################################################

Modified: p5ee/trunk/App-Repository/lib/App/Repository/Oracle.pm
==============================================================================
--- p5ee/trunk/App-Repository/lib/App/Repository/Oracle.pm      (original)
+++ p5ee/trunk/App-Repository/lib/App/Repository/Oracle.pm      Thu Mar 26 
06:19:36 2009
@@ -729,13 +729,13 @@
 
 sub is_retryable_connection_error {
     my ($self, $e) = @_;
-    warn "Oracle-specific error messages not defined";
+    #warn "Oracle-specific error messages not defined";
     return($e =~ /TBD-FOO/);
 }
 
 sub is_retryable_modify_error {
     my ($self, $e) = @_;
-    warn "Oracle-specific error messages not defined";
+    #warn "Oracle-specific error messages not defined";
     return($e =~ /TBD-FOO/);
 }
 

Reply via email to