File Coverage

blib/lib/DBD/ExampleP.pm
Criterion Covered Total %
statement 175 178 98.3
branch 79 88 89.7
condition 25 32 78.1
subroutine 27 29 93.1
pod 0 1 0.0
total 306 328 93.2


line stmt bran cond sub pod time code
1             {
2             package DBD::ExampleP;
3              
4 56     56   13831 use Symbol;
  56         21912  
  56         3839  
5              
6 56     56   272 use DBI qw(:sql_types);
  56         72  
  56         32342  
7              
8             require File::Spec;
9              
10             @EXPORT = qw(); # Do NOT @EXPORT anything.
11             $VERSION = "12.014311";
12              
13             # $Id: ExampleP.pm 14310 2010-08-02 06:35:25Z Jens $
14             #
15             # Copyright (c) 1994,1997,1998 Tim Bunce
16             #
17             # You may distribute under the terms of either the GNU General Public
18             # License or the Artistic License, as specified in the Perl README file.
19              
20             @statnames = qw(dev ino mode nlink
21             uid gid rdev size
22             atime mtime ctime
23             blksize blocks name);
24             @statnames{@statnames} = (0 .. @statnames-1);
25              
26             @stattypes = (SQL_INTEGER, SQL_INTEGER, SQL_INTEGER, SQL_INTEGER,
27             SQL_INTEGER, SQL_INTEGER, SQL_INTEGER, SQL_INTEGER,
28             SQL_INTEGER, SQL_INTEGER, SQL_INTEGER,
29             SQL_INTEGER, SQL_INTEGER, SQL_VARCHAR);
30             @stattypes{@statnames} = @stattypes;
31             @statprec = ((10) x (@statnames-1), 1024);
32             @statprec{@statnames} = @statprec;
33             die unless @statnames == @stattypes;
34             die unless @statprec == @stattypes;
35              
36             $drh = undef; # holds driver handle once initialised
37             #$gensym = "SYM000"; # used by st::execute() for filehandles
38              
39             sub driver{
40 56 50   56 0 166 return $drh if $drh;
41 56         103 my($class, $attr) = @_;
42 56         98 $class .= "::dr";
43 56         364 ($drh) = DBI::_new_drh($class, {
44             'Name' => 'ExampleP',
45             'Version' => $VERSION,
46             'Attribution' => 'DBD Example Perl stub by Tim Bunce',
47             }, ['example implementors private data '.__PACKAGE__]);
48 56         214 $drh;
49             }
50              
51             sub CLONE {
52 0     0   0 undef $drh;
53             }
54             }
55              
56              
57             { package DBD::ExampleP::dr; # ====== DRIVER ======
58             $imp_data_size = 0;
59 56     56   378 use strict;
  56         69  
  56         7652  
60              
61             sub connect { # normally overridden, but a handy default
62 861     861   7065 my($drh, $dbname, $user, $auth)= @_;
63 861         3729 my ($outer, $dbh) = DBI::_new_dbh($drh, {
64             Name => $dbname,
65             examplep_private_dbh_attrib => 42, # an example, for testing
66             });
67 861         3448 $dbh->{examplep_get_info} = {
68             29 => '"', # SQL_IDENTIFIER_QUOTE_CHAR
69             41 => '.', # SQL_CATALOG_NAME_SEPARATOR
70             114 => 1, # SQL_CATALOG_LOCATION
71             };
72             #$dbh->{Name} = $dbname;
73 861         3508 $dbh->STORE('Active', 1);
74 861         4582 return $outer;
75             }
76              
77             sub data_sources {
78 0     0   0 return ("dbi:ExampleP:dir=."); # possibly usefully meaningless
79             }
80              
81             }
82              
83              
84             { package DBD::ExampleP::db; # ====== DATABASE ======
85             $imp_data_size = 0;
86 56     56   303 use strict;
  56         88  
  56         27805  
87              
88             sub prepare {
89 4186     4186   75619 my($dbh, $statement)= @_;
90 4186         3742 my @fields;
91 4186         17337 my($fields, $dir) = $statement =~ m/^\s*select\s+(.*?)\s+from\s+(\S*)/i;
92              
93 4186 100 66     13913 if (defined $fields and defined $dir) {
94 2753 100       11255 @fields = ($fields eq '*')
95             ? keys %DBD::ExampleP::statnames
96             : split(/\s*,\s*/, $fields);
97             }
98             else {
99 1433 50       8717 return $dbh->set_err($DBI::stderr, "Syntax error in select statement (\"$statement\")")
100             unless $statement =~ m/^\s*set\s+/;
101             # the SET syntax is just a hack so the ExampleP driver can
102             # be used to test non-select statements.
103             # Now we have DBI::DBM etc., ExampleP should be deprecated
104             }
105              
106 4186         19590 my ($outer, $sth) = DBI::_new_sth($dbh, {
107             'Statement' => $statement,
108             examplep_private_sth_attrib => 24, # an example, for testing
109             }, ['example implementors private data '.__PACKAGE__]);
110              
111 3959 100       9253 my @bad = map {
112 4186         7509 defined $DBD::ExampleP::statnames{$_} ? () : $_
113             } @fields;
114 4186 100       7995 return $dbh->set_err($DBI::stderr, "Unknown field names: @bad")
115             if @bad;
116              
117 4150         13686 $outer->STORE('NUM_OF_FIELDS' => scalar(@fields));
118              
119 4150 100 100     21799 $sth->{examplep_ex_dir} = $dir if defined($dir) && $dir !~ /\?/;
120 4150 100       12337 $outer->STORE('NUM_OF_PARAMS' => ($dir) ? $dir =~ tr/?/?/ : 0);
121              
122 4150 100       12513 if (@fields) {
123 2717         5487 $outer->STORE('NAME' => \@fields);
124 2717         11951 $outer->STORE('NULLABLE' => [ (0) x @fields ]);
125 2717         11170 $outer->STORE('SCALE' => [ (0) x @fields ]);
126             }
127              
128 4150         23627 $outer;
129             }
130              
131              
132             sub table_info {
133 16     16   1910 my $dbh = shift;
134 16         35 my ($catalog, $schema, $table, $type) = @_;
135              
136 16   100     115 my @types = split(/["']*,["']/, $type || 'TABLE');
137 16         37 my %types = map { $_=>$_ } @types;
  16         66  
138              
139             # Return a list of all subdirectories
140 16         69 my $dh = Symbol::gensym(); # "DBD::ExampleP::".++$DBD::ExampleP::gensym;
141 16   66     334 my $dir = $catalog || File::Spec->curdir();
142 16         26 my @list;
143 16 100       50 if ($types{VIEW}) { # for use by test harness
144 4         13 push @list, [ undef, "schema", "table", 'VIEW', undef ];
145 4         12 push @list, [ undef, "sch-ema", "table", 'VIEW', undef ];
146 4         11 push @list, [ undef, "schema", "ta-ble", 'VIEW', undef ];
147 4         11 push @list, [ undef, "sch ema", "table", 'VIEW', undef ];
148 4         21 push @list, [ undef, "schema", "ta ble", 'VIEW', undef ];
149             }
150 16 100       42 if ($types{TABLE}) {
151 56     56   294 no strict 'refs';
  56         105  
  56         39487  
152 12 50       367 opendir($dh, $dir)
153             or return $dbh->set_err(int($!), "Failed to open directory $dir: $!");
154 12         423 while (defined(my $item = readdir($dh))) {
155 416 50       716 if ($^O eq 'VMS') {
156             # if on VMS then avoid warnings from catdir if you use a file
157             # (not a dir) as the item below
158 0 0       0 next if $item !~ /\.dir$/oi;
159             }
160 416         1279 my $file = File::Spec->catdir($dir,$item);
161 416 100       3369 next unless -d $file;
162 92         470 my($dev, $ino, $mode, $nlink, $uid) = lstat($file);
163 92         101 my $pwnam = undef; # eval { scalar(getpwnam($uid)) } || $uid;
164 92         372 push @list, [ $dir, $pwnam, $item, 'TABLE', undef ];
165             }
166 12         28 close($dh);
167             }
168             # We would like to simply do a DBI->connect() here. However,
169             # this is wrong if we are in a subclass like DBI::ProxyServer.
170 16 50 66     111 $dbh->{'dbd_sponge_dbh'} ||= DBI->connect("DBI:Sponge:", '','')
171             or return $dbh->set_err($DBI::err,
172             "Failed to connect to DBI::Sponge: $DBI::errstr");
173              
174 16         173 my $attr = {
175             'rows' => \@list,
176             'NUM_OF_FIELDS' => 5,
177             'NAME' => ['TABLE_CAT', 'TABLE_SCHEM', 'TABLE_NAME',
178             'TABLE_TYPE', 'REMARKS'],
179             'TYPE' => [DBI::SQL_VARCHAR(), DBI::SQL_VARCHAR(),
180             DBI::SQL_VARCHAR(), DBI::SQL_VARCHAR(), DBI::SQL_VARCHAR() ],
181             'NULLABLE' => [1, 1, 1, 1, 1]
182             };
183 16         33 my $sdbh = $dbh->{'dbd_sponge_dbh'};
184 16 50       98 my $sth = $sdbh->prepare("SHOW TABLES FROM $dir", $attr)
185             or return $dbh->set_err($sdbh->err(), $sdbh->errstr());
186 16         398 $sth;
187             }
188              
189              
190             sub type_info_all {
191 12     12   133 my ($dbh) = @_;
192 12         209 my $ti = [
193             { TYPE_NAME => 0,
194             DATA_TYPE => 1,
195             COLUMN_SIZE => 2,
196             LITERAL_PREFIX => 3,
197             LITERAL_SUFFIX => 4,
198             CREATE_PARAMS => 5,
199             NULLABLE => 6,
200             CASE_SENSITIVE => 7,
201             SEARCHABLE => 8,
202             UNSIGNED_ATTRIBUTE=> 9,
203             FIXED_PREC_SCALE=> 10,
204             AUTO_UNIQUE_VALUE => 11,
205             LOCAL_TYPE_NAME => 12,
206             MINIMUM_SCALE => 13,
207             MAXIMUM_SCALE => 14,
208             },
209             [ 'VARCHAR', DBI::SQL_VARCHAR, 1024, "'","'", undef, 0, 1, 1, 0, 0,0,undef,0,0 ],
210             [ 'INTEGER', DBI::SQL_INTEGER, 10, "","", undef, 0, 0, 1, 0, 0,0,undef,0,0 ],
211             ];
212 12         39 return $ti;
213             }
214              
215              
216             sub ping {
217 3027 100   3027   8352 (shift->FETCH('Active')) ? 2 : 0; # the value 2 is checked for by t/80proxy.t
218             }
219              
220              
221             sub disconnect {
222 835     835   46604 shift->STORE(Active => 0);
223 835         2916 return 1;
224             }
225              
226              
227             sub get_info {
228 72     72   849 my ($dbh, $info_type) = @_;
229 72         324 return $dbh->{examplep_get_info}->{$info_type};
230             }
231              
232              
233             sub FETCH {
234 18966     18966   49188 my ($dbh, $attrib) = @_;
235             # In reality this would interrogate the database engine to
236             # either return dynamic values that cannot be precomputed
237             # or fetch and cache attribute values too expensive to prefetch.
238             # else pass up to DBI to handle
239 18966 100       35506 return $INC{"DBD/ExampleP.pm"} if $attrib eq 'example_driver_path';
240 18169         98186 return $dbh->SUPER::FETCH($attrib);
241             }
242              
243              
244             sub STORE {
245 35035     35035   88617 my ($dbh, $attrib, $value) = @_;
246             # store only known attributes else pass up to DBI to handle
247 35035 100       50862 if ($attrib eq 'examplep_set_err') {
248             # a fake attribute to enable a test case where STORE issues a warning
249 4         20 $dbh->set_err($value, $value);
250 4         287 return;
251             }
252 35031 100       45469 if ($attrib eq 'AutoCommit') {
253             # convert AutoCommit values to magic ones to let DBI
254             # know that the driver has 'handled' the AutoCommit attribute
255 3784 100       6521 $value = ($value) ? -901 : -900;
256             }
257 35031 100       54538 return $dbh->{$attrib} = $value if $attrib =~ /^examplep_/;
258 35027         195960 return $dbh->SUPER::STORE($attrib, $value);
259             }
260              
261             sub DESTROY {
262 827     827   10387 my $dbh = shift;
263 827 100       2168 $dbh->disconnect if $dbh->FETCH('Active');
264             undef
265 827         21068 }
266              
267              
268             # This is an example to demonstrate the use of driver-specific
269             # methods via $dbh->func().
270             # Use it as follows:
271             # my @tables = $dbh->func($re, 'examplep_tables');
272             #
273             # Returns all the tables that match the regular expression $re.
274             sub examplep_tables {
275 4     4   61 my $dbh = shift; my $re = shift;
  4         8  
276 4         18 grep { $_ =~ /$re/ } $dbh->tables();
  32         140  
277             }
278              
279             sub parse_trace_flag {
280 166     166   5656 my ($h, $name) = @_;
281 166 100       342 return 0x01000000 if $name eq 'foo';
282 152 100       275 return 0x02000000 if $name eq 'bar';
283 138 100       237 return 0x04000000 if $name eq 'baz';
284 124 100       210 return 0x08000000 if $name eq 'boo';
285 110 100       191 return 0x10000000 if $name eq 'bop';
286 96         278 return $h->SUPER::parse_trace_flag($name);
287             }
288              
289             sub private_attribute_info {
290 775     775   6496 return { example_driver_path => undef };
291             }
292             }
293              
294              
295             { package DBD::ExampleP::st; # ====== STATEMENT ======
296             $imp_data_size = 0;
297 56     56   294 use strict; no strict 'refs'; # cause problems with filehandles
  56     56   105  
  56         1590  
  56         549  
  56         83  
  56         39122  
298              
299             sub bind_param {
300 892     892   4077 my($sth, $param, $value, $attribs) = @_;
301 892         2198 $sth->{'dbd_param'}->[$param-1] = $value;
302 892         2551 return 1;
303             }
304              
305              
306             sub execute {
307 2337     2337   32586 my($sth, @dir) = @_;
308 2337         1985 my $dir;
309              
310 2337 100       4008 if (@dir) {
311             $sth->bind_param($_, $dir[$_-1]) or return
312 396   50     1418 foreach (1..@dir);
313             }
314              
315 2337   100     7314 my $dbd_param = $sth->{'dbd_param'} || [];
316 2337 100       5285 return $sth->set_err(2, @$dbd_param." values bound when $sth->{NUM_OF_PARAMS} expected")
317             unless @$dbd_param == $sth->{NUM_OF_PARAMS};
318              
319 2325 100       22072 return 0 unless $sth->{NUM_OF_FIELDS}; # not a select
320              
321 892   66     1966 $dir = $dbd_param->[0] || $sth->{examplep_ex_dir};
322 892 50       1662 return $sth->set_err(2, "No bind parameter supplied")
323             unless defined $dir;
324              
325 892         2302 $sth->finish;
326              
327             #
328             # If the users asks for directory "long_list_4532", then we fake a
329             # directory with files "file4351", "file4350", ..., "file0".
330             # This is a special case used for testing, especially DBD::Proxy.
331             #
332 892 100       2272 if ($dir =~ /^long_list_(\d+)$/) {
333 12         45 $sth->{dbd_dir} = [ $1 ]; # array ref indicates special mode
334 12         26 $sth->{dbd_datahandle} = undef;
335             }
336             else {
337 880         1166 $sth->{dbd_dir} = $dir;
338 880         2050 my $sym = Symbol::gensym(); # "DBD::ExampleP::".++$DBD::ExampleP::gensym;
339 880 100       26748 opendir($sym, $dir)
340             or return $sth->set_err(2, "opendir($dir): $!");
341 868         1716 $sth->{dbd_datahandle} = $sym;
342             }
343 880         3028 $sth->STORE(Active => 1);
344 880         4084 return 1;
345             }
346              
347              
348             sub fetch {
349 23046     23046   74918 my $sth = shift;
350 23046         22939 my $dir = $sth->{dbd_dir};
351 23046         16749 my %s;
352              
353 23046 100       26396 if (ref $dir) { # special fake-data test mode
354 1212         1250 my $num = $dir->[0]--;
355 1212 100       1708 unless ($num > 0) {
356 12         49 $sth->finish();
357 12         100 return;
358             }
359 1200         949 my $time = time;
360 1200         7139 @s{@DBD::ExampleP::statnames} =
361             ( 2051, 1000+$num, 0644, 2, $>, $), 0, 1024,
362             $time, $time, $time, 512, 2, "file$num")
363             }
364             else { # normal mode
365 21834 100       36205 my $dh = $sth->{dbd_datahandle}
366             or return $sth->set_err($DBI::stderr, "fetch without successful execute");
367 21699         38468 my $f = readdir($dh);
368 21699 100       30018 unless ($f) {
369 517         1280 $sth->finish;
370 517         3203 return;
371             }
372             # untaint $f so that we can use this for DBI taint tests
373 21182         61522 ($f) = ($f =~ m/^(.*)$/);
374 21182         107589 my $file = File::Spec->catfile($dir, $f);
375             # put in all the data fields
376 21182         249399 @s{ @DBD::ExampleP::statnames } = (lstat($file), $f);
377             }
378              
379             # return just what fields the query asks for
380 22382         24150 my @new = @s{ @{$sth->{NAME}} };
  22382         49335  
381              
382 22382         196052 return $sth->_set_fbav(\@new);
383             }
384             *fetchrow_arrayref = \&fetch;
385              
386              
387             sub finish {
388 2338     2338   13288 my $sth = shift;
389 2338 100       10974 closedir($sth->{dbd_datahandle}) if $sth->{dbd_datahandle};
390 2338         3405 $sth->{dbd_datahandle} = undef;
391 2338         2774 $sth->{dbd_dir} = undef;
392 2338         4609 $sth->SUPER::finish();
393 2338         4333 return 1;
394             }
395              
396              
397             sub FETCH {
398 2527     2527   29961 my ($sth, $attrib) = @_;
399             # In reality this would interrogate the database engine to
400             # either return dynamic values that cannot be precomputed
401             # or fetch and cache attribute values too expensive to prefetch.
402 2527 100       6690 if ($attrib eq 'TYPE'){
    100          
    100          
403 577         675 return [ @DBD::ExampleP::stattypes{ @{ $sth->FETCH(q{NAME_lc}) } } ];
  577         2403  
404             }
405             elsif ($attrib eq 'PRECISION'){
406 577         630 return [ @DBD::ExampleP::statprec{ @{ $sth->FETCH(q{NAME_lc}) } } ];
  577         2293  
407             }
408             elsif ($attrib eq 'ParamValues') {
409 14   50     48 my $dbd_param = $sth->{dbd_param} || [];
410 14         46 my %pv = map { $_ => $dbd_param->[$_-1] } 1..@$dbd_param;
  96         234  
411 14         145 return \%pv;
412             }
413             # else pass up to DBI to handle
414 1359         12060 return $sth->SUPER::FETCH($attrib);
415             }
416              
417              
418             sub STORE {
419 17348     17348   67977 my ($sth, $attrib, $value) = @_;
420             # would normally validate and only store known attributes
421             # else pass up to DBI to handle
422 17348 100 100     97168 return $sth->{$attrib} = $value
      100        
      66        
423             if $attrib eq 'NAME' or $attrib eq 'NULLABLE' or $attrib eq 'SCALE' or $attrib eq 'PRECISION';
424 9197         32830 return $sth->SUPER::STORE($attrib, $value);
425             }
426              
427             *parse_trace_flag = \&DBD::ExampleP::db::parse_trace_flag;
428             }
429              
430             1;
431             # vim: sw=4:ts=8