Skip to content

Commit

Permalink
move find and find_pod methods to query
Browse files Browse the repository at this point in the history
  • Loading branch information
haarg committed Dec 28, 2024
1 parent 8fb204d commit ecfa323
Show file tree
Hide file tree
Showing 11 changed files with 182 additions and 144 deletions.
100 changes: 0 additions & 100 deletions lib/MetaCPAN/Document/File/Set.pm
Original file line number Diff line number Diff line change
Expand Up @@ -7,106 +7,6 @@ use MetaCPAN::Util qw( true false );

extends 'ElasticSearchX::Model::Document::Set';

sub find {
my ( $self, $module ) = @_;

my $query = {
bool => {
must => [
{ term => { indexed => true } },
{ term => { authorized => true } },
{ term => { status => 'latest' } },
{
bool => {
should => [
{ term => { documentation => $module } },
{
nested => {
path => "module",
query => {
bool => {
must => [
{
term => { "module.name" =>
$module }
},
{
bool => { should =>
[
{ term =>
{ "module.authorized"
=> true
} },
{ exists =>
{ field =>
'module.associated_pod'
} },
],
}
},
],
},
},
}
},
]
}
},
],
},
};

my $res = $self->es->search(
es_doc_path('file'),
search_type => 'dfs_query_then_fetch',
body => {
query => $query,
sort => [
'_score',
{ 'version_numified' => { order => 'desc' } },
{ 'date' => { order => 'desc' } },
{ 'mime' => { order => 'asc' } },
{ 'stat.mtime' => { order => 'desc' } }
],
_source => [
qw( documentation module.indexed module.authoried module.name )
],
size => 100,
},
);

my @candidates = @{ $res->{hits}{hits} };

my ($file) = grep {
grep { $_->{indexed} && $_->{authorized} && $_->{name} eq $module }
@{ $_->{module} || [] }
} grep { !$_->{documentation} || $_->{documentation} eq $module }
@candidates;

$file ||= shift @candidates;
return $file ? $self->get( $file->{_id} ) : undef;
}

sub find_pod {
my ( $self, $name ) = @_;
my $file = $self->find($name);
return $file unless ($file);
my ($module)
= grep { $_->indexed && $_->authorized && $_->name eq $name }
@{ $file->module || [] };
if ( $module && ( my $pod = $module->associated_pod ) ) {
my ( $author, $release, @path ) = split( /\//, $pod );
return $self->get( {
author => $author,
release => $release,
path => join( '/', @path ),
} );
}
else {
return $file;
}
}

=head2 history
Find the history of a given module/documentation.
Expand Down
116 changes: 116 additions & 0 deletions lib/MetaCPAN/Query/File.pm
Original file line number Diff line number Diff line change
Expand Up @@ -559,5 +559,121 @@ sub documented_modules {
};
}

sub find_module {
my ( $self, $module, $fields ) = @_;

my $query = {
bool => {
must => [
{ term => { indexed => true } },
{ term => { authorized => true } },
{ term => { status => 'latest' } },
{
bool => {
should => [
{ term => { documentation => $module } },
{
nested => {
path => "module",
query => {
bool => {
must => [
{
term => { "module.name" =>
$module }
},
{
bool => { should =>
[
{ term =>
{ "module.authorized"
=> true
} },
{ exists =>
{ field =>
'module.associated_pod'
} },
],
}
},
],
},
},
}
},
]
}
},
],
},
};

my $res = $self->es->search(
es_doc_path('file'),
search_type => 'dfs_query_then_fetch',
body => {
query => $query,
sort => [
'_score',
{ 'version_numified' => { order => 'desc' } },
{ 'date' => { order => 'desc' } },
{ 'mime' => { order => 'asc' } },
{ 'stat.mtime' => { order => 'desc' } }
],
_source => [
qw( documentation module.indexed module.authoried module.name )
],
size => 100,
},
);

my @candidates = @{ $res->{hits}{hits} };

my ($file) = grep {
grep { $_->{indexed} && $_->{authorized} && $_->{name} eq $module }
@{ $_->{module} || [] }
} grep { !$_->{documentation} || $_->{documentation} eq $module }
@candidates;

$file ||= shift @candidates;
return undef
if !$file;
return $self->es->get_source( es_doc_path('file'), $file->{_id},
( $fields ? ( _source => $fields ) : () ),
);
}

sub find_pod {
my ( $self, $name ) = @_;
my $file = $self->find_module($name);
return $file
unless $file;
my ($module)
= grep { $_->{indexed} && $_->{authorized} && $_->{name} eq $name }
@{ $file->{module} || [] };
if ( $module && ( my $pod = $module->{associated_pod} ) ) {
my ( $author, $release, @path ) = split( /\//, $pod );
my $query = {
bool => {
must => [
{ term => { author => $author } },
{ term => { release => $release } },
{ term => { path => join( '/', @path ) } },
],
},
};
my $pod_file = $self->es->search(
es_doc_path('file'),
body => {
query => $query,
},
);
return $pod_file->{hits}{hits}[0];
}
else {
return $file;
}
}

__PACKAGE__->meta->make_immutable;
1;
8 changes: 3 additions & 5 deletions lib/MetaCPAN/Server/Controller/Module.pm
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,12 @@ has '+type' => ( default => 'file' );

sub get : Path('') : Args(1) {
my ( $self, $c, $name ) = @_;
my $file = $self->model($c)->raw->find($name);
my $file
= $c->model('ESQuery')->file->find_module( $name, $c->req->fields );
if ( !defined $file ) {
$c->detach( '/not_found', [] );
}
$c->stash( $file->{_source}
|| single_valued_arrayref_to_scalar( $file->{fields} ) )
|| $c->detach( '/not_found',
['The requested field(s) could not be found'] );
$c->stash($file);
}

__PACKAGE__->meta->make_immutable();
Expand Down
4 changes: 2 additions & 2 deletions lib/MetaCPAN/Server/Controller/Pod.pm
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ sub find : Path('') {

sub get : Path('') : Args(1) {
my ( $self, $c, $module ) = @_;
$module = $c->model('ESModel')->doc('file')->find_pod($module)
$module = $c->model('ESQuery')->file->find_pod($module)
or $c->detach( '/not_found', [] );
$c->forward( 'find', [ map { $module->$_ } qw(author release path) ] );
$c->forward( 'find', [ map { $module->{$_} } qw(author release path) ] );
}

sub find_dist_links {
Expand Down
7 changes: 5 additions & 2 deletions lib/MetaCPAN/Server/Controller/Source.pm
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,12 @@ sub module : Chained('index') : PathPart('') : Args(1) {

$c->cdn_never_cache(1);

$module = $c->model('ESModel')->doc('file')->find($module)
my $file
= $c->model('ESQuery')
->file->find_module( $module, [qw(author release path)] )
or $c->detach( '/not_found', [] );
$c->forward( 'get', [ map { $module->$_ } qw(author release path) ] );

$c->forward( 'get', [ map { $file->{$_} } qw(author release path) ] );
}

1;
6 changes: 6 additions & 0 deletions lib/MetaCPAN/Server/Role/Request.pm
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,10 @@ around [qw(content_type header)] => sub {
: $header;
};

sub fields {
my $self = shift;
my @fields = map { split /,/ } $self->param('fields');
return @fields ? \@fields : undef;
}

1;
28 changes: 21 additions & 7 deletions t/lib/MetaCPAN/Server/Test.pm
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,22 @@ package MetaCPAN::Server::Test;

use strict;
use warnings;
use feature qw(state);

use HTTP::Request::Common qw( DELETE GET POST ); ## no perlimports
use MetaCPAN::Model ();
use MetaCPAN::Server ();
use MetaCPAN::Server::Config ();
use Plack::Test; ## no perlimports
use HTTP::Request::Common qw( DELETE GET POST ); ## no perlimports
use MetaCPAN::Model ();
use MetaCPAN::Server ();
use MetaCPAN::Server::Config ();
use MooseX::Types::ElasticSearch qw( ES );
use Plack::Test; ## no perlimports

use base 'Exporter';
our @EXPORT_OK = qw(
POST GET DELETE
es
model
test_psgi app
query
);

# Begin the load-order dance.
Expand All @@ -38,9 +42,19 @@ sub app {
return $app;
}

sub es {
state $es = do {
my $c = MetaCPAN::Server::Config::config();
ES->assert_coerce($c);
};
}

sub model {
my $c = MetaCPAN::Server::Config::config();
MetaCPAN::Model->new( es => $c->{elasticsearch_servers} );
state $model = MetaCPAN::Model->new( es => es() );
}

sub query {
state $query = MetaCPAN::Query->new( es => es() );
}

1;
Expand Down
6 changes: 0 additions & 6 deletions t/release/moose.t
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,6 @@ ok(

is( $ppport->name, 'ppphdoc', 'name doesn\'t contain a dot' );

ok( my $moose = $model->doc('file')->find('Moose'), 'find Moose module' );

is( $moose->name, 'Moose.pm', 'defined in Moose.pm' );

is( $moose->module->[0]->associated_pod, 'DOY/Moose-0.02/lib/Moose.pm' );

my $signature;
$signature = $model->doc('file')->query( {
bool => {
Expand Down
Loading

0 comments on commit ecfa323

Please sign in to comment.