| CPAN-SQLite documentation | Contained in the CPAN-SQLite distribution. |
CPAN::SQLite::Search - perform queries on the database
my $max_results = 200;
my $query = CPAN::SQLite::Search->new(db_dir => $db_dir,
db_name => $db_name,
max_results => $max_results);
$query->query(mode => 'module', name => 'Net::FTP');
my $results = $query->{results};
This module queries the database via various types of queries
and returns the results for subsequent display. The
CPAN::SQLite::Search object is created via the new method as
my $query = CPAN::SQLite::Search->new(db_dir => $db_dir,
db_name => $db_name,
max_results => $max_results);
which takes as arguments
This is the directory where the database file is stored. This is
optional if the CPAN option is given.
This option specifies the cpan_home directory of an
already configured CPAN.pm, which is where the database
file will be stored if db_dir is not given.
This is the maximum value used to limit the number of results
returned under a user query. If not specified, a value contained
within CPAN::SQLite::Search will be used.
A basic query then is constructed as
$query->query(mode => $mode, $type => $value);
with the results available as
my $results = $query->{results}
There are three basic modes:
This is for information on modules.
This is for information on distributions.
This is for information on CPAN authors or cpanids.
module, dist, and author modesFor a mode of module, dist, and author, there are
four basic options to be used for the $type => $value option:
This will search through module names,
distribution names, or CPAN author names and ids
(for module, dist, and author modes
respectively). The results are case insensitive,
and Perl regular expressions for the $query_term
are recognized.
This will report exact matches (in a case sensitive manner)
for the module name, distribution name, or CPAN author id,
for module, dist, and author modes
respectively.
This will look up information on the primary key according to the mode specified. This is more for internal use, to help speed up queries; using this "publically" is probably not a good idea, as the ids may change over the course of time.
After making the query, the results can be accessed through
my $results = $query->{results};
No results either can mean no matches were found, or
else an error in making the query resulted (in which case,
a brief error message is contained in $query->{error}).
Assuming there are results, what is returned depends on
the mode and on the type of query. See CPAN::SQLite::Populate
for a description of the fields in the various tables
listed below - these fields are used as the keys of the
hash references that arise.
author modemodule modename or id queryThis returns the mod_id, mod_name, mod_abs, mod_vers,
dslip, chapterid, dist_id, dist_name, dist_file,
auth_id, cpanid, fullname, and email
of the auths, mods, and dists tables.
As well, the following entries may be present.
downloadThis can be used as $CPAN/authors/id/$download
to specify the url of the distribution.
dslip_infoIf dslip is available, an array reference dslip_info is supplied,
each entry being a hash reference. The hash reference contains
two keys - desc, whose value is a general description of the
what the dslip entry represents, and what, whose value is
a description of the entry itself.
query queryIf this results in more than one match, an array reference
is returned, each member of which is a hash reference containing
the mod_id, mod_name, mod_abs, mod_abs, dist_vers, dist_abs,
auth_id, cpanid, dist_id, dist_name, and dist_file.
As well, a download field which
can be used as $CPAN/authors/id/$download
to specify the url of the distribution is provided. If there
is only one result found, a name query based on the
matched mod_name is performed.
dist modename or id queryThis returns the dist_id, dist_name, dist_abs, dist_vers,
dist_file, size, birth, auth_id, cpanid, and fullname
of the auths, mods, and dists tables.
As well, the following entries may be present.
downloadThis can be used as $CPAN/authors/id/$download
to specify the url of the distribution.
modsThis is an array reference containing information on the
modules present. Each entry is a hash reference containing the
mod_id, mod_name, mod_abs, mod_vers, and dslip
fields for the module.
dslip and dslip_infoIf the module name and distribution name are related by
s/::/-, the dslip and dslip_info entries for
that module are returned.
query queryIf this results in more than one match, an array reference
is returned, each member of which is a hash reference containing
the dist_id, dist_name, dist_abs, dist_file,
and cpanid fields. As well, a download field which
can be used as $CPAN/authors/id/$download
to specify the url of the distribution is provided. If there
is only one result found, a name query based on the
matched dist_name is performed.
Randy Kobes (passed away on September 18, 2010)
Serguei Trouchelle <stro@cpan.org>
Copyright 2006,2008 by Randy Kobes <r.kobes@uwinnipeg.ca>.
Copyright 2011 by Serguei Trouchelle <stro@cpan.org>.
Use and redistribution are under the same terms as Perl itself.
| CPAN-SQLite documentation | Contained in the CPAN-SQLite distribution. |
# $Id: Search.pm 35 2011-06-17 01:34:42Z stro $ package CPAN::SQLite::Search; use strict; use warnings; no warnings qw(redefine); use utf8; use CPAN::SQLite::Util qw($mode_info); use CPAN::SQLite::DBI::Search; our $max_results = 0; our $VERSION = '0.202'; my $cdbi_query; my %mode2obj; $mode2obj{$_} = __PACKAGE__ . '::' . $_ for (qw(dist author module)); sub new { my ($class, %args) = @_; $cdbi_query = CPAN::SQLite::DBI::Search->new(%args); $max_results = $args{max_results} if $args{max_results}; my $self = {results => undef, error => '', %args}; return bless $self, $class; } sub query { my ($self, %args) = @_; my $mode = $args{mode} || 'module'; unless ($mode) { $self->{error} = q{Please specify a 'mode' argument}; return; } my $info = $mode_info->{$mode}; my $table = $info->{table}; unless ($table) { $self->{error} = qq{No table exists for '$mode'}; return; } my $cdbi = $cdbi_query->{objs}->{$table}; my $class = 'CPAN::SQLite::DBI::Search::' . $table; unless ($cdbi and ref($cdbi) eq $class) { $self->{error} = qq{No cdbi object exists for '$table'}; return; } my $obj; eval {$obj = $mode2obj{$mode}->make(table => $table, cdbi => $cdbi);}; if ($@) { $self->{error} = qq{Mode '$mode' is not known}; return; } my $value; my $search = {name => $info->{name}, text => $info->{text}, id => $info->{id}, }; TYPE: { ($value = $args{query}) and do { $search->{value} = $value; $search->{type} = 'query'; $search->{wantarray} = 1; last TYPE; }; ($value = $args{id}) and do { $search->{value} = $value; $search->{type} = 'id'; $search->{distinct} = 1; last TYPE; }; ($value = $args{name}) and do { $search->{value} = $value; $search->{type} = 'name'; $search->{distinct} = 1; last TYPE; }; $self->{error} = q{Cannot determine the type of search}; return; } $obj->search(search => $search, meta_obj => $self->{meta_obj}); $self->{results} = $obj->{results}; if (my $error = $obj->{error}) { $self->{error} = $error; return; } return 1; } sub make { my ($class, %args) = @_; for (qw(table cdbi)) { die qq{Must supply an '$_' arg} unless defined $args{$_}; } my $self = {results => undef, error => '', table => $args{table}, cdbi => $args{cdbi}}; return bless $self, $class; } package CPAN::SQLite::Search::author; use base qw(CPAN::SQLite::Search); sub search { my ($self, %args) = @_; return unless $args{search}; my $cdbi = $self->{cdbi}; my $meta_obj = $args{meta_obj}; $args{fields} = [ qw(auth_id cpanid fullname email) ]; $args{table} = 'auths'; if ($max_results) { $args{limit} = $max_results; } $args{order_by} = 'cpanid'; my $results; return unless $results = ($meta_obj ? $cdbi->fetch_and_set(%args) : $cdbi->fetch(%args)); unless ($meta_obj) { $self->{results} = (ref($results) eq 'ARRAY' and scalar @$results == 1) ? $results->[0] : $results; } return 1 if $meta_obj; # The following will get all the dists associated with the cpanid $args{join} = undef; $args{table} = 'dists'; $args{fields} = [ qw(dist_file dist_abs) ]; $args{order_by} = 'dist_file'; my @items = (ref($results) eq 'ARRAY') ? @$results : ($results); foreach my $item (@items) { my $search = {id => 'auth_id', value => $item->{auth_id}, type => 'id', wantarray => 1, }; my $dists; next unless ($dists = $cdbi->fetch(%args, search => $search)); $item->{dists} = (ref($dists) eq 'ARRAY') ? $dists : [$dists]; } $self->{results} = (ref($results) eq 'ARRAY' and scalar @$results == 1) ? $results->[0] : $results; return 1; } package CPAN::SQLite::Search::module; use base qw(CPAN::SQLite::Search); sub search { my ($self, %args) = @_; return unless $args{search}; my $cdbi = $self->{cdbi}; my $meta_obj = $args{meta_obj}; $args{fields} = [ qw(mod_id mod_name mod_abs mod_vers chapterid dslip dist_id dist_name dist_file dist_vers dist_abs auth_id cpanid fullname email) ]; $args{table} = 'dists'; $args{join} = { mods => 'dist_id', auths => 'auth_id', }; $args{order_by} = 'mod_name'; if ($max_results) { $args{limit} = $max_results; } my $results; return unless $results = ($meta_obj ? $cdbi->fetch_and_set(%args, want_ids => 1) : $cdbi->fetch(%args)); # if running under CPAN.pm, need to build a list of modules # contained in the distribution if ($meta_obj) { my %seen; $args{join} = undef; $args{table} = 'mods'; my @items = (ref($results) eq 'ARRAY') ? @$results : ($results); foreach my $item(@items) { my $dist_id = $item->{dist_id}; next if $seen{$dist_id}; $args{fields} = [ qw(mod_name mod_abs) ]; $args{order_by} = 'mod_name'; $args{join} = undef; my $search = {id => 'dist_id', value => $item->{dist_id}, type => 'id', wantarray => 1, }; $seen{$dist_id}++; my $mods; next unless $mods = $cdbi->fetch_and_set(%args, search => $search, set_list => 1, download => $item->{download}); } } unless ($meta_obj) { $self->{results} = (ref($results) eq 'ARRAY' and scalar @$results == 1) ? $results->[0] : $results; } return 1; } package CPAN::SQLite::Search::dist; use base qw(CPAN::SQLite::Search); sub search { my ($self, %args) = @_; return unless $args{search}; my $cdbi = $self->{cdbi}; my $meta_obj = $args{meta_obj}; $args{fields} = [ qw(dist_id dist_name dist_abs dist_vers dist_dslip dist_file auth_id cpanid fullname email) ]; $args{table} = 'dists'; $args{join} = {auths => 'auth_id'}; $args{order_by} = 'dist_name'; if ($max_results) { $args{limit} = $max_results; } my $results; return unless $results = ($meta_obj ? $cdbi->fetch_and_set(%args, want_ids => 1) : $cdbi->fetch(%args)); $args{join} = undef; $args{table} = 'mods'; $args{fields} = [ qw(mod_name mod_abs) ]; $args{order_by} = 'mod_name'; my @items = (ref($results) eq 'ARRAY') ? @$results : ($results); foreach my $item(@items) { my $search = {id => 'dist_id', value => $item->{dist_id}, type => 'id', wantarray => 1, }; my $mods; next unless $mods = ($meta_obj ? $cdbi->fetch_and_set(%args, search => $search, set_list => 1, download => $item->{download}) : $cdbi->fetch(%args, search => $search) ); next if $meta_obj; $item->{mods} = (ref($mods) eq 'ARRAY') ? $mods : [$mods]; } unless ($meta_obj) { $self->{results} = (ref($results) eq 'ARRAY' and scalar @$results == 1) ? $results->[0] : $results; } return 1; } package CPAN::SQLite::Search; sub mod_subchapter { my ($self, $mod_name) = @_; (my $sc = $mod_name) =~ s{^([^:]+).*}{$1}; return $sc; } sub dist_subchapter { my ($self, $dist_name) = @_; (my $sc = $dist_name) =~ s{^([^-]+).*}{$1}; return $sc; } 1; __END__