App-CSVUtils

 view release on metacpan or  search on metacpan

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

}

sub _complete_sort_field {
    _complete_field_or_field_list('sort_field', @_);
}

sub _array2hash {
    my ($row, $fields) = @_;
    my $rowhash = {};
    for my $i (0..$#{$fields}) {
        $rowhash->{ $fields->[$i] } = $row->[$i];
    }
    $rowhash;
}

# check that the first N values of a field are all defined and numeric. if there
# are now rows or less than N values, return true.
sub _is_numeric_field {
    require Scalar::Util::Numeric;

    my ($rows, $field_idx, $num_samples) = @_;
    $num_samples //= 5;

    my $is_numeric = 1;
    for my $row (@$rows) {
        my $val = $row->[$field_idx];
        return 0 unless defined $val;
        return 0 unless Scalar::Util::Numeric::isnum($val);
    }
    $is_numeric;
}

# find a single field by name or index (1-based), return index (0-based). die
# when requested field does not exist.
sub _find_field {
    my ($fields, $name_or_idx) = @_;

    # search by name first
    for my $i (0 .. $#{$fields}) {
        my $field = $fields->[$i];
        return $i if $field eq $name_or_idx;
    }

    if ($name_or_idx eq '0') {
        die [400, "Field index 0 is requested, you probably meant 1 for the first field?"];
    } elsif ($name_or_idx =~ /\A[1-9][0-9]*\z/) {
        if ($name_or_idx > @$fields) {
            die [400, "There are only ".scalar(@$fields)." field(s) but field index $name_or_idx is requested"];
        } else {
            return $name_or_idx-1;
        }
    } elsif ($name_or_idx =~ /\A-[1-9][0-9]*\z/) {
        if (-$name_or_idx > @$fields) {
            die [400, "There are only ".scalar(@$fields)." field(s) but field index $name_or_idx is requested"];
        } else {
            return @$fields + $name_or_idx;
        }
    }

    # not found
    die [404, "Unknown field name/index '$name_or_idx' (known fields include: ".
         join(", ", map { "'$_'" } @$fields).")"];
}

# select one or more fields with options like --include-field, etc
sub _select_fields {
    my ($fields, $field_idxs, $args, $default_select_choice) = @_;

    my @selected_fields;

    my $select_field_options_used;

    if (defined $args->{include_field_pat}) {
        $select_field_options_used++;
        for my $field (@$fields) {
            if ($field =~ $args->{include_field_pat}) {
                push @selected_fields, $field;
            }
        }
    }
    if (defined $args->{exclude_field_pat}) {
        $select_field_options_used++;
        @selected_fields = grep { $_ !~ $args->{exclude_field_pat} }
            @selected_fields;
    }
    if (defined $args->{include_fields}) {
        $select_field_options_used++;
      FIELD:
        for my $field (@{ $args->{include_fields} }) {
            unless (defined $field_idxs->{$field}) {
                return [400, "Unknown field '$field'"] unless $args->{ignore_unknown_fields};
                next FIELD;
            }
            next if grep { $field eq $_ } @selected_fields;
            push @selected_fields, $field;
        }
    }
    if (defined $args->{exclude_fields}) {
        $select_field_options_used++;
      FIELD:
        for my $field (@{ $args->{exclude_fields} }) {
            unless (defined $field_idxs->{$field}) {
                return [400, "Unknown field '$field'"] unless $args->{ignore_unknown_fields};
                next FIELD;
            }
            @selected_fields = grep { $field ne $_ } @selected_fields;
        }
    }

    if (!$select_field_options_used && $default_select_choice) {
        if ($default_select_choice eq 'all') {
            @selected_fields = @$fields;
        } elsif ($default_select_choice eq 'first') {
            @selected_fields = ($fields->[0]) if @$fields;
        } elsif ($default_select_choice eq 'last') {
            @selected_fields = ($fields->[-1]) if @$fields;
        } elsif ($default_select_choice eq 'first-if-only-field') {
            @selected_fields = ($fields->[0]) if @$fields == 1;
        }
    }



( run in 1.285 second using v1.01-cache-2.11-cpan-39bf76dae61 )