App-td

 view release on metacpan or  search on metacpan

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

                if ($n < 0) {
                    $output = [400, "Cannot tail negative number of rows"];
                    last;
                } elsif ($n =~ s/\A\+//) {
                    splice @$rows, 0, $n-1 if $n >= 1;
                } else {
                    splice @$rows, 0, @$rows - $n if $n < @$rows;
                }
            }
            $output = [200, "OK", $rows, {'table.fields' => $cols}];
            last;
        }

        if ($action eq 'colcount') {
            $output = [200, "OK", $input_obj->col_count];
            last;
        }

        if ($action eq 'colnames') {
            my $cols = $input_obj->cols_by_idx;
            my $colnames_row = [map {$cols->[$_]} 0..$#{$cols}];
            $output = [200, "OK", $colnames_row];
            last;
        }

        if ($action eq 'colnames-row') {
            my $cols = $input_obj->cols_by_idx;
            my $rows = $input_obj->rows;
            my $colnames_row;
            if (@$rows && ref $rows->[0] eq 'HASH') {
                $colnames_row = $input_obj->cols_by_name;
            } elsif (@$rows && ref $rows->[0] eq 'ARRAY') {
                $colnames_row = [map {$cols->[$_]} 0..$#{$cols}];
            } else {
                $colnames_row = $cols->[0];
            }
            $output = [200, "OK", [@$rows, $colnames_row],
                       {'table.fields' => $cols}];
            last;
        }

        if ($action eq 'rownum-col') {
            $input_obj->add_col('_rownum', 0); # XXX if table already has that column, use _rownum2, ...
            $input_obj->set_col_val(_rownum => sub { my %a = @_; $a{row_idx}+1 });
            $output = [200, "OK", $input_obj->{data},
                       {'table.fields' => $input_obj->{cols_by_idx}}];
            last;
        }

        if ($action =~ /\A(sum|sum-row|avg|avg-row)\z/) {
            require Scalar::Util;
            my $cols = $input_obj->cols_by_idx;
            my $rows = $input_obj->rows;
            # XXX optimize by not producing two versions of rows
            my $rows_as_aoaos = $input_obj->rows_as_aoaos;
            my $sums = [map {0} @$cols];
            for my $i (0..$#{$rows_as_aoaos}) {
                my $row = $rows_as_aoaos->[$i];
                for my $j (0..@$cols-1) {
                    $sums->[$j] += $row->[$j]
                        if Scalar::Util::looks_like_number($row->[$j]);
                }
            }
            my $avgs;
            my $results;
            if ($action =~ /avg/) {
                if (@$rows) {
                    $avgs = [map { $_ / @$rows } @$sums];
                } else {
                    $avgs = [map {0} @$cols];
                }
                $results = $avgs;
            } else {
                $results = $sums;
            }

            my $result_row;
            if (@$rows && ref $rows->[0] eq 'HASH') {
                $result_row = {map {$cols->[$_] => $results->[$_]}
                                   0..$#{$cols}};
            } elsif (@$rows && ref $rows->[0] eq 'ARRAY') {
                $result_row = $results;
            } else {
                $result_row = $results->[0];
            }

            if ($action =~ /-row/) {
                $output = [200, "OK", [@$rows, $result_row],
                           {'table.fields' => $cols}];
            } else {
                $output = [200, "OK", $result_row,
                           {'table.fields' => $cols}];
            }
            last;
        }

        if ($action eq 'shuf' || $action eq 'pick') {
            my $cols = $input_obj->cols_by_idx;
            my $input_rows = $input_obj->rows;
            my $weight_column_idx = defined $args{weight_column} ?
                $input_obj->col_idx($args{weight_column}) : undef;
            my @output_rows;
            if ($args{repeated}) {
                if (defined $weight_column_idx) {
                    require Array::Sample::WeightedRandom;
                    my @ary = map { [$input_rows->[$_], $input_rows->[$_][$weight_column_idx]] } 0 .. scalar(@$input_rows);
                    @output_rows = Array::Sample::WeightedRandom::sample_weighted_random_with_replacement(\@ary, ($args{lines} // scalar(@$input_rows)));
                } else {
                    for my $i (1 .. ($args{lines} // scalar(@$input_rows))) {
                        $output_rows[$i-1] = $input_rows->[rand() * @$input_rows];
                    }
                }
            } else {
                if (defined $weight_column_idx) {
                    require Array::Sample::WeightedRandom;
                    my @ary = map { [$input_rows->[$_], $input_rows->[$_][$weight_column_idx]] } 0 .. scalar(@$input_rows);
                    @output_rows = Array::Sample::WeightedRandom::sample_weighted_random_no_replacement(\@ary, ($args{lines} // scalar(@$input_rows)));
                } else {
                    require List::MoreUtils;
                    @output_rows = List::MoreUtils::samples(
                        $args{lines} // scalar(@$input_rows),



( run in 2.733 seconds using v1.01-cache-2.11-cpan-75ffa21a3d4 )