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   549 use strict;
  96         185  
  96         2695  
20 96     96   470 use Carp;
  96         174  
  96         22972  
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   653 use constant SQL_ALL_TYPES => 0;
  96         188  
  96         7371  
50 96     96   543 use constant SQL_ARRAY => 50;
  96         196  
  96         4366  
51 96     96   512 use constant SQL_ARRAY_LOCATOR => 51;
  96         196  
  96         4254  
52 96     96   501 use constant SQL_BIGINT => (-5);
  96         160  
  96         4037  
53 96     96   483 use constant SQL_BINARY => (-2);
  96         166  
  96         4042  
54 96     96   506 use constant SQL_BIT => (-7);
  96         170  
  96         3741  
55 96     96   477 use constant SQL_BLOB => 30;
  96         163  
  96         3659  
56 96     96   504 use constant SQL_BLOB_LOCATOR => 31;
  96         189  
  96         3842  
57 96     96   498 use constant SQL_BOOLEAN => 16;
  96         168  
  96         3646  
58 96     96   461 use constant SQL_CHAR => 1;
  96         159  
  96         3755  
59 96     96   487 use constant SQL_CLOB => 40;
  96         1461  
  96         4466  
60 96     96   495 use constant SQL_CLOB_LOCATOR => 41;
  96         169  
  96         3745  
61 96     96   486 use constant SQL_DATE => 9;
  96         170  
  96         3734  
62 96     96   490 use constant SQL_DATETIME => 9;
  96         181  
  96         3866  
63 96     96   503 use constant SQL_DECIMAL => 3;
  96         165  
  96         3838  
64 96     96   478 use constant SQL_DOUBLE => 8;
  96         168  
  96         3505  
65 96     96   461 use constant SQL_FLOAT => 6;
  96         156  
  96         4275  
66 96     96   474 use constant SQL_GUID => (-11);
  96         146  
  96         3598  
67 96     96   460 use constant SQL_INTEGER => 4;
  96         163  
  96         3543  
68 96     96   452 use constant SQL_INTERVAL => 10;
  96         161  
  96         3493  
69 96     96   472 use constant SQL_INTERVAL_DAY => 103;
  96         172  
  96         3602  
70 96     96   465 use constant SQL_INTERVAL_DAY_TO_HOUR => 108;
  96         158  
  96         3613  
71 96     96   446 use constant SQL_INTERVAL_DAY_TO_MINUTE => 109;
  96         178  
  96         3652  
72 96     96   487 use constant SQL_INTERVAL_DAY_TO_SECOND => 110;
  96         167  
  96         3655  
73 96     96   468 use constant SQL_INTERVAL_HOUR => 104;
  96         173  
  96         3654  
74 96     96   447 use constant SQL_INTERVAL_HOUR_TO_MINUTE => 111;
  96         152  
  96         3729  
75 96     96   448 use constant SQL_INTERVAL_HOUR_TO_SECOND => 112;
  96         180  
  96         3519  
76 96     96   449 use constant SQL_INTERVAL_MINUTE => 105;
  96         180  
  96         3462  
77 96     96   465 use constant SQL_INTERVAL_MINUTE_TO_SECOND => 113;
  96         174  
  96         3725  
78 96     96   516 use constant SQL_INTERVAL_MONTH => 102;
  96         175  
  96         3522  
79 96     96   553 use constant SQL_INTERVAL_SECOND => 106;
  96         176  
  96         3549  
80 96     96   459 use constant SQL_INTERVAL_YEAR => 101;
  96         199  
  96         3705  
81 96     96   465 use constant SQL_INTERVAL_YEAR_TO_MONTH => 107;
  96         162  
  96         3712  
82 96     96   473 use constant SQL_LONGVARBINARY => (-4);
  96         203  
  96         3855  
83 96     96   510 use constant SQL_LONGVARCHAR => (-1);
  96         157  
  96         3574  
84 96     96   454 use constant SQL_MULTISET => 55;
  96         150  
  96         3466  
85 96     96   459 use constant SQL_MULTISET_LOCATOR => 56;
  96         217  
  96         3638  
86 96     96   453 use constant SQL_NUMERIC => 2;
  96         162  
  96         3513  
87 96     96   449 use constant SQL_REAL => 7;
  96         162  
  96         3424  
88 96     96   459 use constant SQL_REF => 20;
  96         187  
  96         3593  
89 96     96   459 use constant SQL_ROW => 19;
  96         159  
  96         3437  
90 96     96   451 use constant SQL_SMALLINT => 5;
  96         162  
  96         3500  
91 96     96   431 use constant SQL_TIME => 10;
  96         151  
  96         3484  
92 96     96   480 use constant SQL_TIMESTAMP => 11;
  96         151  
  96         3774  
93 96     96   466 use constant SQL_TINYINT => (-6);
  96         188  
  96         3721  
94 96     96   470 use constant SQL_TYPE_DATE => 91;
  96         169  
  96         3974  
95 96     96   458 use constant SQL_TYPE_TIME => 92;
  96         145  
  96         3510  
96 96     96   438 use constant SQL_TYPE_TIMESTAMP => 93;
  96         154  
  96         3465  
97 96     96   488 use constant SQL_TYPE_TIMESTAMP_WITH_TIMEZONE => 95;
  96         187  
  96         4037  
98 96     96   476 use constant SQL_TYPE_TIME_WITH_TIMEZONE => 94;
  96         184  
  96         3719  
99 96     96   466 use constant SQL_UDT => 17;
  96         157  
  96         3269  
100 96     96   458 use constant SQL_UDT_LOCATOR => 18;
  96         169  
  96         3395  
101 96     96   453 use constant SQL_UNKNOWN_TYPE => 0;
  96         166  
  96         3686  
102 96     96   2379 use constant SQL_VARBINARY => (-3);
  96         213  
  96         3711  
103 96     96   481 use constant SQL_VARCHAR => 12;
  96         167  
  96         3619  
104 96     96   465 use constant SQL_WCHAR => (-8);
  96         164  
  96         3691  
105 96     96   462 use constant SQL_WLONGVARCHAR => (-10);
  96         156  
  96         3885  
106 96     96   463 use constant SQL_WVARCHAR => (-9);
  96         162  
  96         3649  
107              
108             # for Cursor types
109 96     96   489 use constant SQL_CURSOR_FORWARD_ONLY => 0;
  96         176  
  96         3648  
110 96     96   463 use constant SQL_CURSOR_KEYSET_DRIVEN => 1;
  96         180  
  96         3626  
111 96     96   476 use constant SQL_CURSOR_DYNAMIC => 2;
  96         162  
  96         3634  
112 96     96   473 use constant SQL_CURSOR_STATIC => 3;
  96         181  
  96         4039  
113 96     96   520 use constant SQL_CURSOR_TYPE_DEFAULT => SQL_CURSOR_FORWARD_ONLY;
  96         166  
  96         3684  
114              
115 96     96   507 use constant IMA_HAS_USAGE => 0x0001; #/* check parameter usage */
  96         156  
  96         3692  
116 96     96   493 use constant IMA_FUNC_REDIRECT => 0x0002; #/* is $h->func(..., "method")*/
  96         178  
  96         3740  
117 96     96   504 use constant IMA_KEEP_ERR => 0x0004; #/* don't reset err & errstr */
  96         160  
  96         3667  
118 96     96   464 use constant IMA_KEEP_ERR_SUB => 0x0008; #/* '' if in nested call */
  96         157  
  96         3596  
119 96     96   470 use constant IMA_NO_TAINT_IN => 0x0010; #/* don't check for tainted args*/
  96         162  
  96         3789  
120 96     96   455 use constant IMA_NO_TAINT_OUT => 0x0020; #/* don't taint results */
  96         152  
  96         3787  
121 96     96   481 use constant IMA_COPY_UP_STMT => 0x0040; #/* copy sth Statement to dbh */
  96         153  
  96         3518  
122 96     96   468 use constant IMA_END_WORK => 0x0080; #/* set on commit & rollback */
  96         214  
  96         3575  
123 96     96   459 use constant IMA_STUB => 0x0100; #/* do nothing eg $dbh->connected */
  96         165  
  96         3367  
124 96     96   497 use constant IMA_CLEAR_STMT => 0x0200; #/* clear Statement before call */
  96         179  
  96         3376  
125 96     96   434 use constant IMA_UNRELATED_TO_STMT=> 0x0400; #/* profile as empty Statement */
  96         165  
  96         3514  
126 96     96   449 use constant IMA_NOT_FOUND_OKAY => 0x0800; #/* not error if not found */
  96         160  
  96         4092  
127 96     96   502 use constant IMA_EXECUTE => 0x1000; #/* do/execute: DBIcf_Executed */
  96         152  
  96         3505  
128 96     96   463 use constant IMA_SHOW_ERR_STMT => 0x2000; #/* dbh meth relates to Statement*/
  96         151  
  96         3500  
129 96     96   451 use constant IMA_HIDE_ERR_PARAMVALUES => 0x4000; #/* ParamValues are not relevant */
  96         171  
  96         3337  
130 96     96   454 use constant IMA_IS_FACTORY => 0x8000; #/* new h ie connect & prepare */
  96         163  
  96         3460  
131 96     96   515 use constant IMA_CLEAR_CACHED_KIDS => 0x10000; #/* clear CachedKids before call */
  96         150  
  96         3489  
132              
133 96     96   897 use constant DBIstcf_STRICT => 0x0001;
  96         204  
  96         3565  
134 96     96   462 use constant DBIstcf_DISCARD_STRING => 0x0002;
  96         174  
  96         65036  
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 205 $initial_setup = 1;
208 96 50       378 print $DBI::tfh __FILE__ . " version " . $DBI::PurePerl::VERSION . "\n"
209             if $DBI::dbi_debug & 0xF;
210 96         1189 untie $DBI::err;
211 96         310 untie $DBI::errstr;
212 96         241 untie $DBI::state;
213 96         235 untie $DBI::rows;
214             #tie $DBI::lasth, 'DBI::var', '!lasth'; # special case: return boolean
215             }
216              
217             sub _install_method {
218 8928     8928   18742 my ( $caller, $method, $from, $param_hash ) = @_;
219 8928 100       16564 initial_setup() unless $initial_setup;
220              
221 8928         58039 my ($class, $method_name) = $method =~ /^[^:]+::(.+)::(.+)$/;
222 8928   100     29564 my $bitmask = $param_hash->{'O'} || 0;
223 8928         11906 my @pre_call_frag;
224              
225 8928 100       16320 return if $method_name eq 'can';
226              
227 8832 100       14036 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     17448 } if $method_name eq 'FETCH' && !exists $ENV{DBI_TRACE}; # XXX ?
245              
246 8832 50       14946 push @pre_call_frag, "return;"
247             if IMA_STUB & $bitmask;
248              
249 8832 100       14254 push @pre_call_frag, q{
250             $method_name = pop @_;
251             } if IMA_FUNC_REDIRECT & $bitmask;
252              
253 8832 100       13841 push @pre_call_frag, q{
254             my $parent_dbh = $h->{Database};
255             } if (IMA_COPY_UP_STMT|IMA_EXECUTE) & $bitmask;
256              
257 8832 100       13510 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       13298 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       13235 push @pre_call_frag, q{
268             %{ $h->{CachedKids} } = () if $h->{CachedKids};
269             } if IMA_CLEAR_CACHED_KIDS & $bitmask;
270              
271 8832 100       15165 if (IMA_KEEP_ERR & $bitmask) {
272 2616         4615 push @pre_call_frag, q{
273             my $keep_error = DBI::_err_hash($h);
274             };
275             }
276             else {
277 6216 50       10661 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         13051 push @pre_call_frag, qq{
281             my \$keep_error $ke_init;
282             };
283 6216         7731 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       11690 if exists $ENV{DBI_TRACE};
295 6216 50       16427 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         12255 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       15252 } 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       18021 } unless exists $DBI::last_method_except{$method_name};
316              
317             # --- post method call code fragments ---
318 8832         10443 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       13885 } if exists $ENV{DBI_TRACE}; # note use of exists
331              
332 8832 100       13980 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       13475 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         11239 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       49356 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   714 no strict qw(refs);
  96         186  
  96         158841  
457 8832         5379360 my $code_ref = eval qq{#line 1 "DBI::PurePerl $method"\n$method_code};
458 8832 50       142577 warn "$@\n$method_code\n" if $@;
459 8832 50       15865 die "$@\n$method_code\n" if $@;
460 8832         42324 *$method = $code_ref;
461 8832         57097 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   7252 my ($class, $parent, $attr, $imp_data, $imp_class) = @_;
470              
471 3026 100 100     6787 DBI->trace_msg(" New $class (for $imp_class, parent=$parent, id=".($imp_data||'').")\n")
472             if $DBI::dbi_debug >= 3;
473              
474 3026 50       7896 $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         4560 my (%outer, $i, $h);
480 3026         12062 $i = tie %outer, $class, $attr; # ref to inner hash (for driver)
481 3026         5411 $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         7338 DBI::_setup_handle($h, $imp_class, $parent, $imp_data);
485 3026 100       7102 return $h unless wantarray;
486 2370         8877 return ($h, $i);
487             }
488              
489             sub _setup_handle {
490 3026     3026   5800 my($h, $imp_class, $parent, $imp_data) = @_;
491 3026   33     7435 my $h_inner = tied(%$h) || $h;
492 3026 100       6899 if (($DBI::dbi_debug & 0xF) >= 4) {
493 3         9 local $^W;
494 3         31 print $DBI::tfh " _setup_handle(@_)\n";
495             }
496 3026         5303 $h_inner->{"imp_data"} = $imp_data;
497 3026         4472 $h_inner->{"ImplementorClass"} = $imp_class;
498 3026         5905 $h_inner->{"Kids"} = $h_inner->{"ActiveKids"} = 0; # XXX not maintained
499 3026 100       5950 if ($parent) {
500 2920         6116 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     110914 if exists $parent->{$_} && !exists $h_inner->{$_};
507             }
508 2920 100       14111 if (ref($parent) =~ /::db$/) { # is sth
    50          
509 2018         3874 $h_inner->{Database} = $parent;
510 2018         3124 $parent->{Statement} = $h_inner->{Statement};
511 2018         4137 $h_inner->{NUM_OF_PARAMS} = 0;
512 2018         3903 $h_inner->{Active} = 0; # driver sets true when there's data to fetch
513             }
514             elsif (ref($parent) =~ /::dr$/){ # is dbh
515 902         2285 $h_inner->{Driver} = $parent;
516 902         1718 $h_inner->{Active} = 0;
517             }
518             else {
519 0         0 warn "panic: ".ref($parent); # should never happen
520             }
521 2920         4823 $h_inner->{dbi_pp_parent} = $parent;
522              
523             # add to the parent's ChildHandles
524 2920 50       5567 if ($HAS_WEAKEN) {
525 2920   100     7478 my $handles = $parent->{ChildHandles} ||= [];
526 2920         5265 push @$handles, $h;
527 2920         9716 Scalar::Util::weaken($handles->[-1]);
528             # purge destroyed handles occasionally
529 2920 100       7681 if (@$handles % 120 == 0) {
530 10         34 @$handles = grep { defined } @$handles;
  1200         1687  
531 10         43 Scalar::Util::weaken($_) for @$handles; # re-weaken after grep
532             }
533             }
534             }
535             else { # setting up a driver handle
536 106         217 $h_inner->{Warn} = 1;
537 106         225 $h_inner->{PrintWarn} = 1;
538 106         209 $h_inner->{AutoCommit} = 1;
539 106         202 $h_inner->{TraceLevel} = 0;
540 106         359 $h_inner->{CompatMode} = (1==0);
541 106   50     329 $h_inner->{FetchHashKeyName} ||= 'NAME';
542 106   50     579 $h_inner->{LongReadLen} ||= 80;
543 106 50 50     758 $h_inner->{ChildHandles} ||= [] if $HAS_WEAKEN;
544 106   50     538 $h_inner->{Type} ||= 'dr';
545 106         234 $h_inner->{Active} = 1;
546             }
547 3026         5204 $h_inner->{"dbi_pp_call_depth"} = 0;
548 3026         7649 $h_inner->{"dbi_pp_pid"} = $$;
549 3026         5801 $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 11258 my ($h, $level, $file) = @_;
558 18 50 66     100 $level = $h->parse_trace_flags($level)
559             if defined $level and !DBI::looks_like_number($level);
560 18         41 my $old_level = $DBI::dbi_debug;
561 18 100       56 _set_trace_file($file) if $level;
562 18 100       41 if (defined $level) {
563 16         29 $DBI::dbi_debug = $level;
564 16 100       266 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       73 _set_trace_file($file) if !$level;
569 18         52 return $old_level;
570             }
571              
572             sub _set_trace_file {
573 38     38   79 my ($file) = @_;
574             #
575             # DAA add support for filehandle inputs
576             #
577             # DAA required to avoid closing a prior fh trace()
578 38 100       131 $DBI::tfh = undef unless $DBI::tfh_needs_close;
579              
580 38 100       97 if (ref $file eq 'GLOB') {
581 8         14 $DBI::tfh = $file;
582 8         67 select((select($DBI::tfh), $| = 1)[0]);
583 8         40 $DBI::tfh_needs_close = 0;
584 8         12 return 1;
585             }
586 30 100 100     130 if ($file && ref \$file eq 'GLOB') {
587 4         5 $DBI::tfh = *{$file}{IO};
  4         31  
588 4         48 select((select($DBI::tfh), $| = 1)[0]);
589 4         10 $DBI::tfh_needs_close = 0;
590 4         10 return 1;
591             }
592 26         45 $DBI::tfh_needs_close = 1;
593 26 100 100     121 if (!$file || $file eq 'STDERR') {
    100          
594 12 50       288 open $DBI::tfh, ">&STDERR" or carp "Can't dup STDERR: $!";
595             }
596             elsif ($file eq 'STDOUT') {
597 8 50       125 open $DBI::tfh, ">&STDOUT" or carp "Can't dup STDOUT: $!";
598             }
599             else {
600 6 50       335 open $DBI::tfh, ">>$file" or carp "Can't open $file: $!";
601             }
602 26         167 select((select($DBI::tfh), $| = 1)[0]);
603 26         61 return 1;
604             }
605 2     2   1041 sub _get_imp_data { shift->{"imp_data"}; }
606       0     sub _svdump { }
607             sub dump_handle {
608 4     4 0 169 my ($h,$msg,$level) = @_;
609 4   33     14 $msg||="dump_handle $h";
610 4         34 print $DBI::tfh "$msg:\n";
611 4         72 for my $attrib (sort keys %$h) {
612 136         302 print $DBI::tfh "\t$attrib => ".DBI::neat($h->{$attrib})."\n";
613             }
614             }
615              
616             sub _handles {
617 14     14   20 my $h = shift;
618 14         21 my $h_inner = tied %$h;
619 14 50       29 if ($h_inner) { # this is okay
620 14 50       25 return $h unless wantarray;
621 14         45 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 37481 my ($key, $type) = @_;
633 8         12 my ($hash);
634 8 100       25 if (!$type) {
    50          
635 6         8 $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         23 for my $char (unpack ("c*", $key)) {
640 24         29 $hash = $hash * 33 + $char;
641             }
642 6         11 $hash &= 0x7FFFFFFF; # limit to 31 bits
643 6         10 $hash |= 0x40000000; # set bit 31
644 6         25 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         17 require Math::BigInt; # feel free to reimplement w/o BigInt!
649 2   50     13 (my $version = $Math::BigInt::VERSION || 0) =~ s/_.*//; # eg "1.70_01"
650 2 50       14 if ($version >= 1.56) {
651 2         10 $hash = Math::BigInt->new(0x811c9dc5);
652 2         35120 for my $uchar (unpack ("C*", $key)) {
653             # multiply by the 32 bit FNV magic prime mod 2^64
654 10         2582 $hash = ($hash * 0x01000193) & 0xffffffff;
655             # xor the bottom with the current octet
656 10         6337 $hash ^= $uchar;
657             }
658             # cast to int
659 2         662 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 57299 my @new = ();
670 4886         5905 for my $thing(@_) {
671 4898 100 100     10758 if (!defined $thing or $thing eq '') {
672 8         21 push @new, undef;
673             }
674             else {
675 4890 100       14887 push @new, ($thing =~ /^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/) ? 1 : 0;
676             }
677             }
678 4886 100       12379 return (@_ >1) ? @new : $new[0];
679             }
680              
681             sub neat {
682 5595     5595 1 15535 my $v = shift;
683 5595 100       10022 return "undef" unless defined $v;
684 1213         1508 my $quote = q{"};
685 1213 50       2412 if (not utf8::is_utf8($v)) {
686 1213 100       4402 return $v if (($v & ~ $v) eq "0"); # is SvNIOK
687 616         888 $quote = q{'};
688             }
689 616   66     1426 my $maxlen = shift || $DBI::neat_maxlen;
690 616 100 66     1814 if ($maxlen && $maxlen < length($v) + 2) {
691 4         16 $v = substr($v,0,$maxlen-5);
692 4         13 $v .= '...';
693             }
694 616         1230 $v =~ s/[^[:print:]]/./g;
695 616         2349 return "$quote$v$quote";
696             }
697              
698             sub sql_type_cast {
699 28     28 1 17673 my (undef, $sql_type, $flags) = @_;
700              
701 28 100       72 return -1 unless defined $_[0];
702              
703 26         36 my $cast_ok = 1;
704              
705 26 100 33     38 my $evalret = eval {
706 96     96   778 use warnings FATAL => qw(numeric);
  96         175  
  96         35937  
707 26 100       64 if ($sql_type == SQL_INTEGER) {
    100          
    100          
708 16         75 my $dummy = $_[0] + 0;
709 12         29 return 1;
710             }
711             elsif ($sql_type == SQL_DOUBLE) {
712 4         39 my $dummy = $_[0] + 0.0;
713 0         0 return 1;
714             }
715             elsif ($sql_type == SQL_NUMERIC) {
716 4         42 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     119 return $evalret if defined($evalret) && ($evalret == -2);
725 24 100       45 $cast_ok = 0 unless $evalret;
726              
727             # DBIstcf_DISCARD_STRING not supported for PurePerl currently
728              
729 24 100       56 return 2 if $cast_ok;
730 12 100       34 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   8946 sub DBI::st::TIEHASH { bless $_[1] => $_[0] };
739              
740             sub _concat_hash_sorted {
741 228     228   32688 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       595 return undef unless defined $hash_ref;
745 213 100       690 die "hash is not a hash reference" unless ref $hash_ref eq 'HASH';
746 211         446 my $keys = _get_sorted_hash_keys($hash_ref, $num_sort);
747 211         386 my $string = '';
748 211         429 for my $key (@$keys) {
749 5632 100       9040 $string .= $pair_separator if length $string > 0;
750 5632         6745 my $value = $hash_ref->{$key};
751 5632 100       7160 if ($use_neat) {
752 4412         5399 $value = DBI::neat($value, 0);
753             }
754             else {
755 1220 100       2083 $value = (defined $value) ? "'$value'" : 'undef';
756             }
757 5632         11240 $string .= $key . $kv_separator . $value;
758             }
759 211         3232 return $string;
760             }
761              
762             sub _get_sorted_hash_keys {
763 211     211   396 my ($hash_ref, $num_sort) = @_;
764 211 100       451 if (not defined $num_sort) {
765 50         61 my $sort_guess = 1;
766             $sort_guess = (not looks_like_number($_)) ? 0 : $sort_guess
767 50 100       514 for keys %$hash_ref;
768 50         185 $num_sort = $sort_guess;
769             }
770              
771 211         1019 my @keys = keys %$hash_ref;
772 96     96   627 no warnings 'numeric';
  96         244  
  96         202096  
773             my @sorted = ($num_sort)
774 211 50       1225 ? sort { $a <=> $b or $a cmp $b } @keys
  36270 100       45752  
775             : sort @keys;
776 211         681 return \@sorted;
777             }
778              
779             sub _err_hash {
780 73176 100   73176   3781750 return 1 unless defined $_[0]->{err};
781 879         2748 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   2726 my ($h, $level, $file) = @_;
807 160 100 100     498 $level = $h->parse_trace_flags($level)
808             if defined $level and !DBI::looks_like_number($level);
809 160         416 my $old_level = $DBI::dbi_debug;
810 160 100       299 DBI::_set_trace_file($file) if defined $file;
811 160 100       272 if (defined $level) {
812 116         164 $DBI::dbi_debug = $level;
813 116 100       190 if ($DBI::dbi_debug) {
814 78         2248 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       1002 unless exists $ENV{DBI_TRACE};
819             }
820             }
821 160         532 return $old_level;
822             }
823             *debug = \&trace; *debug = \&trace; # twice to avoid typo warning
824              
825             sub FETCH {
826 4397     4397   14678 my($h,$key)= @_;
827 4397         7081 my $v = $h->{$key};
828             #warn ((exists $h->{$key}) ? "$key=$v\n" : "$key NONEXISTANT\n");
829 4397 100       9761 return $v if defined $v;
830 3756 100       7957 if ($key =~ /^NAME_.c$/) {
831 109         314 my $cols = $h->FETCH('NAME');
832 109 100       1120 return undef unless $cols;
833 105         187 my @lcols = map { lc $_ } @$cols;
  281         706  
834 105         322 $h->{NAME_lc} = \@lcols;
835 105         210 my @ucols = map { uc $_ } @$cols;
  281         568  
836 105         251 $h->{NAME_uc} = \@ucols;
837 105         264 return $h->FETCH($key);
838             }
839 3647 100       6851 if ($key =~ /^NAME.*_hash$/) {
840 60         130 my $i=0;
841 60 100       125 for my $c(@{$h->FETCH('NAME')||[]}) {
  60         269  
842 124         932 $h->{'NAME_hash'}->{$c} = $i;
843 124         370 $h->{'NAME_lc_hash'}->{"\L$c"} = $i;
844 124         339 $h->{'NAME_uc_hash'}->{"\U$c"} = $i;
845 124         213 $i++;
846             }
847 60         293 return $h->{$key};
848             }
849 3587 50 33     12473 if (!defined $v && !exists $h->{$key}) {
850 3587 100 33     6308 return ($h->FETCH('TaintIn') && $h->FETCH('TaintOut')) if $key eq'Taint';
851 3579 100       9184 return (1==0) if $is_flag_attribute{$key}; # return perl-style sv_no, not undef
852 2407 100       4447 return $DBI::dbi_debug if $key eq 'TraceLevel';
853 2309 100 66     6272 return [] if $key eq 'ChildHandles' && $HAS_WEAKEN;
854 2267 100       3785 if ($key eq 'Type') {
855 50 50       212 return "dr" if $h->isa('DBI::dr');
856 50 100       172 return "db" if $h->isa('DBI::db');
857 44 50       192 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     6310 if (!$is_valid_attribute{$key} and $key =~ m/^[A-Z]/) {
861 2         8 local $^W; # hide undef warnings
862 2         5 Carp::carp( sprintf "Can't get %s->{%s}: unrecognised attribute (@{[ %$h ]})",$h,$key )
  2         250  
863             }
864             }
865 2217         6067 return $v;
866             }
867             sub STORE {
868 13516     13516   30333 my ($h,$key,$value) = @_;
869 13516 100 100     60715 if ($key eq 'AutoCommit') {
    100 100        
    100          
    100          
    100          
870 568 50 66     2636 Carp::croak("DBD driver has not implemented the AutoCommit attribute")
871             unless $value == -900 || $value == -901;
872 568         1808 $value = ($value == -901);
873             }
874             elsif ($key =~ /^Taint/ ) {
875 24 50       51 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         338 $h->trace($value);
880 94         838 return 1;
881             }
882             elsif ($key eq 'NUM_OF_FIELDS') {
883 2110         4591 $h->{$key} = $value;
884 2110 100       3962 if ($value) {
885 1624         3072 my $fbav = DBD::_::st::dbih_setup_fbav($h);
886 1624 100       4089 @$fbav = (undef) x $value if @$fbav != $value;
887             }
888 2110         5529 return 1;
889             }
890             elsif (!$is_valid_attribute{$key} && $key =~ /^[A-Z]/ && !exists $h->{$key}) {
891 2         397 Carp::carp(sprintf "Can't set %s->{%s}: unrecognised attribute or invalid value %s",
892             $h,$key,$value);
893             }
894 11312 100       29413 $h->{$key} = $is_flag_attribute{$key} ? !!$value : $value;
895 11312 100       19636 Scalar::Util::weaken($h->{$key}) if $key eq 'CachedKids';
896 11312         26134 return 1;
897             }
898             sub DELETE {
899 4     4   72 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   1176 sub err { return shift->{err} }
904 70     70   1433 sub errstr { return shift->{errstr} }
905 10     10   218 sub state { return shift->{state} }
906             sub set_err {
907 1149     1149   74266 my ($h, $errnum,$msg,$state, $method, $rv) = @_;
908 1149   33     4064 $h = tied(%$h) || $h;
909              
910 1149 100       2795 if (my $hss = $h->{HandleSetErr}) {
911 38 100       124 return if $hss->($h, $errnum, $msg, $state, $method);
912             }
913              
914 1147 100       4067 if (!defined $errnum) {
915 800         1577 $h->{err} = $DBI::err = undef;
916 800         1324 $h->{errstr} = $DBI::errstr = undef;
917 800         1515 $h->{state} = $DBI::state = '';
918 800         2243 return;
919             }
920              
921 347 100       864 if ($h->{errstr}) {
922             $h->{errstr} .= sprintf " [err was %s now %s]", $h->{err}, $errnum
923 27 100 100     213 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     191 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         63 $DBI::errstr = $h->{errstr};
928             }
929             else {
930 320         655 $h->{errstr} = $DBI::errstr = $msg;
931             }
932              
933             # assign if higher priority: err > "0" > "" > undef
934 347         478 my $err_changed;
935 347 100 100     1143 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         858 $h->{err} = $DBI::err = $errnum;
941 338 100       884 ++$h->{ErrCount} if $errnum;
942 338         577 ++$err_changed;
943             }
944              
945 347 100       694 if ($err_changed) {
946 338 100 100     1316 $state ||= "S1000" if $DBI::err;
947 338 100       1118 $h->{state} = $DBI::state = ($state eq "00000") ? "" : $state
    100          
948             if $state;
949             }
950              
951 347 100       878 if (my $p = $h->{Database}) { # just sth->dbh, not dbh->drh (see ::db::DESTROY)
952 201         350 $p->{err} = $DBI::err;
953 201         324 $p->{errstr} = $DBI::errstr;
954 201         349 $p->{state} = $DBI::state;
955             }
956              
957 347         551 $h->{'dbi_pp_last_method'} = $method;
958 347         1009 return $rv; # usually undef
959             }
960             sub trace_msg {
961 4433     4433   29234 my ($h, $msg, $minlevel)=@_;
962 4433 100       9429 $minlevel = 1 unless defined $minlevel;
963 4433 100       13302 return unless $minlevel <= ($DBI::dbi_debug & 0xF);
964 73         1747 print $DBI::tfh $msg;
965 73         242 return 1;
966             }
967             sub private_data {
968 0     0   0 warn "private_data @_";
969             }
970             sub take_imp_data {
971 1     1   2031 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         539 require Storable;
979             croak("Can't take_imp_data from handle that's not Active")
980 1 50       2621 unless $dbh->{Active};
981 1 50       3 for my $sth (@{ $dbh->{ChildHandles} || [] }) {
  1         6  
982 3 100       7 next unless $sth;
983 2 100       17 $sth->finish if $sth->{Active};
984 2         44 bless $sth, 'DBI::zombie';
985             }
986 1         42 delete $dbh->{$_} for (keys %is_valid_attribute);
987 1         10 delete $dbh->{$_} for grep { m/^dbi_/ } keys %$dbh;
  11         64  
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         83 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   92 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   1972 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       13 my $row = $h->fetch or return;
1032 4         81 return @$row;
1033             }
1034             *fetchrow = \&fetchrow_array; *fetchrow = \&fetchrow_array;
1035              
1036             sub fetchrow_hashref {
1037 26     26   5473 my $h = shift;
1038 26 100       71 my $row = $h->fetch or return;
1039 24         505 my $FetchCase = shift;
1040 24   50     102 my $FetchHashKeyName = $FetchCase || $h->{'FetchHashKeyName'} || 'NAME';
1041 24         64 my $FetchHashKeys = $h->FETCH($FetchHashKeyName);
1042 24         252 my %rowhash;
1043 24         122 @rowhash{ @$FetchHashKeys } = @$row;
1044 22         66 return \%rowhash;
1045             }
1046             sub dbih_setup_fbav {
1047 1831     1831   2569 my $h = shift;
1048 1831   66     4374 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   8046 my $h = shift;
1058 147   66     710 my $av = $h->{'_fbav'} ||= dbih_setup_fbav($h);
1059 147         289 $DBI::rows = ++$h->{'_rows'};
1060 147         326 return $av;
1061             }
1062             sub _set_fbav {
1063 1558     1558   32262 my $h = shift;
1064 1558         1972 my $fbav = $h->{'_fbav'};
1065 1558 100       2271 if ($fbav) {
1066 1417         1868 $DBI::rows = ++$h->{'_rows'};
1067             }
1068             else {
1069 141         560 $fbav = $h->_get_fbav;
1070             }
1071 1558         3113 my $row = shift;
1072 1558 100       2327 if (my $bc = $h->{'_bound_cols'}) {
1073 182         474 for my $i (0..@$row-1) {
1074 474         589 my $bound = $bc->[$i];
1075 474 100       1018 $fbav->[$i] = ($bound) ? ($$bound = $row->[$i]) : $row->[$i];
1076             }
1077             }
1078             else {
1079 1376         2407 @$fbav = @$row;
1080             }
1081 1558         2769 return $fbav;
1082             }
1083             sub bind_col {
1084 162     162   8692 my ($h, $col, $value_ref,$from_bind_columns) = @_;
1085 162   66     464 my $fbav = $h->{'_fbav'} ||= dbih_setup_fbav($h); # from _get_fbav()
1086 162         241 my $num_of_fields = @$fbav;
1087 162 100 100     1419 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       280 return 1 if not defined $value_ref; # ie caller is just trying to set TYPE
1090 154 50       337 DBI::croak("bind_col($col,$value_ref) needs a reference to a scalar")
1091             unless ref $value_ref eq 'SCALAR';
1092 154         372 $h->{'_bound_cols'}->[$col-1] = $value_ref;
1093 154         362 return 1;
1094             }
1095             sub finish {
1096 1221     1221   29939 my $h = shift;
1097 1221         2402 $h->{'_fbav'} = undef;
1098 1221         2233 $h->{'Active'} = 0;
1099 1221         2709 return 1;
1100             }
1101             sub rows {
1102 3     3   62 my $h = shift;
1103 3         6 my $rows = $h->{'_rows'};
1104 3 50       8 return -1 unless defined $rows;
1105 3         15 return $rows;
1106             }
1107              
1108             1;
1109             __END__