App-Repository

 view release on metacpan or  search on metacpan

lib/App/Repository/DBI.pm  view on Meta::CPAN

        my $options = $self->{context}{options} || {};

        my $config_from_options = 1;
        my $config_from_ext_options = 0;
        foreach my $var qw(dbdsn dbdriver dbhost dbport dbsocket dbname dbuser dbpass dbschema dbioptions) {
            if ($self->{$var}) {
                $config_from_options = 0;
            }
            if ($options->{"${name}.${var}"}) {
                $config_from_ext_options = 1;
            }
        }

        if ($config_from_options) {
            if ($config_from_ext_options) {
                foreach my $var qw(dbdsn dbdriver dbhost dbport dbsocket dbname dbuser dbpass dbschema dbioptions) {
                    if (defined $options->{"${name}.${var}"}) {
                        $self->{$var} = $options->{"${name}.${var}"};
                    }
                }
            }
            else {
                foreach my $var qw(dbdsn dbdriver dbhost dbport dbsocket dbname dbuser dbpass dbschema dbioptions) {
                    if (defined $options->{$var}) {
                        $self->{$var} = $options->{$var};
                    }
                }
            }
        }
    }
    &App::sub_exit() if ($App::trace);
}

sub _get_row {
    &App::sub_entry if ($App::trace);
    my ($self, $table, $params, $cols, $options) = @_;

    # we only need the first row
    $options = {} if (!$options);
    if (! $options->{endrow}) {
        $options->{endrow} = $options->{startrow} || 1;
    }

    my ($sql, $dbh, $row);
    if ($self->{table}{$table}{rawaccess}) {
        $sql = $self->_mk_select_sql($table, $params, $cols, $options);
    }
    else {
        $sql = $self->_mk_select_joined_sql($table, $params, $cols, $options);
    }
    $self->{sql} = $sql;

    $dbh = $self->{dbh};
    if (!$dbh) {
        $self->_connect();
        $dbh = $self->{dbh};
    }

    my $context_options = $self->{context}{options};
    my $debug_sql = $context_options->{debug_sql};
    my ($timer, $elapsed_time);
    if ($debug_sql) {
        $timer = $self->_get_timer();
        print $App::DEBUG_FILE "DEBUG_SQL: _get_row()\n";
        print $App::DEBUG_FILE $sql;
    }
    if ($context_options->{explain_sql}) {
        $self->explain_sql($sql);
    }
    ### TODO: make this similar to the _connect code, using a regex named retryable_select_error_regex
    while (1) {
        eval {
            $row = $dbh->selectrow_arrayref($sql);
        };
        if ($@) {
            $row = undef;
            if ($@ =~ /Lost connection/ || $@ =~ /server has gone away/) {
                $self->{context}->log({level=>1},"DBI Exception (retrying) in _get_row(): $@");
                $self->_disconnect();
                sleep(1);
                $self->_connect();
                $dbh = $self->{dbh};
            }
            else {
                $self->{context}->log({level=>1},"DBI Exception (fail) in _get_rows(): $@$sql");
                die $@;
            }
        }
        else {
            last;
        }
    }
    if ($debug_sql) {
        $elapsed_time = $self->_read_timer($timer);
        print $App::DEBUG_FILE "DEBUG_SQL: nrows [", (defined $row ? 1 : 0), "] ($elapsed_time sec) $DBI::errstr\n";
        if ($debug_sql >= 2) {
            print $App::DEBUG_FILE "DEBUG_SQL: [", ($row ? join("|",map { defined $_ ? $_ : "undef" } @$row) : ""), "]\n";
        }
        print $App::DEBUG_FILE "\n";
    }

    &App::sub_exit($row) if ($App::trace);
    return($row);
}

sub _get_rows {
    &App::sub_entry if ($App::trace);
    my ($self, $table, $params, $cols, $options) = @_;

    my ($sql, $rows, $startrow, $endrow);
    my $table_def = $self->get_table_def($table);
    #print $App::DEBUG_FILE "DBI._get_rows : table=[$table] rawaccess=[$table_def->{rawaccess}]\n";
    #if ($self->{table}{$table}{rawaccess}) {
    if ($table_def->{rawaccess}) {
        $sql = $self->_mk_select_sql($table, $params, $cols, $options);
    }
    else {
        $sql = $self->_mk_select_joined_sql($table, $params, $cols, $options);
    }
    $self->{sql} = $sql;
    die "empty SQL query for table [$table] (does table exist?)" if (!$sql);

    $self->_connect() if (!$self->{dbh});

    $options  = {} if (!$options);
    $startrow = $options->{startrow} || 0;
    $endrow   = $options->{endrow} || 0;

    my $context_options = $self->{context}{options};
    my $debug_sql = $context_options->{debug_sql};
    my ($timer, $elapsed_time);
    if ($debug_sql) {
        $timer = $self->_get_timer();
        print $App::DEBUG_FILE "DEBUG_SQL: _get_rows()\n";
        print $App::DEBUG_FILE $sql;
    }
    if ($context_options->{explain_sql}) {
        $self->explain_sql($sql);
    }
    while (1) {
        eval {
            $rows = $self->_selectrange_arrayref($sql, $startrow, $endrow);
        };
        if ($@) {
            $rows = [];
            if ($@ =~ /Lost connection/ || $@ =~ /server has gone away/) {
                $self->{context}->log({level=>1},"DBI Exception (retrying) in _get_rows(): $@");
                $self->_disconnect();
                sleep(1);
                $self->_connect();
            }
            else {
                $self->{context}->log({level=>1},"DBI Exception (fail) in _get_rows(): $@$sql");
                die $@;
            }
        }
        else {
            last;
        }
    }
    if ($debug_sql) {
        $elapsed_time = $self->_read_timer($timer);
        print $App::DEBUG_FILE "DEBUG_SQL: nrows [", (defined $rows ? ($#$rows+1) : 0), "] ($elapsed_time sec) $DBI::errstr\n";
        if ($debug_sql >= 2) {
            foreach my $row (@$rows) {
                print $App::DEBUG_FILE "DEBUG_SQL: [", join("|",map { defined $_ ? $_ : "undef"} @$row), "]\n";
            }
        }
        print $App::DEBUG_FILE "\n";
    }

    &App::sub_exit($rows) if ($App::trace);
    return($rows);
}

sub _get_default_columns {
    &App::sub_entry if ($App::trace);
    my ($self, $table) = @_;
    $self->_load_table_metadata($table) if (!defined $self->{table}{$table}{loaded});
    my $table_def = $self->{table}{$table};
    my $columns = $table_def->{default_columns} || "";
    if (ref($columns) eq "ARRAY") {
        # do nothing
    }
    elsif ($columns eq "configured") {
        $columns = $table_def->{columns};
    }
    elsif (!$columns || $columns eq "physical") {
        $columns = $table_def->{phys_columns};
    }
    if (!$columns || ref($columns) ne "ARRAY") {
        my $table_def = $self->{table}{$table};
        my $repname = $table_def->{repository};
        my $realtable = $table_def->{table} || $table;
        if (defined $repname && $repname ne $self->{name}) {
            my $rep = $self->{context}->repository($repname);
            $columns = $rep->_get_default_columns($realtable);
        }
        elsif (defined $realtable && $realtable ne $table) {
            $columns = $self->_get_default_columns($realtable);
        }
    }
    if (!$columns || ref($columns) ne "ARRAY") {
        $columns = [];
    }
    &App::sub_exit($columns) if ($App::trace);
    return($columns);
}

# modified from the DBD::_::db::selectall_arrayref in DBI.pm
sub _selectrange_arrayref {
    &App::sub_entry if ($App::trace);
    my ($self, $stmt, $startrow, $endrow, $attr, @bind) = @_;
    my $dbh = $self->{dbh};
    return [] if (!$dbh);

    my $sth = (ref $stmt) ? $stmt : $dbh->prepare($stmt, $attr);
    if ($sth) {
        $sth->execute(@bind) || return;
        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

lib/App/Repository/DBI.pm  view on Meta::CPAN

    }
    &App::sub_exit($rows->[0]) if ($App::trace);
    return ($rows->[0]);
}

# NOTE: everything after the first line is optional
# @rows = $rep->_select_rows($table, \@cols,
#               \@params, \%paramvalues, \@order_by,
#               $startrow, $endrow,
#               \@sortdircol, \@keycolidx, \@writeable, \@columntype, \@summarykeys);
# TODO: get the $startrow/$endrow working when one/both/neither work in the SQL portion
# TODO: rethink $startrow/$endrow vs. $numrows/$skiprows

# this is a new version that uses bind variables instead of relying on my quoting rules
# unfortunately, it doesn't work yet

sub _select_rows {
    &App::sub_entry if ($App::trace);
    my ($self, $table, $cols, $params, $paramvalues, $order_by, $startrow, $endrow,
        $sortdircol, $keycolidx, $writeable, $columntype, $group_by) = @_;
    my ($sql, $param, @params, %paramvalues, @paramvalues);

    $self->{error} = "";

    if (defined $params) {
        @params = @$params;
    }
    else {
        @params = (keys %$paramvalues);
    }
    foreach $param (@params) {
        push(@paramvalues, $paramvalues->{$param});
    }

    if ($self->{table}{$table}{rawaccess}) {
        $sql = $self->_mk_select_sql($table, $cols, \@params, \%paramvalues, $order_by,
            $startrow, $endrow, $sortdircol, $keycolidx, $writeable, $columntype, $group_by);
    }
    else {
        $sql = $self->_mk_select_rows_sql($table, $cols, \@params, \%paramvalues, $order_by,
            $startrow, $endrow, $sortdircol, $keycolidx, $writeable, $columntype, $group_by);
    }
    $self->{sql} = $sql;
    my $retval = $self->_selectrange_arrayref($sql, $startrow, $endrow, undef, @paramvalues);
    &App::sub_exit($retval) if ($App::trace);
    $retval;
}

# $ok = $rep->_insert_row($table, \@cols, \@row);
sub _insert_row {
    &App::sub_entry if ($App::trace);
    my ($self, $table, $cols, $row, $options) = @_;
    $self->{error} = "";
    my $sql = $self->_mk_insert_row_sql($table, $cols, undef, $options);
    $self->{sql} = $sql;
    my $dbh = $self->{dbh};
    my $retval = 0;

    my $context_options = $self->{context}{options};
    my $debug_sql = $context_options->{debug_sql};
    my ($timer, $elapsed_time);
    my $loglevel = 1;
    if ($debug_sql) {
        $timer = $self->_get_timer();
        print $App::DEBUG_FILE "DEBUG_SQL: insert()\n";
        print $App::DEBUG_FILE "DEBUG_SQL: bind vars [", join("|",map { defined $_ ? $_ : "undef" } @$row), "]\n";
        print $App::DEBUG_FILE $sql;
    }
    if ($context_options->{explain_sql}) {
        $self->explain_sql($sql);
    }
    if (defined $dbh) {
        eval {
            ### TODO: make this work with regex for retry
            $retval = $dbh->do($sql, undef, @$row);
            $retval = 0 if ($retval == 0); # turn "0E0" into plain old "0"
        };
        if ($@) {  # Log the error message with the SQL and rethrow the exception
            my $bind_values = join("|", map { defined $_ ? $_ : "undef" } @$row);
            $loglevel = 3 if ($@ =~ /duplicate/i);
            $self->{context}->log({level=>$loglevel}, "DBI Exception (fail) in _insert_row(): $@BIND VALUES: [$bind_values]\nSQL: $sql");
            die $@;
        }
    }
    if ($debug_sql) {
        $elapsed_time = $self->_read_timer($timer);
        print $App::DEBUG_FILE "DEBUG_SQL: retval [$retval] ($elapsed_time sec) $DBI::errstr\n";
        print $App::DEBUG_FILE "\n";
    }

    &App::sub_exit($retval) if ($App::trace);
    $retval;
}

# $nrows = $rep->_insert_rows ($table, \@cols, \@rows);
sub _insert_rows {
    &App::sub_entry if ($App::trace);
    my ($self, $table, $cols, $rows, $options) = @_;
    $self->{error} = "";
    my ($sql, $retval);
   
    my $dbh = $self->{dbh};
    return 0 if (!defined $dbh);

    my $nrows = 0;
    my $ok = 1;
    my $context_options = $self->{context}{options};
    my $debug_sql = $context_options->{debug_sql};
    my $explain_sql = $context_options->{explain_sql};
    my ($timer, $elapsed_time);
    my $loglevel = 1;
    if ($debug_sql) {
        $timer = $self->_get_timer();
    }
    if (ref($rows) eq "ARRAY") {
        $sql = $self->_mk_insert_row_sql($table, $cols);
        foreach my $row (@$rows) {
            if ($debug_sql) {
                print $App::DEBUG_FILE "DEBUG_SQL: _insert_rows()\n";
                print $App::DEBUG_FILE "DEBUG_SQL: bind vars [", join("|",map { defined $_ ? $_ : "undef" } @$row), "]\n";
                print $App::DEBUG_FILE $sql;
            }
            if ($explain_sql) {
                $self->explain_sql($sql);
            }
            if (defined $dbh) {
                eval {
                    ### TODO: make this work with regex for retry
                    $retval = $dbh->do($sql, undef, @$row);
                    $retval = 0 if ($retval == 0); # turn "0E0" into plain old "0"
                };
                if ($@) {  # Log the error message with the SQL and rethrow the exception
                    $loglevel = ($@ =~ /duplicate/i) ? 3 : 1;
                    my $bind_values = join("|", map { defined $_ ? $_ : "undef" } @$row);
                    $self->{context}->log({level=>$loglevel}, "DBI Exception (fail) in _insert_rows() [ARRAY]: $@BIND VALUES: [$bind_values]\nSQL: $sql");
                    die $@;
                }
            }
            if ($debug_sql) {
                print $App::DEBUG_FILE "DEBUG_SQL: retval [$retval] $DBI::errstr\n";
                print $App::DEBUG_FILE "\n";
            }
    
            if ($retval) {
                $nrows ++;
            }
            else {
                $self->{numrows} = $nrows;
                $ok = 0;
                last;
            }
        }
    }
    else {
        my $fh = $rows;                # assume it is a file handle
        $rows = [];                    # we will be refilling this buffer
        my %options = ( %$options );   # make a copy so it can be modified
        $options->{maxrows} = 100;
        $sql = $self->_mk_insert_row_sql($table, $cols);
        while (1) {
            $rows = $self->_read_rows_from_file($fh, $cols, \%options);
            last if ($#$rows == -1);
            foreach my $row (@$rows) {
                if ($debug_sql) {
                    print $App::DEBUG_FILE "DEBUG_SQL: _insert_rows()\n";
                    print $App::DEBUG_FILE "DEBUG_SQL: bind vars [", join("|",map { defined $_ ? $_ : "undef" } @$row), "]\n";
                    print $App::DEBUG_FILE $sql;
                }
                if ($context_options->{explain_sql}) {
                    $self->explain_sql($sql);
                }
                if (defined $dbh) {
                    eval {
                        ### TODO: make this work with regex for retry
                        $retval = $dbh->do($sql, undef, @$row);
                        $retval = 0 if ($retval == 0); # turn "0E0" into plain old "0"
                    };
                    if ($@) {  # Log the error message with the SQL and rethrow the exception
                        $loglevel = ($@ =~ /duplicate/i) ? 3 : 1;
                        my $bind_values = join("|", map { defined $_ ? $_ : "undef" } @$row);
                        $self->{context}->log({level=>$loglevel}, "DBI Exception (fail) in _insert_rows() [FILE]: $@BIND VALUES: [$bind_values]\nSQL: $sql");
                        die $@;
                    }
                }
                if ($debug_sql) {
                    print $App::DEBUG_FILE "DEBUG_SQL: retval [$retval] $DBI::errstr\n";
                    print $App::DEBUG_FILE "\n";
                }
        
                if ($retval) {
                    $nrows ++;
                }
                else {
                    $self->{numrows} = $nrows;
                    $ok = 0;
                }
            }
        }
    }
    if ($debug_sql) {
        $elapsed_time = $self->_read_timer($timer);
        print $App::DEBUG_FILE "DEBUG_SQL: nrows [$nrows] ($elapsed_time sec)\n";
    }
    $self->{sql} = $sql;
    $self->{numrows} = $nrows;
    &App::sub_exit($nrows) if ($App::trace);
    return($nrows);
}

sub _delete {
    &App::sub_entry if ($App::trace);
    my ($self, $table, $params, $cols, $row, $options) = @_;
    $self->{error} = "";
    my $sql = $self->_mk_delete_sql($table, $params, $cols, $row, $options);
    $self->{sql} = $sql;

    my $context_options = $self->{context}{options};
    my $debug_sql = $context_options->{debug_sql};
    my ($timer, $elapsed_time);
    if ($debug_sql) {
        $timer = $self->_get_timer();
        print $App::DEBUG_FILE "DEBUG_SQL: _delete()\n";
        print $App::DEBUG_FILE $sql;
    }
    if ($context_options->{explain_sql}) {
        $self->explain_sql($sql);
    }
    my $retval = 0;
    my $dbh = $self->{dbh};
    if (defined $dbh) {
        eval {
            ### TODO: make this work with regex for retry
            $retval = $dbh->do($sql);
            $retval = 0 if ($retval == 0); # turn "0E0" into plain old "0"
        };
        if ($@) {  # Log the error message with the SQL and rethrow the exception
            $self->{context}->log({level=>1},"DBI Exception (fail) in _delete(): $@SQL: $sql");
            die $@;
        }
    }
    if ($debug_sql) {
        $elapsed_time = $self->_read_timer($timer);
        print $App::DEBUG_FILE "DEBUG_SQL: retval [$retval] ($elapsed_time sec) $DBI::errstr\n";
        print $App::DEBUG_FILE "\n";
    }

    &App::sub_exit($retval) if ($App::trace);
    return($retval);
}

# $nrows = $rep->_update($table, \%params,    \@cols, \@row, \%options);
# $nrows = $rep->_update($table, \@keycolidx, \@cols, \@row, \%options);
# $nrows = $rep->_update($table, \@paramcols, \@cols, \@row, \%options);
# $nrows = $rep->_update($table, $key,        \@cols, \@row, \%options);
# $nrows = $rep->_update($table, undef,       \@cols, \@row, \%options);
sub _update {
    &App::sub_entry if ($App::trace);
    my ($self, $table, $params, $cols, $row, $options) = @_;
    $self->{error} = "";
    my $sql = $self->_mk_update_sql($table, $params, $cols, $row, $options);
    $self->{sql} = $sql;

    my $context_options = $self->{context}{options};
    my $debug_sql = $context_options->{debug_sql};
    my ($timer, $elapsed_time);
    if ($debug_sql) {
        $timer = $self->_get_timer();
        print $App::DEBUG_FILE "DEBUG_SQL: _update()\n";
        print $App::DEBUG_FILE $sql;
    }
    if ($context_options->{explain_sql}) {
        $self->explain_sql($sql);
    }
    my $retval = 0;
    my $dbh = $self->{dbh};
    if (defined $dbh) {
        eval {
            ### TODO: make this work with regex for retry
            $retval = $dbh->do($sql);
            $retval = 0 if ($retval == 0); # turn "0E0" into plain old "0"
        };
        if ($@) {  # Log the error message with the SQL and rethrow the exception
            $self->{context}->log({level=>1},"DBI Exception (fail) in _update(): $@SQL: $sql");
            die $@;
        }
    }
    if ($debug_sql) {
        $elapsed_time = $self->_read_timer($timer);
        print $App::DEBUG_FILE "DEBUG_SQL: retval [$retval] ($elapsed_time sec) $DBI::errstr\n";
        print $App::DEBUG_FILE "\n";
    }

    &App::sub_exit($retval) if ($App::trace);
    return($retval);
}

# $ok = $rep->_delete_row ($table, \@cols, \@row, \@keycolidx);
sub _delete_row {
    &App::sub_entry if ($App::trace);
    my $self = shift;
    $self->{error} = "";
    my $sql = $self->_mk_delete_row_sql(@_);
    $self->{sql} = $sql;

    my $context_options = $self->{context}{options};
    my $debug_sql = $context_options->{debug_sql};
    my ($timer, $elapsed_time);
    if ($debug_sql) {
        $timer = $self->_get_timer();
        print $App::DEBUG_FILE "DEBUG_SQL: _delete_row()\n";
        print $App::DEBUG_FILE $sql;
    }
    if ($context_options->{explain_sql}) {
        $self->explain_sql($sql);
    }
    my $retval = 0;
    my $dbh = $self->{dbh};
    if (defined $dbh) {
        eval {
            ### TODO: make this work with regex for retry
            $retval = $dbh->do($sql);
            $retval = 0 if ($retval == 0); # turn "0E0" into plain old "0"
        };
        if ($@) {  # Log the error message with the SQL and rethrow the exception
            $self->{context}->log({level=>1},"DBI Exception (fail) in _delete_row(): $@SQL: $sql");
            die $@;
        }
    }
    if ($debug_sql) {
        $elapsed_time = $self->_read_timer($timer);
        print $App::DEBUG_FILE "DEBUG_SQL: retval [$retval] ($elapsed_time sec) $DBI::errstr\n";
        print $App::DEBUG_FILE "\n";
    }

    &App::sub_exit($retval) if ($App::trace);
    $retval;
}

# $ok = $rep->_delete_rows($table, \@params, \%paramvalues);
sub _delete_rows {
    &App::sub_entry if ($App::trace);
    my $self = shift;
    $self->{error} = "";
    my $sql = $self->_mk_delete_rows_sql(@_);
    $self->{sql} = $sql;

    my $context_options = $self->{context}{options};
    my $debug_sql = $context_options->{debug_sql};
    my ($timer, $elapsed_time);
    if ($debug_sql) {
        $timer = $self->_get_timer();
        print $App::DEBUG_FILE "DEBUG_SQL: _delete_rows()\n";
        print $App::DEBUG_FILE $sql;
    }
    if ($context_options->{explain_sql}) {
        $self->explain_sql($sql);
    }
    my $retval = 0;
    my $dbh = $self->{dbh};
    if (defined $dbh) {
        eval {
            ### TODO: make this work with regex for retry
            $retval = $dbh->do($sql);
            $retval = 0 if ($retval == 0); # turn "0E0" into plain old "0"
        };
        if ($@) {  # Log the error message with the SQL and rethrow the exception
            $self->{context}->log({level=>1},"DBI Exception (fail) in _delete_rows(): $@SQL: $sql");
            die $@;
        }
    }
    $retval = 0 if ($retval == 0); # turn "0E0" into plain old "0"
    if ($debug_sql) {
        $elapsed_time = $self->_read_timer($timer);
        print $App::DEBUG_FILE "DEBUG_SQL: retval [$retval] ($elapsed_time sec) $DBI::errstr\n";
        print $App::DEBUG_FILE "\n";
    }

    &App::sub_exit($retval) if ($App::trace);
    $retval;
}

sub _do {
    &App::sub_entry if ($App::trace);
    my ($self, $sql) = @_;
    $self->{error} = "";
    $self->{sql} = $sql;
    my $dbh = $self->{dbh};
    my $retval = 0;

    my $context_options = $self->{context}{options};
    my $debug_sql = $context_options->{debug_sql};
    my ($timer, $elapsed_time);
    if ($debug_sql) {
        $timer = $self->_get_timer();
        print $App::DEBUG_FILE "DEBUG_SQL: _do()\n";
        print $App::DEBUG_FILE $sql;
        print $App::DEBUG_FILE "\n" if ($sql !~ /\n$/);
    }
    if ($context_options->{explain_sql}) {
        $self->explain_sql($sql);
    }
    if (defined $dbh) {
        $self->{sql} = $sql;
        my $continue = 1;
        my $tries = 1;
        while ($continue) {
            eval {
                if ($sql =~ /^select/i) {
                    $retval = $dbh->selectall_arrayref($sql);
                }
                else {
                    $retval = $dbh->do($sql);
                    $retval = 0 if ($retval == 0); # turn "0E0" into plain old "0"
                }
            };
            if ($@) {  # Log the error message with the SQL and rethrow the exception
                my $retryable_modify_error_regex = $self->retryable_modify_error_regex();
                if ($@ =~ /$retryable_modify_error_regex/i) {
                    if ($tries >= 3) {
                        $self->{context}->log({level=>1},"DBI Exception (fail) (tries=$tries) in _do(): $@$sql");
                        die $@;
                    }
                    $self->{context}->log({level=>1},"DBI Exception (retry) (tries=$tries) in _do(): $@$sql");
                    $tries++;
                    sleep(1);
                }
                else {
                    $self->{context}->log({level=>1},"DBI Exception (fail) in _do(): $@$sql");
                    die $@;
                }
            }
            else {
                $continue = 0;
            }
        }
    }
    if ($debug_sql) {
        my $nrows = 0;
        if ($retval) {
            if (ref($retval)) {
                $nrows = $#$retval + 1;
            }
            else {
                $nrows = $retval;
            }
        }
        $elapsed_time = $self->_read_timer($timer);
        print $App::DEBUG_FILE "DEBUG_SQL: nrows [$nrows] ($elapsed_time sec) $DBI::errstr\n";
        if ($debug_sql >= 2 && ref($retval)) {
            foreach my $row (@$retval) {
                print $App::DEBUG_FILE "DEBUG_SQL: [", join("|",map { defined $_ ? $_ : "undef"} @$row), "]\n";
            }
        }
        print $App::DEBUG_FILE "\n";
    }

    &App::sub_exit($retval) if ($App::trace);
    $retval;
}

#############################################################################
# begin_work()
#############################################################################

=head2 begin_work()

    * Signature: $rep->begin_work();
    * Param:     void
    * Return:    void
    * Throws:    App::Exception::Repository
    * Since:     0.01

    Sample Usage: 

    $rep->begin_work();

=cut

sub begin_work {
    &App::sub_entry if ($App::trace);
    my $self = shift;
    $self->_connect();
    if (!$self->{in_transaction}) {
        $self->{dbh}->begin_work();
        $self->{in_transaction} = 1;
    }
    &App::sub_exit() if ($App::trace);
}

#############################################################################
# commit()
#############################################################################

=head2 commit()

    * Signature: $rep->commit();
    * Param:     void
    * Return:    void
    * Throws:    App::Exception::Repository
    * Since:     0.01

    Sample Usage: 

    $rep->commit();

=cut



( run in 0.605 second using v1.01-cache-2.11-cpan-adec679a428 )