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 97     97   642 use strict;
  97         207  
  97         2793  
20 97     97   478 use Carp;
  97         186  
  97         26143  
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 97     97   720 use constant SQL_ALL_TYPES => 0;
  97         206  
  97         9190  
50 97     97   638 use constant SQL_ARRAY => 50;
  97         215  
  97         5234  
51 97     97   2627 use constant SQL_ARRAY_LOCATOR => 51;
  97         293  
  97         5112  
52 97     97   577 use constant SQL_BIGINT => (-5);
  97         215  
  97         4700  
53 97     97   546 use constant SQL_BINARY => (-2);
  97         189  
  97         4751  
54 97     97   571 use constant SQL_BIT => (-7);
  97         172  
  97         4887  
55 97     97   554 use constant SQL_BLOB => 30;
  97         165  
  97         4386  
56 97     97   559 use constant SQL_BLOB_LOCATOR => 31;
  97         182  
  97         4361  
57 97     97   541 use constant SQL_BOOLEAN => 16;
  97         186  
  97         4328  
58 97     97   537 use constant SQL_CHAR => 1;
  97         186  
  97         4509  
59 97     97   553 use constant SQL_CLOB => 40;
  97         175  
  97         5200  
60 97     97   564 use constant SQL_CLOB_LOCATOR => 41;
  97         170  
  97         4442  
61 97     97   557 use constant SQL_DATE => 9;
  97         177  
  97         4417  
62 97     97   596 use constant SQL_DATETIME => 9;
  97         186  
  97         4734  
63 97     97   586 use constant SQL_DECIMAL => 3;
  97         175  
  97         4283  
64 97     97   536 use constant SQL_DOUBLE => 8;
  97         165  
  97         4172  
65 97     97   534 use constant SQL_FLOAT => 6;
  97         166  
  97         4441  
66 97     97   532 use constant SQL_GUID => (-11);
  97         181  
  97         4216  
67 97     97   590 use constant SQL_INTEGER => 4;
  97         184  
  97         4373  
68 97     97   565 use constant SQL_INTERVAL => 10;
  97         167  
  97         4305  
69 97     97   533 use constant SQL_INTERVAL_DAY => 103;
  97         224  
  97         4531  
70 97     97   560 use constant SQL_INTERVAL_DAY_TO_HOUR => 108;
  97         187  
  97         4279  
71 97     97   571 use constant SQL_INTERVAL_DAY_TO_MINUTE => 109;
  97         179  
  97         4400  
72 97     97   583 use constant SQL_INTERVAL_DAY_TO_SECOND => 110;
  97         208  
  97         4322  
73 97     97   543 use constant SQL_INTERVAL_HOUR => 104;
  97         192  
  97         4587  
74 97     97   564 use constant SQL_INTERVAL_HOUR_TO_MINUTE => 111;
  97         164  
  97         4354  
75 97     97   539 use constant SQL_INTERVAL_HOUR_TO_SECOND => 112;
  97         200  
  97         4386  
76 97     97   622 use constant SQL_INTERVAL_MINUTE => 105;
  97         200  
  97         4358  
77 97     97   625 use constant SQL_INTERVAL_MINUTE_TO_SECOND => 113;
  97         202  
  97         4258  
78 97     97   540 use constant SQL_INTERVAL_MONTH => 102;
  97         217  
  97         5114  
79 97     97   535 use constant SQL_INTERVAL_SECOND => 106;
  97         172  
  97         4567  
80 97     97   564 use constant SQL_INTERVAL_YEAR => 101;
  97         197  
  97         4756  
81 97     97   562 use constant SQL_INTERVAL_YEAR_TO_MONTH => 107;
  97         186  
  97         4662  
82 97     97   546 use constant SQL_LONGVARBINARY => (-4);
  97         189  
  97         4646  
83 97     97   560 use constant SQL_LONGVARCHAR => (-1);
  97         210  
  97         4518  
84 97     97   601 use constant SQL_MULTISET => 55;
  97         188  
  97         4202  
85 97     97   560 use constant SQL_MULTISET_LOCATOR => 56;
  97         178  
  97         4164  
86 97     97   533 use constant SQL_NUMERIC => 2;
  97         236  
  97         4844  
87 97     97   555 use constant SQL_REAL => 7;
  97         214  
  97         4274  
88 97     97   587 use constant SQL_REF => 20;
  97         269  
  97         4475  
89 97     97   564 use constant SQL_ROW => 19;
  97         168  
  97         4372  
90 97     97   540 use constant SQL_SMALLINT => 5;
  97         180  
  97         4253  
91 97     97   546 use constant SQL_TIME => 10;
  97         186  
  97         4396  
92 97     97   551 use constant SQL_TIMESTAMP => 11;
  97         182  
  97         4358  
93 97     97   557 use constant SQL_TINYINT => (-6);
  97         208  
  97         7610  
94 97     97   740 use constant SQL_TYPE_DATE => 91;
  97         189  
  97         4820  
95 97     97   546 use constant SQL_TYPE_TIME => 92;
  97         170  
  97         4260  
96 97     97   604 use constant SQL_TYPE_TIMESTAMP => 93;
  97         208  
  97         4315  
97 97     97   533 use constant SQL_TYPE_TIMESTAMP_WITH_TIMEZONE => 95;
  97         199  
  97         4405  
98 97     97   553 use constant SQL_TYPE_TIME_WITH_TIMEZONE => 94;
  97         169  
  97         4516  
99 97     97   573 use constant SQL_UDT => 17;
  97         199  
  97         4401  
100 97     97   601 use constant SQL_UDT_LOCATOR => 18;
  97         196  
  97         4201  
101 97     97   543 use constant SQL_UNKNOWN_TYPE => 0;
  97         174  
  97         4336  
102 97     97   534 use constant SQL_VARBINARY => (-3);
  97         166  
  97         4469  
103 97     97   582 use constant SQL_VARCHAR => 12;
  97         185  
  97         4389  
104 97     97   611 use constant SQL_WCHAR => (-8);
  97         180  
  97         4557  
105 97     97   555 use constant SQL_WLONGVARCHAR => (-10);
  97         201  
  97         4820  
106 97     97   611 use constant SQL_WVARCHAR => (-9);
  97         177  
  97         4310  
107              
108             # for Cursor types
109 97     97   537 use constant SQL_CURSOR_FORWARD_ONLY => 0;
  97         241  
  97         4405  
110 97     97   553 use constant SQL_CURSOR_KEYSET_DRIVEN => 1;
  97         186  
  97         4418  
111 97     97   563 use constant SQL_CURSOR_DYNAMIC => 2;
  97         199  
  97         4303  
112 97     97   534 use constant SQL_CURSOR_STATIC => 3;
  97         164  
  97         4845  
113 97     97   594 use constant SQL_CURSOR_TYPE_DEFAULT => SQL_CURSOR_FORWARD_ONLY;
  97         163  
  97         4232  
114              
115 97     97   546 use constant IMA_HAS_USAGE => 0x0001; #/* check parameter usage */
  97         255  
  97         4306  
116 97     97   555 use constant IMA_FUNC_REDIRECT => 0x0002; #/* is $h->func(..., "method")*/
  97         177  
  97         4350  
117 97     97   528 use constant IMA_KEEP_ERR => 0x0004; #/* don't reset err & errstr */
  97         184  
  97         4357  
118 97     97   558 use constant IMA_KEEP_ERR_SUB => 0x0008; #/* '' if in nested call */
  97         193  
  97         4323  
119 97     97   552 use constant IMA_NO_TAINT_IN => 0x0010; #/* don't check for tainted args*/
  97         168  
  97         4135  
120 97     97   537 use constant IMA_NO_TAINT_OUT => 0x0020; #/* don't taint results */
  97         189  
  97         4641  
121 97     97   584 use constant IMA_COPY_UP_STMT => 0x0040; #/* copy sth Statement to dbh */
  97         177  
  97         4393  
122 97     97   583 use constant IMA_END_WORK => 0x0080; #/* set on commit & rollback */
  97         217  
  97         4200  
123 97     97   562 use constant IMA_STUB => 0x0100; #/* do nothing eg $dbh->connected */
  97         183  
  97         4335  
124 97     97   566 use constant IMA_CLEAR_STMT => 0x0200; #/* clear Statement before call */
  97         171  
  97         4289  
125 97     97   553 use constant IMA_UNRELATED_TO_STMT=> 0x0400; #/* profile as empty Statement */
  97         186  
  97         4889  
126 97     97   562 use constant IMA_NOT_FOUND_OKAY => 0x0800; #/* not error if not found */
  97         174  
  97         5336  
127 97     97   590 use constant IMA_EXECUTE => 0x1000; #/* do/execute: DBIcf_Executed */
  97         171  
  97         4505  
128 97     97   578 use constant IMA_SHOW_ERR_STMT => 0x2000; #/* dbh meth relates to Statement*/
  97         173  
  97         4324  
129 97     97   571 use constant IMA_HIDE_ERR_PARAMVALUES => 0x4000; #/* ParamValues are not relevant */
  97         194  
  97         4557  
130 97     97   547 use constant IMA_IS_FACTORY => 0x8000; #/* new h ie connect & prepare */
  97         195  
  97         4493  
131 97     97   561 use constant IMA_CLEAR_CACHED_KIDS => 0x10000; #/* clear CachedKids before call */
  97         186  
  97         4594  
132              
133 97     97   561 use constant DBIstcf_STRICT => 0x0001;
  97         184  
  97         4365  
134 97     97   574 use constant DBIstcf_DISCARD_STRING => 0x0002;
  97         192  
  97         78113  
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 97     97 0 228 $initial_setup = 1;
208 97 50       371 print $DBI::tfh __FILE__ . " version " . $DBI::PurePerl::VERSION . "\n"
209             if $DBI::dbi_debug & 0xF;
210 97         1347 untie $DBI::err;
211 97         362 untie $DBI::errstr;
212 97         309 untie $DBI::state;
213 97         259 untie $DBI::rows;
214             #tie $DBI::lasth, 'DBI::var', '!lasth'; # special case: return boolean
215             }
216              
217             sub _install_method {
218 9024     9024   19390 my ( $caller, $method, $from, $param_hash ) = @_;
219 9024 100       16846 initial_setup() unless $initial_setup;
220              
221 9024         60686 my ($class, $method_name) = $method =~ /^[^:]+::(.+)::(.+)$/;
222 9024   100     30817 my $bitmask = $param_hash->{'O'} || 0;
223 9024         12040 my @pre_call_frag;
224              
225 9024 100       17456 return if $method_name eq 'can';
226              
227 8927 100       14684 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 8927 100 100     18413 } if $method_name eq 'FETCH' && !exists $ENV{DBI_TRACE}; # XXX ?
245              
246 8927 50       16385 push @pre_call_frag, "return;"
247             if IMA_STUB & $bitmask;
248              
249 8927 100       14662 push @pre_call_frag, q{
250             $method_name = pop @_;
251             } if IMA_FUNC_REDIRECT & $bitmask;
252              
253 8927 100       14464 push @pre_call_frag, q{
254             my $parent_dbh = $h->{Database};
255             } if (IMA_COPY_UP_STMT|IMA_EXECUTE) & $bitmask;
256              
257 8927 100       14090 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 8927 100       14682 push @pre_call_frag, q{
263             $h->{Executed} = 1;
264             $parent_dbh->{Executed} = 1 if $parent_dbh;
265             } if IMA_EXECUTE & $bitmask;
266              
267 8927 100       14077 push @pre_call_frag, q{
268             %{ $h->{CachedKids} } = () if $h->{CachedKids};
269             } if IMA_CLEAR_CACHED_KIDS & $bitmask;
270              
271 8927 100       15972 if (IMA_KEEP_ERR & $bitmask) {
272 2642         4657 push @pre_call_frag, q{
273             my $keep_error = DBI::_err_hash($h);
274             };
275             }
276             else {
277 6285 50       10632 my $ke_init = (IMA_KEEP_ERR_SUB & $bitmask)
278             ? q{= ($h->{dbi_pp_parent}->{dbi_pp_call_depth} && DBI::_err_hash($h)) }
279             : "";
280 6285         13490 push @pre_call_frag, qq{
281             my \$keep_error $ke_init;
282             };
283 6285         7963 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 6285 100       12494 if exists $ENV{DBI_TRACE};
295 6285 50       16377 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 8927         12370 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 8927 100       16251 } 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 8927 100       18630 } unless exists $DBI::last_method_except{$method_name};
316              
317             # --- post method call code fragments ---
318 8927         10537 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 8927 100       14496 } if exists $ENV{DBI_TRACE}; # note use of exists
331              
332 8927 100       14673 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 8927 100       13641 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 8927         11408 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 8927 100       52920 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 97     97   746 no strict qw(refs);
  97         193  
  97         188588  
457 8927         6248318 my $code_ref = eval qq{#line 1 "DBI::PurePerl $method"\n$method_code};
458 8927 50       156524 warn "$@\n$method_code\n" if $@;
459 8927 50       16080 die "$@\n$method_code\n" if $@;
460 8927         44148 *$method = $code_ref;
461 8927         61547 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 3037     3037   9787 my ($class, $parent, $attr, $imp_data, $imp_class) = @_;
470              
471 3037 100 100     12318 DBI->trace_msg(" New $class (for $imp_class, parent=$parent, id=".($imp_data||'').")\n")
472             if $DBI::dbi_debug >= 3;
473              
474 3037 50       10506 $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 3037         5544 my (%outer, $i, $h);
480 3037         15114 $i = tie %outer, $class, $attr; # ref to inner hash (for driver)
481 3037         6556 $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 3037         9486 DBI::_setup_handle($h, $imp_class, $parent, $imp_data);
485 3037 100       8548 return $h unless wantarray;
486 2371         10647 return ($h, $i);
487             }
488              
489             sub _setup_handle {
490 3037     3037   7294 my($h, $imp_class, $parent, $imp_data) = @_;
491 3037   33     9481 my $h_inner = tied(%$h) || $h;
492 3037 100       8253 if (($DBI::dbi_debug & 0xF) >= 4) {
493 3         15 local $^W;
494 3         73 print $DBI::tfh " _setup_handle(@_)\n";
495             }
496 3037         6979 $h_inner->{"imp_data"} = $imp_data;
497 3037         5657 $h_inner->{"ImplementorClass"} = $imp_class;
498 3037         6906 $h_inner->{"Kids"} = $h_inner->{"ActiveKids"} = 0; # XXX not maintained
499 3037 100       7403 if ($parent) {
500 2930         8209 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 41020 100 66     137566 if exists $parent->{$_} && !exists $h_inner->{$_};
507             }
508 2930 100       18611 if (ref($parent) =~ /::db$/) { # is sth
    50          
509 2027         5123 $h_inner->{Database} = $parent;
510 2027         4367 $parent->{Statement} = $h_inner->{Statement};
511 2027         5883 $h_inner->{NUM_OF_PARAMS} = 0;
512 2027         4186 $h_inner->{Active} = 0; # driver sets true when there's data to fetch
513             }
514             elsif (ref($parent) =~ /::dr$/){ # is dbh
515 903         2668 $h_inner->{Driver} = $parent;
516 903         1878 $h_inner->{Active} = 0;
517             }
518             else {
519 0         0 warn "panic: ".ref($parent); # should never happen
520             }
521 2930         5735 $h_inner->{dbi_pp_parent} = $parent;
522              
523             # add to the parent's ChildHandles
524 2930 50       6488 if ($HAS_WEAKEN) {
525 2930   100     10679 my $handles = $parent->{ChildHandles} ||= [];
526 2930         7534 push @$handles, $h;
527 2930         11963 Scalar::Util::weaken($handles->[-1]);
528             # purge destroyed handles occasionally
529 2930 100       9700 if (@$handles % 120 == 0) {
530 10         35 @$handles = grep { defined } @$handles;
  1200         1978  
531 10         56 Scalar::Util::weaken($_) for @$handles; # re-weaken after grep
532             }
533             }
534             }
535             else { # setting up a driver handle
536 107         261 $h_inner->{Warn} = 1;
537 107         278 $h_inner->{PrintWarn} = 1;
538 107         229 $h_inner->{AutoCommit} = 1;
539 107         254 $h_inner->{TraceLevel} = 0;
540 107         422 $h_inner->{CompatMode} = (1==0);
541 107   50     467 $h_inner->{FetchHashKeyName} ||= 'NAME';
542 107   50     1974 $h_inner->{LongReadLen} ||= 80;
543 107 50 50     881 $h_inner->{ChildHandles} ||= [] if $HAS_WEAKEN;
544 107   50     741 $h_inner->{Type} ||= 'dr';
545 107         298 $h_inner->{Active} = 1;
546             }
547 3037         6590 $h_inner->{"dbi_pp_call_depth"} = 0;
548 3037         9301 $h_inner->{"dbi_pp_pid"} = $$;
549 3037         7004 $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 10745 my ($h, $level, $file) = @_;
558 18 50 66     98 $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       69 _set_trace_file($file) if $level;
562 18 100       50 if (defined $level) {
563 16         32 $DBI::dbi_debug = $level;
564 16 100       316 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       78 _set_trace_file($file) if !$level;
569 18         62 return $old_level;
570             }
571              
572             sub _set_trace_file {
573 38     38   76 my ($file) = @_;
574             #
575             # DAA add support for filehandle inputs
576             #
577             # DAA required to avoid closing a prior fh trace()
578 38 100       164 $DBI::tfh = undef unless $DBI::tfh_needs_close;
579              
580 38 100       110 if (ref $file eq 'GLOB') {
581 8         12 $DBI::tfh = $file;
582 8         89 select((select($DBI::tfh), $| = 1)[0]);
583 8         41 $DBI::tfh_needs_close = 0;
584 8         18 return 1;
585             }
586 30 100 100     134 if ($file && ref \$file eq 'GLOB') {
587 4         4 $DBI::tfh = *{$file}{IO};
  4         37  
588 4         50 select((select($DBI::tfh), $| = 1)[0]);
589 4         10 $DBI::tfh_needs_close = 0;
590 4         9 return 1;
591             }
592 26         49 $DBI::tfh_needs_close = 1;
593 26 100 100     123 if (!$file || $file eq 'STDERR') {
    100          
594 12 50       431 open $DBI::tfh, ">&STDERR" or carp "Can't dup STDERR: $!";
595             }
596             elsif ($file eq 'STDOUT') {
597 8 50       200 open $DBI::tfh, ">&STDOUT" or carp "Can't dup STDOUT: $!";
598             }
599             else {
600 6 50       25710 open $DBI::tfh, ">>$file" or carp "Can't open $file: $!";
601             }
602 26         213 select((select($DBI::tfh), $| = 1)[0]);
603 26         67 return 1;
604             }
605 2     2   1293 sub _get_imp_data { shift->{"imp_data"}; }
606       0     sub _svdump { }
607             sub dump_handle {
608 4     4 0 235 my ($h,$msg,$level) = @_;
609 4   33     18 $msg||="dump_handle $h";
610 4         67 print $DBI::tfh "$msg:\n";
611 4         89 for my $attrib (sort keys %$h) {
612 136         601 print $DBI::tfh "\t$attrib => ".DBI::neat($h->{$attrib})."\n";
613             }
614             }
615              
616             sub _handles {
617 14     14   22 my $h = shift;
618 14         27 my $h_inner = tied %$h;
619 14 50       29 if ($h_inner) { # this is okay
620 14 50       24 return $h unless wantarray;
621 14         44 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 43014 my ($key, $type) = @_;
633 8         14 my ($hash);
634 8 100       26 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         21 for my $char (unpack ("c*", $key)) {
640 24         30 $hash = $hash * 33 + $char;
641             }
642 6         9 $hash &= 0x7FFFFFFF; # limit to 31 bits
643 6         10 $hash |= 0x40000000; # set bit 31
644 6         23 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       12 if ($version >= 1.56) {
651 2         13 $hash = Math::BigInt->new(0x811c9dc5);
652 2         38168 for my $uchar (unpack ("C*", $key)) {
653             # multiply by the 32 bit FNV magic prime mod 2^64
654 10         1809 $hash = ($hash * 0x01000193) & 0xffffffff;
655             # xor the bottom with the current octet
656 10         4921 $hash ^= $uchar;
657             }
658             # cast to int
659 2         486 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 56060 my @new = ();
670 4886         5474 for my $thing(@_) {
671 4898 100 100     10597 if (!defined $thing or $thing eq '') {
672 8         17 push @new, undef;
673             }
674             else {
675 4890 100       14554 push @new, ($thing =~ /^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/) ? 1 : 0;
676             }
677             }
678 4886 100       11935 return (@_ >1) ? @new : $new[0];
679             }
680              
681             sub neat {
682 5601     5601 1 17659 my $v = shift;
683 5601 100       10116 return "undef" unless defined $v;
684 1219         2041 my $quote = q{"};
685 1219 50       2981 if (not utf8::is_utf8($v)) {
686 1219 100       6348 return $v if (($v & ~ $v) eq "0"); # is SvNIOK
687 618         935 $quote = q{'};
688             }
689 618   66     1715 my $maxlen = shift || $DBI::neat_maxlen;
690 618 100 66     2195 if ($maxlen && $maxlen < length($v) + 2) {
691 6         29 $v = substr($v,0,$maxlen-5);
692 6         14 $v .= '...';
693             }
694 618         1538 $v =~ s/[^[:print:]]/./g;
695 618         3136 return "$quote$v$quote";
696             }
697              
698             sub sql_type_cast {
699 28     28 1 17594 my (undef, $sql_type, $flags) = @_;
700              
701 28 100       76 return -1 unless defined $_[0];
702              
703 26         33 my $cast_ok = 1;
704              
705 26 100 33     36 my $evalret = eval {
706 97     97   1132 use warnings FATAL => qw(numeric);
  97         193  
  97         47362  
707 26 100       72 if ($sql_type == SQL_INTEGER) {
    100          
    100          
708 16         74 my $dummy = $_[0] + 0;
709 12         28 return 1;
710             }
711             elsif ($sql_type == SQL_DOUBLE) {
712 4         40 my $dummy = $_[0] + 0.0;
713 0         0 return 1;
714             }
715             elsif ($sql_type == SQL_NUMERIC) {
716 4         44 my $dummy = $_[0] + 0.0;
717 0         0 return 1;
718             }
719             else {
720 2         10 return -2;
721             }
722             } or $^W && warn $@; # XXX warnings::warnif("numeric", $@) ?
723              
724 26 100 100     112 return $evalret if defined($evalret) && ($evalret == -2);
725 24 100       43 $cast_ok = 0 unless $evalret;
726              
727             # DBIstcf_DISCARD_STRING not supported for PurePerl currently
728              
729 24 100       58 return 2 if $cast_ok;
730 12 100       37 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 3037     3037   10408 sub DBI::st::TIEHASH { bless $_[1] => $_[0] };
739              
740             sub _concat_hash_sorted {
741 228     228   27092 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       615 return undef unless defined $hash_ref;
745 213 100       614 die "hash is not a hash reference" unless ref $hash_ref eq 'HASH';
746 211         492 my $keys = _get_sorted_hash_keys($hash_ref, $num_sort);
747 211         359 my $string = '';
748 211         450 for my $key (@$keys) {
749 5632 100       8815 $string .= $pair_separator if length $string > 0;
750 5632         6773 my $value = $hash_ref->{$key};
751 5632 100       6644 if ($use_neat) {
752 4412         4877 $value = DBI::neat($value, 0);
753             }
754             else {
755 1220 100       2136 $value = (defined $value) ? "'$value'" : 'undef';
756             }
757 5632         12146 $string .= $key . $kv_separator . $value;
758             }
759 211         4629 return $string;
760             }
761              
762             sub _get_sorted_hash_keys {
763 211     211   420 my ($hash_ref, $num_sort) = @_;
764 211 100       493 if (not defined $num_sort) {
765 50         68 my $sort_guess = 1;
766             $sort_guess = (not looks_like_number($_)) ? 0 : $sort_guess
767 50 100       699 for keys %$hash_ref;
768 50         220 $num_sort = $sort_guess;
769             }
770              
771 211         1103 my @keys = keys %$hash_ref;
772 97     97   779 no warnings 'numeric';
  97         234  
  97         251116  
773             my @sorted = ($num_sort)
774 211 50       1186 ? sort { $a <=> $b or $a cmp $b } @keys
  36368 100       43916  
775             : sort @keys;
776 211         686 return \@sorted;
777             }
778              
779             sub _err_hash {
780 73330 100   73330   4564402 return 1 unless defined $_[0]->{err};
781 879         2919 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   2827 my ($h, $level, $file) = @_;
807 160 100 100     530 $level = $h->parse_trace_flags($level)
808             if defined $level and !DBI::looks_like_number($level);
809 160         461 my $old_level = $DBI::dbi_debug;
810 160 100       349 DBI::_set_trace_file($file) if defined $file;
811 160 100       363 if (defined $level) {
812 116         173 $DBI::dbi_debug = $level;
813 116 100       247 if ($DBI::dbi_debug) {
814 78         2627 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       1190 unless exists $ENV{DBI_TRACE};
819             }
820             }
821 160         614 return $old_level;
822             }
823             *debug = \&trace; *debug = \&trace; # twice to avoid typo warning
824              
825             sub FETCH {
826 4406     4406   15164 my($h,$key)= @_;
827 4406         7421 my $v = $h->{$key};
828             #warn ((exists $h->{$key}) ? "$key=$v\n" : "$key NONEXISTANT\n");
829 4406 100       10368 return $v if defined $v;
830 3756 100       8958 if ($key =~ /^NAME_.c$/) {
831 109         364 my $cols = $h->FETCH('NAME');
832 109 100       1272 return undef unless $cols;
833 105         233 my @lcols = map { lc $_ } @$cols;
  281         745  
834 105         332 $h->{NAME_lc} = \@lcols;
835 105         235 my @ucols = map { uc $_ } @$cols;
  281         630  
836 105         287 $h->{NAME_uc} = \@ucols;
837 105         337 return $h->FETCH($key);
838             }
839 3647 100       7615 if ($key =~ /^NAME.*_hash$/) {
840 60         172 my $i=0;
841 60 100       159 for my $c(@{$h->FETCH('NAME')||[]}) {
  60         405  
842 124         1402 $h->{'NAME_hash'}->{$c} = $i;
843 124         503 $h->{'NAME_lc_hash'}->{"\L$c"} = $i;
844 124         537 $h->{'NAME_uc_hash'}->{"\U$c"} = $i;
845 124         296 $i++;
846             }
847 60         371 return $h->{$key};
848             }
849 3587 50 33     13180 if (!defined $v && !exists $h->{$key}) {
850 3587 100 33     8327 return ($h->FETCH('TaintIn') && $h->FETCH('TaintOut')) if $key eq'Taint';
851 3579 100       10258 return (1==0) if $is_flag_attribute{$key}; # return perl-style sv_no, not undef
852 2407 100       4705 return $DBI::dbi_debug if $key eq 'TraceLevel';
853 2309 100 66     5460 return [] if $key eq 'ChildHandles' && $HAS_WEAKEN;
854 2267 100       4282 if ($key eq 'Type') {
855 50 50       273 return "dr" if $h->isa('DBI::dr');
856 50 100       209 return "db" if $h->isa('DBI::db');
857 44 50       235 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     7146 if (!$is_valid_attribute{$key} and $key =~ m/^[A-Z]/) {
861 2         9 local $^W; # hide undef warnings
862 2         6 Carp::carp( sprintf "Can't get %s->{%s}: unrecognised attribute (@{[ %$h ]})",$h,$key )
  2         262  
863             }
864             }
865 2217         6766 return $v;
866             }
867             sub STORE {
868 13550     13550   34237 my ($h,$key,$value) = @_;
869 13550 100 100     71363 if ($key eq 'AutoCommit') {
    100 100        
    100          
    100          
    100          
870 568 50 66     3340 Carp::croak("DBD driver has not implemented the AutoCommit attribute")
871             unless $value == -900 || $value == -901;
872 568         1317 $value = ($value == -901);
873             }
874             elsif ($key =~ /^Taint/ ) {
875 24 50       44 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         321 $h->trace($value);
880 94         989 return 1;
881             }
882             elsif ($key eq 'NUM_OF_FIELDS') {
883 2119         5508 $h->{$key} = $value;
884 2119 100       4821 if ($value) {
885 1628         4426 my $fbav = DBD::_::st::dbih_setup_fbav($h);
886 1628 100       5816 @$fbav = (undef) x $value if @$fbav != $value;
887             }
888 2119         7211 return 1;
889             }
890             elsif (!$is_valid_attribute{$key} && $key =~ /^[A-Z]/ && !exists $h->{$key}) {
891 2         469 Carp::carp(sprintf "Can't set %s->{%s}: unrecognised attribute or invalid value %s",
892             $h,$key,$value);
893             }
894 11337 100       33581 $h->{$key} = $is_flag_attribute{$key} ? !!$value : $value;
895 11337 100       20728 Scalar::Util::weaken($h->{$key}) if $key eq 'CachedKids';
896 11337         29134 return 1;
897             }
898             sub DELETE {
899 4     4   77 my ($h, $key) = @_;
900 4 100       21 return $h->FETCH($key) unless $key =~ /^private_/;
901 2         8 return delete $h->{$key};
902             }
903 55     55   1033 sub err { return shift->{err} }
904 70     70   1354 sub errstr { return shift->{errstr} }
905 10     10   242 sub state { return shift->{state} }
906             sub set_err {
907 1149     1149   73421 my ($h, $errnum,$msg,$state, $method, $rv) = @_;
908 1149   33     4820 $h = tied(%$h) || $h;
909              
910 1149 100       3249 if (my $hss = $h->{HandleSetErr}) {
911 38 100       82 return if $hss->($h, $errnum, $msg, $state, $method);
912             }
913              
914 1147 100       4203 if (!defined $errnum) {
915 800         1808 $h->{err} = $DBI::err = undef;
916 800         1533 $h->{errstr} = $DBI::errstr = undef;
917 800         1786 $h->{state} = $DBI::state = '';
918 800         2486 return;
919             }
920              
921 347 100       1275 if ($h->{errstr}) {
922             $h->{errstr} .= sprintf " [err was %s now %s]", $h->{err}, $errnum
923 27 100 100     184 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     165 if $h->{state} and $h->{state} ne "S1000" && $state && $h->{state} ne $state;
      100        
      100        
926 27 100       91 $h->{errstr} .= "\n$msg" if $h->{errstr} ne $msg;
927 27         48 $DBI::errstr = $h->{errstr};
928             }
929             else {
930 320         740 $h->{errstr} = $DBI::errstr = $msg;
931             }
932              
933             # assign if higher priority: err > "0" > "" > undef
934 347         543 my $err_changed;
935 347 100 100     1253 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         686 $h->{err} = $DBI::err = $errnum;
941 338 100       786 ++$h->{ErrCount} if $errnum;
942 338         578 ++$err_changed;
943             }
944              
945 347 100       860 if ($err_changed) {
946 338 100 100     1412 $state ||= "S1000" if $DBI::err;
947 338 100       1284 $h->{state} = $DBI::state = ($state eq "00000") ? "" : $state
    100          
948             if $state;
949             }
950              
951 347 100       938 if (my $p = $h->{Database}) { # just sth->dbh, not dbh->drh (see ::db::DESTROY)
952 201         458 $p->{err} = $DBI::err;
953 201         413 $p->{errstr} = $DBI::errstr;
954 201         476 $p->{state} = $DBI::state;
955             }
956              
957 347         569 $h->{'dbi_pp_last_method'} = $method;
958 347         1071 return $rv; # usually undef
959             }
960             sub trace_msg {
961 4434     4434   33942 my ($h, $msg, $minlevel)=@_;
962 4434 100       11136 $minlevel = 1 unless defined $minlevel;
963 4434 100       14628 return unless $minlevel <= ($DBI::dbi_debug & 0xF);
964 73         2246 print $DBI::tfh $msg;
965 73         420 return 1;
966             }
967             sub private_data {
968 0     0   0 warn "private_data @_";
969             }
970             sub take_imp_data {
971 1     1   2443 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         680 require Storable;
979             croak("Can't take_imp_data from handle that's not Active")
980 1 50       2722 unless $dbh->{Active};
981 1 50       2 for my $sth (@{ $dbh->{ChildHandles} || [] }) {
  1         7  
982 3 100       8 next unless $sth;
983 2 100       12 $sth->finish if $sth->{Active};
984 2         29 bless $sth, 'DBI::zombie';
985             }
986 1         29 delete $dbh->{$_} for (keys %is_valid_attribute);
987 1         7 delete $dbh->{$_} for grep { m/^dbi_/ } keys %$dbh;
  11         49  
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         112 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   78 return 0;
1005             }
1006              
1007             package
1008             DBD::_::db;
1009              
1010       653     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   2638 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       15 my $row = $h->fetch or return;
1032 4         124 return @$row;
1033             }
1034             *fetchrow = \&fetchrow_array; *fetchrow = \&fetchrow_array;
1035              
1036             sub fetchrow_hashref {
1037 26     26   7448 my $h = shift;
1038 26 100       82 my $row = $h->fetch or return;
1039 24         499 my $FetchCase = shift;
1040 24   50     109 my $FetchHashKeyName = $FetchCase || $h->{'FetchHashKeyName'} || 'NAME';
1041 24         79 my $FetchHashKeys = $h->FETCH($FetchHashKeyName);
1042 24         265 my %rowhash;
1043 24         128 @rowhash{ @$FetchHashKeys } = @$row;
1044 22         74 return \%rowhash;
1045             }
1046             sub dbih_setup_fbav {
1047 1835     1835   3200 my $h = shift;
1048 1835   66     5916 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   9795 my $h = shift;
1058 147   66     833 my $av = $h->{'_fbav'} ||= dbih_setup_fbav($h);
1059 147         336 $DBI::rows = ++$h->{'_rows'};
1060 147         398 return $av;
1061             }
1062             sub _set_fbav {
1063 1570     1570   41167 my $h = shift;
1064 1570         2275 my $fbav = $h->{'_fbav'};
1065 1570 100       2695 if ($fbav) {
1066 1429         2357 $DBI::rows = ++$h->{'_rows'};
1067             }
1068             else {
1069 141         684 $fbav = $h->_get_fbav;
1070             }
1071 1570         3769 my $row = shift;
1072 1570 100       2771 if (my $bc = $h->{'_bound_cols'}) {
1073 182         553 for my $i (0..@$row-1) {
1074 474         628 my $bound = $bc->[$i];
1075 474 100       1092 $fbav->[$i] = ($bound) ? ($$bound = $row->[$i]) : $row->[$i];
1076             }
1077             }
1078             else {
1079 1388         3085 @$fbav = @$row;
1080             }
1081 1570         3376 return $fbav;
1082             }
1083             sub bind_col {
1084 162     162   10676 my ($h, $col, $value_ref,$from_bind_columns) = @_;
1085 162   66     656 my $fbav = $h->{'_fbav'} ||= dbih_setup_fbav($h); # from _get_fbav()
1086 162         282 my $num_of_fields = @$fbav;
1087 162 100 100     1712 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       371 return 1 if not defined $value_ref; # ie caller is just trying to set TYPE
1090 154 50       430 DBI::croak("bind_col($col,$value_ref) needs a reference to a scalar")
1091             unless ref $value_ref eq 'SCALAR';
1092 154         511 $h->{'_bound_cols'}->[$col-1] = $value_ref;
1093 154         484 return 1;
1094             }
1095             sub finish {
1096 1221     1221   36390 my $h = shift;
1097 1221         2881 $h->{'_fbav'} = undef;
1098 1221         2357 $h->{'Active'} = 0;
1099 1221         3360 return 1;
1100             }
1101             sub rows {
1102 3     3   64 my $h = shift;
1103 3         7 my $rows = $h->{'_rows'};
1104 3 50       16 return -1 unless defined $rows;
1105 3         10 return $rows;
1106             }
1107              
1108             1;
1109             __END__