File Coverage

blib/lib/CPAN/SQLite.pm
Criterion Covered Total %
statement 52 73 71.2
branch 6 22 27.2
condition 2 11 18.1
subroutine 8 9 88.8
pod 2 3 66.6
total 70 118 59.3


line stmt bran cond sub pod time code
1             # $Id: SQLite.pm 82 2020-05-30 06:14:27Z stro $
2              
3             package CPAN::SQLite;
4 3     3   350298 use strict;
  3         17  
  3         143  
5 3     3   31 use warnings;
  3         13  
  3         249  
6              
7             our $VERSION = '0.218';
8              
9 3     3   27 use English qw/-no_match_vars/;
  3         12  
  3         55  
10              
11 3     3   4352 use File::HomeDir;
  3         20281  
  3         214  
12             require File::Spec;
13 3     3   32 use Cwd;
  3         6  
  3         324  
14             require CPAN::SQLite::META;
15              
16             # an array ref of distributions to ignore indexing
17             my $ignore = [qw(SpreadSheet-WriteExcel-WebPivot)];
18             our $db_name = 'cpandb.sql';
19              
20 3     3   28 use constant WIN32 => $^O eq 'MSWin32';
  3         6  
  3         2281  
21              
22             sub new {
23 2     2 0 6 my $class = shift;
24 2         3 my %args = @_;
25              
26 2         4 my ($CPAN, $update_indices);
27 2         4 my $db_dir = $args{db_dir};
28 2         5 my $urllist = [];
29 2         4 my $keep_source_where;
30              
31             # for testing under Darwin, must load CPAN::MyConfig contained
32             # in PERL5LIB, as File::HomeDir doesn't use this
33 2 50       9 if ($ENV{CPAN_SQLITE_TESTING}) {
34 2         3 eval { require CPAN::MyConfig; };
  2         12  
35             }
36 2         4 eval { require CPAN; CPAN::HandleConfig->load; };
  2         8  
  2         14  
37 2 50 33     180 if (not $@ and not defined $args{CPAN}) {
38 2         7 $CPAN = $CPAN::Config->{cpan_home};
39 2         3 $db_dir = $CPAN;
40 2         4 $keep_source_where = $CPAN::Config->{keep_source_where};
41 2         11 $urllist = $CPAN::Config->{urllist};
42              
43             # Sometimes this directory doesn't exist (like on new installations)
44 2 50       42 unless (-d $CPAN) {
45 0         0 eval { File::Path::mkpath($CPAN); }; # copied from CPAN.pm
  0         0  
46             }
47 2 50       27 die qq{The '$CPAN' directory doesn't exist} unless -d $CPAN;
48 2         6 $update_indices = 0;
49             } else {
50 0   0     0 $CPAN = $args{CPAN} || '';
51 0 0       0 die qq{Please specify the CPAN location} unless defined $CPAN;
52 0 0       0 die qq{The '$CPAN' directory doesn't exist} unless (-d $CPAN);
53 0 0       0 $update_indices = (-f File::Spec->catfile($CPAN, 'MIRRORING.FROM')) ? 0 : 1;
54             }
55 2         5 push @$urllist, q{http://www.cpan.org/};
56 2   33     6 $db_dir ||= cwd;
57 2         14 my $self = {
58             %args,
59             CPAN => $CPAN,
60             update_indices => $update_indices,
61             db_name => $db_name,
62             urllist => $urllist,
63             keep_source_where => $keep_source_where,
64             db_dir => $db_dir
65             };
66 2         11 return bless $self, $class;
67             }
68              
69             sub index {
70 0     0 1 0 my ($self, %args) = @_;
71 0         0 require CPAN::SQLite::Index;
72 0         0 my %wanted = map { $_ => $self->{$_} } qw(CPAN ignore update_indices db_name db_dir keep_source_where setup reindex urllist);
  0         0  
73 0   0     0 my $log_dir = $self->{CPAN} || $self->{db_dir};
74 0 0       0 die qq{Please create the directory '$log_dir' first} unless -d $log_dir;
75 0         0 my $index = CPAN::SQLite::Index->new(%wanted, %args, log_dir => $log_dir);
76 0 0       0 $index->index() or do {
77 0         0 warn qq{Indexing failed!};
78 0         0 return;
79             };
80 0         0 return 1;
81             }
82              
83             sub query {
84 947     947 1 3457 my ($self, %args) = @_;
85 947         9015 require CPAN::SQLite::Search;
86 947         2074 my %wanted = map { $_ => $self->{$_} } qw(max_results CPAN db_name db_dir meta_obj);
  4735         10741  
87 947         4866 my $query = CPAN::SQLite::Search->new(%wanted, %args);
88 947         2207 %wanted = map { $_ => $self->{$_} } qw(mode query id name);
  3788         9057  
89 947 50       3907 $query->query(%wanted, %args) or do {
90 0         0 warn qq{Query failed!};
91 0         0 return;
92             };
93 947         2146 my $results = $query->{results};
94 947 50       5230 return unless defined $results;
95 0           $self->{results} = $query->{results};
96 0           return 1;
97             }
98              
99             1;
100              
101             =head1 NAME
102              
103             CPAN::SQLite - maintain and search a minimal CPAN database
104              
105             =head1 VERSION
106              
107             version 0.218
108              
109             =head1 SYNOPSIS
110              
111             my $obj = CPAN::SQLite->new(CPAN => '/path/to/CPAN');
112             $obj->index(setup => 1);
113              
114             $obj->query(mode => 'dist', name => 'CPAN');
115             my $results = $obj->{results};
116              
117             =head1 DESCRIPTION
118              
119             This package is used for setting up, maintaining, and
120             searching a CPAN database consisting of the information
121             stored in the two main CPAN indices:
122             F<$CPAN/modules/02packages.details.txt.gz> and
123             F<$CPAN/authors/01mailrc.txt.gz>. It should be
124             considered at an alpha stage of development.
125              
126             One begins by creating the object as
127              
128             my $obj = CPAN::SQLite->new(%args);
129              
130             which accepts the following arguments:
131              
132             =over 3
133              
134             =item * C '/path/to/CPAN'>
135              
136             This specifies the path to where the index files are
137             to be stored. This could be a local CPAN mirror,
138             defined here by the presence of a F file beneath
139             this directory, or a local directory in which to store
140             these files from a remote CPAN mirror. In the latter case,
141             the index files are fetched from a remote CPAN mirror,
142             using the same list that C uses, if this is
143             configured, and are updated if they are more than one
144             day old.
145              
146             If the C option is not given, it will default
147             to C of L, if this is configured,
148             with the index files found under C.
149             A fatal error results if such a directory isn't found.
150             Updates to these index files are assumed here to be
151             handled by C.
152              
153             =item * C '/path/to/db/dir'>
154              
155             This specifies the path to where the database file is
156             found. If not given, it defaults to the
157             C directory of C, if present, or to
158             the directory in which the script was invoked. The name
159             of the database file is C.
160              
161             =back
162              
163             There are two main methods available.
164              
165             =head2 C<$obj-Eindex(%args);>
166              
167             This is used to set up and maintain the database. The
168             following arguments are accepted:
169              
170             =over 3
171              
172             =item * setup =E 1
173              
174             This specifies that the database is to be created and
175             populated from the CPAN indices; any existing database
176             will be overwritten. Not specifying this option will
177             assume that an existing database is to be updated.
178              
179             =item * reindex =E 'dist_name'
180              
181             This specifies that the CPAN distribution C
182             is to be reindexed.
183              
184             =back
185              
186             =head2 C<$obj-Equery(%args);>
187              
188             This is used for querying the database by distribution
189             name, module name, or CPAN author name. There are
190             two arguments needed to specify such queries.
191              
192             =over 3
193              
194             =item * C some_value>
195              
196             This specifies what type of query to perform,
197             with C being one of C, C,
198             or C, for searching through, respectively,
199             CPAN distribution names, module names, or author names and
200             CPAN ids.
201              
202             =item * C query_term>
203              
204             This specifies the query term for the search, with
205             C being one of C, to search for an
206             exact match, or C, for searching for partial
207             matches. Perl regular expressions are supported in
208             the C for the C option.
209              
210             =back
211              
212             As well, an option of C some_number> will
213             limit the number of results returned; if not specified,
214             the limit doesn't apply.
215              
216             =head1 CPAN.pm support
217              
218             As of CPAN.pm version 1.88_65, there is experimental support
219             within CPAN.pm for using CPAN::SQLite to obtain
220             information on packages, modules, and authors. One goal
221             of this is to reduce the memory footprint of the CPAN.pm
222             shell, as this information is no longer all preloaded into
223             memory. This can be enabled through
224              
225             perl -MCPAN -e shell
226             cpan> o conf use_sqlite 1
227              
228             Use
229              
230             cpan> o conf commit
231              
232             to save this setting for future sessions.
233              
234             Using CPAN::SQLite, what happens is that a request for information
235             through CPAN.pm, such as
236              
237             cpan> a ANDK
238              
239             will cause a query to the SQLite database to be made.
240             If successful, this will place the relevant data for this
241             request into the data structure CPAN.pm uses to store and
242             retrieve such information. Thus, at any given time, the
243             only information CPAN.pm stores in memory is that for
244             packages, modules, and authors for which previous queries
245             have been made. There are certain requests, such as
246              
247             cpan> r
248              
249             to make a list of recommended packages for which upgrades
250             on CPAN are available, which will result in loading
251             information on all available packages into memory; if such
252             a query is made, the subsequent memory footprint of CPAN.pm
253             with and without CPAN::SQLite will be essentially the same.
254              
255             The database itself, called F, will be stored
256             in the location specified by C<$CPAN::Config-E{cpan_home}>.
257             When first started, this database will be created, and afterwards,
258             it will be updated if the database is older than one day since
259             the last update. A log file of the creation or update process, called
260             F, will be created in the same
261             directory as the database file.
262              
263             =head1 SEE ALSO
264              
265             L, for setting up and maintaining the database, and
266             L for an interface to querying the database. Some
267             details of the interaction with L is available from
268             L. See also the L script for a command-line
269             interface to the indexing and querying of the database.
270              
271             =head1 SUPPORT
272              
273             You can find documentation for this module with the perldoc command.
274              
275             perldoc CPAN::SQLite
276              
277             You can also look for information at:
278              
279             =over 4
280              
281             =item * AnnoCPAN: Annotated CPAN documentation
282              
283             L
284              
285             =item * CPAN::Forum: Discussion forum
286              
287             L
288              
289             =item * CPAN Ratings
290              
291             L
292              
293             =item * RT: CPAN's request tracker
294              
295             L
296              
297             =item * Search CPAN
298              
299             L
300              
301             =back
302              
303             =head1 BUGS
304              
305             At this time, CPAN::SQLite keeps information contained only
306             in the latest version of a CPAN distribution. This means that
307             modules that are provided only in older versions of a CPAN
308             distribution will not be present in the database; for example,
309             at this time, the latest version of the I distribution
310             on CPAN is 5.805, but there are modules such as I
311             contained in version 5.10 of libwww-perl that are not present in 5.805.
312             This behaviour differs from that of L without CPAN::SQLite.
313             This may change in the future.
314              
315             Please report bugs and feature requests via
316             L.
317              
318             =head1 ENVIRONMENT VARIABLES
319              
320             Information messages from the indexing procedures are printed
321             out to STDOUT if the environment variable CPAN_SQLITE_DEBUG
322             is set. This is automatically set within L.
323             If CPAN_SQLITE_NO_LOG_FILES is set, no log files will be created
324             during the indexing procedures. Log files are deleted automatically
325             in 30 days. To override this, set CPAN_SQLITE_LOG_FILES_CLEANUP.
326             To stop automatic cleanup, set this variable to 0.
327              
328             If CPAN_SQLITE_DOWNLOAD variable are set, an already existing and
329             up-to-date cpandb.sql file will be downloaded from
330             http://cpansqlite.trouchelle.com/ where it's updated every hour. This
331             greatly increases performance and decreases CPU and memory consumption
332             during the indexing process.
333              
334             See L for more details, potential problems, and more
335             configuration options.
336              
337             =head1 AUTHORS
338              
339             Randy Kobes (passed away on September 18, 2010)
340              
341             Serguei Trouchelle Estro@cpan.orgE
342              
343             =head1 COPYRIGHT
344              
345             Copyright 2006,2008 by Randy Kobes Er.kobes@uwinnipeg.caE.
346              
347             Copyright 2011-2014 by Serguei Trouchelle Estro@cpan.orgE.
348              
349             Use and redistribution are under the same terms as Perl itself.
350              
351             =cut