CPAN-Common-Index

 view release on metacpan or  search on metacpan

lib/CPAN/Common/Index/Mirror.pm  view on Meta::CPAN

        my $v   = version->parse($arg);
        return sub {
            eval { version->parse( $_[0] ) == $v };
        };
    },
);

my %QUERY_TYPES = (
    # package search
    package => 'regexp',
    version => 'version',
    dist    => 'regexp',

    # author search
    id       => 'regexp_nocase', # XXX need to add "alias " first
    fullname => 'regexp_nocase',
    email    => 'regexp_nocase',
);

sub cached_package {
    my ($self) = @_;
    my $package = File::Spec->catfile( $self->cache,
        File::Basename::basename( $INDICES{packages} ) );
    $package =~ s/\.gz$//;
    $self->refresh_index unless -r $package;
    return $package;
}

sub cached_mailrc {
    my ($self) = @_;
    my $mailrc =
      File::Spec->catfile( $self->cache, File::Basename::basename( $INDICES{mailrc} ) );
    $mailrc =~ s/\.gz$//;
    $self->refresh_index unless -r $mailrc;
    return $mailrc;
}

sub refresh_index {
    my ($self) = @_;
    for my $file ( values %INDICES ) {
        my $remote = URI->new_abs( $file, $self->mirror );
        $remote =~ s/\.gz$//
          unless $HAS_IO_UNCOMPRESS_GUNZIP;
        my $ff = File::Fetch->new( uri => $remote );
        my $where = $ff->fetch( to => $self->cache )
          or Carp::croak( $ff->error );
        if ($HAS_IO_UNCOMPRESS_GUNZIP) {
            ( my $uncompressed = $where ) =~ s/\.gz$//;
            no warnings 'once';
            IO::Uncompress::Gunzip::gunzip( $where, $uncompressed )
              or Carp::croak "gunzip failed: $IO::Uncompress::Gunzip::GunzipError\n";
        }
    }
    return 1;
}

# epoch secs
sub index_age {
    my ($self) = @_;
    my $package = $self->cached_package;
    return ( -r $package ? ( stat($package) )[9] : 0 ); # mtime if readable
}

sub search_packages {
    my ( $self, $args ) = @_;
    Carp::croak("Argument to search_packages must be hash reference")
      unless ref $args eq 'HASH';

    my $index_path = $self->cached_package;
    die "Can't read $index_path" unless -r $index_path;

    my $fh = IO::Handle->new;
    tie *$fh, 'Tie::Handle::SkipHeader', "<", $index_path
      or die "Can't tie $index_path: $!";

    # Convert scalars or regexps to subs
    my $rules;
    while ( my ( $k, $v ) = each %$args ) {
        $rules->{$k} = _rulify( $k, $v );
    }

    my @found;
    if ( $args->{package} and ref $args->{package} eq '' ) {
        # binary search 02packages on package
        my $pos = look $fh, $args->{package}, { xfrm => \&_xform_package, fold => 1 };
        return if $pos == -1;
        # loop over any case-insensitive matching lines
        LINE: while ( my $line = <$fh> ) {
            last unless $line =~ /\A\Q$args->{package}\E\s+/i;
            push @found, _match_package_line( $line, $rules );
        }
    }
    else {
        # iterate all lines looking for match
        LINE: while ( my $line = <$fh> ) {
            push @found, _match_package_line( $line, $rules );
        }
    }
    return wantarray ? @found : $found[0];
}

sub search_authors {
    my ( $self, $args ) = @_;
    Carp::croak("Argument to search_authors must be hash reference")
      unless ref $args eq 'HASH';

    my $index_path = $self->cached_mailrc;
    die "Can't read $index_path" unless -r $index_path;
    open my $fh, $index_path or die "Can't open $index_path: $!";

    # Convert scalars or regexps to subs
    my $rules;
    while ( my ( $k, $v ) = each %$args ) {
        $rules->{$k} = _rulify( $k, $v );
    }

    my @found;
    if ( $args->{id} and ref $args->{id} eq '' ) {
        # binary search mailrec on package
        my $pos = look $fh, $args->{id}, { xfrm => \&_xform_mailrc, fold => 1 };
        return if $pos == -1;



( run in 0.723 second using v1.01-cache-2.11-cpan-5a3173703d6 )