File Coverage

blib/lib/App/perlrdf/Command.pm
Criterion Covered Total %
statement 29 81 35.8
branch 0 42 0.0
condition 0 12 0.0
subroutine 10 13 76.9
pod 0 3 0.0
total 39 151 25.8


line stmt bran cond sub pod time code
1             package App::perlrdf::Command;
2              
3 2     2   2141 use 5.010;
  2         6  
  2         77  
4 2     2   11 use strict;
  2         4  
  2         99  
5 2     2   10 use warnings;
  2         4  
  2         49  
6 2     2   15 use utf8;
  2         17  
  2         15  
7              
8             BEGIN {
9 2     2   122 $App::perlrdf::Command::AUTHORITY = 'cpan:TOBYINK';
10 2         55 $App::perlrdf::Command::VERSION = '0.006';
11             }
12              
13 2     2   10 use App::Cmd::Setup -command;
  2         4  
  2         14  
14              
15 2         217 use constant store_opt_spec => (
16             [ 'database|t=s' => '"sqlite", "mysql" or "pg"' ],
17             [ 'dbname|d=s' => 'Database name (file name for SQLite)' ],
18             [ 'host|h=s' => 'Database server host name or IP address' ],
19             [ 'port=i' => 'Database server port' ],
20             [ 'username|u=s' => 'User name for database login' ],
21             [ 'password=s' => 'Password for database login' ],
22             []=>=>=>=>=>=>=>=>=>=>=>=>=>=>=>=>=>=>=>=>=>=>=>=>=>=>=>=>,
23             [ 'dbi|D=s' => 'DBI DSN' ],
24             [ 'sqlite|Q=s' => 'SQLite file name' ],
25             []=>=>=>=>=>=>=>=>=>=>=>=>=>=>=>=>=>=>=>=>=>=>=>=>=>=>=>=>,
26             [ 'store|T=s' => 'Trine store configuration string' ],
27             [ 'model|M=s' => 'Database model name (defaults to "")' ],
28 2     2   548 );
  2         4  
29              
30 2         1790 use constant store_help => q(
31             The database to connect to can be specified using the 'database', 'dbname',
32             'host', 'port', 'username' and 'password' options. Alternatively you can
33             specify an exact DBI DSN (in which case the 'database', 'dbname', 'host' and
34             'port' options must not be specified). The 'sqlite' option is a shortcut for
35             setting the 'database' option to 'sqlite', and setting the 'dbname' option.
36              
37             Alternatively, you may specify an RDF::Trine::Store configuration string.
38             If you want to connect to a non-DBI store, this is the only way to specify
39             it.
40              
41             Several DBI-based stores can share the same SQL database. This is achieved
42             by giving them each a different model name (which confusingly has nothing to
43             do with the RDF::Trine::Model class!).
44 2     2   12 );
  2         4  
45              
46             sub get_filespecs
47             {
48 0     0 0   my ($self, $class, $name, $opt) = @_;
49            
50 0           my @specs = map {
51             $class->new_from_filespec(
52             $_,
53             $opt->{$name.'_format'},
54             $opt->{$name.'_base'},
55             )
56 0           } do {
57 0 0         if (ref $opt->{$name.'_spec'} eq 'ARRAY')
    0          
58 0           { @{$opt->{$name.'_spec'}} }
  0            
59             elsif (defined $opt->{$name.'_spec'})
60 0           { ($opt->{$name.'_spec'}) }
61             else
62 0           { qw() }
63             };
64            
65 0           push @specs, map {
66             $class->new_from_filespec(
67             "{}$_",
68             $opt->{$name.'_format'},
69             $opt->{$name.'_base'},
70             )
71 0           } do {
72 0 0         if (ref $opt->{$name} eq 'ARRAY')
    0          
73 0           { @{$opt->{$name}} }
  0            
74             elsif (defined $opt->{$name})
75 0           { ($opt->{$name}) }
76             else
77 0           { qw() }
78             };
79              
80 0           return @specs;
81             }
82              
83             sub get_store
84             {
85 0     0 0   require RDF::Trine;
86            
87 0           my ($self, $opt) = @_;
88            
89 0           my %exclusions = (
90             store => [qw[ dbi sqlite username password host port dbname database ]],
91             sqlite => [qw[ dbi username password host port dbname database ]],
92             dbi => [qw[ host port dbname database ]],
93             );
94            
95 0           foreach my $k (keys %exclusions)
96             {
97 0 0         next unless exists $opt->{$k};
98 0           foreach my $e (@{ $exclusions{$k} })
  0            
99             {
100 0 0         next unless exists $opt->{$e};
101 0           $self->usage_error("Must not provide both '$k' and '$e' options.");
102             }
103             }
104            
105 0 0 0       if (exists $opt->{dbname} or exists $opt->{database})
106             {
107 0 0 0       $self->usage_error("'dbname' and 'database' options must be used in conjunction.")
108             unless exists $opt->{dbname} && exists $opt->{database};
109             }
110            
111 0 0         return RDF::Trine::store($opt->{store}) if exists $opt->{store};
112            
113             my $dsn = exists $opt->{dbi}
114             ? $opt->{dbi}
115 0 0         : do {
116 0           my ($database, $dbname, $host, $port) =
117 0           map { $opt->{$_} }
118             qw(database dbname host port);
119 0 0         if ($opt->{sqlite})
120             {
121 0           $database = 'sqlite';
122 0           $dbname = $opt->{sqlite};
123             }
124            
125 0           my $d;
126 0 0         if (lc $database eq 'sqlite')
    0          
    0          
127             {
128 0           $d = "DBI:SQLite:dbname=${dbname}";
129 0 0 0       $self->usage_error("SQLite does not support 'host' and 'port'.")
130             if $opt->{host} || $opt->{port};
131             }
132             elsif (lc $database eq 'mysql')
133             {
134 0           $d = "DBI:mysql:database=${dbname}";
135 0 0         $d .= ";host=$host" if $host;
136 0 0         $d .= ";port=$port" if $port;
137             }
138             elsif ($database =~ m{^(pg|psql|pgsql|postgres|postgresql)$}i)
139             {
140 0           $d = "DBI:Pg:dbname=${dbname}";
141 0 0         $d .= ";host=$host" if $host;
142 0 0         $d .= ";port=$port" if $port;
143             }
144 0           $d;
145             };
146            
147 0 0         if (length $dsn)
148             {
149 2     2   13 no warnings;
  2         4  
  2         388  
150 0           return RDF::Trine::Store::DBI->new(
151             "$opt->{model}",
152             $dsn,
153             $opt->{username},
154             $opt->{password},
155             );
156             }
157            
158 0 0         return RDF::Trine::store($ENV{PERLRDF_STORE})
159             if defined $ENV{PERLRDF_STORE};
160            
161 0           $self->usage_error("No SQLite, MySQL or Pg database specified.");
162             }
163              
164             sub AUTHORITY
165             {
166 0   0 0 0   my $class = ref($_[0]) || $_[0];
167 2     2   10 no strict qw(refs);
  2         4  
  2         127  
168 0           ${"$class\::AUTHORITY"};
  0            
169             }
170              
171             1;