line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# -*- perl -*- |
2
|
|
|
|
|
|
|
# |
3
|
|
|
|
|
|
|
# DBI::DBD::SqlEngine - A base class for implementing DBI drivers that |
4
|
|
|
|
|
|
|
# have not an own SQL engine |
5
|
|
|
|
|
|
|
# |
6
|
|
|
|
|
|
|
# This module is currently maintained by |
7
|
|
|
|
|
|
|
# |
8
|
|
|
|
|
|
|
# H.Merijn Brand & Jens Rehsack |
9
|
|
|
|
|
|
|
# |
10
|
|
|
|
|
|
|
# The original author is Jochen Wiedmann. |
11
|
|
|
|
|
|
|
# |
12
|
|
|
|
|
|
|
# Copyright (C) 2009-2013 by H.Merijn Brand & Jens Rehsack |
13
|
|
|
|
|
|
|
# Copyright (C) 2004 by Jeff Zucker |
14
|
|
|
|
|
|
|
# Copyright (C) 1998 by Jochen Wiedmann |
15
|
|
|
|
|
|
|
# |
16
|
|
|
|
|
|
|
# All rights reserved. |
17
|
|
|
|
|
|
|
# |
18
|
|
|
|
|
|
|
# You may distribute this module under the terms of either the GNU |
19
|
|
|
|
|
|
|
# General Public License or the Artistic License, as specified in |
20
|
|
|
|
|
|
|
# the Perl README file. |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
require 5.008; |
23
|
|
|
|
|
|
|
|
24
|
54
|
|
|
54
|
|
12305
|
use strict; |
|
54
|
|
|
|
|
116
|
|
|
54
|
|
|
|
|
1405
|
|
25
|
|
|
|
|
|
|
|
26
|
54
|
|
|
54
|
|
245
|
use DBI (); |
|
54
|
|
|
|
|
103
|
|
|
54
|
|
|
|
|
2944
|
|
27
|
|
|
|
|
|
|
require DBI::SQL::Nano; |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
package DBI::DBD::SqlEngine; |
30
|
|
|
|
|
|
|
|
31
|
54
|
|
|
54
|
|
288
|
use strict; |
|
54
|
|
|
|
|
95
|
|
|
54
|
|
|
|
|
1103
|
|
32
|
|
|
|
|
|
|
|
33
|
54
|
|
|
54
|
|
279
|
use Carp; |
|
54
|
|
|
|
|
117
|
|
|
54
|
|
|
|
|
3514
|
|
34
|
54
|
|
|
54
|
|
332
|
use vars qw( @ISA $VERSION $drh %methods_installed); |
|
54
|
|
|
|
|
109
|
|
|
54
|
|
|
|
|
8853
|
|
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
$VERSION = "0.06"; |
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
$drh = undef; # holds driver handle(s) once initialized |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
DBI->setup_driver("DBI::DBD::SqlEngine"); # only needed once but harmless to repeat |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
my %accessors = ( |
43
|
|
|
|
|
|
|
versions => "get_driver_versions", |
44
|
|
|
|
|
|
|
new_meta => "new_sql_engine_meta", |
45
|
|
|
|
|
|
|
get_meta => "get_sql_engine_meta", |
46
|
|
|
|
|
|
|
set_meta => "set_sql_engine_meta", |
47
|
|
|
|
|
|
|
clear_meta => "clear_sql_engine_meta", |
48
|
|
|
|
|
|
|
); |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
sub driver ($;$) |
51
|
|
|
|
|
|
|
{ |
52
|
46
|
|
|
46
|
0
|
159
|
my ( $class, $attr ) = @_; |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
# Drivers typically use a singleton object for the $drh |
55
|
|
|
|
|
|
|
# We use a hash here to have one singleton per subclass. |
56
|
|
|
|
|
|
|
# (Otherwise DBD::CSV and DBD::DBM, for example, would |
57
|
|
|
|
|
|
|
# share the same driver object which would cause problems.) |
58
|
|
|
|
|
|
|
# An alternative would be to not cache the $drh here at all |
59
|
|
|
|
|
|
|
# and require that subclasses do that. Subclasses should do |
60
|
|
|
|
|
|
|
# their own caching, so caching here just provides extra safety. |
61
|
46
|
50
|
|
|
|
211
|
$drh->{$class} and return $drh->{$class}; |
62
|
|
|
|
|
|
|
|
63
|
46
|
|
50
|
|
|
155
|
$attr ||= {}; |
64
|
|
|
|
|
|
|
{ |
65
|
54
|
|
|
54
|
|
387
|
no strict "refs"; |
|
54
|
|
|
|
|
115
|
|
|
54
|
|
|
|
|
19757
|
|
|
46
|
|
|
|
|
94
|
|
66
|
46
|
50
|
|
|
|
224
|
unless ( $attr->{Attribution} ) |
67
|
|
|
|
|
|
|
{ |
68
|
|
|
|
|
|
|
$class eq "DBI::DBD::SqlEngine" |
69
|
0
|
0
|
|
|
|
0
|
and $attr->{Attribution} = "$class by Jens Rehsack"; |
70
|
0
|
|
0
|
|
|
0
|
$attr->{Attribution} ||= ${ $class . "::ATTRIBUTION" } |
|
|
|
0
|
|
|
|
|
71
|
|
|
|
|
|
|
|| "oops the author of $class forgot to define this"; |
72
|
|
|
|
|
|
|
} |
73
|
46
|
|
66
|
|
|
202
|
$attr->{Version} ||= ${ $class . "::VERSION" }; |
|
2
|
|
|
|
|
10
|
|
74
|
46
|
100
|
|
|
|
196
|
$attr->{Name} or ( $attr->{Name} = $class ) =~ s/^DBD\:\://; |
75
|
|
|
|
|
|
|
} |
76
|
|
|
|
|
|
|
|
77
|
46
|
|
|
|
|
319
|
$drh->{$class} = DBI::_new_drh( $class . "::dr", $attr ); |
78
|
46
|
|
|
|
|
1550
|
$drh->{$class}->STORE( ShowErrorStatement => 1 ); |
79
|
|
|
|
|
|
|
|
80
|
46
|
|
|
|
|
551
|
my $prefix = DBI->driver_prefix($class); |
81
|
46
|
50
|
|
|
|
236
|
if ($prefix) |
82
|
|
|
|
|
|
|
{ |
83
|
46
|
|
|
|
|
184
|
my $dbclass = $class . "::db"; |
84
|
46
|
|
|
|
|
331
|
while ( my ( $accessor, $funcname ) = each %accessors ) |
85
|
|
|
|
|
|
|
{ |
86
|
230
|
|
|
|
|
577
|
my $method = $prefix . $accessor; |
87
|
230
|
50
|
|
|
|
2738
|
$dbclass->can($method) and next; |
88
|
230
|
|
|
|
|
1056
|
my $inject = sprintf <<'EOI', $dbclass, $method, $dbclass, $funcname; |
89
|
|
|
|
|
|
|
sub %s::%s |
90
|
|
|
|
|
|
|
{ |
91
|
|
|
|
|
|
|
my $func = %s->can (q{%s}); |
92
|
|
|
|
|
|
|
goto &$func; |
93
|
|
|
|
|
|
|
} |
94
|
|
|
|
|
|
|
EOI |
95
|
230
|
|
|
0
|
|
13732
|
eval $inject; |
|
0
|
|
|
38
|
|
0
|
|
|
0
|
|
|
6
|
|
0
|
|
|
38
|
|
|
8
|
|
9100
|
|
|
38
|
|
|
8
|
|
214
|
|
|
6
|
|
|
4
|
|
1694
|
|
|
6
|
|
|
0
|
|
37
|
|
|
8
|
|
|
0
|
|
5811
|
|
|
8
|
|
|
0
|
|
46
|
|
|
8
|
|
|
8
|
|
277
|
|
|
8
|
|
|
|
|
44
|
|
|
4
|
|
|
|
|
2363
|
|
|
4
|
|
|
|
|
23
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
8
|
|
|
|
|
381
|
|
|
8
|
|
|
|
|
39
|
|
96
|
230
|
|
|
|
|
1460
|
$dbclass->install_method($method); |
97
|
|
|
|
|
|
|
} |
98
|
|
|
|
|
|
|
} |
99
|
|
|
|
|
|
|
else |
100
|
|
|
|
|
|
|
{ |
101
|
0
|
|
|
|
|
0
|
warn "Using DBI::DBD::SqlEngine with unregistered driver $class.\n" |
102
|
|
|
|
|
|
|
. "Reading documentation how to prevent is strongly recommended.\n"; |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
} |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
# XXX inject DBD::XXX::Statement unless exists |
107
|
|
|
|
|
|
|
|
108
|
46
|
|
|
|
|
261
|
my $stclass = $class . "::st"; |
109
|
46
|
100
|
|
|
|
1306
|
$stclass->install_method("sql_get_colnames") unless ( $methods_installed{__PACKAGE__}++ ); |
110
|
|
|
|
|
|
|
|
111
|
46
|
|
|
|
|
582
|
return $drh->{$class}; |
112
|
|
|
|
|
|
|
} # driver |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
sub CLONE |
115
|
|
|
|
|
|
|
{ |
116
|
0
|
|
|
0
|
|
0
|
undef $drh; |
117
|
|
|
|
|
|
|
} # CLONE |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
# ====== DRIVER ================================================================ |
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
package DBI::DBD::SqlEngine::dr; |
122
|
|
|
|
|
|
|
|
123
|
54
|
|
|
54
|
|
441
|
use strict; |
|
54
|
|
|
|
|
127
|
|
|
54
|
|
|
|
|
1330
|
|
124
|
54
|
|
|
54
|
|
278
|
use warnings; |
|
54
|
|
|
|
|
109
|
|
|
54
|
|
|
|
|
2000
|
|
125
|
|
|
|
|
|
|
|
126
|
54
|
|
|
54
|
|
336
|
use vars qw(@ISA $imp_data_size); |
|
54
|
|
|
|
|
1128
|
|
|
54
|
|
|
|
|
2617
|
|
127
|
|
|
|
|
|
|
|
128
|
54
|
|
|
54
|
|
334
|
use Carp qw/carp/; |
|
54
|
|
|
|
|
110
|
|
|
54
|
|
|
|
|
45063
|
|
129
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
$imp_data_size = 0; |
131
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
sub connect ($$;$$$) |
133
|
|
|
|
|
|
|
{ |
134
|
582
|
|
|
582
|
|
1700
|
my ( $drh, $dbname, $user, $auth, $attr ) = @_; |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
# create a 'blank' dbh |
137
|
582
|
|
|
|
|
3383
|
my $dbh = DBI::_new_dbh( |
138
|
|
|
|
|
|
|
$drh, |
139
|
|
|
|
|
|
|
{ |
140
|
|
|
|
|
|
|
Name => $dbname, |
141
|
|
|
|
|
|
|
USER => $user, |
142
|
|
|
|
|
|
|
CURRENT_USER => $user, |
143
|
|
|
|
|
|
|
} |
144
|
|
|
|
|
|
|
); |
145
|
|
|
|
|
|
|
|
146
|
582
|
50
|
|
|
|
1880
|
if ($dbh) |
147
|
|
|
|
|
|
|
{ |
148
|
|
|
|
|
|
|
# must be done first, because setting flags implicitly calls $dbdname::db->STORE |
149
|
582
|
|
|
|
|
3673
|
$dbh->func( 0, "init_default_attributes" ); |
150
|
582
|
|
|
|
|
3056
|
my $two_phased_init; |
151
|
582
|
50
|
|
|
|
5951
|
defined $dbh->{sql_init_phase} and $two_phased_init = ++$dbh->{sql_init_phase}; |
152
|
582
|
|
|
|
|
7107
|
my %second_phase_attrs; |
153
|
|
|
|
|
|
|
my @func_inits; |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
# this must be done to allow DBI.pm reblessing got handle after successful connecting |
156
|
582
|
50
|
|
|
|
1572
|
exists $attr->{RootClass} and $second_phase_attrs{RootClass} = delete $attr->{RootClass}; |
157
|
|
|
|
|
|
|
|
158
|
582
|
|
|
|
|
1113
|
my ( $var, $val ); |
159
|
582
|
|
|
|
|
1737
|
while ( length $dbname ) |
160
|
|
|
|
|
|
|
{ |
161
|
1136
|
100
|
|
|
|
7350
|
if ( $dbname =~ s/^((?:[^\\;]|\\.)*?);//s ) |
162
|
|
|
|
|
|
|
{ |
163
|
804
|
|
|
|
|
1987
|
$var = $1; |
164
|
|
|
|
|
|
|
} |
165
|
|
|
|
|
|
|
else |
166
|
|
|
|
|
|
|
{ |
167
|
332
|
|
|
|
|
558
|
$var = $dbname; |
168
|
332
|
|
|
|
|
527
|
$dbname = ""; |
169
|
|
|
|
|
|
|
} |
170
|
|
|
|
|
|
|
|
171
|
1136
|
50
|
|
|
|
4087
|
if ( $var =~ m/^(.+?)=(.*)/s ) |
|
|
0
|
|
|
|
|
|
172
|
|
|
|
|
|
|
{ |
173
|
1136
|
|
|
|
|
2209
|
$var = $1; |
174
|
1136
|
|
|
|
|
2354
|
( $val = $2 ) =~ s/\\(.)/$1/g; |
175
|
1136
|
50
|
33
|
|
|
3441
|
exists $attr->{$var} |
176
|
|
|
|
|
|
|
and carp("$var is given in DSN *and* \$attr during DBI->connect()") |
177
|
|
|
|
|
|
|
if ($^W); |
178
|
1136
|
50
|
|
|
|
3688
|
exists $attr->{$var} or $attr->{$var} = $val; |
179
|
|
|
|
|
|
|
} |
180
|
|
|
|
|
|
|
elsif ( $var =~ m/^(.+?)=>(.*)/s ) |
181
|
|
|
|
|
|
|
{ |
182
|
0
|
|
|
|
|
0
|
$var = $1; |
183
|
0
|
|
|
|
|
0
|
( $val = $2 ) =~ s/\\(.)/$1/g; |
184
|
0
|
|
|
|
|
0
|
my $ref = eval $val; |
185
|
|
|
|
|
|
|
# $dbh->$var($ref); |
186
|
0
|
|
|
|
|
0
|
push( @func_inits, $var, $ref ); |
187
|
|
|
|
|
|
|
} |
188
|
|
|
|
|
|
|
} |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
# The attributes need to be sorted in a specific way as the |
191
|
|
|
|
|
|
|
# assignment is through tied hashes and calls STORE on each |
192
|
|
|
|
|
|
|
# attribute. Some attributes require to be called prior to |
193
|
|
|
|
|
|
|
# others |
194
|
|
|
|
|
|
|
# e.g. f_dir *must* be done before xx_tables in DBD::File |
195
|
|
|
|
|
|
|
# The dbh attribute sql_init_order is a hash with the order |
196
|
|
|
|
|
|
|
# as key (low is first, 0 .. 100) and the attributes that |
197
|
|
|
|
|
|
|
# are set to that oreder as anon-list as value: |
198
|
|
|
|
|
|
|
# { 0 => [qw( AutoCommit PrintError RaiseError Profile ... )], |
199
|
|
|
|
|
|
|
# 10 => [ list of attr to be dealt with immediately after first ], |
200
|
|
|
|
|
|
|
# 50 => [ all fields that are unspecified or default sort order ], |
201
|
|
|
|
|
|
|
# 90 => [ all fields that are needed after other initialisation ], |
202
|
|
|
|
|
|
|
# } |
203
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
my %order = map { |
205
|
1164
|
|
|
|
|
1942
|
my $order = $_; |
206
|
1164
|
|
|
|
|
1541
|
map { ( $_ => $order ) } @{ $dbh->{sql_init_order}{$order} }; |
|
3878
|
|
|
|
|
14923
|
|
|
1164
|
|
|
|
|
4599
|
|
207
|
582
|
50
|
|
|
|
1027
|
} sort { $a <=> $b } keys %{ $dbh->{sql_init_order} || {} }; |
|
582
|
|
|
|
|
7097
|
|
|
582
|
|
|
|
|
4263
|
|
208
|
|
|
|
|
|
|
my @ordered_attr = |
209
|
5924
|
|
|
|
|
8958
|
map { $_->[0] } |
210
|
13202
|
|
|
|
|
17015
|
sort { $a->[1] <=> $b->[1] } |
211
|
582
|
100
|
|
|
|
2957
|
map { [ $_, defined $order{$_} ? $order{$_} : 50 ] } |
|
5924
|
|
|
|
|
13730
|
|
212
|
|
|
|
|
|
|
keys %$attr; |
213
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
# initialize given attributes ... lower weighted before higher weighted |
215
|
582
|
|
|
|
|
2656
|
foreach my $a (@ordered_attr) |
216
|
|
|
|
|
|
|
{ |
217
|
5924
|
50
|
|
|
|
11366
|
exists $attr->{$a} or next; |
218
|
5924
|
50
|
|
|
|
10458
|
$two_phased_init and eval { |
219
|
5924
|
|
|
|
|
22853
|
$dbh->{$a} = $attr->{$a}; |
220
|
5924
|
|
|
|
|
33012
|
delete $attr->{$a}; |
221
|
|
|
|
|
|
|
}; |
222
|
5924
|
50
|
|
|
|
10564
|
$@ and $second_phase_attrs{$a} = delete $attr->{$a}; |
223
|
5924
|
50
|
|
|
|
11394
|
$two_phased_init or $dbh->STORE( $a, delete $attr->{$a} ); |
224
|
|
|
|
|
|
|
} |
225
|
|
|
|
|
|
|
|
226
|
582
|
50
|
|
|
|
3139
|
$two_phased_init and $dbh->func( 1, "init_default_attributes" ); |
227
|
582
|
|
|
|
|
3286
|
%$attr = %second_phase_attrs; |
228
|
|
|
|
|
|
|
|
229
|
582
|
|
|
|
|
3106
|
for ( my $i = 0; $i < scalar(@func_inits); $i += 2 ) |
230
|
|
|
|
|
|
|
{ |
231
|
0
|
|
|
|
|
0
|
my $func = $func_inits[$i]; |
232
|
0
|
|
|
|
|
0
|
my $arg = $func_inits[ $i + 1 ]; |
233
|
0
|
|
|
|
|
0
|
$dbh->$func($arg); |
234
|
|
|
|
|
|
|
} |
235
|
|
|
|
|
|
|
|
236
|
582
|
|
|
|
|
2672
|
$dbh->func("init_done"); |
237
|
|
|
|
|
|
|
|
238
|
582
|
|
|
|
|
3462
|
$dbh->STORE( Active => 1 ); |
239
|
|
|
|
|
|
|
} |
240
|
|
|
|
|
|
|
|
241
|
582
|
|
|
|
|
5215
|
return $dbh; |
242
|
|
|
|
|
|
|
} # connect |
243
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
sub data_sources ($;$) |
245
|
|
|
|
|
|
|
{ |
246
|
32
|
|
|
32
|
|
679
|
my ( $drh, $attr ) = @_; |
247
|
|
|
|
|
|
|
|
248
|
32
|
|
|
|
|
52
|
my $tbl_src; |
249
|
|
|
|
|
|
|
$attr |
250
|
|
|
|
|
|
|
and defined $attr->{sql_table_source} |
251
|
|
|
|
|
|
|
and $attr->{sql_table_source}->isa('DBI::DBD::SqlEngine::TableSource') |
252
|
32
|
50
|
33
|
|
|
190
|
and $tbl_src = $attr->{sql_table_source}; |
|
|
|
33
|
|
|
|
|
253
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
!defined($tbl_src) |
255
|
|
|
|
|
|
|
and $drh->{ImplementorClass}->can('default_table_source') |
256
|
32
|
50
|
33
|
|
|
396
|
and $tbl_src = $drh->{ImplementorClass}->default_table_source(); |
257
|
32
|
50
|
|
|
|
100
|
defined($tbl_src) or return; |
258
|
|
|
|
|
|
|
|
259
|
32
|
|
|
|
|
454
|
$tbl_src->data_sources( $drh, $attr ); |
260
|
|
|
|
|
|
|
} # data_sources |
261
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
sub disconnect_all |
263
|
|
|
|
2
|
|
|
{ |
264
|
|
|
|
|
|
|
} # disconnect_all |
265
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
sub DESTROY |
267
|
|
|
|
|
|
|
{ |
268
|
0
|
|
|
0
|
|
0
|
undef; |
269
|
|
|
|
|
|
|
} # DESTROY |
270
|
|
|
|
|
|
|
|
271
|
|
|
|
|
|
|
# ====== DATABASE ============================================================== |
272
|
|
|
|
|
|
|
|
273
|
|
|
|
|
|
|
package DBI::DBD::SqlEngine::db; |
274
|
|
|
|
|
|
|
|
275
|
54
|
|
|
54
|
|
470
|
use strict; |
|
54
|
|
|
|
|
120
|
|
|
54
|
|
|
|
|
1344
|
|
276
|
54
|
|
|
54
|
|
287
|
use warnings; |
|
54
|
|
|
|
|
104
|
|
|
54
|
|
|
|
|
1821
|
|
277
|
|
|
|
|
|
|
|
278
|
54
|
|
|
54
|
|
284
|
use vars qw(@ISA $imp_data_size); |
|
54
|
|
|
|
|
105
|
|
|
54
|
|
|
|
|
2563
|
|
279
|
|
|
|
|
|
|
|
280
|
54
|
|
|
54
|
|
384
|
use Carp; |
|
54
|
|
|
|
|
122
|
|
|
54
|
|
|
|
|
227697
|
|
281
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
if ( eval { require Clone; } ) |
283
|
|
|
|
|
|
|
{ |
284
|
|
|
|
|
|
|
Clone->import("clone"); |
285
|
|
|
|
|
|
|
} |
286
|
|
|
|
|
|
|
else |
287
|
|
|
|
|
|
|
{ |
288
|
|
|
|
|
|
|
require Storable; # in CORE since 5.7.3 |
289
|
|
|
|
|
|
|
*clone = \&Storable::dclone; |
290
|
|
|
|
|
|
|
} |
291
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
$imp_data_size = 0; |
293
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
sub ping |
295
|
|
|
|
|
|
|
{ |
296
|
348
|
50
|
|
348
|
|
3949
|
( $_[0]->FETCH("Active") ) ? 1 : 0; |
297
|
|
|
|
|
|
|
} # ping |
298
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
sub data_sources |
300
|
|
|
|
|
|
|
{ |
301
|
24
|
|
|
24
|
|
48
|
my ( $dbh, $attr, @other ) = @_; |
302
|
24
|
|
|
|
|
56
|
my $drh = $dbh->{Driver}; # XXX proxy issues? |
303
|
24
|
50
|
|
|
|
62
|
ref($attr) eq 'HASH' or $attr = {}; |
304
|
24
|
50
|
|
|
|
78
|
defined( $attr->{sql_table_source} ) or $attr->{sql_table_source} = $dbh->{sql_table_source}; |
305
|
24
|
|
|
|
|
111
|
return $drh->data_sources( $attr, @other ); |
306
|
|
|
|
|
|
|
} |
307
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
sub prepare ($$;@) |
309
|
|
|
|
|
|
|
{ |
310
|
750
|
|
|
750
|
|
37791
|
my ( $dbh, $statement, @attribs ) = @_; |
311
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
# create a 'blank' sth |
313
|
750
|
|
|
|
|
3396
|
my $sth = DBI::_new_sth( $dbh, { Statement => $statement } ); |
314
|
|
|
|
|
|
|
|
315
|
750
|
50
|
|
|
|
2395
|
if ($sth) |
316
|
|
|
|
|
|
|
{ |
317
|
750
|
|
|
|
|
3209
|
my $class = $sth->FETCH("ImplementorClass"); |
318
|
750
|
|
|
|
|
7267
|
$class =~ s/::st$/::Statement/; |
319
|
750
|
|
|
|
|
1390
|
my $stmt; |
320
|
|
|
|
|
|
|
|
321
|
|
|
|
|
|
|
# if using SQL::Statement version > 1 |
322
|
|
|
|
|
|
|
# cache the parser object if the DBD supports parser caching |
323
|
|
|
|
|
|
|
# SQL::Nano and older SQL::Statements don't support this |
324
|
|
|
|
|
|
|
|
325
|
750
|
50
|
|
|
|
6516
|
if ( $class->isa("SQL::Statement") ) |
326
|
|
|
|
|
|
|
{ |
327
|
0
|
|
|
|
|
0
|
my $parser = $dbh->{sql_parser_object}; |
328
|
0
|
|
0
|
|
|
0
|
$parser ||= eval { $dbh->func("sql_parser_object") }; |
|
0
|
|
|
|
|
0
|
|
329
|
0
|
0
|
|
|
|
0
|
if ($@) |
330
|
|
|
|
|
|
|
{ |
331
|
0
|
|
|
|
|
0
|
$stmt = eval { $class->new($statement) }; |
|
0
|
|
|
|
|
0
|
|
332
|
|
|
|
|
|
|
} |
333
|
|
|
|
|
|
|
else |
334
|
|
|
|
|
|
|
{ |
335
|
0
|
|
|
|
|
0
|
$stmt = eval { $class->new( $statement, $parser ) }; |
|
0
|
|
|
|
|
0
|
|
336
|
|
|
|
|
|
|
} |
337
|
|
|
|
|
|
|
} |
338
|
|
|
|
|
|
|
else |
339
|
|
|
|
|
|
|
{ |
340
|
750
|
|
|
|
|
1507
|
$stmt = eval { $class->new($statement) }; |
|
750
|
|
|
|
|
3243
|
|
341
|
|
|
|
|
|
|
} |
342
|
750
|
100
|
66
|
|
|
3682
|
if ( $@ || $stmt->{errstr} ) |
343
|
|
|
|
|
|
|
{ |
344
|
48
|
|
33
|
|
|
493
|
$dbh->set_err( $DBI::stderr, $@ || $stmt->{errstr} ); |
345
|
48
|
|
|
|
|
435
|
undef $sth; |
346
|
|
|
|
|
|
|
} |
347
|
|
|
|
|
|
|
else |
348
|
|
|
|
|
|
|
{ |
349
|
702
|
|
|
|
|
3875
|
$sth->STORE( "sql_stmt", $stmt ); |
350
|
702
|
|
|
|
|
5002
|
$sth->STORE( "sql_params", [] ); |
351
|
702
|
|
|
|
|
4784
|
$sth->STORE( "NUM_OF_PARAMS", scalar( $stmt->params() ) ); |
352
|
702
|
|
|
|
|
5414
|
my @colnames = $sth->sql_get_colnames(); |
353
|
702
|
|
|
|
|
5988
|
$sth->STORE( "NUM_OF_FIELDS", scalar @colnames ); |
354
|
|
|
|
|
|
|
} |
355
|
|
|
|
|
|
|
} |
356
|
750
|
|
|
|
|
5908
|
return $sth; |
357
|
|
|
|
|
|
|
} # prepare |
358
|
|
|
|
|
|
|
|
359
|
|
|
|
|
|
|
sub set_versions |
360
|
|
|
|
|
|
|
{ |
361
|
582
|
|
|
582
|
|
983
|
my $dbh = $_[0]; |
362
|
582
|
|
|
|
|
1227
|
$dbh->{sql_engine_version} = $DBI::DBD::SqlEngine::VERSION; |
363
|
582
|
|
|
|
|
1480
|
for (qw( nano_version statement_version )) |
364
|
|
|
|
|
|
|
{ |
365
|
1164
|
100
|
|
|
|
3380
|
defined $DBI::SQL::Nano::versions->{$_} or next; |
366
|
582
|
|
|
|
|
2163
|
$dbh->{"sql_$_"} = $DBI::SQL::Nano::versions->{$_}; |
367
|
|
|
|
|
|
|
} |
368
|
|
|
|
|
|
|
$dbh->{sql_handler} = |
369
|
|
|
|
|
|
|
$dbh->{sql_statement_version} |
370
|
582
|
50
|
|
|
|
1940
|
? "SQL::Statement" |
371
|
|
|
|
|
|
|
: "DBI::SQL::Nano"; |
372
|
|
|
|
|
|
|
|
373
|
582
|
|
|
|
|
1503
|
return $dbh; |
374
|
|
|
|
|
|
|
} # set_versions |
375
|
|
|
|
|
|
|
|
376
|
|
|
|
|
|
|
sub init_valid_attributes |
377
|
|
|
|
|
|
|
{ |
378
|
582
|
|
|
582
|
|
1107
|
my $dbh = $_[0]; |
379
|
|
|
|
|
|
|
|
380
|
|
|
|
|
|
|
$dbh->{sql_valid_attrs} = { |
381
|
582
|
|
|
|
|
6202
|
sql_engine_version => 1, # DBI::DBD::SqlEngine version |
382
|
|
|
|
|
|
|
sql_handler => 1, # Nano or S:S |
383
|
|
|
|
|
|
|
sql_nano_version => 1, # Nano version |
384
|
|
|
|
|
|
|
sql_statement_version => 1, # S:S version |
385
|
|
|
|
|
|
|
sql_flags => 1, # flags for SQL::Parser |
386
|
|
|
|
|
|
|
sql_dialect => 1, # dialect for SQL::Parser |
387
|
|
|
|
|
|
|
sql_quoted_identifier_case => 1, # case for quoted identifiers |
388
|
|
|
|
|
|
|
sql_identifier_case => 1, # case for non-quoted identifiers |
389
|
|
|
|
|
|
|
sql_parser_object => 1, # SQL::Parser instance |
390
|
|
|
|
|
|
|
sql_sponge_driver => 1, # Sponge driver for table_info () |
391
|
|
|
|
|
|
|
sql_valid_attrs => 1, # SQL valid attributes |
392
|
|
|
|
|
|
|
sql_readonly_attrs => 1, # SQL readonly attributes |
393
|
|
|
|
|
|
|
sql_init_phase => 1, # Only during initialization |
394
|
|
|
|
|
|
|
sql_meta => 1, # meta data for tables |
395
|
|
|
|
|
|
|
sql_meta_map => 1, # mapping table for identifier case |
396
|
|
|
|
|
|
|
sql_data_source => 1, # reasonable datasource class |
397
|
|
|
|
|
|
|
}; |
398
|
|
|
|
|
|
|
$dbh->{sql_readonly_attrs} = { |
399
|
582
|
|
|
|
|
3286
|
sql_engine_version => 1, # DBI::DBD::SqlEngine version |
400
|
|
|
|
|
|
|
sql_handler => 1, # Nano or S:S |
401
|
|
|
|
|
|
|
sql_nano_version => 1, # Nano version |
402
|
|
|
|
|
|
|
sql_statement_version => 1, # S:S version |
403
|
|
|
|
|
|
|
sql_quoted_identifier_case => 1, # case for quoted identifiers |
404
|
|
|
|
|
|
|
sql_parser_object => 1, # SQL::Parser instance |
405
|
|
|
|
|
|
|
sql_sponge_driver => 1, # Sponge driver for table_info () |
406
|
|
|
|
|
|
|
sql_valid_attrs => 1, # SQL valid attributes |
407
|
|
|
|
|
|
|
sql_readonly_attrs => 1, # SQL readonly attributes |
408
|
|
|
|
|
|
|
}; |
409
|
|
|
|
|
|
|
|
410
|
582
|
|
|
|
|
1747
|
return $dbh; |
411
|
|
|
|
|
|
|
} # init_valid_attributes |
412
|
|
|
|
|
|
|
|
413
|
|
|
|
|
|
|
sub init_default_attributes |
414
|
|
|
|
|
|
|
{ |
415
|
1164
|
|
|
1164
|
|
2144
|
my ( $dbh, $phase ) = @_; |
416
|
1164
|
|
|
|
|
1756
|
my $given_phase = $phase; |
417
|
|
|
|
|
|
|
|
418
|
1164
|
50
|
|
|
|
2600
|
unless ( defined($phase) ) |
419
|
|
|
|
|
|
|
{ |
420
|
|
|
|
|
|
|
# we have an "old" driver here |
421
|
0
|
|
|
|
|
0
|
$phase = defined $dbh->{sql_init_phase}; |
422
|
0
|
0
|
|
|
|
0
|
$phase and $phase = $dbh->{sql_init_phase}; |
423
|
|
|
|
|
|
|
} |
424
|
|
|
|
|
|
|
|
425
|
1164
|
100
|
|
|
|
2539
|
if ( 0 == $phase ) |
426
|
|
|
|
|
|
|
{ |
427
|
|
|
|
|
|
|
# must be done first, because setting flags implicitly calls $dbdname::db->STORE |
428
|
582
|
|
|
|
|
2438
|
$dbh->func("init_valid_attributes"); |
429
|
|
|
|
|
|
|
|
430
|
582
|
|
|
|
|
5086
|
$dbh->func("set_versions"); |
431
|
|
|
|
|
|
|
|
432
|
582
|
|
|
|
|
3291
|
$dbh->{sql_identifier_case} = 2; # SQL_IC_LOWER |
433
|
582
|
|
|
|
|
1134
|
$dbh->{sql_quoted_identifier_case} = 3; # SQL_IC_SENSITIVE |
434
|
|
|
|
|
|
|
|
435
|
582
|
|
|
|
|
1152
|
$dbh->{sql_dialect} = "CSV"; |
436
|
|
|
|
|
|
|
|
437
|
582
|
|
|
|
|
1057
|
$dbh->{sql_init_phase} = $given_phase; |
438
|
|
|
|
|
|
|
|
439
|
|
|
|
|
|
|
# complete derived attributes, if required |
440
|
582
|
|
|
|
|
3513
|
( my $drv_class = $dbh->{ImplementorClass} ) =~ s/::db$//; |
441
|
582
|
|
|
|
|
2467
|
my $drv_prefix = DBI->driver_prefix($drv_class); |
442
|
582
|
|
|
|
|
1464
|
my $valid_attrs = $drv_prefix . "valid_attrs"; |
443
|
582
|
|
|
|
|
1262
|
my $ro_attrs = $drv_prefix . "readonly_attrs"; |
444
|
|
|
|
|
|
|
|
445
|
|
|
|
|
|
|
# check whether we're running in a Gofer server or not (see |
446
|
|
|
|
|
|
|
# validate_FETCH_attr for details) |
447
|
|
|
|
|
|
|
$dbh->{sql_engine_in_gofer} = |
448
|
582
|
|
100
|
|
|
6225
|
( defined $INC{"DBD/Gofer.pm"} && ( caller(5) )[0] eq "DBI::Gofer::Execute" ); |
449
|
582
|
|
|
|
|
1759
|
$dbh->{sql_meta} = {}; |
450
|
582
|
|
|
|
|
1276
|
$dbh->{sql_meta_map} = {}; # choose new name because it contains other keys |
451
|
|
|
|
|
|
|
|
452
|
|
|
|
|
|
|
# init_default_attributes calls inherited routine before derived DBD's |
453
|
|
|
|
|
|
|
# init their default attributes, so we don't override something here |
454
|
|
|
|
|
|
|
# |
455
|
|
|
|
|
|
|
# defining an order of attribute initialization from connect time |
456
|
|
|
|
|
|
|
# specified ones with a magic baarier (see next statement) |
457
|
582
|
|
|
|
|
1286
|
my $drv_pfx_meta = $drv_prefix . "meta"; |
458
|
|
|
|
|
|
|
$dbh->{sql_init_order} = { |
459
|
|
|
|
|
|
|
0 => [qw( Profile RaiseError PrintError AutoCommit )], |
460
|
582
|
100
|
|
|
|
4722
|
90 => [ "sql_meta", $dbh->{$drv_pfx_meta} ? $dbh->{$drv_pfx_meta} : () ], |
461
|
|
|
|
|
|
|
}; |
462
|
|
|
|
|
|
|
# ensuring Profile, RaiseError, PrintError, AutoCommit are initialized |
463
|
|
|
|
|
|
|
# first when initializing attributes from connect time specified |
464
|
|
|
|
|
|
|
# attributes |
465
|
|
|
|
|
|
|
# further, initializations to predefined tables are happens after any |
466
|
|
|
|
|
|
|
# unspecified attribute initialization (that default to order 50) |
467
|
|
|
|
|
|
|
|
468
|
582
|
|
|
|
|
1716
|
my @comp_attrs = qw(valid_attrs version readonly_attrs); |
469
|
|
|
|
|
|
|
|
470
|
582
|
100
|
66
|
|
|
2582
|
if ( exists $dbh->{$drv_pfx_meta} and !$dbh->{sql_engine_in_gofer} ) |
471
|
|
|
|
|
|
|
{ |
472
|
388
|
|
|
|
|
779
|
my $attr = $dbh->{$drv_pfx_meta}; |
473
|
|
|
|
|
|
|
defined $attr |
474
|
|
|
|
|
|
|
and defined $dbh->{$valid_attrs} |
475
|
|
|
|
|
|
|
and !defined $dbh->{$valid_attrs}{$attr} |
476
|
388
|
50
|
33
|
|
|
3624
|
and $dbh->{$valid_attrs}{$attr} = 1; |
|
|
|
33
|
|
|
|
|
477
|
|
|
|
|
|
|
|
478
|
388
|
|
|
|
|
670
|
my %h; |
479
|
388
|
|
|
|
|
2180
|
tie %h, "DBI::DBD::SqlEngine::TieTables", $dbh; |
480
|
388
|
|
|
|
|
1372
|
$dbh->{$attr} = \%h; |
481
|
|
|
|
|
|
|
|
482
|
388
|
|
|
|
|
1024
|
push @comp_attrs, "meta"; |
483
|
|
|
|
|
|
|
} |
484
|
|
|
|
|
|
|
|
485
|
582
|
|
|
|
|
1374
|
foreach my $comp_attr (@comp_attrs) |
486
|
|
|
|
|
|
|
{ |
487
|
2134
|
|
|
|
|
3809
|
my $attr = $drv_prefix . $comp_attr; |
488
|
|
|
|
|
|
|
defined $dbh->{$valid_attrs} |
489
|
|
|
|
|
|
|
and !defined $dbh->{$valid_attrs}{$attr} |
490
|
2134
|
50
|
33
|
|
|
7365
|
and $dbh->{$valid_attrs}{$attr} = 1; |
491
|
|
|
|
|
|
|
defined $dbh->{$ro_attrs} |
492
|
|
|
|
|
|
|
and !defined $dbh->{$ro_attrs}{$attr} |
493
|
2134
|
50
|
33
|
|
|
7945
|
and $dbh->{$ro_attrs}{$attr} = 1; |
494
|
|
|
|
|
|
|
} |
495
|
|
|
|
|
|
|
} |
496
|
|
|
|
|
|
|
|
497
|
1164
|
|
|
|
|
2556
|
return $dbh; |
498
|
|
|
|
|
|
|
} # init_default_attributes |
499
|
|
|
|
|
|
|
|
500
|
|
|
|
|
|
|
sub init_done |
501
|
|
|
|
|
|
|
{ |
502
|
582
|
50
|
|
582
|
|
5523
|
defined $_[0]->{sql_init_phase} and delete $_[0]->{sql_init_phase}; |
503
|
582
|
|
|
|
|
1238
|
delete $_[0]->{sql_valid_attrs}->{sql_init_phase}; |
504
|
582
|
|
|
|
|
1209
|
return; |
505
|
|
|
|
|
|
|
} |
506
|
|
|
|
|
|
|
|
507
|
|
|
|
|
|
|
sub sql_parser_object |
508
|
|
|
|
|
|
|
{ |
509
|
0
|
|
|
0
|
|
0
|
my $dbh = $_[0]; |
510
|
0
|
|
0
|
|
|
0
|
my $dialect = $dbh->{sql_dialect} || "CSV"; |
511
|
0
|
|
|
|
|
0
|
my $parser = { |
512
|
|
|
|
|
|
|
RaiseError => $dbh->FETCH("RaiseError"), |
513
|
|
|
|
|
|
|
PrintError => $dbh->FETCH("PrintError"), |
514
|
|
|
|
|
|
|
}; |
515
|
0
|
|
0
|
|
|
0
|
my $sql_flags = $dbh->FETCH("sql_flags") || {}; |
516
|
0
|
|
|
|
|
0
|
%$parser = ( %$parser, %$sql_flags ); |
517
|
0
|
|
|
|
|
0
|
$parser = SQL::Parser->new( $dialect, $parser ); |
518
|
0
|
|
|
|
|
0
|
$dbh->{sql_parser_object} = $parser; |
519
|
0
|
|
|
|
|
0
|
return $parser; |
520
|
|
|
|
|
|
|
} # sql_parser_object |
521
|
|
|
|
|
|
|
|
522
|
|
|
|
|
|
|
sub sql_sponge_driver |
523
|
|
|
|
|
|
|
{ |
524
|
28
|
|
|
28
|
|
401
|
my $dbh = $_[0]; |
525
|
28
|
|
|
|
|
108
|
my $dbh2 = $dbh->{sql_sponge_driver}; |
526
|
28
|
50
|
|
|
|
154
|
unless ($dbh2) |
527
|
|
|
|
|
|
|
{ |
528
|
28
|
|
|
|
|
225
|
$dbh2 = $dbh->{sql_sponge_driver} = DBI->connect("DBI:Sponge:"); |
529
|
28
|
50
|
|
|
|
381
|
unless ($dbh2) |
530
|
|
|
|
|
|
|
{ |
531
|
0
|
|
|
|
|
0
|
$dbh->set_err( $DBI::stderr, $DBI::errstr ); |
532
|
0
|
|
|
|
|
0
|
return; |
533
|
|
|
|
|
|
|
} |
534
|
|
|
|
|
|
|
} |
535
|
|
|
|
|
|
|
} |
536
|
|
|
|
|
|
|
|
537
|
|
|
|
|
|
|
sub disconnect ($) |
538
|
|
|
|
|
|
|
{ |
539
|
210
|
|
|
210
|
|
14351
|
%{ $_[0]->{sql_meta} } = (); |
|
210
|
|
|
|
|
949
|
|
540
|
210
|
|
|
|
|
423
|
%{ $_[0]->{sql_meta_map} } = (); |
|
210
|
|
|
|
|
525
|
|
541
|
210
|
|
|
|
|
995
|
$_[0]->STORE( Active => 0 ); |
542
|
210
|
|
|
|
|
1274
|
return 1; |
543
|
|
|
|
|
|
|
} # disconnect |
544
|
|
|
|
|
|
|
|
545
|
|
|
|
|
|
|
sub validate_FETCH_attr |
546
|
|
|
|
|
|
|
{ |
547
|
0
|
|
|
0
|
|
0
|
my ( $dbh, $attrib ) = @_; |
548
|
|
|
|
|
|
|
|
549
|
|
|
|
|
|
|
# If running in a Gofer server, access to our tied compatibility hash |
550
|
|
|
|
|
|
|
# would force Gofer to serialize the tieing object including it's |
551
|
|
|
|
|
|
|
# private $dbh reference used to do the driver function calls. |
552
|
|
|
|
|
|
|
# This will result in nasty exceptions. So return a copy of the |
553
|
|
|
|
|
|
|
# sql_meta structure instead, which is the source of for the compatibility |
554
|
|
|
|
|
|
|
# tie-hash. It's not as good as liked, but the best we can do in this |
555
|
|
|
|
|
|
|
# situation. |
556
|
0
|
0
|
|
|
|
0
|
if ( $dbh->{sql_engine_in_gofer} ) |
557
|
|
|
|
|
|
|
{ |
558
|
0
|
|
|
|
|
0
|
( my $drv_class = $dbh->{ImplementorClass} ) =~ s/::db$//; |
559
|
0
|
|
|
|
|
0
|
my $drv_prefix = DBI->driver_prefix($drv_class); |
560
|
0
|
0
|
0
|
|
|
0
|
exists $dbh->{ $drv_prefix . "meta" } && $attrib eq $dbh->{ $drv_prefix . "meta" } |
561
|
|
|
|
|
|
|
and $attrib = "sql_meta"; |
562
|
|
|
|
|
|
|
} |
563
|
|
|
|
|
|
|
|
564
|
0
|
|
|
|
|
0
|
return $attrib; |
565
|
|
|
|
|
|
|
} |
566
|
|
|
|
|
|
|
|
567
|
|
|
|
|
|
|
sub FETCH ($$) |
568
|
|
|
|
|
|
|
{ |
569
|
3676
|
|
|
3676
|
|
22902
|
my ( $dbh, $attrib ) = @_; |
570
|
3676
|
50
|
|
|
|
7372
|
$attrib eq "AutoCommit" |
571
|
|
|
|
|
|
|
and return 1; |
572
|
|
|
|
|
|
|
|
573
|
|
|
|
|
|
|
# Driver private attributes are lower cased |
574
|
3676
|
50
|
|
|
|
7307
|
if ( $attrib eq ( lc $attrib ) ) |
575
|
|
|
|
|
|
|
{ |
576
|
|
|
|
|
|
|
# first let the implementation deliver an alias for the attribute to fetch |
577
|
|
|
|
|
|
|
# after it validates the legitimation of the fetch request |
578
|
0
|
0
|
|
|
|
0
|
$attrib = $dbh->func( $attrib, "validate_FETCH_attr" ) or return; |
579
|
|
|
|
|
|
|
|
580
|
0
|
|
|
|
|
0
|
my $attr_prefix; |
581
|
0
|
0
|
|
|
|
0
|
$attrib =~ m/^([a-z]+_)/ and $attr_prefix = $1; |
582
|
0
|
0
|
|
|
|
0
|
unless ($attr_prefix) |
583
|
|
|
|
|
|
|
{ |
584
|
0
|
|
|
|
|
0
|
( my $drv_class = $dbh->{ImplementorClass} ) =~ s/::db$//; |
585
|
0
|
|
|
|
|
0
|
$attr_prefix = DBI->driver_prefix($drv_class); |
586
|
0
|
|
|
|
|
0
|
$attrib = $attr_prefix . $attrib; |
587
|
|
|
|
|
|
|
} |
588
|
0
|
|
|
|
|
0
|
my $valid_attrs = $attr_prefix . "valid_attrs"; |
589
|
0
|
|
|
|
|
0
|
my $ro_attrs = $attr_prefix . "readonly_attrs"; |
590
|
|
|
|
|
|
|
|
591
|
|
|
|
|
|
|
exists $dbh->{$valid_attrs} |
592
|
0
|
0
|
0
|
|
|
0
|
and ( $dbh->{$valid_attrs}{$attrib} |
593
|
|
|
|
|
|
|
or return $dbh->set_err( $DBI::stderr, "Invalid attribute '$attrib'" ) ); |
594
|
|
|
|
|
|
|
exists $dbh->{$ro_attrs} |
595
|
|
|
|
|
|
|
and $dbh->{$ro_attrs}{$attrib} |
596
|
|
|
|
|
|
|
and defined $dbh->{$attrib} |
597
|
|
|
|
|
|
|
and refaddr( $dbh->{$attrib} ) |
598
|
0
|
0
|
0
|
|
|
0
|
and return clone( $dbh->{$attrib} ); |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
599
|
|
|
|
|
|
|
|
600
|
0
|
|
|
|
|
0
|
return $dbh->{$attrib}; |
601
|
|
|
|
|
|
|
} |
602
|
|
|
|
|
|
|
# else pass up to DBI to handle |
603
|
3676
|
|
|
|
|
19316
|
return $dbh->SUPER::FETCH($attrib); |
604
|
|
|
|
|
|
|
} # FETCH |
605
|
|
|
|
|
|
|
|
606
|
|
|
|
|
|
|
sub validate_STORE_attr |
607
|
|
|
|
|
|
|
{ |
608
|
4092
|
|
|
4092
|
|
7283
|
my ( $dbh, $attrib, $value ) = @_; |
609
|
|
|
|
|
|
|
|
610
|
4092
|
50
|
66
|
|
|
14112
|
if ( $attrib eq "sql_identifier_case" || $attrib eq "sql_quoted_identifier_case" |
|
|
|
33
|
|
|
|
|
|
|
|
66
|
|
|
|
|
611
|
|
|
|
|
|
|
and $value < 1 || $value > 4 ) |
612
|
|
|
|
|
|
|
{ |
613
|
0
|
|
|
|
|
0
|
croak "attribute '$attrib' must have a value from 1 .. 4 (SQL_IC_UPPER .. SQL_IC_MIXED)"; |
614
|
|
|
|
|
|
|
# XXX correctly a remap of all entries in sql_meta/sql_meta_map is required here |
615
|
|
|
|
|
|
|
} |
616
|
|
|
|
|
|
|
|
617
|
4092
|
|
|
|
|
19745
|
( my $drv_class = $dbh->{ImplementorClass} ) =~ s/::db$//; |
618
|
4092
|
|
|
|
|
12547
|
my $drv_prefix = DBI->driver_prefix($drv_class); |
619
|
|
|
|
|
|
|
|
620
|
|
|
|
|
|
|
exists $dbh->{ $drv_prefix . "meta" } |
621
|
4092
|
100
|
100
|
|
|
17470
|
and $attrib eq $dbh->{ $drv_prefix . "meta" } |
622
|
|
|
|
|
|
|
and $attrib = "sql_meta"; |
623
|
|
|
|
|
|
|
|
624
|
4092
|
|
|
|
|
13923
|
return ( $attrib, $value ); |
625
|
|
|
|
|
|
|
} |
626
|
|
|
|
|
|
|
|
627
|
|
|
|
|
|
|
# the ::db::STORE method is what gets called when you set |
628
|
|
|
|
|
|
|
# a lower-cased database handle attribute such as $dbh->{somekey}=$someval; |
629
|
|
|
|
|
|
|
# |
630
|
|
|
|
|
|
|
# STORE should check to make sure that "somekey" is a valid attribute name |
631
|
|
|
|
|
|
|
# but only if it is really one of our attributes (starts with dbm_ or foo_) |
632
|
|
|
|
|
|
|
# You can also check for valid values for the attributes if needed |
633
|
|
|
|
|
|
|
# and/or perform other operations |
634
|
|
|
|
|
|
|
# |
635
|
|
|
|
|
|
|
sub STORE ($$$) |
636
|
|
|
|
|
|
|
{ |
637
|
9832
|
|
|
9832
|
|
81329
|
my ( $dbh, $attrib, $value ) = @_; |
638
|
|
|
|
|
|
|
|
639
|
9832
|
100
|
|
|
|
18905
|
if ( $attrib eq "AutoCommit" ) |
640
|
|
|
|
|
|
|
{ |
641
|
774
|
50
|
|
|
|
2589
|
$value and return 1; # is already set |
642
|
0
|
|
|
|
|
0
|
croak "Can't disable AutoCommit"; |
643
|
|
|
|
|
|
|
} |
644
|
|
|
|
|
|
|
|
645
|
9058
|
100
|
|
|
|
17985
|
if ( $attrib eq lc $attrib ) |
646
|
|
|
|
|
|
|
{ |
647
|
|
|
|
|
|
|
# Driver private attributes are lower cased |
648
|
|
|
|
|
|
|
|
649
|
4092
|
|
|
|
|
13038
|
( $attrib, $value ) = $dbh->func( $attrib, $value, "validate_STORE_attr" ); |
650
|
4092
|
50
|
|
|
|
24123
|
$attrib or return; |
651
|
|
|
|
|
|
|
|
652
|
4092
|
|
|
|
|
5304
|
my $attr_prefix; |
653
|
4092
|
50
|
|
|
|
19303
|
$attrib =~ m/^([a-z]+_)/ and $attr_prefix = $1; |
654
|
4092
|
50
|
|
|
|
8024
|
unless ($attr_prefix) |
655
|
|
|
|
|
|
|
{ |
656
|
0
|
|
|
|
|
0
|
( my $drv_class = $dbh->{ImplementorClass} ) =~ s/::db$//; |
657
|
0
|
|
|
|
|
0
|
$attr_prefix = DBI->driver_prefix($drv_class); |
658
|
0
|
|
|
|
|
0
|
$attrib = $attr_prefix . $attrib; |
659
|
|
|
|
|
|
|
} |
660
|
4092
|
|
|
|
|
6897
|
my $valid_attrs = $attr_prefix . "valid_attrs"; |
661
|
4092
|
|
|
|
|
5911
|
my $ro_attrs = $attr_prefix . "readonly_attrs"; |
662
|
|
|
|
|
|
|
|
663
|
|
|
|
|
|
|
exists $dbh->{$valid_attrs} |
664
|
4092
|
100
|
100
|
|
|
11124
|
and ( $dbh->{$valid_attrs}{$attrib} |
665
|
|
|
|
|
|
|
or return $dbh->set_err( $DBI::stderr, "Invalid attribute '$attrib'" ) ); |
666
|
|
|
|
|
|
|
exists $dbh->{$ro_attrs} |
667
|
|
|
|
|
|
|
and $dbh->{$ro_attrs}{$attrib} |
668
|
4088
|
50
|
66
|
|
|
13051
|
and defined $dbh->{$attrib} |
|
|
|
33
|
|
|
|
|
669
|
|
|
|
|
|
|
and return $dbh->set_err( $DBI::stderr, |
670
|
|
|
|
|
|
|
"attribute '$attrib' is readonly and must not be modified" ); |
671
|
|
|
|
|
|
|
|
672
|
4088
|
100
|
|
|
|
7974
|
if ( $attrib eq "sql_meta" ) |
673
|
|
|
|
|
|
|
{ |
674
|
36
|
|
|
|
|
220
|
while ( my ( $k, $v ) = each %$value ) |
675
|
|
|
|
|
|
|
{ |
676
|
36
|
|
|
|
|
181
|
$dbh->{$attrib}{$k} = $v; |
677
|
|
|
|
|
|
|
} |
678
|
|
|
|
|
|
|
} |
679
|
|
|
|
|
|
|
else |
680
|
|
|
|
|
|
|
{ |
681
|
4052
|
|
|
|
|
8063
|
$dbh->{$attrib} = $value; |
682
|
|
|
|
|
|
|
} |
683
|
|
|
|
|
|
|
|
684
|
4088
|
|
|
|
|
15952
|
return 1; |
685
|
|
|
|
|
|
|
} |
686
|
|
|
|
|
|
|
|
687
|
4966
|
|
|
|
|
18124
|
return $dbh->SUPER::STORE( $attrib, $value ); |
688
|
|
|
|
|
|
|
} # STORE |
689
|
|
|
|
|
|
|
|
690
|
|
|
|
|
|
|
sub get_driver_versions |
691
|
|
|
|
|
|
|
{ |
692
|
16
|
|
|
16
|
|
55
|
my ( $dbh, $table ) = @_; |
693
|
16
|
|
|
|
|
331
|
my %vsn = ( |
694
|
|
|
|
|
|
|
OS => "$^O ($Config::Config{osvers})", |
695
|
|
|
|
|
|
|
Perl => "$] ($Config::Config{archname})", |
696
|
|
|
|
|
|
|
DBI => $DBI::VERSION, |
697
|
|
|
|
|
|
|
); |
698
|
16
|
|
|
|
|
45
|
my %vmp; |
699
|
|
|
|
|
|
|
|
700
|
|
|
|
|
|
|
my $sql_engine_verinfo = |
701
|
|
|
|
|
|
|
join " ", |
702
|
|
|
|
|
|
|
$dbh->{sql_engine_version}, "using", $dbh->{sql_handler}, |
703
|
|
|
|
|
|
|
$dbh->{sql_handler} eq "SQL::Statement" |
704
|
|
|
|
|
|
|
? $dbh->{sql_statement_version} |
705
|
16
|
50
|
|
|
|
115
|
: $dbh->{sql_nano_version}; |
706
|
|
|
|
|
|
|
|
707
|
16
|
|
|
|
|
39
|
my $indent = 0; |
708
|
16
|
|
|
|
|
47
|
my @deriveds = ( $dbh->{ImplementorClass} ); |
709
|
16
|
|
|
|
|
64
|
while (@deriveds) |
710
|
|
|
|
|
|
|
{ |
711
|
40
|
|
|
|
|
83
|
my $derived = shift @deriveds; |
712
|
40
|
100
|
|
|
|
109
|
$derived eq "DBI::DBD::SqlEngine::db" and last; |
713
|
24
|
50
|
|
|
|
213
|
$derived->isa("DBI::DBD::SqlEngine::db") or next; |
714
|
|
|
|
|
|
|
#no strict 'refs'; |
715
|
24
|
|
|
|
|
1414
|
eval "push \@deriveds, \@${derived}::ISA"; |
716
|
|
|
|
|
|
|
#use strict; |
717
|
24
|
|
|
|
|
158
|
( my $drv_class = $derived ) =~ s/::db$//; |
718
|
24
|
|
|
|
|
99
|
my $drv_prefix = DBI->driver_prefix($drv_class); |
719
|
24
|
|
|
|
|
172
|
my $ddgv = $dbh->{ImplementorClass}->can("get_${drv_prefix}versions"); |
720
|
24
|
50
|
|
|
|
168
|
my $drv_version = $ddgv ? &$ddgv( $dbh, $table ) : $dbh->{ $drv_prefix . "version" }; |
721
|
|
|
|
|
|
|
$drv_version ||= |
722
|
24
|
|
33
|
|
|
73
|
eval { $derived->VERSION() }; # XXX access $drv_class::VERSION via symbol table |
|
0
|
|
|
|
|
0
|
|
723
|
24
|
|
|
|
|
58
|
$vsn{$drv_class} = $drv_version; |
724
|
24
|
100
|
|
|
|
76
|
$indent and $vmp{$drv_class} = " " x $indent . $drv_class; |
725
|
24
|
|
|
|
|
73
|
$indent += 2; |
726
|
|
|
|
|
|
|
} |
727
|
|
|
|
|
|
|
|
728
|
16
|
|
|
|
|
1008
|
$vsn{"DBI::DBD::SqlEngine"} = $sql_engine_verinfo; |
729
|
16
|
50
|
|
|
|
97
|
$indent and $vmp{"DBI::DBD::SqlEngine"} = " " x $indent . "DBI::DBD::SqlEngine"; |
730
|
|
|
|
|
|
|
|
731
|
16
|
100
|
|
|
|
60
|
$DBI::PurePerl and $vsn{"DBI::PurePerl"} = $DBI::PurePerl::VERSION; |
732
|
|
|
|
|
|
|
|
733
|
16
|
|
|
|
|
27
|
$indent += 20; |
734
|
96
|
|
66
|
|
|
629
|
my @versions = map { sprintf "%-${indent}s %s", $vmp{$_} || $_, $vsn{$_} } |
735
|
|
|
|
|
|
|
sort { |
736
|
16
|
100
|
|
|
|
104
|
$a->isa($b) and return -1; |
|
158
|
|
|
|
|
554
|
|
737
|
146
|
100
|
|
|
|
535
|
$b->isa($a) and return 1; |
738
|
132
|
100
|
|
|
|
334
|
$a->isa("DBI::DBD::SqlEngine") and return -1; |
739
|
91
|
100
|
|
|
|
252
|
$b->isa("DBI::DBD::SqlEngine") and return 1; |
740
|
57
|
|
|
|
|
116
|
return $a cmp $b; |
741
|
|
|
|
|
|
|
} keys %vsn; |
742
|
|
|
|
|
|
|
|
743
|
16
|
50
|
|
|
|
189
|
return wantarray ? @versions : join "\n", @versions; |
744
|
|
|
|
|
|
|
} # get_versions |
745
|
|
|
|
|
|
|
|
746
|
|
|
|
|
|
|
sub get_single_table_meta |
747
|
|
|
|
|
|
|
{ |
748
|
62
|
|
|
62
|
|
132
|
my ( $dbh, $table, $attr ) = @_; |
749
|
62
|
|
|
|
|
100
|
my $meta; |
750
|
|
|
|
|
|
|
|
751
|
62
|
50
|
|
|
|
150
|
$table eq "." |
752
|
|
|
|
|
|
|
and return $dbh->FETCH($attr); |
753
|
|
|
|
|
|
|
|
754
|
62
|
|
|
|
|
314
|
( my $class = $dbh->{ImplementorClass} ) =~ s/::db$/::Table/; |
755
|
62
|
|
|
|
|
247
|
( undef, $meta ) = $class->get_table_meta( $dbh, $table, 1 ); |
756
|
62
|
50
|
|
|
|
170
|
$meta or croak "No such table '$table'"; |
757
|
|
|
|
|
|
|
|
758
|
|
|
|
|
|
|
# prevent creation of undef attributes |
759
|
62
|
|
|
|
|
260
|
return $class->get_table_meta_attr( $meta, $attr ); |
760
|
|
|
|
|
|
|
} # get_single_table_meta |
761
|
|
|
|
|
|
|
|
762
|
|
|
|
|
|
|
sub get_sql_engine_meta |
763
|
|
|
|
|
|
|
{ |
764
|
38
|
|
|
38
|
|
125
|
my ( $dbh, $table, $attr ) = @_; |
765
|
|
|
|
|
|
|
|
766
|
38
|
|
|
|
|
211
|
my $gstm = $dbh->{ImplementorClass}->can("get_single_table_meta"); |
767
|
|
|
|
|
|
|
|
768
|
|
|
|
|
|
|
$table eq "*" |
769
|
38
|
50
|
|
|
|
154
|
and $table = [ ".", keys %{ $dbh->{sql_meta} } ]; |
|
0
|
|
|
|
|
0
|
|
770
|
|
|
|
|
|
|
$table eq "+" |
771
|
38
|
50
|
|
|
|
118
|
and $table = [ grep { m/^[_A-Za-z0-9]+$/ } keys %{ $dbh->{sql_meta} } ]; |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
772
|
|
|
|
|
|
|
ref $table eq "Regexp" |
773
|
38
|
50
|
|
|
|
112
|
and $table = [ grep { $_ =~ $table } keys %{ $dbh->{sql_meta} } ]; |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
774
|
|
|
|
|
|
|
|
775
|
38
|
100
|
100
|
|
|
240
|
ref $table || ref $attr |
776
|
|
|
|
|
|
|
or return $gstm->( $dbh, $table, $attr ); |
777
|
|
|
|
|
|
|
|
778
|
10
|
100
|
|
|
|
46
|
ref $table or $table = [$table]; |
779
|
10
|
50
|
|
|
|
52
|
ref $attr or $attr = [$attr]; |
780
|
10
|
50
|
|
|
|
42
|
"ARRAY" eq ref $table |
781
|
|
|
|
|
|
|
or return |
782
|
|
|
|
|
|
|
$dbh->set_err( $DBI::stderr, |
783
|
|
|
|
|
|
|
"Invalid argument for \$table - SCALAR, Regexp or ARRAY expected but got " . ref $table ); |
784
|
10
|
50
|
|
|
|
40
|
"ARRAY" eq ref $attr |
785
|
|
|
|
|
|
|
or return $dbh->set_err( |
786
|
|
|
|
|
|
|
"Invalid argument for \$attr - SCALAR or ARRAY expected but got " . ref $attr ); |
787
|
|
|
|
|
|
|
|
788
|
10
|
|
|
|
|
24
|
my %results; |
789
|
10
|
|
|
|
|
20
|
foreach my $tname ( @{$table} ) |
|
10
|
|
|
|
|
33
|
|
790
|
|
|
|
|
|
|
{ |
791
|
18
|
|
|
|
|
30
|
my %tattrs; |
792
|
18
|
|
|
|
|
29
|
foreach my $aname ( @{$attr} ) |
|
18
|
|
|
|
|
53
|
|
793
|
|
|
|
|
|
|
{ |
794
|
34
|
|
|
|
|
73
|
$tattrs{$aname} = $gstm->( $dbh, $tname, $aname ); |
795
|
|
|
|
|
|
|
} |
796
|
18
|
|
|
|
|
69
|
$results{$tname} = \%tattrs; |
797
|
|
|
|
|
|
|
} |
798
|
|
|
|
|
|
|
|
799
|
10
|
|
|
|
|
59
|
return \%results; |
800
|
|
|
|
|
|
|
} # get_sql_engine_meta |
801
|
|
|
|
|
|
|
|
802
|
|
|
|
|
|
|
sub new_sql_engine_meta |
803
|
|
|
|
|
|
|
{ |
804
|
6
|
|
|
6
|
|
23
|
my ( $dbh, $table, $values ) = @_; |
805
|
6
|
|
|
|
|
24
|
my $respect_case = 0; |
806
|
|
|
|
|
|
|
|
807
|
6
|
50
|
|
|
|
32
|
"HASH" eq ref $values |
808
|
|
|
|
|
|
|
or croak "Invalid argument for \$values - SCALAR or HASH expected but got " . ref $values; |
809
|
|
|
|
|
|
|
|
810
|
6
|
50
|
|
|
|
26
|
$table =~ s/^\"// and $respect_case = 1; # handle quoted identifiers |
811
|
6
|
|
|
|
|
18
|
$table =~ s/\"$//; |
812
|
|
|
|
|
|
|
|
813
|
6
|
50
|
|
|
|
23
|
unless ($respect_case) |
814
|
|
|
|
|
|
|
{ |
815
|
6
|
50
|
|
|
|
34
|
defined $dbh->{sql_meta_map}{$table} and $table = $dbh->{sql_meta_map}{$table}; |
816
|
|
|
|
|
|
|
} |
817
|
|
|
|
|
|
|
|
818
|
6
|
|
|
|
|
14
|
$dbh->{sql_meta}{$table} = { %{$values} }; |
|
6
|
|
|
|
|
33
|
|
819
|
6
|
|
|
|
|
15
|
my $class; |
820
|
6
|
100
|
|
|
|
22
|
defined $values->{sql_table_class} and $class = $values->{sql_table_class}; |
821
|
6
|
100
|
|
|
|
54
|
defined $class or ( $class = $dbh->{ImplementorClass} ) =~ s/::db$/::Table/; |
822
|
|
|
|
|
|
|
# XXX we should never hit DBD::File::Table::get_table_meta here ... |
823
|
6
|
|
|
|
|
44
|
my ( undef, $meta ) = $class->get_table_meta( $dbh, $table, $respect_case ); |
824
|
6
|
|
|
|
|
37
|
1; |
825
|
|
|
|
|
|
|
} # new_sql_engine_meta |
826
|
|
|
|
|
|
|
|
827
|
|
|
|
|
|
|
sub set_single_table_meta |
828
|
|
|
|
|
|
|
{ |
829
|
8
|
|
|
8
|
|
27
|
my ( $dbh, $table, $attr, $value ) = @_; |
830
|
8
|
|
|
|
|
14
|
my $meta; |
831
|
|
|
|
|
|
|
|
832
|
8
|
50
|
|
|
|
22
|
$table eq "." |
833
|
|
|
|
|
|
|
and return $dbh->STORE( $attr, $value ); |
834
|
|
|
|
|
|
|
|
835
|
8
|
|
|
|
|
53
|
( my $class = $dbh->{ImplementorClass} ) =~ s/::db$/::Table/; |
836
|
8
|
|
|
|
|
54
|
( undef, $meta ) = $class->get_table_meta( $dbh, $table, 1 ); # 1 means: respect case |
837
|
8
|
50
|
|
|
|
26
|
$meta or croak "No such table '$table'"; |
838
|
8
|
|
|
|
|
67
|
$class->set_table_meta_attr( $meta, $attr, $value ); |
839
|
|
|
|
|
|
|
|
840
|
8
|
|
|
|
|
40
|
return $dbh; |
841
|
|
|
|
|
|
|
} # set_single_table_meta |
842
|
|
|
|
|
|
|
|
843
|
|
|
|
|
|
|
sub set_sql_engine_meta |
844
|
|
|
|
|
|
|
{ |
845
|
8
|
|
|
8
|
|
32
|
my ( $dbh, $table, $attr, $value ) = @_; |
846
|
|
|
|
|
|
|
|
847
|
8
|
|
|
|
|
47
|
my $sstm = $dbh->{ImplementorClass}->can("set_single_table_meta"); |
848
|
|
|
|
|
|
|
|
849
|
|
|
|
|
|
|
$table eq "*" |
850
|
8
|
50
|
|
|
|
32
|
and $table = [ ".", keys %{ $dbh->{sql_meta} } ]; |
|
0
|
|
|
|
|
0
|
|
851
|
|
|
|
|
|
|
$table eq "+" |
852
|
8
|
50
|
|
|
|
25
|
and $table = [ grep { m/^[_A-Za-z0-9]+$/ } keys %{ $dbh->{sql_meta} } ]; |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
853
|
|
|
|
|
|
|
ref($table) eq "Regexp" |
854
|
8
|
50
|
|
|
|
22
|
and $table = [ grep { $_ =~ $table } keys %{ $dbh->{sql_meta} } ]; |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
855
|
|
|
|
|
|
|
|
856
|
8
|
100
|
66
|
|
|
92
|
ref $table || ref $attr |
857
|
|
|
|
|
|
|
or return $sstm->( $dbh, $table, $attr, $value ); |
858
|
|
|
|
|
|
|
|
859
|
4
|
50
|
|
|
|
20
|
ref $table or $table = [$table]; |
860
|
4
|
50
|
|
|
|
16
|
ref $attr or $attr = { $attr => $value }; |
861
|
4
|
50
|
|
|
|
16
|
"ARRAY" eq ref $table |
862
|
|
|
|
|
|
|
or croak "Invalid argument for \$table - SCALAR, Regexp or ARRAY expected but got " |
863
|
|
|
|
|
|
|
. ref $table; |
864
|
4
|
50
|
|
|
|
29
|
"HASH" eq ref $attr |
865
|
|
|
|
|
|
|
or croak "Invalid argument for \$attr - SCALAR or HASH expected but got " . ref $attr; |
866
|
|
|
|
|
|
|
|
867
|
4
|
|
|
|
|
9
|
foreach my $tname ( @{$table} ) |
|
4
|
|
|
|
|
15
|
|
868
|
|
|
|
|
|
|
{ |
869
|
4
|
|
|
|
|
23
|
while ( my ( $aname, $aval ) = each %$attr ) |
870
|
|
|
|
|
|
|
{ |
871
|
4
|
|
|
|
|
17
|
$sstm->( $dbh, $tname, $aname, $aval ); |
872
|
|
|
|
|
|
|
} |
873
|
|
|
|
|
|
|
} |
874
|
|
|
|
|
|
|
|
875
|
4
|
|
|
|
|
19
|
return $dbh; |
876
|
|
|
|
|
|
|
} # set_file_meta |
877
|
|
|
|
|
|
|
|
878
|
|
|
|
|
|
|
sub clear_sql_engine_meta |
879
|
|
|
|
|
|
|
{ |
880
|
4
|
|
|
4
|
|
14
|
my ( $dbh, $table ) = @_; |
881
|
|
|
|
|
|
|
|
882
|
4
|
|
|
|
|
26
|
( my $class = $dbh->{ImplementorClass} ) =~ s/::db$/::Table/; |
883
|
4
|
|
|
|
|
22
|
my ( undef, $meta ) = $class->get_table_meta( $dbh, $table, 1 ); |
884
|
4
|
50
|
|
|
|
16
|
$meta and %{$meta} = (); |
|
4
|
|
|
|
|
21
|
|
885
|
|
|
|
|
|
|
|
886
|
4
|
|
|
|
|
15
|
return; |
887
|
|
|
|
|
|
|
} # clear_file_meta |
888
|
|
|
|
|
|
|
|
889
|
|
|
|
|
|
|
sub DESTROY ($) |
890
|
|
|
|
|
|
|
{ |
891
|
194
|
|
|
194
|
|
11071
|
my $dbh = shift; |
892
|
194
|
50
|
|
|
|
1023
|
$dbh->SUPER::FETCH("Active") and $dbh->disconnect; |
893
|
194
|
|
|
|
|
5757
|
undef $dbh->{sql_parser_object}; |
894
|
|
|
|
|
|
|
} # DESTROY |
895
|
|
|
|
|
|
|
|
896
|
|
|
|
|
|
|
sub type_info_all ($) |
897
|
|
|
|
|
|
|
{ |
898
|
|
|
|
|
|
|
[ |
899
|
|
|
|
|
|
|
{ |
900
|
0
|
|
|
0
|
|
0
|
TYPE_NAME => 0, |
901
|
|
|
|
|
|
|
DATA_TYPE => 1, |
902
|
|
|
|
|
|
|
PRECISION => 2, |
903
|
|
|
|
|
|
|
LITERAL_PREFIX => 3, |
904
|
|
|
|
|
|
|
LITERAL_SUFFIX => 4, |
905
|
|
|
|
|
|
|
CREATE_PARAMS => 5, |
906
|
|
|
|
|
|
|
NULLABLE => 6, |
907
|
|
|
|
|
|
|
CASE_SENSITIVE => 7, |
908
|
|
|
|
|
|
|
SEARCHABLE => 8, |
909
|
|
|
|
|
|
|
UNSIGNED_ATTRIBUTE => 9, |
910
|
|
|
|
|
|
|
MONEY => 10, |
911
|
|
|
|
|
|
|
AUTO_INCREMENT => 11, |
912
|
|
|
|
|
|
|
LOCAL_TYPE_NAME => 12, |
913
|
|
|
|
|
|
|
MINIMUM_SCALE => 13, |
914
|
|
|
|
|
|
|
MAXIMUM_SCALE => 14, |
915
|
|
|
|
|
|
|
}, |
916
|
|
|
|
|
|
|
[ |
917
|
|
|
|
|
|
|
"VARCHAR", DBI::SQL_VARCHAR(), undef, "'", "'", undef, 0, 1, 1, 0, 0, 0, undef, 1, 999999, |
918
|
|
|
|
|
|
|
], |
919
|
|
|
|
|
|
|
[ "CHAR", DBI::SQL_CHAR(), undef, "'", "'", undef, 0, 1, 1, 0, 0, 0, undef, 1, 999999, ], |
920
|
|
|
|
|
|
|
[ "INTEGER", DBI::SQL_INTEGER(), undef, "", "", undef, 0, 0, 1, 0, 0, 0, undef, 0, 0, ], |
921
|
|
|
|
|
|
|
[ "REAL", DBI::SQL_REAL(), undef, "", "", undef, 0, 0, 1, 0, 0, 0, undef, 0, 0, ], |
922
|
|
|
|
|
|
|
[ |
923
|
|
|
|
|
|
|
"BLOB", DBI::SQL_LONGVARBINARY(), undef, "'", "'", undef, 0, 1, 1, 0, 0, 0, undef, 1, |
924
|
|
|
|
|
|
|
999999, |
925
|
|
|
|
|
|
|
], |
926
|
|
|
|
|
|
|
[ |
927
|
|
|
|
|
|
|
"BLOB", DBI::SQL_LONGVARBINARY(), undef, "'", "'", undef, 0, 1, 1, 0, 0, 0, undef, 1, |
928
|
|
|
|
|
|
|
999999, |
929
|
|
|
|
|
|
|
], |
930
|
|
|
|
|
|
|
[ |
931
|
|
|
|
|
|
|
"TEXT", DBI::SQL_LONGVARCHAR(), undef, "'", "'", undef, 0, 1, 1, 0, 0, 0, undef, 1, |
932
|
|
|
|
|
|
|
999999, |
933
|
|
|
|
|
|
|
], |
934
|
|
|
|
|
|
|
]; |
935
|
|
|
|
|
|
|
} # type_info_all |
936
|
|
|
|
|
|
|
|
937
|
|
|
|
|
|
|
sub get_avail_tables |
938
|
|
|
|
|
|
|
{ |
939
|
36
|
|
|
36
|
|
370
|
my $dbh = $_[0]; |
940
|
36
|
|
|
|
|
85
|
my @tables = (); |
941
|
|
|
|
|
|
|
|
942
|
36
|
0
|
33
|
|
|
154
|
if ( $dbh->{sql_handler} eq "SQL::Statement" and $dbh->{sql_ram_tables} ) |
943
|
|
|
|
|
|
|
{ |
944
|
|
|
|
|
|
|
# XXX map +[ undef, undef, $_, "TABLE", "TEMP" ], keys %{...} |
945
|
0
|
|
|
|
|
0
|
foreach my $table ( keys %{ $dbh->{sql_ram_tables} } ) |
|
0
|
|
|
|
|
0
|
|
946
|
|
|
|
|
|
|
{ |
947
|
0
|
|
|
|
|
0
|
push @tables, [ undef, undef, $table, "TABLE", "TEMP" ]; |
948
|
|
|
|
|
|
|
} |
949
|
|
|
|
|
|
|
} |
950
|
|
|
|
|
|
|
|
951
|
36
|
|
|
|
|
73
|
my $tbl_src; |
952
|
|
|
|
|
|
|
defined $dbh->{sql_table_source} |
953
|
|
|
|
|
|
|
and $dbh->{sql_table_source}->isa('DBI::DBD::SqlEngine::TableSource') |
954
|
36
|
50
|
33
|
|
|
154
|
and $tbl_src = $dbh->{sql_table_source}; |
955
|
|
|
|
|
|
|
|
956
|
|
|
|
|
|
|
!defined($tbl_src) |
957
|
|
|
|
|
|
|
and $dbh->{Driver}->{ImplementorClass}->can('default_table_source') |
958
|
36
|
50
|
33
|
|
|
674
|
and $tbl_src = $dbh->{Driver}->{ImplementorClass}->default_table_source(); |
959
|
36
|
50
|
|
|
|
362
|
defined($tbl_src) and push( @tables, $tbl_src->avail_tables($dbh) ); |
960
|
|
|
|
|
|
|
|
961
|
36
|
|
|
|
|
199
|
return @tables; |
962
|
|
|
|
|
|
|
} # get_avail_tables |
963
|
|
|
|
|
|
|
|
964
|
|
|
|
|
|
|
{ |
965
|
|
|
|
|
|
|
my $names = [qw( TABLE_QUALIFIER TABLE_OWNER TABLE_NAME TABLE_TYPE REMARKS )]; |
966
|
|
|
|
|
|
|
|
967
|
|
|
|
|
|
|
sub table_info ($) |
968
|
|
|
|
|
|
|
{ |
969
|
28
|
|
|
28
|
|
3410
|
my $dbh = shift; |
970
|
|
|
|
|
|
|
|
971
|
28
|
|
|
|
|
500
|
my @tables = $dbh->func("get_avail_tables"); |
972
|
|
|
|
|
|
|
|
973
|
|
|
|
|
|
|
# Temporary kludge: DBD::Sponge dies if @tables is empty. :-( |
974
|
|
|
|
|
|
|
# this no longer seems to be true @tables or return; |
975
|
|
|
|
|
|
|
|
976
|
28
|
|
|
|
|
409
|
my $dbh2 = $dbh->func("sql_sponge_driver"); |
977
|
28
|
|
|
|
|
462
|
my $sth = $dbh2->prepare( |
978
|
|
|
|
|
|
|
"TABLE_INFO", |
979
|
|
|
|
|
|
|
{ |
980
|
|
|
|
|
|
|
rows => \@tables, |
981
|
|
|
|
|
|
|
NAME => $names, |
982
|
|
|
|
|
|
|
} |
983
|
|
|
|
|
|
|
); |
984
|
28
|
50
|
|
|
|
443
|
$sth or return $dbh->set_err( $DBI::stderr, $dbh2->errstr ); |
985
|
28
|
50
|
|
|
|
220
|
$sth->execute or return; |
986
|
28
|
|
|
|
|
378
|
return $sth; |
987
|
|
|
|
|
|
|
} # table_info |
988
|
|
|
|
|
|
|
} |
989
|
|
|
|
|
|
|
|
990
|
|
|
|
|
|
|
sub list_tables ($) |
991
|
|
|
|
|
|
|
{ |
992
|
8
|
|
|
8
|
|
135
|
my $dbh = shift; |
993
|
8
|
|
|
|
|
18
|
my @table_list; |
994
|
|
|
|
|
|
|
|
995
|
8
|
50
|
|
|
|
49
|
my @tables = $dbh->func("get_avail_tables") or return; |
996
|
8
|
|
|
|
|
80
|
foreach my $ref (@tables) |
997
|
|
|
|
|
|
|
{ |
998
|
|
|
|
|
|
|
# rt69260 and rt67223 - the same issue in 2 different queues |
999
|
16
|
|
|
|
|
47
|
push @table_list, $ref->[2]; |
1000
|
|
|
|
|
|
|
} |
1001
|
|
|
|
|
|
|
|
1002
|
8
|
|
|
|
|
41
|
return @table_list; |
1003
|
|
|
|
|
|
|
} # list_tables |
1004
|
|
|
|
|
|
|
|
1005
|
|
|
|
|
|
|
sub quote ($$;$) |
1006
|
|
|
|
|
|
|
{ |
1007
|
0
|
|
|
0
|
|
0
|
my ( $self, $str, $type ) = @_; |
1008
|
0
|
0
|
|
|
|
0
|
defined $str or return "NULL"; |
1009
|
0
|
0
|
0
|
|
|
0
|
defined $type && ( $type == DBI::SQL_NUMERIC() |
|
|
|
0
|
|
|
|
|
1010
|
|
|
|
|
|
|
|| $type == DBI::SQL_DECIMAL() |
1011
|
|
|
|
|
|
|
|| $type == DBI::SQL_INTEGER() |
1012
|
|
|
|
|
|
|
|| $type == DBI::SQL_SMALLINT() |
1013
|
|
|
|
|
|
|
|| $type == DBI::SQL_FLOAT() |
1014
|
|
|
|
|
|
|
|| $type == DBI::SQL_REAL() |
1015
|
|
|
|
|
|
|
|| $type == DBI::SQL_DOUBLE() |
1016
|
|
|
|
|
|
|
|| $type == DBI::SQL_TINYINT() ) |
1017
|
|
|
|
|
|
|
and return $str; |
1018
|
|
|
|
|
|
|
|
1019
|
0
|
|
|
|
|
0
|
$str =~ s/\\/\\\\/sg; |
1020
|
0
|
|
|
|
|
0
|
$str =~ s/\0/\\0/sg; |
1021
|
0
|
|
|
|
|
0
|
$str =~ s/\'/\\\'/sg; |
1022
|
0
|
|
|
|
|
0
|
$str =~ s/\n/\\n/sg; |
1023
|
0
|
|
|
|
|
0
|
$str =~ s/\r/\\r/sg; |
1024
|
0
|
|
|
|
|
0
|
return "'$str'"; |
1025
|
|
|
|
|
|
|
} # quote |
1026
|
|
|
|
|
|
|
|
1027
|
|
|
|
|
|
|
sub commit ($) |
1028
|
|
|
|
|
|
|
{ |
1029
|
0
|
|
|
0
|
|
0
|
my $dbh = shift; |
1030
|
0
|
0
|
|
|
|
0
|
$dbh->FETCH("Warn") |
1031
|
|
|
|
|
|
|
and carp "Commit ineffective while AutoCommit is on", -1; |
1032
|
0
|
|
|
|
|
0
|
return 1; |
1033
|
|
|
|
|
|
|
} # commit |
1034
|
|
|
|
|
|
|
|
1035
|
|
|
|
|
|
|
sub rollback ($) |
1036
|
|
|
|
|
|
|
{ |
1037
|
0
|
|
|
0
|
|
0
|
my $dbh = shift; |
1038
|
0
|
0
|
|
|
|
0
|
$dbh->FETCH("Warn") |
1039
|
|
|
|
|
|
|
and carp "Rollback ineffective while AutoCommit is on", -1; |
1040
|
0
|
|
|
|
|
0
|
return 0; |
1041
|
|
|
|
|
|
|
} # rollback |
1042
|
|
|
|
|
|
|
|
1043
|
|
|
|
|
|
|
# ====== Tie-Meta ============================================================== |
1044
|
|
|
|
|
|
|
|
1045
|
|
|
|
|
|
|
package DBI::DBD::SqlEngine::TieMeta; |
1046
|
|
|
|
|
|
|
|
1047
|
54
|
|
|
54
|
|
550
|
use Carp qw(croak); |
|
54
|
|
|
|
|
132
|
|
|
54
|
|
|
|
|
20057
|
|
1048
|
|
|
|
|
|
|
require Tie::Hash; |
1049
|
|
|
|
|
|
|
@DBI::DBD::SqlEngine::TieMeta::ISA = qw(Tie::Hash); |
1050
|
|
|
|
|
|
|
|
1051
|
|
|
|
|
|
|
sub TIEHASH |
1052
|
|
|
|
|
|
|
{ |
1053
|
24
|
|
|
24
|
|
52
|
my ( $class, $tblClass, $tblMeta ) = @_; |
1054
|
|
|
|
|
|
|
|
1055
|
24
|
|
|
|
|
63
|
my $self = bless( |
1056
|
|
|
|
|
|
|
{ |
1057
|
|
|
|
|
|
|
tblClass => $tblClass, |
1058
|
|
|
|
|
|
|
tblMeta => $tblMeta, |
1059
|
|
|
|
|
|
|
}, |
1060
|
|
|
|
|
|
|
$class |
1061
|
|
|
|
|
|
|
); |
1062
|
24
|
|
|
|
|
50
|
return $self; |
1063
|
|
|
|
|
|
|
} # new |
1064
|
|
|
|
|
|
|
|
1065
|
|
|
|
|
|
|
sub STORE |
1066
|
|
|
|
|
|
|
{ |
1067
|
4
|
|
|
4
|
|
17
|
my ( $self, $meta_attr, $meta_val ) = @_; |
1068
|
|
|
|
|
|
|
|
1069
|
4
|
|
|
|
|
47
|
$self->{tblClass}->set_table_meta_attr( $self->{tblMeta}, $meta_attr, $meta_val ); |
1070
|
|
|
|
|
|
|
|
1071
|
4
|
|
|
|
|
13
|
return; |
1072
|
|
|
|
|
|
|
} # STORE |
1073
|
|
|
|
|
|
|
|
1074
|
|
|
|
|
|
|
sub FETCH |
1075
|
|
|
|
|
|
|
{ |
1076
|
20
|
|
|
20
|
|
61
|
my ( $self, $meta_attr ) = @_; |
1077
|
|
|
|
|
|
|
|
1078
|
20
|
|
|
|
|
77
|
return $self->{tblClass}->get_table_meta_attr( $self->{tblMeta}, $meta_attr ); |
1079
|
|
|
|
|
|
|
} # FETCH |
1080
|
|
|
|
|
|
|
|
1081
|
|
|
|
|
|
|
sub FIRSTKEY |
1082
|
|
|
|
|
|
|
{ |
1083
|
0
|
|
|
0
|
|
0
|
my $a = scalar keys %{ $_[0]->{tblMeta} }; |
|
0
|
|
|
|
|
0
|
|
1084
|
0
|
|
|
|
|
0
|
each %{ $_[0]->{tblMeta} }; |
|
0
|
|
|
|
|
0
|
|
1085
|
|
|
|
|
|
|
} # FIRSTKEY |
1086
|
|
|
|
|
|
|
|
1087
|
|
|
|
|
|
|
sub NEXTKEY |
1088
|
|
|
|
|
|
|
{ |
1089
|
0
|
|
|
0
|
|
0
|
each %{ $_[0]->{tblMeta} }; |
|
0
|
|
|
|
|
0
|
|
1090
|
|
|
|
|
|
|
} # NEXTKEY |
1091
|
|
|
|
|
|
|
|
1092
|
|
|
|
|
|
|
sub EXISTS |
1093
|
|
|
|
|
|
|
{ |
1094
|
0
|
|
|
0
|
|
0
|
exists $_[0]->{tblMeta}{ $_[1] }; |
1095
|
|
|
|
|
|
|
} # EXISTS |
1096
|
|
|
|
|
|
|
|
1097
|
|
|
|
|
|
|
sub DELETE |
1098
|
|
|
|
|
|
|
{ |
1099
|
0
|
|
|
0
|
|
0
|
croak "Can't delete single attributes from table meta structure"; |
1100
|
|
|
|
|
|
|
} # DELETE |
1101
|
|
|
|
|
|
|
|
1102
|
|
|
|
|
|
|
sub CLEAR |
1103
|
|
|
|
|
|
|
{ |
1104
|
0
|
|
|
0
|
|
0
|
%{ $_[0]->{tblMeta} } = (); |
|
0
|
|
|
|
|
0
|
|
1105
|
|
|
|
|
|
|
} # CLEAR |
1106
|
|
|
|
|
|
|
|
1107
|
|
|
|
|
|
|
sub SCALAR |
1108
|
|
|
|
|
|
|
{ |
1109
|
0
|
|
|
0
|
|
0
|
scalar %{ $_[0]->{tblMeta} }; |
|
0
|
|
|
|
|
0
|
|
1110
|
|
|
|
|
|
|
} # SCALAR |
1111
|
|
|
|
|
|
|
|
1112
|
|
|
|
|
|
|
# ====== Tie-Tables ============================================================ |
1113
|
|
|
|
|
|
|
|
1114
|
|
|
|
|
|
|
package DBI::DBD::SqlEngine::TieTables; |
1115
|
|
|
|
|
|
|
|
1116
|
54
|
|
|
54
|
|
483
|
use Carp qw(croak); |
|
54
|
|
|
|
|
131
|
|
|
54
|
|
|
|
|
31955
|
|
1117
|
|
|
|
|
|
|
require Tie::Hash; |
1118
|
|
|
|
|
|
|
@DBI::DBD::SqlEngine::TieTables::ISA = qw(Tie::Hash); |
1119
|
|
|
|
|
|
|
|
1120
|
|
|
|
|
|
|
sub TIEHASH |
1121
|
|
|
|
|
|
|
{ |
1122
|
388
|
|
|
388
|
|
970
|
my ( $class, $dbh ) = @_; |
1123
|
|
|
|
|
|
|
|
1124
|
388
|
|
|
|
|
2020
|
( my $tbl_class = $dbh->{ImplementorClass} ) =~ s/::db$/::Table/; |
1125
|
388
|
|
|
|
|
1749
|
my $self = bless( |
1126
|
|
|
|
|
|
|
{ |
1127
|
|
|
|
|
|
|
dbh => $dbh, |
1128
|
|
|
|
|
|
|
tblClass => $tbl_class, |
1129
|
|
|
|
|
|
|
}, |
1130
|
|
|
|
|
|
|
$class |
1131
|
|
|
|
|
|
|
); |
1132
|
388
|
|
|
|
|
1229
|
return $self; |
1133
|
|
|
|
|
|
|
} # new |
1134
|
|
|
|
|
|
|
|
1135
|
|
|
|
|
|
|
sub STORE |
1136
|
|
|
|
|
|
|
{ |
1137
|
0
|
|
|
0
|
|
0
|
my ( $self, $table, $tbl_meta ) = @_; |
1138
|
|
|
|
|
|
|
|
1139
|
0
|
0
|
|
|
|
0
|
"HASH" eq ref $tbl_meta |
1140
|
|
|
|
|
|
|
or croak "Invalid data for storing as table meta data (must be hash)"; |
1141
|
|
|
|
|
|
|
|
1142
|
0
|
|
|
|
|
0
|
( undef, my $meta ) = $self->{tblClass}->get_table_meta( $self->{dbh}, $table, 1 ); |
1143
|
0
|
0
|
|
|
|
0
|
$meta or croak "Invalid table name '$table'"; |
1144
|
|
|
|
|
|
|
|
1145
|
0
|
|
|
|
|
0
|
while ( my ( $meta_attr, $meta_val ) = each %$tbl_meta ) |
1146
|
|
|
|
|
|
|
{ |
1147
|
0
|
|
|
|
|
0
|
$self->{tblClass}->set_table_meta_attr( $meta, $meta_attr, $meta_val ); |
1148
|
|
|
|
|
|
|
} |
1149
|
|
|
|
|
|
|
|
1150
|
0
|
|
|
|
|
0
|
return; |
1151
|
|
|
|
|
|
|
} # STORE |
1152
|
|
|
|
|
|
|
|
1153
|
|
|
|
|
|
|
sub FETCH |
1154
|
|
|
|
|
|
|
{ |
1155
|
24
|
|
|
24
|
|
5625
|
my ( $self, $table ) = @_; |
1156
|
|
|
|
|
|
|
|
1157
|
24
|
|
|
|
|
113
|
( undef, my $meta ) = $self->{tblClass}->get_table_meta( $self->{dbh}, $table, 1 ); |
1158
|
24
|
50
|
|
|
|
56
|
$meta or croak "Invalid table name '$table'"; |
1159
|
|
|
|
|
|
|
|
1160
|
24
|
|
|
|
|
34
|
my %h; |
1161
|
24
|
|
|
|
|
95
|
tie %h, "DBI::DBD::SqlEngine::TieMeta", $self->{tblClass}, $meta; |
1162
|
|
|
|
|
|
|
|
1163
|
24
|
|
|
|
|
116
|
return \%h; |
1164
|
|
|
|
|
|
|
} # FETCH |
1165
|
|
|
|
|
|
|
|
1166
|
|
|
|
|
|
|
sub FIRSTKEY |
1167
|
|
|
|
|
|
|
{ |
1168
|
0
|
|
|
0
|
|
0
|
my $a = scalar keys %{ $_[0]->{dbh}->{sql_meta} }; |
|
0
|
|
|
|
|
0
|
|
1169
|
0
|
|
|
|
|
0
|
each %{ $_[0]->{dbh}->{sql_meta} }; |
|
0
|
|
|
|
|
0
|
|
1170
|
|
|
|
|
|
|
} # FIRSTKEY |
1171
|
|
|
|
|
|
|
|
1172
|
|
|
|
|
|
|
sub NEXTKEY |
1173
|
|
|
|
|
|
|
{ |
1174
|
0
|
|
|
0
|
|
0
|
each %{ $_[0]->{dbh}->{sql_meta} }; |
|
0
|
|
|
|
|
0
|
|
1175
|
|
|
|
|
|
|
} # NEXTKEY |
1176
|
|
|
|
|
|
|
|
1177
|
|
|
|
|
|
|
sub EXISTS |
1178
|
|
|
|
|
|
|
{ |
1179
|
|
|
|
|
|
|
exists $_[0]->{dbh}->{sql_meta}->{ $_[1] } |
1180
|
0
|
0
|
|
0
|
|
0
|
or exists $_[0]->{dbh}->{sql_meta_map}->{ $_[1] }; |
1181
|
|
|
|
|
|
|
} # EXISTS |
1182
|
|
|
|
|
|
|
|
1183
|
|
|
|
|
|
|
sub DELETE |
1184
|
|
|
|
|
|
|
{ |
1185
|
0
|
|
|
0
|
|
0
|
my ( $self, $table ) = @_; |
1186
|
|
|
|
|
|
|
|
1187
|
0
|
|
|
|
|
0
|
( undef, my $meta ) = $self->{tblClass}->get_table_meta( $self->{dbh}, $table, 1 ); |
1188
|
0
|
0
|
|
|
|
0
|
$meta or croak "Invalid table name '$table'"; |
1189
|
|
|
|
|
|
|
|
1190
|
0
|
|
|
|
|
0
|
delete $_[0]->{dbh}->{sql_meta}->{ $meta->{table_name} }; |
1191
|
|
|
|
|
|
|
} # DELETE |
1192
|
|
|
|
|
|
|
|
1193
|
|
|
|
|
|
|
sub CLEAR |
1194
|
|
|
|
|
|
|
{ |
1195
|
0
|
|
|
0
|
|
0
|
%{ $_[0]->{dbh}->{sql_meta} } = (); |
|
0
|
|
|
|
|
0
|
|
1196
|
0
|
|
|
|
|
0
|
%{ $_[0]->{dbh}->{sql_meta_map} } = (); |
|
0
|
|
|
|
|
0
|
|
1197
|
|
|
|
|
|
|
} # CLEAR |
1198
|
|
|
|
|
|
|
|
1199
|
|
|
|
|
|
|
sub SCALAR |
1200
|
|
|
|
|
|
|
{ |
1201
|
0
|
|
|
0
|
|
0
|
scalar %{ $_[0]->{dbh}->{sql_meta} }; |
|
0
|
|
|
|
|
0
|
|
1202
|
|
|
|
|
|
|
} # SCALAR |
1203
|
|
|
|
|
|
|
|
1204
|
|
|
|
|
|
|
# ====== STATEMENT ============================================================= |
1205
|
|
|
|
|
|
|
|
1206
|
|
|
|
|
|
|
package DBI::DBD::SqlEngine::st; |
1207
|
|
|
|
|
|
|
|
1208
|
54
|
|
|
54
|
|
469
|
use strict; |
|
54
|
|
|
|
|
128
|
|
|
54
|
|
|
|
|
1506
|
|
1209
|
54
|
|
|
54
|
|
308
|
use warnings; |
|
54
|
|
|
|
|
133
|
|
|
54
|
|
|
|
|
2185
|
|
1210
|
|
|
|
|
|
|
|
1211
|
54
|
|
|
54
|
|
341
|
use vars qw(@ISA $imp_data_size); |
|
54
|
|
|
|
|
131
|
|
|
54
|
|
|
|
|
33466
|
|
1212
|
|
|
|
|
|
|
|
1213
|
|
|
|
|
|
|
$imp_data_size = 0; |
1214
|
|
|
|
|
|
|
|
1215
|
|
|
|
|
|
|
sub bind_param ($$$;$) |
1216
|
|
|
|
|
|
|
{ |
1217
|
108
|
|
|
108
|
|
1655
|
my ( $sth, $pNum, $val, $attr ) = @_; |
1218
|
108
|
50
|
33
|
|
|
321
|
if ( $attr && defined $val ) |
1219
|
|
|
|
|
|
|
{ |
1220
|
0
|
0
|
|
|
|
0
|
my $type = ref $attr eq "HASH" ? $attr->{TYPE} : $attr; |
1221
|
0
|
0
|
0
|
|
|
0
|
if ( $type == DBI::SQL_BIGINT() |
|
|
0
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
1222
|
|
|
|
|
|
|
|| $type == DBI::SQL_INTEGER() |
1223
|
|
|
|
|
|
|
|| $type == DBI::SQL_SMALLINT() |
1224
|
|
|
|
|
|
|
|| $type == DBI::SQL_TINYINT() ) |
1225
|
|
|
|
|
|
|
{ |
1226
|
0
|
|
|
|
|
0
|
$val += 0; |
1227
|
|
|
|
|
|
|
} |
1228
|
|
|
|
|
|
|
elsif ( $type == DBI::SQL_DECIMAL() |
1229
|
|
|
|
|
|
|
|| $type == DBI::SQL_DOUBLE() |
1230
|
|
|
|
|
|
|
|| $type == DBI::SQL_FLOAT() |
1231
|
|
|
|
|
|
|
|| $type == DBI::SQL_NUMERIC() |
1232
|
|
|
|
|
|
|
|| $type == DBI::SQL_REAL() ) |
1233
|
|
|
|
|
|
|
{ |
1234
|
0
|
|
|
|
|
0
|
$val += 0.; |
1235
|
|
|
|
|
|
|
} |
1236
|
|
|
|
|
|
|
else |
1237
|
|
|
|
|
|
|
{ |
1238
|
0
|
|
|
|
|
0
|
$val = "$val"; |
1239
|
|
|
|
|
|
|
} |
1240
|
|
|
|
|
|
|
} |
1241
|
108
|
|
|
|
|
336
|
$sth->{sql_params}[ $pNum - 1 ] = $val; |
1242
|
108
|
|
|
|
|
302
|
return 1; |
1243
|
|
|
|
|
|
|
} # bind_param |
1244
|
|
|
|
|
|
|
|
1245
|
|
|
|
|
|
|
sub execute |
1246
|
|
|
|
|
|
|
{ |
1247
|
502
|
|
|
502
|
|
15707
|
my $sth = shift; |
1248
|
502
|
100
|
|
|
|
1619
|
my $params = @_ ? ( $sth->{sql_params} = [@_] ) : $sth->{sql_params}; |
1249
|
|
|
|
|
|
|
|
1250
|
502
|
|
|
|
|
2217
|
$sth->finish; |
1251
|
502
|
|
|
|
|
3181
|
my $stmt = $sth->{sql_stmt}; |
1252
|
|
|
|
|
|
|
|
1253
|
|
|
|
|
|
|
# must not proved when already executed - SQL::Statement modifies |
1254
|
|
|
|
|
|
|
# received params |
1255
|
502
|
50
|
|
|
|
1728
|
unless ( $sth->{sql_params_checked}++ ) |
1256
|
|
|
|
|
|
|
{ |
1257
|
|
|
|
|
|
|
# SQL::Statement and DBI::SQL::Nano will return the list of required params |
1258
|
|
|
|
|
|
|
# when called in list context. Do not look into the several items, they're |
1259
|
|
|
|
|
|
|
# implementation specific and may change without warning |
1260
|
502
|
50
|
|
|
|
1510
|
unless ( ( my $req_prm = $stmt->params() ) == ( my $nparm = @$params ) ) |
1261
|
|
|
|
|
|
|
{ |
1262
|
0
|
|
|
|
|
0
|
my $msg = "You passed $nparm parameters where $req_prm required"; |
1263
|
0
|
|
|
|
|
0
|
return $sth->set_err( $DBI::stderr, $msg ); |
1264
|
|
|
|
|
|
|
} |
1265
|
|
|
|
|
|
|
} |
1266
|
|
|
|
|
|
|
|
1267
|
502
|
|
|
|
|
1020
|
my @err; |
1268
|
|
|
|
|
|
|
my $result; |
1269
|
502
|
|
|
|
|
873
|
eval { |
1270
|
502
|
|
|
0
|
|
3997
|
local $SIG{__WARN__} = sub { push @err, @_ }; |
|
0
|
|
|
|
|
0
|
|
1271
|
502
|
|
|
|
|
2135
|
$result = $stmt->execute( $sth, $params ); |
1272
|
|
|
|
|
|
|
}; |
1273
|
502
|
100
|
|
|
|
3446
|
unless ( defined $result ) |
1274
|
|
|
|
|
|
|
{ |
1275
|
32
|
|
0
|
|
|
368
|
$sth->set_err( $DBI::stderr, $@ || $stmt->{errstr} || $err[0] ); |
1276
|
32
|
|
|
|
|
462
|
return; |
1277
|
|
|
|
|
|
|
} |
1278
|
|
|
|
|
|
|
|
1279
|
470
|
100
|
|
|
|
1331
|
if ( $stmt->{NUM_OF_FIELDS} ) |
1280
|
|
|
|
|
|
|
{ # is a SELECT statement |
1281
|
96
|
|
|
|
|
598
|
$sth->STORE( Active => 1 ); |
1282
|
|
|
|
|
|
|
$sth->FETCH("NUM_OF_FIELDS") |
1283
|
96
|
100
|
|
|
|
911
|
or $sth->STORE( "NUM_OF_FIELDS", $stmt->{NUM_OF_FIELDS} ); |
1284
|
|
|
|
|
|
|
} |
1285
|
470
|
|
|
|
|
2470
|
return $result; |
1286
|
|
|
|
|
|
|
} # execute |
1287
|
|
|
|
|
|
|
|
1288
|
|
|
|
|
|
|
sub finish |
1289
|
|
|
|
|
|
|
{ |
1290
|
934
|
|
|
934
|
|
13850
|
my $sth = $_[0]; |
1291
|
934
|
|
|
|
|
3000
|
$sth->SUPER::STORE( Active => 0 ); |
1292
|
934
|
|
|
|
|
1784
|
delete $sth->{sql_stmt}{data}; |
1293
|
934
|
|
|
|
|
2133
|
return 1; |
1294
|
|
|
|
|
|
|
} # finish |
1295
|
|
|
|
|
|
|
|
1296
|
|
|
|
|
|
|
sub fetch ($) |
1297
|
|
|
|
|
|
|
{ |
1298
|
322
|
|
|
322
|
|
8139
|
my $sth = $_[0]; |
1299
|
322
|
|
|
|
|
633
|
my $data = $sth->{sql_stmt}{data}; |
1300
|
322
|
100
|
66
|
|
|
1439
|
if ( !$data || ref $data ne "ARRAY" ) |
1301
|
|
|
|
|
|
|
{ |
1302
|
64
|
|
|
|
|
544
|
$sth->set_err( |
1303
|
|
|
|
|
|
|
$DBI::stderr, |
1304
|
|
|
|
|
|
|
"Attempt to fetch row without a preceding execute () call or from a non-SELECT statement" |
1305
|
|
|
|
|
|
|
); |
1306
|
64
|
|
|
|
|
544
|
return; |
1307
|
|
|
|
|
|
|
} |
1308
|
258
|
|
|
|
|
496
|
my $dav = shift @$data; |
1309
|
258
|
100
|
|
|
|
621
|
unless ($dav) |
1310
|
|
|
|
|
|
|
{ |
1311
|
82
|
|
|
|
|
341
|
$sth->finish; |
1312
|
82
|
|
|
|
|
591
|
return; |
1313
|
|
|
|
|
|
|
} |
1314
|
176
|
50
|
|
|
|
643
|
if ( $sth->FETCH("ChopBlanks") ) # XXX: (TODO) Only chop on CHAR fields, |
1315
|
|
|
|
|
|
|
{ # not on VARCHAR or NUMERIC (see DBI docs) |
1316
|
0
|
|
0
|
|
|
0
|
$_ && $_ =~ s/ +$// for @$dav; |
1317
|
|
|
|
|
|
|
} |
1318
|
176
|
|
|
|
|
2329
|
return $sth->_set_fbav($dav); |
1319
|
|
|
|
|
|
|
} # fetch |
1320
|
|
|
|
|
|
|
|
1321
|
54
|
|
|
54
|
|
411
|
no warnings 'once'; |
|
54
|
|
|
|
|
112
|
|
|
54
|
|
|
|
|
3239
|
|
1322
|
|
|
|
|
|
|
*fetchrow_arrayref = \&fetch; |
1323
|
|
|
|
|
|
|
|
1324
|
54
|
|
|
54
|
|
317
|
use warnings; |
|
54
|
|
|
|
|
130
|
|
|
54
|
|
|
|
|
26715
|
|
1325
|
|
|
|
|
|
|
|
1326
|
|
|
|
|
|
|
sub sql_get_colnames |
1327
|
|
|
|
|
|
|
{ |
1328
|
2054
|
|
|
2054
|
|
28682
|
my $sth = $_[0]; |
1329
|
|
|
|
|
|
|
# Being a bit dirty here, as neither SQL::Statement::Structure nor |
1330
|
|
|
|
|
|
|
# DBI::SQL::Nano::Statement_ does not offer an interface to the |
1331
|
|
|
|
|
|
|
# required data |
1332
|
2054
|
|
|
|
|
2943
|
my @colnames; |
1333
|
2054
|
100
|
66
|
|
|
10619
|
if ( $sth->{sql_stmt}->{NAME} and "ARRAY" eq ref( $sth->{sql_stmt}->{NAME} ) ) |
|
|
50
|
|
|
|
|
|
1334
|
|
|
|
|
|
|
{ |
1335
|
632
|
|
|
|
|
932
|
@colnames = @{ $sth->{sql_stmt}->{NAME} }; |
|
632
|
|
|
|
|
1602
|
|
1336
|
|
|
|
|
|
|
} |
1337
|
|
|
|
|
|
|
elsif ( $sth->{sql_stmt}->isa('SQL::Statement') ) |
1338
|
|
|
|
|
|
|
{ |
1339
|
0
|
|
0
|
|
|
0
|
my $stmt = $sth->{sql_stmt} || {}; |
1340
|
0
|
0
|
|
|
|
0
|
my @coldefs = @{ $stmt->{column_defs} || [] }; |
|
0
|
|
|
|
|
0
|
|
1341
|
0
|
0
|
|
|
|
0
|
@colnames = map { $_->{name} || $_->{value} } @coldefs; |
|
0
|
|
|
|
|
0
|
|
1342
|
|
|
|
|
|
|
} |
1343
|
2054
|
100
|
|
|
|
7072
|
@colnames = $sth->{sql_stmt}->column_names() unless (@colnames); |
1344
|
|
|
|
|
|
|
|
1345
|
2054
|
50
|
|
|
|
4199
|
@colnames = () if ( grep { m/\*/ } @colnames ); |
|
2024
|
|
|
|
|
6070
|
|
1346
|
|
|
|
|
|
|
|
1347
|
2054
|
|
|
|
|
6395
|
return @colnames; |
1348
|
|
|
|
|
|
|
} |
1349
|
|
|
|
|
|
|
|
1350
|
|
|
|
|
|
|
sub FETCH ($$) |
1351
|
|
|
|
|
|
|
{ |
1352
|
2018
|
|
|
2018
|
|
3546
|
my ( $sth, $attrib ) = @_; |
1353
|
|
|
|
|
|
|
|
1354
|
2018
|
100
|
|
|
|
4305
|
$attrib eq "NAME" and return [ $sth->sql_get_colnames() ]; |
1355
|
|
|
|
|
|
|
|
1356
|
1682
|
100
|
|
|
|
3947
|
$attrib eq "TYPE" and return [ ( DBI::SQL_VARCHAR() ) x scalar $sth->sql_get_colnames() ]; |
1357
|
1342
|
100
|
|
|
|
2511
|
$attrib eq "TYPE_NAME" and return [ ("VARCHAR") x scalar $sth->sql_get_colnames() ]; |
1358
|
1338
|
100
|
|
|
|
3032
|
$attrib eq "PRECISION" and return [ (0) x scalar $sth->sql_get_colnames() ]; |
1359
|
1002
|
100
|
|
|
|
1970
|
$attrib eq "NULLABLE" and return [ (1) x scalar $sth->sql_get_colnames() ]; |
1360
|
|
|
|
|
|
|
|
1361
|
930
|
100
|
|
|
|
2203
|
if ( $attrib eq lc $attrib ) |
1362
|
|
|
|
|
|
|
{ |
1363
|
|
|
|
|
|
|
# Private driver attributes are lower cased |
1364
|
336
|
|
|
|
|
1472
|
return $sth->{$attrib}; |
1365
|
|
|
|
|
|
|
} |
1366
|
|
|
|
|
|
|
|
1367
|
|
|
|
|
|
|
# else pass up to DBI to handle |
1368
|
594
|
|
|
|
|
2940
|
return $sth->SUPER::FETCH($attrib); |
1369
|
|
|
|
|
|
|
} # FETCH |
1370
|
|
|
|
|
|
|
|
1371
|
|
|
|
|
|
|
sub STORE ($$$) |
1372
|
|
|
|
|
|
|
{ |
1373
|
3010
|
|
|
3010
|
|
35467
|
my ( $sth, $attrib, $value ) = @_; |
1374
|
3010
|
100
|
|
|
|
6735
|
if ( $attrib eq lc $attrib ) # Private driver attributes are lower cased |
1375
|
|
|
|
|
|
|
{ |
1376
|
1404
|
|
|
|
|
2974
|
$sth->{$attrib} = $value; |
1377
|
1404
|
|
|
|
|
3111
|
return 1; |
1378
|
|
|
|
|
|
|
} |
1379
|
1606
|
|
|
|
|
6818
|
return $sth->SUPER::STORE( $attrib, $value ); |
1380
|
|
|
|
|
|
|
} # STORE |
1381
|
|
|
|
|
|
|
|
1382
|
|
|
|
|
|
|
sub DESTROY ($) |
1383
|
|
|
|
|
|
|
{ |
1384
|
750
|
|
|
750
|
|
47844
|
my $sth = shift; |
1385
|
750
|
100
|
|
|
|
3119
|
$sth->SUPER::FETCH("Active") and $sth->finish; |
1386
|
750
|
|
|
|
|
3852
|
undef $sth->{sql_stmt}; |
1387
|
750
|
|
|
|
|
4643
|
undef $sth->{sql_params}; |
1388
|
|
|
|
|
|
|
} # DESTROY |
1389
|
|
|
|
|
|
|
|
1390
|
|
|
|
|
|
|
sub rows ($) |
1391
|
|
|
|
|
|
|
{ |
1392
|
236
|
|
|
236
|
|
11298
|
return $_[0]->{sql_stmt}{NUM_OF_ROWS}; |
1393
|
|
|
|
|
|
|
} # rows |
1394
|
|
|
|
|
|
|
|
1395
|
|
|
|
|
|
|
# ====== TableSource =========================================================== |
1396
|
|
|
|
|
|
|
|
1397
|
|
|
|
|
|
|
package DBI::DBD::SqlEngine::TableSource; |
1398
|
|
|
|
|
|
|
|
1399
|
54
|
|
|
54
|
|
434
|
use strict; |
|
54
|
|
|
|
|
119
|
|
|
54
|
|
|
|
|
1360
|
|
1400
|
54
|
|
|
54
|
|
284
|
use warnings; |
|
54
|
|
|
|
|
131
|
|
|
54
|
|
|
|
|
1571
|
|
1401
|
|
|
|
|
|
|
|
1402
|
54
|
|
|
54
|
|
338
|
use Carp; |
|
54
|
|
|
|
|
120
|
|
|
54
|
|
|
|
|
9427
|
|
1403
|
|
|
|
|
|
|
|
1404
|
|
|
|
|
|
|
sub data_sources ($;$) |
1405
|
|
|
|
|
|
|
{ |
1406
|
0
|
|
|
0
|
|
0
|
my ( $class, $drh, $attrs ) = @_; |
1407
|
0
|
0
|
|
|
|
0
|
croak( ( ref( $_[0] ) ? ref( $_[0] ) : $_[0] ) . " must implement data_sources" ); |
1408
|
|
|
|
|
|
|
} |
1409
|
|
|
|
|
|
|
|
1410
|
|
|
|
|
|
|
sub avail_tables |
1411
|
|
|
|
|
|
|
{ |
1412
|
0
|
|
|
0
|
|
0
|
my ( $self, $dbh ) = @_; |
1413
|
0
|
0
|
|
|
|
0
|
croak( ( ref( $_[0] ) ? ref( $_[0] ) : $_[0] ) . " must implement avail_tables" ); |
1414
|
|
|
|
|
|
|
} |
1415
|
|
|
|
|
|
|
|
1416
|
|
|
|
|
|
|
# ====== DataSource ============================================================ |
1417
|
|
|
|
|
|
|
|
1418
|
|
|
|
|
|
|
package DBI::DBD::SqlEngine::DataSource; |
1419
|
|
|
|
|
|
|
|
1420
|
54
|
|
|
54
|
|
379
|
use strict; |
|
54
|
|
|
|
|
132
|
|
|
54
|
|
|
|
|
1367
|
|
1421
|
54
|
|
|
54
|
|
292
|
use warnings; |
|
54
|
|
|
|
|
142
|
|
|
54
|
|
|
|
|
1469
|
|
1422
|
|
|
|
|
|
|
|
1423
|
54
|
|
|
54
|
|
309
|
use Carp; |
|
54
|
|
|
|
|
124
|
|
|
54
|
|
|
|
|
8850
|
|
1424
|
|
|
|
|
|
|
|
1425
|
|
|
|
|
|
|
sub complete_table_name ($$;$) |
1426
|
|
|
|
|
|
|
{ |
1427
|
0
|
|
|
0
|
|
0
|
my ( $self, $meta, $table, $respect_case ) = @_; |
1428
|
0
|
0
|
|
|
|
0
|
croak( ( ref( $_[0] ) ? ref( $_[0] ) : $_[0] ) . " must implement complete_table_name" ); |
1429
|
|
|
|
|
|
|
} |
1430
|
|
|
|
|
|
|
|
1431
|
|
|
|
|
|
|
sub open_data ($) |
1432
|
|
|
|
|
|
|
{ |
1433
|
0
|
|
|
0
|
|
0
|
my ( $self, $meta, $attrs, $flags ) = @_; |
1434
|
0
|
0
|
|
|
|
0
|
croak( ( ref( $_[0] ) ? ref( $_[0] ) : $_[0] ) . " must implement open_data" ); |
1435
|
|
|
|
|
|
|
} |
1436
|
|
|
|
|
|
|
|
1437
|
|
|
|
|
|
|
# ====== SQL::STATEMENT ======================================================== |
1438
|
|
|
|
|
|
|
|
1439
|
|
|
|
|
|
|
package DBI::DBD::SqlEngine::Statement; |
1440
|
|
|
|
|
|
|
|
1441
|
54
|
|
|
54
|
|
399
|
use strict; |
|
54
|
|
|
|
|
149
|
|
|
54
|
|
|
|
|
1265
|
|
1442
|
54
|
|
|
54
|
|
286
|
use warnings; |
|
54
|
|
|
|
|
114
|
|
|
54
|
|
|
|
|
1496
|
|
1443
|
|
|
|
|
|
|
|
1444
|
54
|
|
|
54
|
|
278
|
use Carp; |
|
54
|
|
|
|
|
116
|
|
|
54
|
|
|
|
|
14931
|
|
1445
|
|
|
|
|
|
|
|
1446
|
|
|
|
|
|
|
@DBI::DBD::SqlEngine::Statement::ISA = qw(DBI::SQL::Nano::Statement); |
1447
|
|
|
|
|
|
|
|
1448
|
|
|
|
|
|
|
sub open_table ($$$$$) |
1449
|
|
|
|
|
|
|
{ |
1450
|
502
|
|
|
502
|
|
1347
|
my ( $self, $data, $table, $createMode, $lockMode ) = @_; |
1451
|
|
|
|
|
|
|
|
1452
|
502
|
|
|
|
|
1110
|
my $class = ref $self; |
1453
|
502
|
|
|
|
|
2110
|
$class =~ s/::Statement/::Table/; |
1454
|
|
|
|
|
|
|
|
1455
|
502
|
|
|
|
|
1911
|
my $flags = { |
1456
|
|
|
|
|
|
|
createMode => $createMode, |
1457
|
|
|
|
|
|
|
lockMode => $lockMode, |
1458
|
|
|
|
|
|
|
}; |
1459
|
502
|
100
|
|
|
|
1771
|
$self->{command} eq "DROP" and $flags->{dropMode} = 1; |
1460
|
|
|
|
|
|
|
|
1461
|
502
|
50
|
|
|
|
2768
|
my ( $tblnm, $table_meta ) = $class->get_table_meta( $data->{Database}, $table, 1 ) |
1462
|
|
|
|
|
|
|
or croak "Cannot find appropriate meta for table '$table'"; |
1463
|
|
|
|
|
|
|
|
1464
|
502
|
100
|
|
|
|
1535
|
defined $table_meta->{sql_table_class} and $class = $table_meta->{sql_table_class}; |
1465
|
|
|
|
|
|
|
|
1466
|
|
|
|
|
|
|
# because column name mapping is initialized in constructor ... |
1467
|
|
|
|
|
|
|
# and therefore specific opening operations might be done before |
1468
|
|
|
|
|
|
|
# reaching DBI::DBD::SqlEngine::Table->new(), we need to intercept |
1469
|
|
|
|
|
|
|
# ReadOnly here |
1470
|
502
|
|
66
|
|
|
2451
|
my $write_op = $createMode || $lockMode || $flags->{dropMode}; |
1471
|
502
|
100
|
|
|
|
1179
|
if ($write_op) |
1472
|
|
|
|
|
|
|
{ |
1473
|
|
|
|
|
|
|
$table_meta->{readonly} |
1474
|
|
|
|
|
|
|
and croak "Table '$table' is marked readonly - " |
1475
|
|
|
|
|
|
|
. $self->{command} |
1476
|
398
|
50
|
|
|
|
5948
|
. ( $lockMode ? " with locking" : "" ) |
|
|
100
|
|
|
|
|
|
1477
|
|
|
|
|
|
|
. " command forbidden"; |
1478
|
|
|
|
|
|
|
} |
1479
|
|
|
|
|
|
|
|
1480
|
478
|
|
|
|
|
2471
|
return $class->new( $data, { table => $table }, $flags ); |
1481
|
|
|
|
|
|
|
} # open_table |
1482
|
|
|
|
|
|
|
|
1483
|
|
|
|
|
|
|
# ====== SQL::TABLE ============================================================ |
1484
|
|
|
|
|
|
|
|
1485
|
|
|
|
|
|
|
package DBI::DBD::SqlEngine::Table; |
1486
|
|
|
|
|
|
|
|
1487
|
54
|
|
|
54
|
|
402
|
use strict; |
|
54
|
|
|
|
|
117
|
|
|
54
|
|
|
|
|
1341
|
|
1488
|
54
|
|
|
54
|
|
289
|
use warnings; |
|
54
|
|
|
|
|
111
|
|
|
54
|
|
|
|
|
1491
|
|
1489
|
|
|
|
|
|
|
|
1490
|
54
|
|
|
54
|
|
318
|
use Carp; |
|
54
|
|
|
|
|
115
|
|
|
54
|
|
|
|
|
56545
|
|
1491
|
|
|
|
|
|
|
|
1492
|
|
|
|
|
|
|
@DBI::DBD::SqlEngine::Table::ISA = qw(DBI::SQL::Nano::Table); |
1493
|
|
|
|
|
|
|
|
1494
|
|
|
|
|
|
|
sub bootstrap_table_meta |
1495
|
|
|
|
|
|
|
{ |
1496
|
522
|
|
|
522
|
|
1308
|
my ( $self, $dbh, $meta, $table ) = @_; |
1497
|
|
|
|
|
|
|
|
1498
|
|
|
|
|
|
|
defined $dbh->{ReadOnly} |
1499
|
|
|
|
|
|
|
and !defined( $meta->{readonly} ) |
1500
|
522
|
100
|
100
|
|
|
1704
|
and $meta->{readonly} = $dbh->{ReadOnly}; |
1501
|
|
|
|
|
|
|
defined $meta->{sql_identifier_case} |
1502
|
522
|
100
|
|
|
|
1726
|
or $meta->{sql_identifier_case} = $dbh->{sql_identifier_case}; |
1503
|
|
|
|
|
|
|
|
1504
|
522
|
100
|
|
|
|
1482
|
exists $meta->{sql_data_source} or $meta->{sql_data_source} = $dbh->{sql_data_source}; |
1505
|
|
|
|
|
|
|
|
1506
|
522
|
|
|
|
|
1090
|
$meta; |
1507
|
|
|
|
|
|
|
} |
1508
|
|
|
|
|
|
|
|
1509
|
|
|
|
|
|
|
sub init_table_meta |
1510
|
|
|
|
|
|
|
{ |
1511
|
356
|
|
|
356
|
|
575
|
my ( $self, $dbh, $meta, $table ) = @_ if (0); |
1512
|
|
|
|
|
|
|
|
1513
|
356
|
|
|
|
|
686
|
return; |
1514
|
|
|
|
|
|
|
} # init_table_meta |
1515
|
|
|
|
|
|
|
|
1516
|
|
|
|
|
|
|
sub get_table_meta ($$$;$) |
1517
|
|
|
|
|
|
|
{ |
1518
|
1260
|
|
|
1260
|
|
2990
|
my ( $self, $dbh, $table, $respect_case, @other ) = @_; |
1519
|
1260
|
100
|
|
|
|
2875
|
unless ( defined $respect_case ) |
1520
|
|
|
|
|
|
|
{ |
1521
|
1048
|
|
|
|
|
1504
|
$respect_case = 0; |
1522
|
1048
|
50
|
|
|
|
2490
|
$table =~ s/^\"// and $respect_case = 1; # handle quoted identifiers |
1523
|
1048
|
|
|
|
|
1867
|
$table =~ s/\"$//; |
1524
|
|
|
|
|
|
|
} |
1525
|
|
|
|
|
|
|
|
1526
|
1260
|
100
|
|
|
|
2493
|
unless ($respect_case) |
1527
|
|
|
|
|
|
|
{ |
1528
|
1224
|
100
|
|
|
|
3273
|
defined $dbh->{sql_meta_map}{$table} and $table = $dbh->{sql_meta_map}{$table}; |
1529
|
|
|
|
|
|
|
} |
1530
|
|
|
|
|
|
|
|
1531
|
1260
|
|
|
|
|
2176
|
my $meta = {}; |
1532
|
1260
|
100
|
|
|
|
3588
|
defined $dbh->{sql_meta}{$table} and $meta = $dbh->{sql_meta}{$table}; |
1533
|
|
|
|
|
|
|
|
1534
|
|
|
|
|
|
|
do_initialize: |
1535
|
1294
|
100
|
|
|
|
2955
|
unless ( $meta->{initialized} ) |
1536
|
|
|
|
|
|
|
{ |
1537
|
518
|
|
|
|
|
2450
|
$self->bootstrap_table_meta( $dbh, $meta, $table, @other ); |
1538
|
518
|
100
|
|
|
|
3302
|
$meta->{sql_data_source}->complete_table_name( $meta, $table, $respect_case, @other ) |
1539
|
|
|
|
|
|
|
or return; |
1540
|
|
|
|
|
|
|
|
1541
|
390
|
100
|
100
|
|
|
2195
|
if ( defined $meta->{table_name} and $table ne $meta->{table_name} ) |
1542
|
|
|
|
|
|
|
{ |
1543
|
178
|
|
|
|
|
624
|
$dbh->{sql_meta_map}{$table} = $meta->{table_name}; |
1544
|
178
|
|
|
|
|
375
|
$table = $meta->{table_name}; |
1545
|
|
|
|
|
|
|
} |
1546
|
|
|
|
|
|
|
|
1547
|
|
|
|
|
|
|
# now we know a bit more - let's check if user can't use consequent spelling |
1548
|
|
|
|
|
|
|
# XXX add know issue about reset sql_identifier_case here ... |
1549
|
390
|
100
|
|
|
|
1249
|
if ( defined $dbh->{sql_meta}{$table} ) |
1550
|
|
|
|
|
|
|
{ |
1551
|
70
|
|
|
|
|
304
|
$meta = delete $dbh->{sql_meta}{$table}; # avoid endless loop |
1552
|
|
|
|
|
|
|
$meta->{initialized} |
1553
|
70
|
100
|
|
|
|
488
|
or goto do_initialize; |
1554
|
|
|
|
|
|
|
#or $meta->{sql_data_source}->complete_table_name( $meta, $table, $respect_case, @other ) |
1555
|
|
|
|
|
|
|
#or return; |
1556
|
|
|
|
|
|
|
} |
1557
|
|
|
|
|
|
|
|
1558
|
356
|
50
|
|
|
|
1308
|
unless ( $dbh->{sql_meta}{$table}{initialized} ) |
1559
|
|
|
|
|
|
|
{ |
1560
|
356
|
|
|
|
|
2481
|
$self->init_table_meta( $dbh, $meta, $table ); |
1561
|
356
|
|
|
|
|
745
|
$meta->{initialized} = 1; |
1562
|
356
|
|
|
|
|
959
|
$dbh->{sql_meta}{$table} = $meta; |
1563
|
|
|
|
|
|
|
} |
1564
|
|
|
|
|
|
|
} |
1565
|
|
|
|
|
|
|
|
1566
|
1132
|
|
|
|
|
2883
|
return ( $table, $meta ); |
1567
|
|
|
|
|
|
|
} # get_table_meta |
1568
|
|
|
|
|
|
|
|
1569
|
|
|
|
|
|
|
my %reset_on_modify = (); |
1570
|
|
|
|
|
|
|
my %compat_map = (); |
1571
|
|
|
|
|
|
|
|
1572
|
|
|
|
|
|
|
sub register_reset_on_modify |
1573
|
|
|
|
|
|
|
{ |
1574
|
88
|
|
|
88
|
|
357
|
my ( $proto, $extra_resets ) = @_; |
1575
|
88
|
|
|
|
|
409
|
foreach my $cv ( keys %$extra_resets ) |
1576
|
|
|
|
|
|
|
{ |
1577
|
|
|
|
|
|
|
#%reset_on_modify = ( %reset_on_modify, %$extra_resets ); |
1578
|
332
|
|
|
|
|
1184
|
push @{ $reset_on_modify{$cv} }, |
1579
|
332
|
100
|
|
|
|
494
|
ref $extra_resets->{$cv} ? @{ $extra_resets->{$cv} } : ( $extra_resets->{$cv} ); |
|
104
|
|
|
|
|
295
|
|
1580
|
|
|
|
|
|
|
} |
1581
|
88
|
|
|
|
|
313
|
return; |
1582
|
|
|
|
|
|
|
} # register_reset_on_modify |
1583
|
|
|
|
|
|
|
|
1584
|
|
|
|
|
|
|
sub register_compat_map |
1585
|
|
|
|
|
|
|
{ |
1586
|
88
|
|
|
88
|
|
273
|
my ( $proto, $extra_compat_map ) = @_; |
1587
|
88
|
|
|
|
|
655
|
%compat_map = ( %compat_map, %$extra_compat_map ); |
1588
|
88
|
|
|
|
|
269
|
return; |
1589
|
|
|
|
|
|
|
} # register_compat_map |
1590
|
|
|
|
|
|
|
|
1591
|
|
|
|
|
|
|
sub get_table_meta_attr |
1592
|
|
|
|
|
|
|
{ |
1593
|
82
|
|
|
82
|
|
211
|
my ( $class, $meta, $attrib ) = @_; |
1594
|
|
|
|
|
|
|
exists $compat_map{$attrib} |
1595
|
82
|
50
|
|
|
|
231
|
and $attrib = $compat_map{$attrib}; |
1596
|
|
|
|
|
|
|
exists $meta->{$attrib} |
1597
|
82
|
50
|
|
|
|
543
|
and return $meta->{$attrib}; |
1598
|
0
|
|
|
|
|
0
|
return; |
1599
|
|
|
|
|
|
|
} # get_table_meta_attr |
1600
|
|
|
|
|
|
|
|
1601
|
|
|
|
|
|
|
sub set_table_meta_attr |
1602
|
|
|
|
|
|
|
{ |
1603
|
12
|
|
|
12
|
|
41
|
my ( $class, $meta, $attrib, $value ) = @_; |
1604
|
|
|
|
|
|
|
exists $compat_map{$attrib} |
1605
|
12
|
100
|
|
|
|
47
|
and $attrib = $compat_map{$attrib}; |
1606
|
12
|
|
|
|
|
69
|
$class->table_meta_attr_changed( $meta, $attrib, $value ); |
1607
|
12
|
|
|
|
|
36
|
$meta->{$attrib} = $value; |
1608
|
|
|
|
|
|
|
} # set_table_meta_attr |
1609
|
|
|
|
|
|
|
|
1610
|
|
|
|
|
|
|
sub table_meta_attr_changed |
1611
|
|
|
|
|
|
|
{ |
1612
|
12
|
|
|
12
|
|
37
|
my ( $class, $meta, $attrib, $value ) = @_; |
1613
|
|
|
|
|
|
|
defined $reset_on_modify{$attrib} |
1614
|
12
|
|
|
|
|
85
|
and delete @$meta{ @{ $reset_on_modify{$attrib} } } |
1615
|
12
|
50
|
33
|
|
|
62
|
and $meta->{initialized} = 0; |
1616
|
|
|
|
|
|
|
} # table_meta_attr_changed |
1617
|
|
|
|
|
|
|
|
1618
|
|
|
|
|
|
|
sub open_data |
1619
|
|
|
|
|
|
|
{ |
1620
|
478
|
|
|
478
|
|
1140
|
my ( $self, $meta, $attrs, $flags ) = @_; |
1621
|
|
|
|
|
|
|
|
1622
|
|
|
|
|
|
|
$meta->{sql_data_source} |
1623
|
478
|
50
|
|
|
|
1821
|
or croak "Table " . $meta->{table_name} . " not completely initialized"; |
1624
|
478
|
|
|
|
|
2743
|
$meta->{sql_data_source}->open_data( $meta, $attrs, $flags ); |
1625
|
|
|
|
|
|
|
|
1626
|
430
|
|
|
|
|
1311
|
return; |
1627
|
|
|
|
|
|
|
} # open_data |
1628
|
|
|
|
|
|
|
|
1629
|
|
|
|
|
|
|
# ====== SQL::Eval API ========================================================= |
1630
|
|
|
|
|
|
|
|
1631
|
|
|
|
|
|
|
sub new |
1632
|
|
|
|
|
|
|
{ |
1633
|
478
|
|
|
478
|
|
1290
|
my ( $className, $data, $attrs, $flags ) = @_; |
1634
|
478
|
|
|
|
|
1356
|
my $dbh = $data->{Database}; |
1635
|
|
|
|
|
|
|
|
1636
|
478
|
50
|
|
|
|
1461
|
my ( $tblnm, $meta ) = $className->get_table_meta( $dbh, $attrs->{table}, 1 ) |
1637
|
|
|
|
|
|
|
or croak "Cannot find appropriate table '$attrs->{table}'"; |
1638
|
478
|
|
|
|
|
1080
|
$attrs->{table} = $tblnm; |
1639
|
|
|
|
|
|
|
|
1640
|
|
|
|
|
|
|
# Being a bit dirty here, as SQL::Statement::Structure does not offer |
1641
|
|
|
|
|
|
|
# me an interface to the data I want |
1642
|
|
|
|
|
|
|
$flags->{createMode} && $data->{sql_stmt}{table_defs} |
1643
|
478
|
50
|
66
|
|
|
1496
|
and $meta->{table_defs} = $data->{sql_stmt}{table_defs}; |
1644
|
|
|
|
|
|
|
|
1645
|
|
|
|
|
|
|
# open_file must be called before inherited new is invoked |
1646
|
|
|
|
|
|
|
# because column name mapping is initialized in constructor ... |
1647
|
478
|
|
|
|
|
2113
|
$className->open_data( $meta, $attrs, $flags ); |
1648
|
|
|
|
|
|
|
|
1649
|
|
|
|
|
|
|
my $tbl = { |
1650
|
430
|
|
|
|
|
3099
|
%{$attrs}, |
1651
|
|
|
|
|
|
|
meta => $meta, |
1652
|
430
|
|
100
|
|
|
864
|
col_names => $meta->{col_names} || [], |
1653
|
|
|
|
|
|
|
}; |
1654
|
430
|
|
|
|
|
3453
|
return $className->SUPER::new($tbl); |
1655
|
|
|
|
|
|
|
} # new |
1656
|
|
|
|
|
|
|
|
1657
|
|
|
|
|
|
|
sub DESTROY |
1658
|
|
|
|
|
|
|
{ |
1659
|
430
|
|
|
430
|
|
860
|
my $self = shift; |
1660
|
430
|
|
|
|
|
829
|
my $meta = $self->{meta}; |
1661
|
430
|
100
|
|
|
|
1149
|
$self->{row} and undef $self->{row}; |
1662
|
|
|
|
|
|
|
() |
1663
|
430
|
|
|
|
|
3529
|
} |
1664
|
|
|
|
|
|
|
|
1665
|
|
|
|
|
|
|
1; |
1666
|
|
|
|
|
|
|
|
1667
|
|
|
|
|
|
|
=pod |
1668
|
|
|
|
|
|
|
|
1669
|
|
|
|
|
|
|
=head1 NAME |
1670
|
|
|
|
|
|
|
|
1671
|
|
|
|
|
|
|
DBI::DBD::SqlEngine - Base class for DBI drivers without their own SQL engine |
1672
|
|
|
|
|
|
|
|
1673
|
|
|
|
|
|
|
=head1 SYNOPSIS |
1674
|
|
|
|
|
|
|
|
1675
|
|
|
|
|
|
|
package DBD::myDriver; |
1676
|
|
|
|
|
|
|
|
1677
|
|
|
|
|
|
|
use base qw(DBI::DBD::SqlEngine); |
1678
|
|
|
|
|
|
|
|
1679
|
|
|
|
|
|
|
sub driver |
1680
|
|
|
|
|
|
|
{ |
1681
|
|
|
|
|
|
|
... |
1682
|
|
|
|
|
|
|
my $drh = $proto->SUPER::driver($attr); |
1683
|
|
|
|
|
|
|
... |
1684
|
|
|
|
|
|
|
return $drh->{class}; |
1685
|
|
|
|
|
|
|
} |
1686
|
|
|
|
|
|
|
|
1687
|
|
|
|
|
|
|
package DBD::myDriver::dr; |
1688
|
|
|
|
|
|
|
|
1689
|
|
|
|
|
|
|
@ISA = qw(DBI::DBD::SqlEngine::dr); |
1690
|
|
|
|
|
|
|
|
1691
|
|
|
|
|
|
|
sub data_sources { ... } |
1692
|
|
|
|
|
|
|
... |
1693
|
|
|
|
|
|
|
|
1694
|
|
|
|
|
|
|
package DBD::myDriver::db; |
1695
|
|
|
|
|
|
|
|
1696
|
|
|
|
|
|
|
@ISA = qw(DBI::DBD::SqlEngine::db); |
1697
|
|
|
|
|
|
|
|
1698
|
|
|
|
|
|
|
sub init_valid_attributes { ... } |
1699
|
|
|
|
|
|
|
sub init_default_attributes { ... } |
1700
|
|
|
|
|
|
|
sub set_versions { ... } |
1701
|
|
|
|
|
|
|
sub validate_STORE_attr { my ($dbh, $attrib, $value) = @_; ... } |
1702
|
|
|
|
|
|
|
sub validate_FETCH_attr { my ($dbh, $attrib) = @_; ... } |
1703
|
|
|
|
|
|
|
sub get_myd_versions { ... } |
1704
|
|
|
|
|
|
|
sub get_avail_tables { ... } |
1705
|
|
|
|
|
|
|
|
1706
|
|
|
|
|
|
|
package DBD::myDriver::st; |
1707
|
|
|
|
|
|
|
|
1708
|
|
|
|
|
|
|
@ISA = qw(DBI::DBD::SqlEngine::st); |
1709
|
|
|
|
|
|
|
|
1710
|
|
|
|
|
|
|
sub FETCH { ... } |
1711
|
|
|
|
|
|
|
sub STORE { ... } |
1712
|
|
|
|
|
|
|
|
1713
|
|
|
|
|
|
|
package DBD::myDriver::Statement; |
1714
|
|
|
|
|
|
|
|
1715
|
|
|
|
|
|
|
@ISA = qw(DBI::DBD::SqlEngine::Statement); |
1716
|
|
|
|
|
|
|
|
1717
|
|
|
|
|
|
|
sub open_table { ... } |
1718
|
|
|
|
|
|
|
|
1719
|
|
|
|
|
|
|
package DBD::myDriver::Table; |
1720
|
|
|
|
|
|
|
|
1721
|
|
|
|
|
|
|
@ISA = qw(DBI::DBD::SqlEngine::Table); |
1722
|
|
|
|
|
|
|
|
1723
|
|
|
|
|
|
|
sub new { ... } |
1724
|
|
|
|
|
|
|
|
1725
|
|
|
|
|
|
|
=head1 DESCRIPTION |
1726
|
|
|
|
|
|
|
|
1727
|
|
|
|
|
|
|
DBI::DBD::SqlEngine abstracts the usage of SQL engines from the |
1728
|
|
|
|
|
|
|
DBD. DBD authors can concentrate on the data retrieval they want to |
1729
|
|
|
|
|
|
|
provide. |
1730
|
|
|
|
|
|
|
|
1731
|
|
|
|
|
|
|
It is strongly recommended that you read L and |
1732
|
|
|
|
|
|
|
L, because many of the DBD::File API is provided |
1733
|
|
|
|
|
|
|
by DBI::DBD::SqlEngine. |
1734
|
|
|
|
|
|
|
|
1735
|
|
|
|
|
|
|
Currently the API of DBI::DBD::SqlEngine is experimental and will |
1736
|
|
|
|
|
|
|
likely change in the near future to provide the table meta data basics |
1737
|
|
|
|
|
|
|
like DBD::File. |
1738
|
|
|
|
|
|
|
|
1739
|
|
|
|
|
|
|
DBI::DBD::SqlEngine expects that any driver in inheritance chain has |
1740
|
|
|
|
|
|
|
a L. |
1741
|
|
|
|
|
|
|
|
1742
|
|
|
|
|
|
|
=head2 Metadata |
1743
|
|
|
|
|
|
|
|
1744
|
|
|
|
|
|
|
The following attributes are handled by DBI itself and not by |
1745
|
|
|
|
|
|
|
DBI::DBD::SqlEngine, thus they all work as expected: |
1746
|
|
|
|
|
|
|
|
1747
|
|
|
|
|
|
|
Active |
1748
|
|
|
|
|
|
|
ActiveKids |
1749
|
|
|
|
|
|
|
CachedKids |
1750
|
|
|
|
|
|
|
CompatMode (Not used) |
1751
|
|
|
|
|
|
|
InactiveDestroy |
1752
|
|
|
|
|
|
|
AutoInactiveDestroy |
1753
|
|
|
|
|
|
|
Kids |
1754
|
|
|
|
|
|
|
PrintError |
1755
|
|
|
|
|
|
|
RaiseError |
1756
|
|
|
|
|
|
|
Warn (Not used) |
1757
|
|
|
|
|
|
|
|
1758
|
|
|
|
|
|
|
=head3 The following DBI attributes are handled by DBI::DBD::SqlEngine: |
1759
|
|
|
|
|
|
|
|
1760
|
|
|
|
|
|
|
=head4 AutoCommit |
1761
|
|
|
|
|
|
|
|
1762
|
|
|
|
|
|
|
Always on. |
1763
|
|
|
|
|
|
|
|
1764
|
|
|
|
|
|
|
=head4 ChopBlanks |
1765
|
|
|
|
|
|
|
|
1766
|
|
|
|
|
|
|
Works. |
1767
|
|
|
|
|
|
|
|
1768
|
|
|
|
|
|
|
=head4 NUM_OF_FIELDS |
1769
|
|
|
|
|
|
|
|
1770
|
|
|
|
|
|
|
Valid after C<< $sth->execute >>. |
1771
|
|
|
|
|
|
|
|
1772
|
|
|
|
|
|
|
=head4 NUM_OF_PARAMS |
1773
|
|
|
|
|
|
|
|
1774
|
|
|
|
|
|
|
Valid after C<< $sth->prepare >>. |
1775
|
|
|
|
|
|
|
|
1776
|
|
|
|
|
|
|
=head4 NAME |
1777
|
|
|
|
|
|
|
|
1778
|
|
|
|
|
|
|
Valid after C<< $sth->execute >>; probably undef for Non-Select statements. |
1779
|
|
|
|
|
|
|
|
1780
|
|
|
|
|
|
|
=head4 NULLABLE |
1781
|
|
|
|
|
|
|
|
1782
|
|
|
|
|
|
|
Not really working, always returns an array ref of ones, as DBD::CSV |
1783
|
|
|
|
|
|
|
does not verify input data. Valid after C<< $sth->execute >>; undef for |
1784
|
|
|
|
|
|
|
non-select statements. |
1785
|
|
|
|
|
|
|
|
1786
|
|
|
|
|
|
|
=head3 The following DBI attributes and methods are not supported: |
1787
|
|
|
|
|
|
|
|
1788
|
|
|
|
|
|
|
=over 4 |
1789
|
|
|
|
|
|
|
|
1790
|
|
|
|
|
|
|
=item bind_param_inout |
1791
|
|
|
|
|
|
|
|
1792
|
|
|
|
|
|
|
=item CursorName |
1793
|
|
|
|
|
|
|
|
1794
|
|
|
|
|
|
|
=item LongReadLen |
1795
|
|
|
|
|
|
|
|
1796
|
|
|
|
|
|
|
=item LongTruncOk |
1797
|
|
|
|
|
|
|
|
1798
|
|
|
|
|
|
|
=back |
1799
|
|
|
|
|
|
|
|
1800
|
|
|
|
|
|
|
=head3 DBI::DBD::SqlEngine specific attributes |
1801
|
|
|
|
|
|
|
|
1802
|
|
|
|
|
|
|
In addition to the DBI attributes, you can use the following dbh |
1803
|
|
|
|
|
|
|
attributes: |
1804
|
|
|
|
|
|
|
|
1805
|
|
|
|
|
|
|
=head4 sql_engine_version |
1806
|
|
|
|
|
|
|
|
1807
|
|
|
|
|
|
|
Contains the module version of this driver (B) |
1808
|
|
|
|
|
|
|
|
1809
|
|
|
|
|
|
|
=head4 sql_nano_version |
1810
|
|
|
|
|
|
|
|
1811
|
|
|
|
|
|
|
Contains the module version of DBI::SQL::Nano (B) |
1812
|
|
|
|
|
|
|
|
1813
|
|
|
|
|
|
|
=head4 sql_statement_version |
1814
|
|
|
|
|
|
|
|
1815
|
|
|
|
|
|
|
Contains the module version of SQL::Statement, if available (B) |
1816
|
|
|
|
|
|
|
|
1817
|
|
|
|
|
|
|
=head4 sql_handler |
1818
|
|
|
|
|
|
|
|
1819
|
|
|
|
|
|
|
Contains the SQL Statement engine, either DBI::SQL::Nano or SQL::Statement |
1820
|
|
|
|
|
|
|
(B). |
1821
|
|
|
|
|
|
|
|
1822
|
|
|
|
|
|
|
=head4 sql_parser_object |
1823
|
|
|
|
|
|
|
|
1824
|
|
|
|
|
|
|
Contains an instantiated instance of SQL::Parser (B). |
1825
|
|
|
|
|
|
|
This is filled when used first time (only when used with SQL::Statement). |
1826
|
|
|
|
|
|
|
|
1827
|
|
|
|
|
|
|
=head4 sql_sponge_driver |
1828
|
|
|
|
|
|
|
|
1829
|
|
|
|
|
|
|
Contains an internally used DBD::Sponge handle (B). |
1830
|
|
|
|
|
|
|
|
1831
|
|
|
|
|
|
|
=head4 sql_valid_attrs |
1832
|
|
|
|
|
|
|
|
1833
|
|
|
|
|
|
|
Contains the list of valid attributes for each DBI::DBD::SqlEngine based |
1834
|
|
|
|
|
|
|
driver (B). |
1835
|
|
|
|
|
|
|
|
1836
|
|
|
|
|
|
|
=head4 sql_readonly_attrs |
1837
|
|
|
|
|
|
|
|
1838
|
|
|
|
|
|
|
Contains the list of those attributes which are readonly (B). |
1839
|
|
|
|
|
|
|
|
1840
|
|
|
|
|
|
|
=head4 sql_identifier_case |
1841
|
|
|
|
|
|
|
|
1842
|
|
|
|
|
|
|
Contains how DBI::DBD::SqlEngine deals with non-quoted SQL identifiers: |
1843
|
|
|
|
|
|
|
|
1844
|
|
|
|
|
|
|
* SQL_IC_UPPER (1) means all identifiers are internally converted |
1845
|
|
|
|
|
|
|
into upper-cased pendants |
1846
|
|
|
|
|
|
|
* SQL_IC_LOWER (2) means all identifiers are internally converted |
1847
|
|
|
|
|
|
|
into lower-cased pendants |
1848
|
|
|
|
|
|
|
* SQL_IC_MIXED (4) means all identifiers are taken as they are |
1849
|
|
|
|
|
|
|
|
1850
|
|
|
|
|
|
|
These conversions happen if (and only if) no existing identifier matches. |
1851
|
|
|
|
|
|
|
Once existing identifier is used as known. |
1852
|
|
|
|
|
|
|
|
1853
|
|
|
|
|
|
|
The SQL statement execution classes doesn't have to care, so don't expect |
1854
|
|
|
|
|
|
|
C affects column names in statements like |
1855
|
|
|
|
|
|
|
|
1856
|
|
|
|
|
|
|
SELECT * FROM foo |
1857
|
|
|
|
|
|
|
|
1858
|
|
|
|
|
|
|
=head4 sql_quoted_identifier_case |
1859
|
|
|
|
|
|
|
|
1860
|
|
|
|
|
|
|
Contains how DBI::DBD::SqlEngine deals with quoted SQL identifiers |
1861
|
|
|
|
|
|
|
(B). It's fixated to SQL_IC_SENSITIVE (3), which is interpreted |
1862
|
|
|
|
|
|
|
as SQL_IC_MIXED. |
1863
|
|
|
|
|
|
|
|
1864
|
|
|
|
|
|
|
=head4 sql_flags |
1865
|
|
|
|
|
|
|
|
1866
|
|
|
|
|
|
|
Contains additional flags to instantiate an SQL::Parser. Because an |
1867
|
|
|
|
|
|
|
SQL::Parser is instantiated only once, it's recommended to set this flag |
1868
|
|
|
|
|
|
|
before any statement is executed. |
1869
|
|
|
|
|
|
|
|
1870
|
|
|
|
|
|
|
=head4 sql_dialect |
1871
|
|
|
|
|
|
|
|
1872
|
|
|
|
|
|
|
Controls the dialect understood by SQL::Parser. Possible values (delivery |
1873
|
|
|
|
|
|
|
state of SQL::Statement): |
1874
|
|
|
|
|
|
|
|
1875
|
|
|
|
|
|
|
* ANSI |
1876
|
|
|
|
|
|
|
* CSV |
1877
|
|
|
|
|
|
|
* AnyData |
1878
|
|
|
|
|
|
|
|
1879
|
|
|
|
|
|
|
Defaults to "CSV". Because an SQL::Parser is instantiated only once and |
1880
|
|
|
|
|
|
|
SQL::Parser doesn't allow one to modify the dialect once instantiated, |
1881
|
|
|
|
|
|
|
it's strongly recommended to set this flag before any statement is |
1882
|
|
|
|
|
|
|
executed (best place is connect attribute hash). |
1883
|
|
|
|
|
|
|
|
1884
|
|
|
|
|
|
|
=head4 sql_engine_in_gofer |
1885
|
|
|
|
|
|
|
|
1886
|
|
|
|
|
|
|
This value has a true value in case of this driver is operated via |
1887
|
|
|
|
|
|
|
L. The impact of being operated via Gofer is a read-only |
1888
|
|
|
|
|
|
|
driver (not read-only databases!), so you cannot modify any attributes |
1889
|
|
|
|
|
|
|
later - neither any table settings. B you won't get an error in |
1890
|
|
|
|
|
|
|
cases you modify table attributes, so please carefully watch |
1891
|
|
|
|
|
|
|
C. |
1892
|
|
|
|
|
|
|
|
1893
|
|
|
|
|
|
|
=head4 sql_meta |
1894
|
|
|
|
|
|
|
|
1895
|
|
|
|
|
|
|
Private data area which contains information about the tables this |
1896
|
|
|
|
|
|
|
module handles. Table meta data might not be available until the |
1897
|
|
|
|
|
|
|
table has been accessed for the first time e.g., by issuing a select |
1898
|
|
|
|
|
|
|
on it however it is possible to pre-initialize attributes for each table |
1899
|
|
|
|
|
|
|
you use. |
1900
|
|
|
|
|
|
|
|
1901
|
|
|
|
|
|
|
DBI::DBD::SqlEngine recognizes the (public) attributes C, |
1902
|
|
|
|
|
|
|
C, C, C and C. |
1903
|
|
|
|
|
|
|
Be very careful when modifying attributes you do not know, the consequence |
1904
|
|
|
|
|
|
|
might be a destroyed or corrupted table. |
1905
|
|
|
|
|
|
|
|
1906
|
|
|
|
|
|
|
While C is a private and readonly attribute (which means, you |
1907
|
|
|
|
|
|
|
cannot modify it's values), derived drivers might provide restricted |
1908
|
|
|
|
|
|
|
write access through another attribute. Well known accessors are |
1909
|
|
|
|
|
|
|
C for L, C for L and |
1910
|
|
|
|
|
|
|
C for L. |
1911
|
|
|
|
|
|
|
|
1912
|
|
|
|
|
|
|
=head4 sql_table_source |
1913
|
|
|
|
|
|
|
|
1914
|
|
|
|
|
|
|
Controls the class which will be used for fetching available tables. |
1915
|
|
|
|
|
|
|
|
1916
|
|
|
|
|
|
|
See L for details. |
1917
|
|
|
|
|
|
|
|
1918
|
|
|
|
|
|
|
=head4 sql_data_source |
1919
|
|
|
|
|
|
|
|
1920
|
|
|
|
|
|
|
Contains the class name to be used for opening tables. |
1921
|
|
|
|
|
|
|
|
1922
|
|
|
|
|
|
|
See L for details. |
1923
|
|
|
|
|
|
|
|
1924
|
|
|
|
|
|
|
=head2 Driver private methods |
1925
|
|
|
|
|
|
|
|
1926
|
|
|
|
|
|
|
=head3 Default DBI methods |
1927
|
|
|
|
|
|
|
|
1928
|
|
|
|
|
|
|
=head4 data_sources |
1929
|
|
|
|
|
|
|
|
1930
|
|
|
|
|
|
|
The C method returns a list of subdirectories of the current |
1931
|
|
|
|
|
|
|
directory in the form "dbi:CSV:f_dir=$dirname". |
1932
|
|
|
|
|
|
|
|
1933
|
|
|
|
|
|
|
If you want to read the subdirectories of another directory, use |
1934
|
|
|
|
|
|
|
|
1935
|
|
|
|
|
|
|
my ($drh) = DBI->install_driver ("CSV"); |
1936
|
|
|
|
|
|
|
my (@list) = $drh->data_sources (f_dir => "/usr/local/csv_data"); |
1937
|
|
|
|
|
|
|
|
1938
|
|
|
|
|
|
|
=head4 list_tables |
1939
|
|
|
|
|
|
|
|
1940
|
|
|
|
|
|
|
This method returns a list of file names inside $dbh->{f_dir}. |
1941
|
|
|
|
|
|
|
Example: |
1942
|
|
|
|
|
|
|
|
1943
|
|
|
|
|
|
|
my ($dbh) = DBI->connect ("dbi:CSV:f_dir=/usr/local/csv_data"); |
1944
|
|
|
|
|
|
|
my (@list) = $dbh->func ("list_tables"); |
1945
|
|
|
|
|
|
|
|
1946
|
|
|
|
|
|
|
Note that the list includes all files contained in the directory, even |
1947
|
|
|
|
|
|
|
those that have non-valid table names, from the view of SQL. |
1948
|
|
|
|
|
|
|
|
1949
|
|
|
|
|
|
|
=head3 Additional methods |
1950
|
|
|
|
|
|
|
|
1951
|
|
|
|
|
|
|
The following methods are only available via their documented name when |
1952
|
|
|
|
|
|
|
DBI::DBD::SQlEngine is used directly. Because this is only reasonable for |
1953
|
|
|
|
|
|
|
testing purposes, the real names must be used instead. Those names can be |
1954
|
|
|
|
|
|
|
computed by replacing the C in the method name with the driver prefix. |
1955
|
|
|
|
|
|
|
|
1956
|
|
|
|
|
|
|
=head4 sql_versions |
1957
|
|
|
|
|
|
|
|
1958
|
|
|
|
|
|
|
Signature: |
1959
|
|
|
|
|
|
|
|
1960
|
|
|
|
|
|
|
sub sql_versions (;$) { |
1961
|
|
|
|
|
|
|
my ($table_name) = @_; |
1962
|
|
|
|
|
|
|
$table_name ||= "."; |
1963
|
|
|
|
|
|
|
... |
1964
|
|
|
|
|
|
|
} |
1965
|
|
|
|
|
|
|
|
1966
|
|
|
|
|
|
|
Returns the versions of the driver, including the DBI version, the Perl |
1967
|
|
|
|
|
|
|
version, DBI::PurePerl version (if DBI::PurePerl is active) and the version |
1968
|
|
|
|
|
|
|
of the SQL engine in use. |
1969
|
|
|
|
|
|
|
|
1970
|
|
|
|
|
|
|
my $dbh = DBI->connect ("dbi:File:"); |
1971
|
|
|
|
|
|
|
my $sql_versions = $dbh->func( "sql_versions" ); |
1972
|
|
|
|
|
|
|
print "$sql_versions\n"; |
1973
|
|
|
|
|
|
|
__END__ |
1974
|
|
|
|
|
|
|
# DBI::DBD::SqlEngine 0.05 using SQL::Statement 1.402 |
1975
|
|
|
|
|
|
|
# DBI 1.623 |
1976
|
|
|
|
|
|
|
# OS netbsd (6.99.12) |
1977
|
|
|
|
|
|
|
# Perl 5.016002 (x86_64-netbsd-thread-multi) |
1978
|
|
|
|
|
|
|
|
1979
|
|
|
|
|
|
|
Called in list context, sql_versions will return an array containing each |
1980
|
|
|
|
|
|
|
line as single entry. |
1981
|
|
|
|
|
|
|
|
1982
|
|
|
|
|
|
|
Some drivers might use the optional (table name) argument and modify |
1983
|
|
|
|
|
|
|
version information related to the table (e.g. DBD::DBM provides storage |
1984
|
|
|
|
|
|
|
backend information for the requested table, when it has a table name). |
1985
|
|
|
|
|
|
|
|
1986
|
|
|
|
|
|
|
=head4 sql_get_meta |
1987
|
|
|
|
|
|
|
|
1988
|
|
|
|
|
|
|
Signature: |
1989
|
|
|
|
|
|
|
|
1990
|
|
|
|
|
|
|
sub sql_get_meta ($$) |
1991
|
|
|
|
|
|
|
{ |
1992
|
|
|
|
|
|
|
my ($table_name, $attrib) = @_; |
1993
|
|
|
|
|
|
|
... |
1994
|
|
|
|
|
|
|
} |
1995
|
|
|
|
|
|
|
|
1996
|
|
|
|
|
|
|
Returns the value of a meta attribute set for a specific table, if any. |
1997
|
|
|
|
|
|
|
See L for the possible attributes. |
1998
|
|
|
|
|
|
|
|
1999
|
|
|
|
|
|
|
A table name of C<"."> (single dot) is interpreted as the default table. |
2000
|
|
|
|
|
|
|
This will retrieve the appropriate attribute globally from the dbh. |
2001
|
|
|
|
|
|
|
This has the same restrictions as C<< $dbh->{$attrib} >>. |
2002
|
|
|
|
|
|
|
|
2003
|
|
|
|
|
|
|
=head4 sql_set_meta |
2004
|
|
|
|
|
|
|
|
2005
|
|
|
|
|
|
|
Signature: |
2006
|
|
|
|
|
|
|
|
2007
|
|
|
|
|
|
|
sub sql_set_meta ($$$) |
2008
|
|
|
|
|
|
|
{ |
2009
|
|
|
|
|
|
|
my ($table_name, $attrib, $value) = @_; |
2010
|
|
|
|
|
|
|
... |
2011
|
|
|
|
|
|
|
} |
2012
|
|
|
|
|
|
|
|
2013
|
|
|
|
|
|
|
Sets the value of a meta attribute set for a specific table. |
2014
|
|
|
|
|
|
|
See L for the possible attributes. |
2015
|
|
|
|
|
|
|
|
2016
|
|
|
|
|
|
|
A table name of C<"."> (single dot) is interpreted as the default table |
2017
|
|
|
|
|
|
|
which will set the specified attribute globally for the dbh. |
2018
|
|
|
|
|
|
|
This has the same restrictions as C<< $dbh->{$attrib} = $value >>. |
2019
|
|
|
|
|
|
|
|
2020
|
|
|
|
|
|
|
=head4 sql_clear_meta |
2021
|
|
|
|
|
|
|
|
2022
|
|
|
|
|
|
|
Signature: |
2023
|
|
|
|
|
|
|
|
2024
|
|
|
|
|
|
|
sub sql_clear_meta ($) |
2025
|
|
|
|
|
|
|
{ |
2026
|
|
|
|
|
|
|
my ($table_name) = @_; |
2027
|
|
|
|
|
|
|
... |
2028
|
|
|
|
|
|
|
} |
2029
|
|
|
|
|
|
|
|
2030
|
|
|
|
|
|
|
Clears the table specific meta information in the private storage of the |
2031
|
|
|
|
|
|
|
dbh. |
2032
|
|
|
|
|
|
|
|
2033
|
|
|
|
|
|
|
=head2 Extensibility |
2034
|
|
|
|
|
|
|
|
2035
|
|
|
|
|
|
|
=head3 DBI::DBD::SqlEngine::TableSource |
2036
|
|
|
|
|
|
|
|
2037
|
|
|
|
|
|
|
Provides data sources and table information on database driver and database |
2038
|
|
|
|
|
|
|
handle level. |
2039
|
|
|
|
|
|
|
|
2040
|
|
|
|
|
|
|
package DBI::DBD::SqlEngine::TableSource; |
2041
|
|
|
|
|
|
|
|
2042
|
|
|
|
|
|
|
sub data_sources ($;$) |
2043
|
|
|
|
|
|
|
{ |
2044
|
|
|
|
|
|
|
my ( $class, $drh, $attrs ) = @_; |
2045
|
|
|
|
|
|
|
... |
2046
|
|
|
|
|
|
|
} |
2047
|
|
|
|
|
|
|
|
2048
|
|
|
|
|
|
|
sub avail_tables |
2049
|
|
|
|
|
|
|
{ |
2050
|
|
|
|
|
|
|
my ( $class, $drh ) = @_; |
2051
|
|
|
|
|
|
|
... |
2052
|
|
|
|
|
|
|
} |
2053
|
|
|
|
|
|
|
|
2054
|
|
|
|
|
|
|
The C method is called when the user invokes any of the |
2055
|
|
|
|
|
|
|
following: |
2056
|
|
|
|
|
|
|
|
2057
|
|
|
|
|
|
|
@ary = DBI->data_sources($driver); |
2058
|
|
|
|
|
|
|
@ary = DBI->data_sources($driver, \%attr); |
2059
|
|
|
|
|
|
|
|
2060
|
|
|
|
|
|
|
@ary = $dbh->data_sources(); |
2061
|
|
|
|
|
|
|
@ary = $dbh->data_sources(\%attr); |
2062
|
|
|
|
|
|
|
|
2063
|
|
|
|
|
|
|
The C method is called when the user invokes any of the |
2064
|
|
|
|
|
|
|
following: |
2065
|
|
|
|
|
|
|
|
2066
|
|
|
|
|
|
|
@names = $dbh->tables( $catalog, $schema, $table, $type ); |
2067
|
|
|
|
|
|
|
|
2068
|
|
|
|
|
|
|
$sth = $dbh->table_info( $catalog, $schema, $table, $type ); |
2069
|
|
|
|
|
|
|
$sth = $dbh->table_info( $catalog, $schema, $table, $type, \%attr ); |
2070
|
|
|
|
|
|
|
|
2071
|
|
|
|
|
|
|
$dbh->func( "list_tables" ); |
2072
|
|
|
|
|
|
|
|
2073
|
|
|
|
|
|
|
Every time where an C<\%attr> argument can be specified, this C<\%attr> |
2074
|
|
|
|
|
|
|
object's C attribute is preferred over the C<$dbh> |
2075
|
|
|
|
|
|
|
attribute or the driver default, eg. |
2076
|
|
|
|
|
|
|
|
2077
|
|
|
|
|
|
|
@ary = DBI->data_sources("dbi:CSV:", { |
2078
|
|
|
|
|
|
|
f_dir => "/your/csv/tables", |
2079
|
|
|
|
|
|
|
# note: this class doesn't comes with DBI |
2080
|
|
|
|
|
|
|
sql_table_source => "DBD::File::Archive::Tar::TableSource", |
2081
|
|
|
|
|
|
|
# scan tarballs instead of directories |
2082
|
|
|
|
|
|
|
}); |
2083
|
|
|
|
|
|
|
|
2084
|
|
|
|
|
|
|
When you're going to implement such a DBD::File::Archive::Tar::TableSource |
2085
|
|
|
|
|
|
|
class, remember to add correct attributes (including C |
2086
|
|
|
|
|
|
|
and C) to the returned DSN's. |
2087
|
|
|
|
|
|
|
|
2088
|
|
|
|
|
|
|
=head3 DBI::DBD::SqlEngine::DataSource |
2089
|
|
|
|
|
|
|
|
2090
|
|
|
|
|
|
|
Provides base functionality for dealing with tables. It is primarily |
2091
|
|
|
|
|
|
|
designed for allowing transparent access to files on disk or already |
2092
|
|
|
|
|
|
|
opened (file-)streams (eg. for DBD::CSV). |
2093
|
|
|
|
|
|
|
|
2094
|
|
|
|
|
|
|
Derived classes shall be restricted to similar functionality, too (eg. |
2095
|
|
|
|
|
|
|
opening streams from an archive, transparently compress/uncompress |
2096
|
|
|
|
|
|
|
log files before parsing them, |
2097
|
|
|
|
|
|
|
|
2098
|
|
|
|
|
|
|
package DBI::DBD::SqlEngine::DataSource; |
2099
|
|
|
|
|
|
|
|
2100
|
|
|
|
|
|
|
sub complete_table_name ($$;$) |
2101
|
|
|
|
|
|
|
{ |
2102
|
|
|
|
|
|
|
my ( $self, $meta, $table, $respect_case ) = @_; |
2103
|
|
|
|
|
|
|
... |
2104
|
|
|
|
|
|
|
} |
2105
|
|
|
|
|
|
|
|
2106
|
|
|
|
|
|
|
The method C is called when first setting up the |
2107
|
|
|
|
|
|
|
I for a table: |
2108
|
|
|
|
|
|
|
|
2109
|
|
|
|
|
|
|
"SELECT user.id, user.name, user.shell FROM user WHERE ..." |
2110
|
|
|
|
|
|
|
|
2111
|
|
|
|
|
|
|
results in opening the table C. First step of the table open |
2112
|
|
|
|
|
|
|
process is completing the name. Let's imagine you're having a L |
2113
|
|
|
|
|
|
|
handle with following settings: |
2114
|
|
|
|
|
|
|
|
2115
|
|
|
|
|
|
|
$dbh->{sql_identifier_case} = SQL_IC_LOWER; |
2116
|
|
|
|
|
|
|
$dbh->{f_ext} = '.lst'; |
2117
|
|
|
|
|
|
|
$dbh->{f_dir} = '/data/web/adrmgr'; |
2118
|
|
|
|
|
|
|
|
2119
|
|
|
|
|
|
|
Those settings will result in looking for files matching |
2120
|
|
|
|
|
|
|
C<[Uu][Ss][Ee][Rr](\.lst)?$> in C. The scanning of the |
2121
|
|
|
|
|
|
|
directory C and the pattern match check will be done |
2122
|
|
|
|
|
|
|
in C by the C method. |
2123
|
|
|
|
|
|
|
|
2124
|
|
|
|
|
|
|
If you intend to provide other sources of data streams than files, in |
2125
|
|
|
|
|
|
|
addition to provide an appropriate C method, a method |
2126
|
|
|
|
|
|
|
to open the resource is required: |
2127
|
|
|
|
|
|
|
|
2128
|
|
|
|
|
|
|
package DBI::DBD::SqlEngine::DataSource; |
2129
|
|
|
|
|
|
|
|
2130
|
|
|
|
|
|
|
sub open_data ($) |
2131
|
|
|
|
|
|
|
{ |
2132
|
|
|
|
|
|
|
my ( $self, $meta, $attrs, $flags ) = @_; |
2133
|
|
|
|
|
|
|
... |
2134
|
|
|
|
|
|
|
} |
2135
|
|
|
|
|
|
|
|
2136
|
|
|
|
|
|
|
After the method C has been run successfully, the table's meta |
2137
|
|
|
|
|
|
|
information are in a state which allowes the table's data accessor methods |
2138
|
|
|
|
|
|
|
will be able to fetch/store row information. Implementation details heavily |
2139
|
|
|
|
|
|
|
depends on the table implementation, whereby the most famous is surely |
2140
|
|
|
|
|
|
|
L. |
2141
|
|
|
|
|
|
|
|
2142
|
|
|
|
|
|
|
=head1 SQL ENGINES |
2143
|
|
|
|
|
|
|
|
2144
|
|
|
|
|
|
|
DBI::DBD::SqlEngine currently supports two SQL engines: |
2145
|
|
|
|
|
|
|
L and |
2146
|
|
|
|
|
|
|
L. DBI::SQL::Nano supports a |
2147
|
|
|
|
|
|
|
I limited subset of SQL statements, but it might be faster for some |
2148
|
|
|
|
|
|
|
very simple tasks. SQL::Statement in contrast supports a much larger subset |
2149
|
|
|
|
|
|
|
of ANSI SQL. |
2150
|
|
|
|
|
|
|
|
2151
|
|
|
|
|
|
|
To use SQL::Statement, you need at least version 1.401 of |
2152
|
|
|
|
|
|
|
SQL::Statement and the environment variable C must not |
2153
|
|
|
|
|
|
|
be set to a true value. |
2154
|
|
|
|
|
|
|
|
2155
|
|
|
|
|
|
|
=head1 SUPPORT |
2156
|
|
|
|
|
|
|
|
2157
|
|
|
|
|
|
|
You can find documentation for this module with the perldoc command. |
2158
|
|
|
|
|
|
|
|
2159
|
|
|
|
|
|
|
perldoc DBI::DBD::SqlEngine |
2160
|
|
|
|
|
|
|
|
2161
|
|
|
|
|
|
|
You can also look for information at: |
2162
|
|
|
|
|
|
|
|
2163
|
|
|
|
|
|
|
=over 4 |
2164
|
|
|
|
|
|
|
|
2165
|
|
|
|
|
|
|
=item * RT: CPAN's request tracker |
2166
|
|
|
|
|
|
|
|
2167
|
|
|
|
|
|
|
L |
2168
|
|
|
|
|
|
|
L |
2169
|
|
|
|
|
|
|
|
2170
|
|
|
|
|
|
|
=item * AnnoCPAN: Annotated CPAN documentation |
2171
|
|
|
|
|
|
|
|
2172
|
|
|
|
|
|
|
L |
2173
|
|
|
|
|
|
|
L |
2174
|
|
|
|
|
|
|
|
2175
|
|
|
|
|
|
|
=item * CPAN Ratings |
2176
|
|
|
|
|
|
|
|
2177
|
|
|
|
|
|
|
L |
2178
|
|
|
|
|
|
|
|
2179
|
|
|
|
|
|
|
=item * Search CPAN |
2180
|
|
|
|
|
|
|
|
2181
|
|
|
|
|
|
|
L |
2182
|
|
|
|
|
|
|
|
2183
|
|
|
|
|
|
|
=back |
2184
|
|
|
|
|
|
|
|
2185
|
|
|
|
|
|
|
=head2 Where can I go for more help? |
2186
|
|
|
|
|
|
|
|
2187
|
|
|
|
|
|
|
For questions about installation or usage, please ask on the |
2188
|
|
|
|
|
|
|
dbi-dev@perl.org mailing list. |
2189
|
|
|
|
|
|
|
|
2190
|
|
|
|
|
|
|
If you have a bug report, patch or suggestion, please open |
2191
|
|
|
|
|
|
|
a new report ticket on CPAN, if there is not already one for |
2192
|
|
|
|
|
|
|
the issue you want to report. Of course, you can mail any of the |
2193
|
|
|
|
|
|
|
module maintainers, but it is less likely to be missed if |
2194
|
|
|
|
|
|
|
it is reported on RT. |
2195
|
|
|
|
|
|
|
|
2196
|
|
|
|
|
|
|
Report tickets should contain a detailed description of the bug or |
2197
|
|
|
|
|
|
|
enhancement request you want to report and at least an easy way to |
2198
|
|
|
|
|
|
|
verify/reproduce the issue and any supplied fix. Patches are always |
2199
|
|
|
|
|
|
|
welcome, too. |
2200
|
|
|
|
|
|
|
|
2201
|
|
|
|
|
|
|
=head1 ACKNOWLEDGEMENTS |
2202
|
|
|
|
|
|
|
|
2203
|
|
|
|
|
|
|
Thanks to Tim Bunce, Martin Evans and H.Merijn Brand for their continued |
2204
|
|
|
|
|
|
|
support while developing DBD::File, DBD::DBM and DBD::AnyData. |
2205
|
|
|
|
|
|
|
Their support, hints and feedback helped to design and implement this |
2206
|
|
|
|
|
|
|
module. |
2207
|
|
|
|
|
|
|
|
2208
|
|
|
|
|
|
|
=head1 AUTHOR |
2209
|
|
|
|
|
|
|
|
2210
|
|
|
|
|
|
|
This module is currently maintained by |
2211
|
|
|
|
|
|
|
|
2212
|
|
|
|
|
|
|
H.Merijn Brand < h.m.brand at xs4all.nl > and |
2213
|
|
|
|
|
|
|
Jens Rehsack < rehsack at googlemail.com > |
2214
|
|
|
|
|
|
|
|
2215
|
|
|
|
|
|
|
The original authors are Jochen Wiedmann and Jeff Zucker. |
2216
|
|
|
|
|
|
|
|
2217
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
2218
|
|
|
|
|
|
|
|
2219
|
|
|
|
|
|
|
Copyright (C) 2009-2013 by H.Merijn Brand & Jens Rehsack |
2220
|
|
|
|
|
|
|
Copyright (C) 2004-2009 by Jeff Zucker |
2221
|
|
|
|
|
|
|
Copyright (C) 1998-2004 by Jochen Wiedmann |
2222
|
|
|
|
|
|
|
|
2223
|
|
|
|
|
|
|
All rights reserved. |
2224
|
|
|
|
|
|
|
|
2225
|
|
|
|
|
|
|
You may freely distribute and/or modify this module under the terms of |
2226
|
|
|
|
|
|
|
either the GNU General Public License (GPL) or the Artistic License, as |
2227
|
|
|
|
|
|
|
specified in the Perl README file. |
2228
|
|
|
|
|
|
|
|
2229
|
|
|
|
|
|
|
=head1 SEE ALSO |
2230
|
|
|
|
|
|
|
|
2231
|
|
|
|
|
|
|
L, L, L and L. |
2232
|
|
|
|
|
|
|
|
2233
|
|
|
|
|
|
|
=cut |