File Coverage

blib/lib/CPANDB.pm
Criterion Covered Total %
statement 23 82 28.0
branch 0 10 0.0
condition 0 6 0.0
subroutine 8 17 47.0
pod 0 8 0.0
total 31 123 25.2


line stmt bran cond sub pod time code
1             package CPANDB; # git description: af7547f
2              
3 1     1   705 use 5.008005;
  1         4  
4 1     1   5 use strict;
  1         1  
  1         19  
5 1     1   4 use warnings;
  1         2  
  1         22  
6 1     1   440 use IO::File ();
  1         8792  
  1         30  
7 1     1   2016 use DateTime 0.55 ();
  1         628240  
  1         66  
8 1     1   11 use Params::Util 1.00 ();
  1         16  
  1         25  
9 1     1   850 use ORLite 1.51 ();
  1         34894  
  1         37  
10 1     1   470 use ORLite::Mirror 1.20 ();
  1         85455  
  1         833  
11              
12             our $VERSION = '0.19';
13             our @LOCATION = (
14             locale => 'C',
15             time_zone => 'UTC',
16             );
17              
18             sub import {
19 0     0     my $class = shift;
20 0   0       my $params = Params::Util::_HASH(shift) || {};
21              
22             # Pass through any params from above
23 0   0       $params->{url} ||= 'http://svn.ali.as/db/cpandb.bz2';
24 0   0       $params->{maxage} ||= 24 * 60 * 60; # One day
25              
26             # Always turn on string eval debugging if Perl is new enough
27 0 0         if ( $^V > 5.008008 ) {
28 0           $^P = $^P | 0x800;
29             }
30              
31             # Prevent double-initialisation
32 0 0         $class->can('orlite') or
33             ORLite::Mirror->import( $params );
34              
35 0           return 1;
36             }
37              
38             sub latest {
39 0     0 0   my $class = shift;
40              
41             # Find the distribution most recently uploaded
42 0           my @latest = CPANDB::Distribution->select(
43             'ORDER BY uploaded DESC LIMIT 1',
44             );
45 0 0         unless ( @latest == 1 ) {
46 0           die "Unexpected number of uploads";
47             }
48              
49             # When was it?
50 0           return $latest[0]->uploaded;
51             }
52              
53             sub latest_datetime {
54 0     0 0   my $class = shift;
55 0           my @latest = split /\D+/, $class->latest;
56 0           return DateTime->new(
57             year => $latest[0],
58             month => $latest[1],
59             day => $latest[2],
60             @LOCATION,
61             );
62             }
63              
64             sub age {
65 0     0 0   my $class = shift;
66 0           my $latest = $class->latest_datetime;
67 0           my $today = DateTime->today( @LOCATION );
68 0           my $duration = $today - $latest;
69 0           return $duration->in_units('days');
70             }
71              
72             sub distribution {
73 0     0 0   my $self = shift;
74 0           my @dist = CPANDB::Distribution->select(
75             'where distribution = ?', $_[0],
76             );
77 0 0         unless ( @dist ) {
78 0           die("Distribution '$_[0]' does not exist");
79             }
80 0           return $dist[0];
81             }
82              
83             sub graph {
84 0     0 0   require Graph;
85 0           require Graph::Directed;
86 0           my $class = shift;
87 0           my $graph = Graph::Directed->new;
88 0           foreach my $vertex ( CPANDB::Distribution->select ) {
89 0           $graph->add_vertex( $vertex->distribution );
90             }
91 0           foreach my $edge ( CPANDB::Dependency->select ) {
92 0           $graph->add_edge( $edge->distribution => $edge->dependency );
93             }
94 0           return $graph;
95             }
96              
97             sub easy {
98 0     0 0   require Graph::Easy;
99 0           my $class = shift;
100 0           my $graph = Graph::Easy->new;
101 0           foreach my $vertex ( CPANDB::Distribution->select ) {
102 0           $graph->add_vertex( $vertex->distribution );
103             }
104 0           foreach my $edge ( CPANDB::Dependency->select ) {
105 0           $graph->add_edge( $edge->distribution => $edge->dependency );
106             }
107 0           return $graph;
108             }
109              
110             sub xgmml {
111 0     0 0   require Graph::XGMML;
112 0           my $class = shift;
113 0 0         my @param = ( @_ == 1 ) ? ( OUTPUT => IO::File->new( shift, 'w' ) ) : ( @_ );
114 0           my $graph = Graph::XGMML->new( directed => 1, @param );
115 0           foreach my $vertex ( CPANDB::Distribution->select ) {
116 0           $graph->add_vertex( $vertex->distribution );
117             }
118 0           foreach my $edge ( CPANDB::Dependency->select ) {
119 0           $graph->add_edge( $edge->distribution => $edge->dependency );
120             }
121 0           $graph->end;
122 0           return 1;
123             }
124              
125             sub csv {
126 0     0 0   my $class = shift;
127 0           my $file = shift;
128 0           my $csv = IO::File->new($file, 'w');
129 0           foreach my $edge ( CPANDB::Dependency->select ) {
130 0           $csv->print( $edge->distribution . "\t" . $edge->dependency . "\n" );
131             }
132 0           $csv->close;
133             }
134              
135             1;
136             __END__
137              
138             =pod
139              
140             =head1 NAME
141              
142             CPANDB - A unified database of CPAN metadata information
143              
144             =head1 DESCRIPTION
145              
146             B<CPANDB> is an module for accessing CPAN metadata merged from many different
147             CPAN websites into a single object model, downloaded automatically and without
148             the need for any configuration.
149              
150             =head1 METHODS
151              
152             =head2 dsn
153              
154             my $string = CPANDB->dsn;
155              
156             The C<dsn> accessor returns the L<DBI> connection string used to connect
157             to the SQLite database as a string.
158              
159             =head2 dbh
160              
161             my $handle = CPANDB->dbh;
162              
163             To reliably prevent potential L<SQLite> deadlocks resulting from multiple
164             connections in a single process, each ORLite package will only ever
165             maintain a single connection to the database.
166              
167             During a transaction, this will be the same (cached) database handle.
168              
169             Although in most situations you should not need a direct DBI connection
170             handle, the C<dbh> method provides a method for getting a direct
171             connection in a way that is compatible with connection management in
172             L<ORLite>.
173              
174             Please note that these connections should be short-lived, you should
175             never hold onto a connection beyond your immediate scope.
176              
177             The transaction system in ORLite is specifically designed so that code
178             using the database should never have to know whether or not it is in a
179             transation.
180              
181             Because of this, you should B<never> call the -E<gt>disconnect method
182             on the database handles yourself, as the handle may be that of a
183             currently running transaction.
184              
185             Further, you should do your own transaction management on a handle
186             provided by the <dbh> method.
187              
188             In cases where there are extreme needs, and you B<absolutely> have to
189             violate these connection handling rules, you should create your own
190             completely manual DBI-E<gt>connect call to the database, using the connect
191             string provided by the C<dsn> method.
192              
193             The C<dbh> method returns a L<DBI::db> object, or throws an exception on
194             error.
195              
196             =head2 begin
197              
198             CPANDB->begin;
199              
200             The C<begin> method indicates the start of a transaction.
201              
202             In the same way that ORLite allows only a single connection, likewise
203             it allows only a single application-wide transaction.
204              
205             No indication is given as to whether you are currently in a transaction
206             or not, all code should be written neutrally so that it works either way
207             or doesn't need to care.
208              
209             Returns true or throws an exception on error.
210              
211             =head2 rollback
212              
213             The C<rollback> method rolls back the current transaction. If called outside
214             of a current transaction, it is accepted and treated as a null operation.
215              
216             Once the rollback has been completed, the database connection falls back
217             into auto-commit state. If you wish to immediately start another
218             transaction, you will need to issue a separate -E<gt>begin call.
219              
220             If a transaction exists at END-time as the process exits, it will be
221             automatically rolled back.
222              
223             Returns true or throws an exception on error.
224              
225             =head2 do
226              
227             CPANDB->do(
228             'insert into table ( foo, bar ) values ( ?, ? )', {},
229             \$foo_value,
230             \$bar_value,
231             );
232              
233             The C<do> method is a direct wrapper around the equivalent L<DBI> method,
234             but applied to the appropriate locally-provided connection or transaction.
235              
236             It takes the same parameters and has the same return values and error
237             behaviour.
238              
239             =head2 selectall_arrayref
240              
241             The C<selectall_arrayref> method is a direct wrapper around the equivalent
242             L<DBI> method, but applied to the appropriate locally-provided connection
243             or transaction.
244              
245             It takes the same parameters and has the same return values and error
246             behaviour.
247              
248             =head2 selectall_hashref
249              
250             The C<selectall_hashref> method is a direct wrapper around the equivalent
251             L<DBI> method, but applied to the appropriate locally-provided connection
252             or transaction.
253              
254             It takes the same parameters and has the same return values and error
255             behaviour.
256              
257             =head2 selectcol_arrayref
258              
259             The C<selectcol_arrayref> method is a direct wrapper around the equivalent
260             L<DBI> method, but applied to the appropriate locally-provided connection
261             or transaction.
262              
263             It takes the same parameters and has the same return values and error
264             behaviour.
265              
266             =head2 selectrow_array
267              
268             The C<selectrow_array> method is a direct wrapper around the equivalent
269             L<DBI> method, but applied to the appropriate locally-provided connection
270             or transaction.
271              
272             It takes the same parameters and has the same return values and error
273             behaviour.
274              
275             =head2 selectrow_arrayref
276              
277             The C<selectrow_arrayref> method is a direct wrapper around the equivalent
278             L<DBI> method, but applied to the appropriate locally-provided connection
279             or transaction.
280              
281             It takes the same parameters and has the same return values and error
282             behaviour.
283              
284             =head2 selectrow_hashref
285              
286             The C<selectrow_hashref> method is a direct wrapper around the equivalent
287             L<DBI> method, but applied to the appropriate locally-provided connection
288             or transaction.
289              
290             It takes the same parameters and has the same return values and error
291             behaviour.
292              
293             =head2 prepare
294              
295             The C<prepare> method is a direct wrapper around the equivalent
296             L<DBI> method, but applied to the appropriate locally-provided connection
297             or transaction
298              
299             It takes the same parameters and has the same return values and error
300             behaviour.
301              
302             In general though, you should try to avoid the use of your own prepared
303             statements if possible, although this is only a recommendation and by
304             no means prohibited.
305              
306             =head2 pragma
307              
308             # Get the user_version for the schema
309             my $version = CPANDB->pragma('user_version');
310              
311             The C<pragma> method provides a convenient method for fetching a pragma
312             for a database. See the L<SQLite> documentation for more details.
313              
314             =head1 SUPPORT
315              
316             B<CPANDB> is based on L<ORLite>.
317              
318             Documentation created by L<ORLite::Pod> 0.10.
319              
320             Bugs should be reported via the CPAN bug tracker at
321              
322             L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=CPANDB>
323              
324             For other issues, contact the author.
325              
326             =head1 AUTHOR
327              
328             Adam Kennedy E<lt>adamk@cpan.orgE<gt>
329              
330             =head1 COPYRIGHT
331              
332             Copyright 2009 - 2012 Adam Kennedy.
333              
334             This program is free software; you can redistribute
335             it and/or modify it under the same terms as Perl itself.
336              
337             The full text of the license can be found in the
338             LICENSE file included with this module.
339              
340             =cut