App-Repository

 view release on metacpan or  search on metacpan

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

    my $field_sep           = $options->{field_sep} || ",";
    my $field_quote         = $options->{field_quote} || "";
    my $field_escape        = $options->{field_escape} || "";
    die "TODO: field_escape not yet implemented" if ($field_escape);
    my $fieldsep_regexp     = ($field_sep eq "|") ? '\|' : $field_sep;
    my $quoted_field_regexp = "$field_sep?$field_quote([^$field_quote]*)$field_quote";
    my $field_regexp        = "$field_sep?([^$field_sep]*)";
    my $num_cols = $#$cols + 1;
    my $rows_read = 0;
    my $rows = [];
    my ($num_values_read, $line, $line_remainder, $row);
    while (<$fh>) {
        chomp;
        $line = $_;
        if ($line) {
            if (!$field_quote && !$field_escape) {
                $row = [ map { $_ eq $null_value ? undef : $_ } split(/$fieldsep_regexp/, $line) ];
                $num_values_read = $#$row + 1;
            }
            else {
                $num_values_read = 0;
                $line_remainder = $line;
                $row = [];
                while ($line_remainder) {
                    if ($line_remainder =~ s/^$quoted_field_regexp//) {
                        push(@$row, $1 eq $null_value ? undef : $1);
                    }
                    elsif ($line_remainder =~ s/^$field_regexp//) {
                        push(@$row, $1 eq $null_value ? undef : $1);
                    }
                    else {
                        die "Imported data [$line] doesn't match quoted or unquoted field at [$line_remainder]";
                    }
                }
            }
            die "In imported data [$line], num values on line [$num_values_read] != num columns expected [$num_cols]"
                if ($num_values_read != $num_cols);
            push(@$rows, $row);
            $rows_read ++;
            if ($maxrows && $rows_read >= $maxrows) {
                last;
            }
        }
    }
    &App::sub_exit($rows) if ($App::trace);
    return($rows);
}

#############################################################################
# METHODS
#############################################################################

=head1 Methods: Locking (Concurrency Management)

=cut

# this is a write lock for the table
sub _lock_table {
    &App::sub_entry if ($App::trace);
    my ($self, $table) = @_;
    if (! $self->{locked}) {   # I have locked it myself, so I don't need to again
        my ($name, $dbname, $context, $rlock);
        $name = $self->{name};
        $dbname = $self->{dbname};
        $context = $self->{context};
        $rlock = $context->resource_locker($name);  # get the one that corresponds to this repository
        $rlock->lock("db.$dbname.$table");
        $self->{locked} = 1;
    }
    &App::sub_exit() if ($App::trace);
}

# unlocks the write lock for the table
sub _unlock_table {
    &App::sub_entry if ($App::trace);
    my ($self, $table) = @_;
    if ($self->{locked}) {
        my ($name, $dbname, $context, $rlock);
        $name = $self->{name};
        $dbname = $self->{dbname};
        $context = $self->{context};
        $rlock = $context->resource_locker($name);  # get the one that corresponds to this repository
        $rlock->unlock("db.$dbname.$table");
        delete $self->{locked};
    }
    &App::sub_exit() if ($App::trace);
}

#############################################################################
# METHODS
#############################################################################

=head1 Methods: Miscellaneous

=cut

#############################################################################
# summarize_rows()
#############################################################################

=head2 summarize_rows()

    * Signature: $summarized_rows = $rep->summarize_rows($table, $rows, $columns, $summary_keys, $options);
    * Param:     $table            string
    * Param:     $rows             [][]
    * Param:     $columns          []
    * Param:     $summary_keys       []
    * Param:     $formulas         {}
    * Return:    $summarized_rows  []
    * Throws:    App::Exception::Repository
    * Since:     0.01

    Sample Usage: 

    @rows = (
        [ 5, "Jim", "Green", 13.5, 320, ],
        [ 3, "Bob", "Green",  4.2, 230, ],
        [ 9, "Ken", "Green", 27.4, 170, ],
        [ 2, "Kim", "Blue",  11.7, 440, ],
        [ 7, "Jan", "Blue",  55.1,  90, ],
        [ 1, "Ben", "Blue",  22.6, 195, ],
    );
    @columns = ( "id", "name", "team", "rating", "score" );
    @summary_keys = ( "team" );

    $summarized_rows = $rep->summarize_rows(\@rows, \@columns, \@summary_keys, \%formulas);

    @rows = (
        { id=>5, name=>"Jim", team=>"Green", rating=>13.5, score=>320, },
        { id=>3, name=>"Bob", team=>"Green", rating=> 4.2, score=>230, },
        { id=>9, name=>"Ken", team=>"Green", rating=>27.4, score=>170, },
        { id=>2, name=>"Kim", team=>"Blue",  rating=>11.7, score=>440, },
        { id=>7, name=>"Jan", team=>"Blue",  rating=>55.1, score=> 90, },
        { id=>1, name=>"Ben", team=>"Blue",  rating=>22.6, score=>195, },
    );
    @columns = ( "rating", "score" );  # summarize a subset of the columns
    @summary_keys = ( "team" );
    %options = (
        ext_summaries => \%summaries,         # extended summaries
        ext_summary_columns => [ "rating", "score", "team", ],   # optional
        ext_summary_functions => {  # optional
            sum      => 1,
            count    => 1,
            sum_sq   => 1,



( run in 1.172 second using v1.01-cache-2.11-cpan-e1769b4cff6 )