File Coverage

blib/lib/DBI/PurePerl.pm
Criterion Covered Total %
statement 628 655 95.8
branch 250 292 85.6
condition 91 119 76.4
subroutine 125 134 93.2
pod 5 10 50.0
total 1099 1210 90.8


line stmt bran cond sub pod time code
1             ########################################################################
2             package # hide from PAUSE
3             DBI;
4             # vim: ts=8:sw=4
5             ########################################################################
6             #
7             # Copyright (c) 2002,2003 Tim Bunce Ireland.
8             #
9             # See COPYRIGHT section in DBI.pm for usage and distribution rights.
10             #
11             ########################################################################
12             #
13             # Please send patches and bug reports to
14             #
15             # Jeff Zucker with cc to
16             #
17             ########################################################################
18              
19 96     96   520 use strict;
  96         150  
  96         2489  
20 96     96   403 use Carp;
  96         159  
  96         22094  
21             require Symbol;
22              
23             require utf8;
24             *utf8::is_utf8 = sub { # hack for perl 5.6
25             require bytes;
26             return unless defined $_[0];
27             return !(length($_[0]) == bytes::length($_[0]))
28             } unless defined &utf8::is_utf8;
29              
30             $DBI::PurePerl = $ENV{DBI_PUREPERL} || 1;
31             $DBI::PurePerl::VERSION = "2.014286";
32              
33             $DBI::neat_maxlen ||= 400;
34              
35             $DBI::tfh = Symbol::gensym();
36             open $DBI::tfh, ">&STDERR" or warn "Can't dup STDERR: $!";
37             select( (select($DBI::tfh), $| = 1)[0] ); # autoflush
38              
39             # check for weaken support, used by ChildHandles
40             my $HAS_WEAKEN = eval {
41             require Scalar::Util;
42             # this will croak() if this Scalar::Util doesn't have a working weaken().
43             Scalar::Util::weaken( my $test = [] );
44             1;
45             };
46              
47             %DBI::last_method_except = map { $_=>1 } qw(DESTROY _set_fbav set_err);
48              
49 96     96   660 use constant SQL_ALL_TYPES => 0;
  96         164  
  96         6825  
50 96     96   502 use constant SQL_ARRAY => 50;
  96         178  
  96         3887  
51 96     96   520 use constant SQL_ARRAY_LOCATOR => 51;
  96         165  
  96         3939  
52 96     96   444 use constant SQL_BIGINT => (-5);
  96         174  
  96         3733  
53 96     96   450 use constant SQL_BINARY => (-2);
  96         158  
  96         3751  
54 96     96   487 use constant SQL_BIT => (-7);
  96         156  
  96         3518  
55 96     96   446 use constant SQL_BLOB => 30;
  96         152  
  96         3510  
56 96     96   471 use constant SQL_BLOB_LOCATOR => 31;
  96         172  
  96         3649  
57 96     96   442 use constant SQL_BOOLEAN => 16;
  96         157  
  96         3599  
58 96     96   431 use constant SQL_CHAR => 1;
  96         157  
  96         3419  
59 96     96   561 use constant SQL_CLOB => 40;
  96         1406  
  96         3998  
60 96     96   452 use constant SQL_CLOB_LOCATOR => 41;
  96         148  
  96         3456  
61 96     96   455 use constant SQL_DATE => 9;
  96         155  
  96         3399  
62 96     96   455 use constant SQL_DATETIME => 9;
  96         157  
  96         3741  
63 96     96   448 use constant SQL_DECIMAL => 3;
  96         156  
  96         3366  
64 96     96   478 use constant SQL_DOUBLE => 8;
  96         157  
  96         3403  
65 96     96   457 use constant SQL_FLOAT => 6;
  96         151  
  96         3907  
66 96     96   440 use constant SQL_GUID => (-11);
  96         150  
  96         3373  
67 96     96   462 use constant SQL_INTEGER => 4;
  96         151  
  96         3340  
68 96     96   482 use constant SQL_INTERVAL => 10;
  96         156  
  96         3358  
69 96     96   447 use constant SQL_INTERVAL_DAY => 103;
  96         155  
  96         3490  
70 96     96   466 use constant SQL_INTERVAL_DAY_TO_HOUR => 108;
  96         146  
  96         3400  
71 96     96   446 use constant SQL_INTERVAL_DAY_TO_MINUTE => 109;
  96         171  
  96         3480  
72 96     96   473 use constant SQL_INTERVAL_DAY_TO_SECOND => 110;
  96         150  
  96         3328  
73 96     96   448 use constant SQL_INTERVAL_HOUR => 104;
  96         158  
  96         3462  
74 96     96   440 use constant SQL_INTERVAL_HOUR_TO_MINUTE => 111;
  96         140  
  96         3389  
75 96     96   427 use constant SQL_INTERVAL_HOUR_TO_SECOND => 112;
  96         230  
  96         3320  
76 96     96   419 use constant SQL_INTERVAL_MINUTE => 105;
  96         154  
  96         3307  
77 96     96   434 use constant SQL_INTERVAL_MINUTE_TO_SECOND => 113;
  96         169  
  96         3284  
78 96     96   500 use constant SQL_INTERVAL_MONTH => 102;
  96         158  
  96         3312  
79 96     96   441 use constant SQL_INTERVAL_SECOND => 106;
  96         140  
  96         3473  
80 96     96   435 use constant SQL_INTERVAL_YEAR => 101;
  96         163  
  96         3300  
81 96     96   424 use constant SQL_INTERVAL_YEAR_TO_MONTH => 107;
  96         181  
  96         3701  
82 96     96   428 use constant SQL_LONGVARBINARY => (-4);
  96         167  
  96         3506  
83 96     96   419 use constant SQL_LONGVARCHAR => (-1);
  96         150  
  96         3344  
84 96     96   432 use constant SQL_MULTISET => 55;
  96         149  
  96         3239  
85 96     96   419 use constant SQL_MULTISET_LOCATOR => 56;
  96         193  
  96         3219  
86 96     96   435 use constant SQL_NUMERIC => 2;
  96         148  
  96         3234  
87 96     96   422 use constant SQL_REAL => 7;
  96         146  
  96         3184  
88 96     96   419 use constant SQL_REF => 20;
  96         168  
  96         3232  
89 96     96   440 use constant SQL_ROW => 19;
  96         150  
  96         3303  
90 96     96   443 use constant SQL_SMALLINT => 5;
  96         149  
  96         3329  
91 96     96   435 use constant SQL_TIME => 10;
  96         162  
  96         3363  
92 96     96   596 use constant SQL_TIMESTAMP => 11;
  96         159  
  96         3712  
93 96     96   450 use constant SQL_TINYINT => (-6);
  96         177  
  96         3398  
94 96     96   433 use constant SQL_TYPE_DATE => 91;
  96         155  
  96         3687  
95 96     96   450 use constant SQL_TYPE_TIME => 92;
  96         161  
  96         3249  
96 96     96   410 use constant SQL_TYPE_TIMESTAMP => 93;
  96         160  
  96         3368  
97 96     96   438 use constant SQL_TYPE_TIMESTAMP_WITH_TIMEZONE => 95;
  96         162  
  96         3875  
98 96     96   453 use constant SQL_TYPE_TIME_WITH_TIMEZONE => 94;
  96         158  
  96         3481  
99 96     96   465 use constant SQL_UDT => 17;
  96         156  
  96         3277  
100 96     96   434 use constant SQL_UDT_LOCATOR => 18;
  96         170  
  96         3172  
101 96     96   416 use constant SQL_UNKNOWN_TYPE => 0;
  96         162  
  96         3362  
102 96     96   2296 use constant SQL_VARBINARY => (-3);
  96         208  
  96         3591  
103 96     96   472 use constant SQL_VARCHAR => 12;
  96         150  
  96         3413  
104 96     96   423 use constant SQL_WCHAR => (-8);
  96         152  
  96         3424  
105 96     96   417 use constant SQL_WLONGVARCHAR => (-10);
  96         150  
  96         3516  
106 96     96   444 use constant SQL_WVARCHAR => (-9);
  96         150  
  96         3409  
107              
108             # for Cursor types
109 96     96   438 use constant SQL_CURSOR_FORWARD_ONLY => 0;
  96         155  
  96         3313  
110 96     96   435 use constant SQL_CURSOR_KEYSET_DRIVEN => 1;
  96         160  
  96         3402  
111 96     96   476 use constant SQL_CURSOR_DYNAMIC => 2;
  96         154  
  96         3329  
112 96     96   439 use constant SQL_CURSOR_STATIC => 3;
  96         162  
  96         3717  
113 96     96   447 use constant SQL_CURSOR_TYPE_DEFAULT => SQL_CURSOR_FORWARD_ONLY;
  96         149  
  96         3540  
114              
115 96     96   439 use constant IMA_HAS_USAGE => 0x0001; #/* check parameter usage */
  96         166  
  96         3378  
116 96     96   453 use constant IMA_FUNC_REDIRECT => 0x0002; #/* is $h->func(..., "method")*/
  96         146  
  96         3265  
117 96     96   482 use constant IMA_KEEP_ERR => 0x0004; #/* don't reset err & errstr */
  96         152  
  96         3513  
118 96     96   446 use constant IMA_KEEP_ERR_SUB => 0x0008; #/* '' if in nested call */
  96         154  
  96         3420  
119 96     96   445 use constant IMA_NO_TAINT_IN => 0x0010; #/* don't check for tainted args*/
  96         161  
  96         3497  
120 96     96   445 use constant IMA_NO_TAINT_OUT => 0x0020; #/* don't taint results */
  96         151  
  96         3290  
121 96     96   471 use constant IMA_COPY_UP_STMT => 0x0040; #/* copy sth Statement to dbh */
  96         158  
  96         3294  
122 96     96   449 use constant IMA_END_WORK => 0x0080; #/* set on commit & rollback */
  96         158  
  96         3581  
123 96     96   448 use constant IMA_STUB => 0x0100; #/* do nothing eg $dbh->connected */
  96         156  
  96         3302  
124 96     96   512 use constant IMA_CLEAR_STMT => 0x0200; #/* clear Statement before call */
  96         159  
  96         3452  
125 96     96   452 use constant IMA_UNRELATED_TO_STMT=> 0x0400; #/* profile as empty Statement */
  96         150  
  96         3401  
126 96     96   443 use constant IMA_NOT_FOUND_OKAY => 0x0800; #/* not error if not found */
  96         162  
  96         3954  
127 96     96   555 use constant IMA_EXECUTE => 0x1000; #/* do/execute: DBIcf_Executed */
  96         156  
  96         3366  
128 96     96   494 use constant IMA_SHOW_ERR_STMT => 0x2000; #/* dbh meth relates to Statement*/
  96         157  
  96         3283  
129 96     96   427 use constant IMA_HIDE_ERR_PARAMVALUES => 0x4000; #/* ParamValues are not relevant */
  96         214  
  96         3288  
130 96     96   449 use constant IMA_IS_FACTORY => 0x8000; #/* new h ie connect & prepare */
  96         159  
  96         3296  
131 96     96   452 use constant IMA_CLEAR_CACHED_KIDS => 0x10000; #/* clear CachedKids before call */
  96         146  
  96         3314  
132              
133 96     96   439 use constant DBIstcf_STRICT => 0x0001;
  96         149  
  96         3206  
134 96     96   411 use constant DBIstcf_DISCARD_STRING => 0x0002;
  96         158  
  96         60281  
135              
136             my %is_flag_attribute = map {$_ =>1 } qw(
137             Active
138             AutoCommit
139             ChopBlanks
140             CompatMode
141             Executed
142             Taint
143             TaintIn
144             TaintOut
145             InactiveDestroy
146             AutoInactiveDestroy
147             LongTruncOk
148             MultiThread
149             PrintError
150             PrintWarn
151             RaiseError
152             ShowErrorStatement
153             Warn
154             );
155             my %is_valid_attribute = map {$_ =>1 } (keys %is_flag_attribute, qw(
156             ActiveKids
157             Attribution
158             BegunWork
159             CachedKids
160             Callbacks
161             ChildHandles
162             CursorName
163             Database
164             DebugDispatch
165             Driver
166             Err
167             Errstr
168             ErrCount
169             FetchHashKeyName
170             HandleError
171             HandleSetErr
172             ImplementorClass
173             Kids
174             LongReadLen
175             NAME NAME_uc NAME_lc NAME_uc_hash NAME_lc_hash
176             NULLABLE
177             NUM_OF_FIELDS
178             NUM_OF_PARAMS
179             Name
180             PRECISION
181             ParamValues
182             Profile
183             Provider
184             ReadOnly
185             RootClass
186             RowCacheSize
187             RowsInCache
188             SCALE
189             State
190             Statement
191             TYPE
192             Type
193             TraceLevel
194             Username
195             Version
196             ));
197              
198             sub valid_attribute {
199 0     0 0 0 my $attr = shift;
200 0 0       0 return 1 if $is_valid_attribute{$attr};
201 0 0       0 return 1 if $attr =~ m/^[a-z]/; # starts with lowercase letter
202 0         0 return 0
203             }
204              
205             my $initial_setup;
206             sub initial_setup {
207 96     96 0 186 $initial_setup = 1;
208 96 50       362 print $DBI::tfh __FILE__ . " version " . $DBI::PurePerl::VERSION . "\n"
209             if $DBI::dbi_debug & 0xF;
210 96         1041 untie $DBI::err;
211 96         291 untie $DBI::errstr;
212 96         239 untie $DBI::state;
213 96         209 untie $DBI::rows;
214             #tie $DBI::lasth, 'DBI::var', '!lasth'; # special case: return boolean
215             }
216              
217             sub _install_method {
218 8928     8928   18515 my ( $caller, $method, $from, $param_hash ) = @_;
219 8928 100       15910 initial_setup() unless $initial_setup;
220              
221 8928         56999 my ($class, $method_name) = $method =~ /^[^:]+::(.+)::(.+)$/;
222 8928   100     28888 my $bitmask = $param_hash->{'O'} || 0;
223 8928         11520 my @pre_call_frag;
224              
225 8928 100       15915 return if $method_name eq 'can';
226              
227 8832 100       14130 push @pre_call_frag, q{
228             delete $h->{CachedKids};
229             # ignore DESTROY for outer handle (DESTROY for inner likely to follow soon)
230             return if $h_inner;
231             # handle AutoInactiveDestroy and InactiveDestroy
232             $h->{InactiveDestroy} = 1
233             if $h->{AutoInactiveDestroy} and $$ != $h->{dbi_pp_pid};
234             $h->{Active} = 0
235             if $h->{InactiveDestroy};
236             # copy err/errstr/state up to driver so $DBI::err etc still work
237             if ($h->{err} and my $drh = $h->{Driver}) {
238             $drh->{$_} = $h->{$_} for ('err','errstr','state');
239             }
240             } if $method_name eq 'DESTROY';
241              
242             push @pre_call_frag, q{
243             return $h->{$_[0]} if exists $h->{$_[0]};
244 8832 100 100     17074 } if $method_name eq 'FETCH' && !exists $ENV{DBI_TRACE}; # XXX ?
245              
246 8832 50       14712 push @pre_call_frag, "return;"
247             if IMA_STUB & $bitmask;
248              
249 8832 100       13906 push @pre_call_frag, q{
250             $method_name = pop @_;
251             } if IMA_FUNC_REDIRECT & $bitmask;
252              
253 8832 100       13527 push @pre_call_frag, q{
254             my $parent_dbh = $h->{Database};
255             } if (IMA_COPY_UP_STMT|IMA_EXECUTE) & $bitmask;
256              
257 8832 100       13512 push @pre_call_frag, q{
258             warn "No Database set for $h on $method_name!" unless $parent_dbh; # eg proxy problems
259             $parent_dbh->{Statement} = $h->{Statement} if $parent_dbh;
260             } if IMA_COPY_UP_STMT & $bitmask;
261              
262 8832 100       13418 push @pre_call_frag, q{
263             $h->{Executed} = 1;
264             $parent_dbh->{Executed} = 1 if $parent_dbh;
265             } if IMA_EXECUTE & $bitmask;
266              
267 8832 100       13231 push @pre_call_frag, q{
268             %{ $h->{CachedKids} } = () if $h->{CachedKids};
269             } if IMA_CLEAR_CACHED_KIDS & $bitmask;
270              
271 8832 100       14757 if (IMA_KEEP_ERR & $bitmask) {
272 2616         4293 push @pre_call_frag, q{
273             my $keep_error = DBI::_err_hash($h);
274             };
275             }
276             else {
277 6216 50       10146 my $ke_init = (IMA_KEEP_ERR_SUB & $bitmask)
278             ? q{= ($h->{dbi_pp_parent}->{dbi_pp_call_depth} && DBI::_err_hash($h)) }
279             : "";
280 6216         13102 push @pre_call_frag, qq{
281             my \$keep_error $ke_init;
282             };
283 6216         7675 my $clear_error_code = q{
284             #warn "$method_name cleared err";
285             $h->{err} = $DBI::err = undef;
286             $h->{errstr} = $DBI::errstr = undef;
287             $h->{state} = $DBI::state = '';
288             };
289             $clear_error_code = q{
290             printf $DBI::tfh " !! %s: %s CLEARED by call to }.$method_name.q{ method\n".
291             $h->{err}, $h->{err}
292             if defined $h->{err} && $DBI::dbi_debug & 0xF;
293             }. $clear_error_code
294 6216 100       11749 if exists $ENV{DBI_TRACE};
295 6216 50       15708 push @pre_call_frag, ($ke_init)
    100          
296             ? qq{ unless (\$keep_error) { $clear_error_code }}
297             : $clear_error_code
298             unless $method_name eq 'set_err';
299             }
300              
301 8832         11935 push @pre_call_frag, q{
302             my $ErrCount = $h->{ErrCount};
303             };
304              
305             push @pre_call_frag, q{
306             if (($DBI::dbi_debug & 0xF) >= 2) {
307             local $^W;
308             my $args = join " ", map { DBI::neat($_) } ($h, @_);
309             printf $DBI::tfh " > $method_name in $imp ($args) [$@]\n";
310             }
311 8832 100       14980 } if exists $ENV{DBI_TRACE}; # note use of 'exists'
312              
313             push @pre_call_frag, q{
314             $h->{'dbi_pp_last_method'} = $method_name;
315 8832 100       17719 } unless exists $DBI::last_method_except{$method_name};
316              
317             # --- post method call code fragments ---
318 8832         10139 my @post_call_frag;
319              
320             push @post_call_frag, q{
321             if (my $trace_level = ($DBI::dbi_debug & 0xF)) {
322             if ($h->{err}) {
323             printf $DBI::tfh " !! ERROR: %s %s\n", $h->{err}, $h->{errstr};
324             }
325             my $ret = join " ", map { DBI::neat($_) } @ret;
326             my $msg = " < $method_name= $ret";
327             $msg = ($trace_level >= 2) ? Carp::shortmess($msg) : "$msg\n";
328             print $DBI::tfh $msg;
329             }
330 8832 100       13816 } if exists $ENV{DBI_TRACE}; # note use of exists
331              
332 8832 100       13958 push @post_call_frag, q{
333             $h->{Executed} = 0;
334             if ($h->{BegunWork}) {
335             $h->{BegunWork} = 0;
336             $h->{AutoCommit} = 1;
337             }
338             } if IMA_END_WORK & $bitmask;
339              
340 8832 100       13399 push @post_call_frag, q{
341             if ( ref $ret[0] and
342             UNIVERSAL::isa($ret[0], 'DBI::_::common') and
343             defined( (my $h_new = tied(%{$ret[0]})||$ret[0])->{err} )
344             ) {
345             # copy up info/warn to drh so PrintWarn on connect is triggered
346             $h->set_err($h_new->{err}, $h_new->{errstr}, $h_new->{state})
347             }
348             } if IMA_IS_FACTORY & $bitmask;
349              
350 8832         11352 push @post_call_frag, q{
351             if ($keep_error) {
352             $keep_error = 0
353             if $h->{ErrCount} > $ErrCount
354             or DBI::_err_hash($h) ne $keep_error;
355             }
356              
357             $DBI::err = $h->{err};
358             $DBI::errstr = $h->{errstr};
359             $DBI::state = $h->{state};
360              
361             if ( !$keep_error
362             && defined(my $err = $h->{err})
363             && ($call_depth <= 1 && !$h->{dbi_pp_parent}{dbi_pp_call_depth})
364             ) {
365              
366             my($pe,$pw,$re,$he) = @{$h}{qw(PrintError PrintWarn RaiseError HandleError)};
367             my $msg;
368              
369             if ($err && ($pe || $re || $he) # error
370             or (!$err && length($err) && $pw) # warning
371             ) {
372             my $last = ($DBI::last_method_except{$method_name})
373             ? ($h->{'dbi_pp_last_method'}||$method_name) : $method_name;
374             my $errstr = $h->{errstr} || $DBI::errstr || $err || '';
375             my $msg = sprintf "%s %s %s: %s", $imp, $last,
376             ($err eq "0") ? "warning" : "failed", $errstr;
377              
378             if ($h->{'ShowErrorStatement'} and my $Statement = $h->{Statement}) {
379             $msg .= ' [for Statement "' . $Statement;
380             if (my $ParamValues = $h->FETCH('ParamValues')) {
381             $msg .= '" with ParamValues: ';
382             $msg .= DBI::_concat_hash_sorted($ParamValues, "=", ", ", 1, undef);
383             $msg .= "]";
384             }
385             else {
386             $msg .= '"]';
387             }
388             }
389             if ($err eq "0") { # is 'warning' (not info)
390             carp $msg if $pw;
391             }
392             else {
393             my $do_croak = 1;
394             if (my $subsub = $h->{'HandleError'}) {
395             $do_croak = 0 if &$subsub($msg,$h,$ret[0]);
396             }
397             if ($do_croak) {
398             printf $DBI::tfh " $method_name has failed ($h->{PrintError},$h->{RaiseError})\n"
399             if ($DBI::dbi_debug & 0xF) >= 4;
400             carp $msg if $pe;
401             die $msg if $h->{RaiseError};
402             }
403             }
404             }
405             }
406             };
407              
408              
409 8832 100       48508 my $method_code = q[
410             sub {
411             my $h = shift;
412             my $h_inner = tied(%$h);
413             $h = $h_inner if $h_inner;
414              
415             my $imp;
416             if ($method_name eq 'DESTROY') {
417             # during global destruction, $h->{...} can trigger "Can't call FETCH on an undef value"
418             # implying that tied() above lied to us, so we need to use eval
419             local $@; # protect $@
420             $imp = eval { $h->{"ImplementorClass"} } or return; # probably global destruction
421             }
422             else {
423             $imp = $h->{"ImplementorClass"} or do {
424             warn "Can't call $method_name method on handle $h after take_imp_data()\n"
425             if not exists $h->{Active};
426             return; # or, more likely, global destruction
427             };
428             }
429              
430             ] . join("\n", '', @pre_call_frag, '') . q[
431              
432             my $call_depth = $h->{'dbi_pp_call_depth'} + 1;
433             local ($h->{'dbi_pp_call_depth'}) = $call_depth;
434              
435             my @ret;
436             my $sub = $imp->can($method_name);
437             if (!$sub and IMA_FUNC_REDIRECT & $bitmask and $sub = $imp->can('func')) {
438             push @_, $method_name;
439             }
440             if ($sub) {
441             (wantarray) ? (@ret = &$sub($h,@_)) : (@ret = scalar &$sub($h,@_));
442             }
443             else {
444             # XXX could try explicit fallback to $imp->can('AUTOLOAD') etc
445             # which would then let Multiplex pass PurePerl tests, but some
446             # hook into install_method may be better.
447             croak "Can't locate DBI object method \"$method_name\" via package \"$imp\""
448             if ] . ((IMA_NOT_FOUND_OKAY & $bitmask) ? 0 : 1) . q[;
449             }
450              
451             ] . join("\n", '', @post_call_frag, '') . q[
452              
453             return (wantarray) ? @ret : $ret[0];
454             }
455             ];
456 96     96   645 no strict qw(refs);
  96         175  
  96         149611  
457 8832         5280865 my $code_ref = eval qq{#line 1 "DBI::PurePerl $method"\n$method_code};
458 8832 50       138247 warn "$@\n$method_code\n" if $@;
459 8832 50       15847 die "$@\n$method_code\n" if $@;
460 8832         40940 *$method = $code_ref;
461 8832         55366 if (0 && $method =~ /\b(connect|FETCH)\b/) { # debuging tool
462             my $l=0; # show line-numbered code for method
463             warn "*$method code:\n".join("\n", map { ++$l.": $_" } split/\n/,$method_code);
464             }
465             }
466              
467              
468             sub _new_handle {
469 3026     3026   6869 my ($class, $parent, $attr, $imp_data, $imp_class) = @_;
470              
471 3026 100 100     6574 DBI->trace_msg(" New $class (for $imp_class, parent=$parent, id=".($imp_data||'').")\n")
472             if $DBI::dbi_debug >= 3;
473              
474 3026 50       7823 $attr->{ImplementorClass} = $imp_class
475             or Carp::croak("_new_handle($class): 'ImplementorClass' attribute not given");
476              
477             # This is how we create a DBI style Object:
478             # %outer gets tied to %$attr (which becomes the 'inner' handle)
479 3026         4363 my (%outer, $i, $h);
480 3026         11822 $i = tie %outer, $class, $attr; # ref to inner hash (for driver)
481 3026         5316 $h = bless \%outer, $class; # ref to outer hash (for application)
482             # The above tie and bless may migrate down into _setup_handle()...
483             # Now add magic so DBI method dispatch works
484 3026         7404 DBI::_setup_handle($h, $imp_class, $parent, $imp_data);
485 3026 100       7401 return $h unless wantarray;
486 2370         8237 return ($h, $i);
487             }
488              
489             sub _setup_handle {
490 3026     3026   5690 my($h, $imp_class, $parent, $imp_data) = @_;
491 3026   33     7499 my $h_inner = tied(%$h) || $h;
492 3026 100       6589 if (($DBI::dbi_debug & 0xF) >= 4) {
493 3         10 local $^W;
494 3         29 print $DBI::tfh " _setup_handle(@_)\n";
495             }
496 3026         5343 $h_inner->{"imp_data"} = $imp_data;
497 3026         4784 $h_inner->{"ImplementorClass"} = $imp_class;
498 3026         5612 $h_inner->{"Kids"} = $h_inner->{"ActiveKids"} = 0; # XXX not maintained
499 3026 100       6254 if ($parent) {
500 2920         6299 foreach (qw(
501             RaiseError PrintError PrintWarn HandleError HandleSetErr
502             Warn LongTruncOk ChopBlanks AutoCommit ReadOnly
503             ShowErrorStatement FetchHashKeyName LongReadLen CompatMode
504             )) {
505             $h_inner->{$_} = $parent->{$_}
506 40880 100 66     111152 if exists $parent->{$_} && !exists $h_inner->{$_};
507             }
508 2920 100       13815 if (ref($parent) =~ /::db$/) { # is sth
    50          
509 2018         3758 $h_inner->{Database} = $parent;
510 2018         3311 $parent->{Statement} = $h_inner->{Statement};
511 2018         4047 $h_inner->{NUM_OF_PARAMS} = 0;
512 2018         3815 $h_inner->{Active} = 0; # driver sets true when there's data to fetch
513             }
514             elsif (ref($parent) =~ /::dr$/){ # is dbh
515 902         2174 $h_inner->{Driver} = $parent;
516 902         1754 $h_inner->{Active} = 0;
517             }
518             else {
519 0         0 warn "panic: ".ref($parent); # should never happen
520             }
521 2920         4581 $h_inner->{dbi_pp_parent} = $parent;
522              
523             # add to the parent's ChildHandles
524 2920 50       5392 if ($HAS_WEAKEN) {
525 2920   100     7579 my $handles = $parent->{ChildHandles} ||= [];
526 2920         5216 push @$handles, $h;
527 2920         9576 Scalar::Util::weaken($handles->[-1]);
528             # purge destroyed handles occasionally
529 2920 100       7754 if (@$handles % 120 == 0) {
530 10         41 @$handles = grep { defined } @$handles;
  1200         1832  
531 10         69 Scalar::Util::weaken($_) for @$handles; # re-weaken after grep
532             }
533             }
534             }
535             else { # setting up a driver handle
536 106         210 $h_inner->{Warn} = 1;
537 106         214 $h_inner->{PrintWarn} = 1;
538 106         189 $h_inner->{AutoCommit} = 1;
539 106         175 $h_inner->{TraceLevel} = 0;
540 106         338 $h_inner->{CompatMode} = (1==0);
541 106   50     317 $h_inner->{FetchHashKeyName} ||= 'NAME';
542 106   50     592 $h_inner->{LongReadLen} ||= 80;
543 106 50 50     730 $h_inner->{ChildHandles} ||= [] if $HAS_WEAKEN;
544 106   50     521 $h_inner->{Type} ||= 'dr';
545 106         225 $h_inner->{Active} = 1;
546             }
547 3026         5106 $h_inner->{"dbi_pp_call_depth"} = 0;
548 3026         7176 $h_inner->{"dbi_pp_pid"} = $$;
549 3026         5844 $h_inner->{ErrCount} = 0;
550             }
551              
552             sub constant {
553 0     0 0 0 warn "constant(@_) called unexpectedly"; return undef;
  0         0  
554             }
555              
556             sub trace {
557 18     18 1 8816 my ($h, $level, $file) = @_;
558 18 50 66     78 $level = $h->parse_trace_flags($level)
559             if defined $level and !DBI::looks_like_number($level);
560 18         36 my $old_level = $DBI::dbi_debug;
561 18 100       47 _set_trace_file($file) if $level;
562 18 100       43 if (defined $level) {
563 16         24 $DBI::dbi_debug = $level;
564 16 100       293 print $DBI::tfh " DBI $DBI::VERSION (PurePerl) "
565             . "dispatch trace level set to $DBI::dbi_debug\n"
566             if $DBI::dbi_debug & 0xF;
567             }
568 18 100       60 _set_trace_file($file) if !$level;
569 18         44 return $old_level;
570             }
571              
572             sub _set_trace_file {
573 38     38   69 my ($file) = @_;
574             #
575             # DAA add support for filehandle inputs
576             #
577             # DAA required to avoid closing a prior fh trace()
578 38 100       113 $DBI::tfh = undef unless $DBI::tfh_needs_close;
579              
580 38 100       90 if (ref $file eq 'GLOB') {
581 8         10 $DBI::tfh = $file;
582 8         58 select((select($DBI::tfh), $| = 1)[0]);
583 8         32 $DBI::tfh_needs_close = 0;
584 8         14 return 1;
585             }
586 30 100 100     122 if ($file && ref \$file eq 'GLOB') {
587 4         5 $DBI::tfh = *{$file}{IO};
  4         21  
588 4         36 select((select($DBI::tfh), $| = 1)[0]);
589 4         7 $DBI::tfh_needs_close = 0;
590 4         7 return 1;
591             }
592 26         45 $DBI::tfh_needs_close = 1;
593 26 100 100     100 if (!$file || $file eq 'STDERR') {
    100          
594 12 50       250 open $DBI::tfh, ">&STDERR" or carp "Can't dup STDERR: $!";
595             }
596             elsif ($file eq 'STDOUT') {
597 8 50       112 open $DBI::tfh, ">&STDOUT" or carp "Can't dup STDOUT: $!";
598             }
599             else {
600 6 50       311 open $DBI::tfh, ">>$file" or carp "Can't open $file: $!";
601             }
602 26         152 select((select($DBI::tfh), $| = 1)[0]);
603 26         53 return 1;
604             }
605 2     2   1009 sub _get_imp_data { shift->{"imp_data"}; }
606       0     sub _svdump { }
607             sub dump_handle {
608 4     4 0 166 my ($h,$msg,$level) = @_;
609 4   33     11 $msg||="dump_handle $h";
610 4         31 print $DBI::tfh "$msg:\n";
611 4         61 for my $attrib (sort keys %$h) {
612 136         282 print $DBI::tfh "\t$attrib => ".DBI::neat($h->{$attrib})."\n";
613             }
614             }
615              
616             sub _handles {
617 14     14   17 my $h = shift;
618 14         20 my $h_inner = tied %$h;
619 14 50       28 if ($h_inner) { # this is okay
620 14 50       24 return $h unless wantarray;
621 14         38 return ($h, $h_inner);
622             }
623             # XXX this isn't okay... we have an inner handle but
624             # currently have no way to get at its outer handle,
625             # so we just warn and return the inner one for both...
626 0         0 Carp::carp("Can't return outer handle from inner handle using DBI::PurePerl");
627 0 0       0 return $h unless wantarray;
628 0         0 return ($h,$h);
629             }
630              
631             sub hash {
632 8     8 1 40082 my ($key, $type) = @_;
633 8         13 my ($hash);
634 8 100       29 if (!$type) {
    50          
635 6         11 $hash = 0;
636             # XXX The C version uses the "char" type, which could be either
637             # signed or unsigned. I use signed because so do the two
638             # compilers on my system.
639 6         26 for my $char (unpack ("c*", $key)) {
640 24         39 $hash = $hash * 33 + $char;
641             }
642 6         14 $hash &= 0x7FFFFFFF; # limit to 31 bits
643 6         13 $hash |= 0x40000000; # set bit 31
644 6         26 return -$hash; # return negative int
645             }
646             elsif ($type == 1) { # Fowler/Noll/Vo hash
647             # see http://www.isthe.com/chongo/tech/comp/fnv/
648 2         18 require Math::BigInt; # feel free to reimplement w/o BigInt!
649 2   50     12 (my $version = $Math::BigInt::VERSION || 0) =~ s/_.*//; # eg "1.70_01"
650 2 50       15 if ($version >= 1.56) {
651 2         10 $hash = Math::BigInt->new(0x811c9dc5);
652 2         31792 for my $uchar (unpack ("C*", $key)) {
653             # multiply by the 32 bit FNV magic prime mod 2^64
654 10         1799 $hash = ($hash * 0x01000193) & 0xffffffff;
655             # xor the bottom with the current octet
656 10         4533 $hash ^= $uchar;
657             }
658             # cast to int
659 2         464 return unpack "i", pack "i", $hash;
660             }
661 0         0 croak("DBI::PurePerl doesn't support hash type 1 without Math::BigInt >= 1.56 (available on CPAN)");
662             }
663             else {
664 0         0 croak("bad hash type $type");
665             }
666             }
667              
668             sub looks_like_number {
669 4886     4886 1 57716 my @new = ();
670 4886         6851 for my $thing(@_) {
671 4898 100 100     13142 if (!defined $thing or $thing eq '') {
672 8         17 push @new, undef;
673             }
674             else {
675 4890 100       17624 push @new, ($thing =~ /^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/) ? 1 : 0;
676             }
677             }
678 4886 100       15099 return (@_ >1) ? @new : $new[0];
679             }
680              
681             sub neat {
682 5595     5595 1 15384 my $v = shift;
683 5595 100       10544 return "undef" unless defined $v;
684 1213         1409 my $quote = q{"};
685 1213 50       2277 if (not utf8::is_utf8($v)) {
686 1213 100       4182 return $v if (($v & ~ $v) eq "0"); # is SvNIOK
687 616         787 $quote = q{'};
688             }
689 616   66     1397 my $maxlen = shift || $DBI::neat_maxlen;
690 616 100 66     1678 if ($maxlen && $maxlen < length($v) + 2) {
691 4         13 $v = substr($v,0,$maxlen-5);
692 4         6 $v .= '...';
693             }
694 616         1231 $v =~ s/[^[:print:]]/./g;
695 616         2293 return "$quote$v$quote";
696             }
697              
698             sub sql_type_cast {
699 28     28 1 19460 my (undef, $sql_type, $flags) = @_;
700              
701 28 100       84 return -1 unless defined $_[0];
702              
703 26         41 my $cast_ok = 1;
704              
705 26 100 33     48 my $evalret = eval {
706 96     96   743 use warnings FATAL => qw(numeric);
  96         163  
  96         34324  
707 26 100       74 if ($sql_type == SQL_INTEGER) {
    100          
    100          
708 16         75 my $dummy = $_[0] + 0;
709 12         37 return 1;
710             }
711             elsif ($sql_type == SQL_DOUBLE) {
712 4         45 my $dummy = $_[0] + 0.0;
713 0         0 return 1;
714             }
715             elsif ($sql_type == SQL_NUMERIC) {
716 4         49 my $dummy = $_[0] + 0.0;
717 0         0 return 1;
718             }
719             else {
720 2         11 return -2;
721             }
722             } or $^W && warn $@; # XXX warnings::warnif("numeric", $@) ?
723              
724 26 100 100     110 return $evalret if defined($evalret) && ($evalret == -2);
725 24 100       55 $cast_ok = 0 unless $evalret;
726              
727             # DBIstcf_DISCARD_STRING not supported for PurePerl currently
728              
729 24 100       61 return 2 if $cast_ok;
730 12 100       45 return 0 if $flags & DBIstcf_STRICT;
731 6         20 return 1;
732             }
733              
734             sub dbi_time {
735 0     0 0 0 return time();
736             }
737              
738 3026     3026   8859 sub DBI::st::TIEHASH { bless $_[1] => $_[0] };
739              
740             sub _concat_hash_sorted {
741 228     228   30025 my ( $hash_ref, $kv_separator, $pair_separator, $use_neat, $num_sort ) = @_;
742             # $num_sort: 0=lexical, 1=numeric, undef=try to guess
743              
744 228 100       604 return undef unless defined $hash_ref;
745 213 100       561 die "hash is not a hash reference" unless ref $hash_ref eq 'HASH';
746 211         449 my $keys = _get_sorted_hash_keys($hash_ref, $num_sort);
747 211         363 my $string = '';
748 211         414 for my $key (@$keys) {
749 5632 100       9660 $string .= $pair_separator if length $string > 0;
750 5632         7326 my $value = $hash_ref->{$key};
751 5632 100       7590 if ($use_neat) {
752 4412         5968 $value = DBI::neat($value, 0);
753             }
754             else {
755 1220 100       2089 $value = (defined $value) ? "'$value'" : 'undef';
756             }
757 5632         12451 $string .= $key . $kv_separator . $value;
758             }
759 211         3506 return $string;
760             }
761              
762             sub _get_sorted_hash_keys {
763 211     211   391 my ($hash_ref, $num_sort) = @_;
764 211 100       452 if (not defined $num_sort) {
765 50         72 my $sort_guess = 1;
766             $sort_guess = (not looks_like_number($_)) ? 0 : $sort_guess
767 50 100       626 for keys %$hash_ref;
768 50         249 $num_sort = $sort_guess;
769             }
770              
771 211         1108 my @keys = keys %$hash_ref;
772 96     96   640 no warnings 'numeric';
  96         189  
  96         190679  
773             my @sorted = ($num_sort)
774 211 50       1231 ? sort { $a <=> $b or $a cmp $b } @keys
  36297 100       49719  
775             : sort @keys;
776 211         689 return \@sorted;
777             }
778              
779             sub _err_hash {
780 73176 100   73176   3410904 return 1 unless defined $_[0]->{err};
781 879         2630 return "$_[0]->{err} $_[0]->{errstr}"
782             }
783              
784              
785             package
786             DBI::var;
787              
788             sub FETCH {
789 0     0   0 my($key)=shift;
790 0 0       0 return $DBI::err if $$key eq '*err';
791 0 0       0 return $DBI::errstr if $$key eq '&errstr';
792 0         0 Carp::confess("FETCH $key not supported when using DBI::PurePerl");
793             }
794              
795             package
796             DBD::_::common;
797              
798             sub swap_inner_handle {
799 0     0   0 my ($h1, $h2) = @_;
800             # can't make this work till we can get the outer handle from the inner one
801             # probably via a WeakRef
802 0         0 return $h1->set_err($DBI::stderr, "swap_inner_handle not currently supported by DBI::PurePerl");
803             }
804              
805             sub trace { # XXX should set per-handle level, not global
806 160     160   2238 my ($h, $level, $file) = @_;
807 160 100 100     448 $level = $h->parse_trace_flags($level)
808             if defined $level and !DBI::looks_like_number($level);
809 160         397 my $old_level = $DBI::dbi_debug;
810 160 100       276 DBI::_set_trace_file($file) if defined $file;
811 160 100       285 if (defined $level) {
812 116         146 $DBI::dbi_debug = $level;
813 116 100       192 if ($DBI::dbi_debug) {
814 78         1741 printf $DBI::tfh
815             " %s trace level set to %d in DBI $DBI::VERSION (PurePerl)\n",
816             $h, $DBI::dbi_debug;
817             print $DBI::tfh " Full trace not available because DBI_TRACE is not in environment\n"
818 78 100       923 unless exists $ENV{DBI_TRACE};
819             }
820             }
821 160         448 return $old_level;
822             }
823             *debug = \&trace; *debug = \&trace; # twice to avoid typo warning
824              
825             sub FETCH {
826 4397     4397   14691 my($h,$key)= @_;
827 4397         6795 my $v = $h->{$key};
828             #warn ((exists $h->{$key}) ? "$key=$v\n" : "$key NONEXISTANT\n");
829 4397 100       10151 return $v if defined $v;
830 3756 100       7752 if ($key =~ /^NAME_.c$/) {
831 109         290 my $cols = $h->FETCH('NAME');
832 109 100       1043 return undef unless $cols;
833 105         196 my @lcols = map { lc $_ } @$cols;
  281         694  
834 105         279 $h->{NAME_lc} = \@lcols;
835 105         182 my @ucols = map { uc $_ } @$cols;
  281         522  
836 105         224 $h->{NAME_uc} = \@ucols;
837 105         244 return $h->FETCH($key);
838             }
839 3647 100       6946 if ($key =~ /^NAME.*_hash$/) {
840 60         130 my $i=0;
841 60 100       128 for my $c(@{$h->FETCH('NAME')||[]}) {
  60         260  
842 124         979 $h->{'NAME_hash'}->{$c} = $i;
843 124         350 $h->{'NAME_lc_hash'}->{"\L$c"} = $i;
844 124         316 $h->{'NAME_uc_hash'}->{"\U$c"} = $i;
845 124         211 $i++;
846             }
847 60         291 return $h->{$key};
848             }
849 3587 50 33     12176 if (!defined $v && !exists $h->{$key}) {
850 3587 100 33     6154 return ($h->FETCH('TaintIn') && $h->FETCH('TaintOut')) if $key eq'Taint';
851 3579 100       8890 return (1==0) if $is_flag_attribute{$key}; # return perl-style sv_no, not undef
852 2407 100       4667 return $DBI::dbi_debug if $key eq 'TraceLevel';
853 2309 100 66     5943 return [] if $key eq 'ChildHandles' && $HAS_WEAKEN;
854 2267 100       3691 if ($key eq 'Type') {
855 50 50       168 return "dr" if $h->isa('DBI::dr');
856 50 100       143 return "db" if $h->isa('DBI::db');
857 44 50       146 return "st" if $h->isa('DBI::st');
858 0         0 Carp::carp( sprintf "Can't determine Type for %s",$h );
859             }
860 2217 100 100     6070 if (!$is_valid_attribute{$key} and $key =~ m/^[A-Z]/) {
861 2         9 local $^W; # hide undef warnings
862 2         5 Carp::carp( sprintf "Can't get %s->{%s}: unrecognised attribute (@{[ %$h ]})",$h,$key )
  2         575  
863             }
864             }
865 2217         5833 return $v;
866             }
867             sub STORE {
868 13516     13516   29162 my ($h,$key,$value) = @_;
869 13516 100 100     59446 if ($key eq 'AutoCommit') {
    100 100        
    100          
    100          
    100          
870 568 50 66     2603 Carp::croak("DBD driver has not implemented the AutoCommit attribute")
871             unless $value == -900 || $value == -901;
872 568         1868 $value = ($value == -901);
873             }
874             elsif ($key =~ /^Taint/ ) {
875 24 50       43 Carp::croak(sprintf "Can't set %s->{%s}: Taint mode not supported by DBI::PurePerl",$h,$key)
876             if $value;
877             }
878             elsif ($key eq 'TraceLevel') {
879 94         271 $h->trace($value);
880 94         777 return 1;
881             }
882             elsif ($key eq 'NUM_OF_FIELDS') {
883 2110         4398 $h->{$key} = $value;
884 2110 100       4261 if ($value) {
885 1624         3236 my $fbav = DBD::_::st::dbih_setup_fbav($h);
886 1624 100       4520 @$fbav = (undef) x $value if @$fbav != $value;
887             }
888 2110         5566 return 1;
889             }
890             elsif (!$is_valid_attribute{$key} && $key =~ /^[A-Z]/ && !exists $h->{$key}) {
891 2         398 Carp::carp(sprintf "Can't set %s->{%s}: unrecognised attribute or invalid value %s",
892             $h,$key,$value);
893             }
894 11312 100       29637 $h->{$key} = $is_flag_attribute{$key} ? !!$value : $value;
895 11312 100       29952 Scalar::Util::weaken($h->{$key}) if $key eq 'CachedKids';
896 11312         26104 return 1;
897             }
898             sub DELETE {
899 4     4   77 my ($h, $key) = @_;
900 4 100       20 return $h->FETCH($key) unless $key =~ /^private_/;
901 2         8 return delete $h->{$key};
902             }
903 55     55   963 sub err { return shift->{err} }
904 70     70   1287 sub errstr { return shift->{errstr} }
905 10     10   231 sub state { return shift->{state} }
906             sub set_err {
907 1149     1149   61853 my ($h, $errnum,$msg,$state, $method, $rv) = @_;
908 1149   33     4064 $h = tied(%$h) || $h;
909              
910 1149 100       2716 if (my $hss = $h->{HandleSetErr}) {
911 38 100       94 return if $hss->($h, $errnum, $msg, $state, $method);
912             }
913              
914 1147 100       2950 if (!defined $errnum) {
915 800         1628 $h->{err} = $DBI::err = undef;
916 800         1345 $h->{errstr} = $DBI::errstr = undef;
917 800         1514 $h->{state} = $DBI::state = '';
918 800         2477 return;
919             }
920              
921 347 100       805 if ($h->{errstr}) {
922             $h->{errstr} .= sprintf " [err was %s now %s]", $h->{err}, $errnum
923 27 100 100     170 if $h->{err} && $errnum && $h->{err} ne $errnum;
      100        
924             $h->{errstr} .= sprintf " [state was %s now %s]", $h->{state}, $state
925 27 100 100     141 if $h->{state} and $h->{state} ne "S1000" && $state && $h->{state} ne $state;
      100        
      100        
926 27 100       109 $h->{errstr} .= "\n$msg" if $h->{errstr} ne $msg;
927 27         53 $DBI::errstr = $h->{errstr};
928             }
929             else {
930 320         650 $h->{errstr} = $DBI::errstr = $msg;
931             }
932              
933             # assign if higher priority: err > "0" > "" > undef
934 347         462 my $err_changed;
935 347 100 100     1157 if ($errnum # new error: so assign
      66        
      100        
936             or !defined $h->{err} # no existing warn/info: so assign
937             # new warn ("0" len 1) > info ("" len 0): so assign
938             or defined $errnum && length($errnum) > length($h->{err})
939             ) {
940 338         872 $h->{err} = $DBI::err = $errnum;
941 338 100       783 ++$h->{ErrCount} if $errnum;
942 338         543 ++$err_changed;
943             }
944              
945 347 100       643 if ($err_changed) {
946 338 100 100     1296 $state ||= "S1000" if $DBI::err;
947 338 100       1095 $h->{state} = $DBI::state = ($state eq "00000") ? "" : $state
    100          
948             if $state;
949             }
950              
951 347 100       823 if (my $p = $h->{Database}) { # just sth->dbh, not dbh->drh (see ::db::DESTROY)
952 201         367 $p->{err} = $DBI::err;
953 201         310 $p->{errstr} = $DBI::errstr;
954 201         335 $p->{state} = $DBI::state;
955             }
956              
957 347         530 $h->{'dbi_pp_last_method'} = $method;
958 347         911 return $rv; # usually undef
959             }
960             sub trace_msg {
961 4433     4433   29061 my ($h, $msg, $minlevel)=@_;
962 4433 100       9360 $minlevel = 1 unless defined $minlevel;
963 4433 100       12952 return unless $minlevel <= ($DBI::dbi_debug & 0xF);
964 73         878 print $DBI::tfh $msg;
965 73         203 return 1;
966             }
967             sub private_data {
968 0     0   0 warn "private_data @_";
969             }
970             sub take_imp_data {
971 1     1   1992 my $dbh = shift;
972             # A reasonable default implementation based on the one in DBI.xs.
973             # Typically a pure-perl driver would have their own take_imp_data method
974             # that would delete all but the essential items in the hash before ending with:
975             # return $dbh->SUPER::take_imp_data();
976             # Of course it's useless if the driver doesn't also implement support for
977             # the dbi_imp_data attribute to the connect() method.
978 1         484 require Storable;
979             croak("Can't take_imp_data from handle that's not Active")
980 1 50       2540 unless $dbh->{Active};
981 1 50       2 for my $sth (@{ $dbh->{ChildHandles} || [] }) {
  1         5  
982 3 100       7 next unless $sth;
983 2 100       14 $sth->finish if $sth->{Active};
984 2         33 bless $sth, 'DBI::zombie';
985             }
986 1         24 delete $dbh->{$_} for (keys %is_valid_attribute);
987 1         24 delete $dbh->{$_} for grep { m/^dbi_/ } keys %$dbh;
  11         48  
988             # warn "@{[ %$dbh ]}";
989 1         3 local $Storable::forgive_me = 1; # in case there are some CODE refs
990 1         4 my $imp_data = Storable::freeze($dbh);
991             # XXX um, should probably untie here - need to check dispatch behaviour
992 1         76 return $imp_data;
993             }
994             sub rows {
995 0     0   0 return -1; # always returns -1 here, see DBD::_::st::rows below
996             }
997       2024     sub DESTROY {
998             }
999              
1000             package
1001             DBD::_::dr;
1002              
1003             sub dbixs_revision {
1004 4     4   79 return 0;
1005             }
1006              
1007             package
1008             DBD::_::db;
1009              
1010       652     sub connected {
1011             }
1012              
1013              
1014             package
1015             DBD::_::st;
1016              
1017             sub fetchrow_arrayref {
1018 0     0   0 my $h = shift;
1019             # if we're here then driver hasn't implemented fetch/fetchrow_arrayref
1020             # so we assume they've implemented fetchrow_array and call that instead
1021 0 0       0 my @row = $h->fetchrow_array or return;
1022 0         0 return $h->_set_fbav(\@row);
1023             }
1024             # twice to avoid typo warning
1025             *fetch = \&fetchrow_arrayref; *fetch = \&fetchrow_arrayref;
1026              
1027             sub fetchrow_array {
1028 4     4   2159 my $h = shift;
1029             # if we're here then driver hasn't implemented fetchrow_array
1030             # so we assume they've implemented fetch/fetchrow_arrayref
1031 4 50       16 my $row = $h->fetch or return;
1032 4         85 return @$row;
1033             }
1034             *fetchrow = \&fetchrow_array; *fetchrow = \&fetchrow_array;
1035              
1036             sub fetchrow_hashref {
1037 26     26   5414 my $h = shift;
1038 26 100       63 my $row = $h->fetch or return;
1039 24         395 my $FetchCase = shift;
1040 24   50     88 my $FetchHashKeyName = $FetchCase || $h->{'FetchHashKeyName'} || 'NAME';
1041 24         59 my $FetchHashKeys = $h->FETCH($FetchHashKeyName);
1042 24         211 my %rowhash;
1043 24         111 @rowhash{ @$FetchHashKeys } = @$row;
1044 22         55 return \%rowhash;
1045             }
1046             sub dbih_setup_fbav {
1047 1831     1831   2507 my $h = shift;
1048 1831   66     5009 return $h->{'_fbav'} || do {
1049             $DBI::rows = $h->{'_rows'} = 0;
1050             my $fields = $h->{'NUM_OF_FIELDS'}
1051             or DBI::croak("NUM_OF_FIELDS not set");
1052             my @row = (undef) x $fields;
1053             \@row;
1054             };
1055             }
1056             sub _get_fbav {
1057 147     147   8208 my $h = shift;
1058 147   66     648 my $av = $h->{'_fbav'} ||= dbih_setup_fbav($h);
1059 147         312 $DBI::rows = ++$h->{'_rows'};
1060 147         343 return $av;
1061             }
1062             sub _set_fbav {
1063 1558     1558   31744 my $h = shift;
1064 1558         1848 my $fbav = $h->{'_fbav'};
1065 1558 100       2246 if ($fbav) {
1066 1417         1847 $DBI::rows = ++$h->{'_rows'};
1067             }
1068             else {
1069 141         500 $fbav = $h->_get_fbav;
1070             }
1071 1558         3021 my $row = shift;
1072 1558 100       2225 if (my $bc = $h->{'_bound_cols'}) {
1073 182         472 for my $i (0..@$row-1) {
1074 474         593 my $bound = $bc->[$i];
1075 474 100       984 $fbav->[$i] = ($bound) ? ($$bound = $row->[$i]) : $row->[$i];
1076             }
1077             }
1078             else {
1079 1376         2343 @$fbav = @$row;
1080             }
1081 1558         2749 return $fbav;
1082             }
1083             sub bind_col {
1084 162     162   8649 my ($h, $col, $value_ref,$from_bind_columns) = @_;
1085 162   66     491 my $fbav = $h->{'_fbav'} ||= dbih_setup_fbav($h); # from _get_fbav()
1086 162         246 my $num_of_fields = @$fbav;
1087 162 100 100     1443 DBI::croak("bind_col: column $col is not a valid column (1..$num_of_fields)")
1088             if $col < 1 or $col > $num_of_fields;
1089 156 100       291 return 1 if not defined $value_ref; # ie caller is just trying to set TYPE
1090 154 50       328 DBI::croak("bind_col($col,$value_ref) needs a reference to a scalar")
1091             unless ref $value_ref eq 'SCALAR';
1092 154         340 $h->{'_bound_cols'}->[$col-1] = $value_ref;
1093 154         355 return 1;
1094             }
1095             sub finish {
1096 1221     1221   30220 my $h = shift;
1097 1221         2368 $h->{'_fbav'} = undef;
1098 1221         2077 $h->{'Active'} = 0;
1099 1221         2832 return 1;
1100             }
1101             sub rows {
1102 3     3   57 my $h = shift;
1103 3         7 my $rows = $h->{'_rows'};
1104 3 50       8 return -1 unless defined $rows;
1105 3         10 return $rows;
1106             }
1107              
1108             1;
1109             __END__