line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
######################################################################### |
2
|
|
|
|
|
|
|
# DBD::AnyData - a DBI driver for files and data structures |
3
|
|
|
|
|
|
|
# |
4
|
|
|
|
|
|
|
# This module is copyright (c), 2001 by Jeff Zucker |
5
|
|
|
|
|
|
|
# All rights reserved. |
6
|
|
|
|
|
|
|
# |
7
|
|
|
|
|
|
|
# This is free software. You may distribute it under |
8
|
|
|
|
|
|
|
# the same terms as Perl itself as specified in the |
9
|
|
|
|
|
|
|
# Perl README file. |
10
|
|
|
|
|
|
|
# |
11
|
|
|
|
|
|
|
# WARNING: no warranty of any kind is implied. |
12
|
|
|
|
|
|
|
# |
13
|
|
|
|
|
|
|
# To learn more: enter "perldoc DBD::AnyData" at the command prompt, |
14
|
|
|
|
|
|
|
# or search in this file for =head1 and read the text below it |
15
|
|
|
|
|
|
|
# |
16
|
|
|
|
|
|
|
######################################################################### |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
package DBD::AnyData; |
19
|
|
|
|
|
|
|
|
20
|
2
|
|
|
2
|
|
91594
|
use strict; |
|
2
|
|
|
|
|
6
|
|
|
2
|
|
|
|
|
82
|
|
21
|
2
|
|
|
2
|
|
45
|
use warnings; |
|
2
|
|
|
|
|
5
|
|
|
2
|
|
|
|
|
366
|
|
22
|
|
|
|
|
|
|
|
23
|
2
|
|
|
2
|
|
7468
|
use AnyData; |
|
2
|
|
|
|
|
25507
|
|
|
2
|
|
|
|
|
248
|
|
24
|
|
|
|
|
|
|
require DBI::DBD::SqlEngine; |
25
|
2
|
|
|
2
|
|
19
|
use base qw(DBI::DBD::SqlEngine); |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
3590
|
|
26
|
|
|
|
|
|
|
require SQL::Statement; |
27
|
|
|
|
|
|
|
require SQL::Eval; |
28
|
|
|
|
|
|
|
|
29
|
2
|
|
|
2
|
|
596722
|
use vars qw($VERSION $err $errstr $sqlstate $drh $methods_already_installed); |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
534
|
|
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
$VERSION = '0.110'; |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
$err = 0; # holds error code for DBI::err |
34
|
|
|
|
|
|
|
$errstr = ""; # holds error string for DBI::errstr |
35
|
|
|
|
|
|
|
$sqlstate = ""; # holds SQL state for DBI::state |
36
|
|
|
|
|
|
|
$drh = undef; # holds driver handle once initialized |
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
sub driver |
39
|
|
|
|
|
|
|
{ |
40
|
1
|
|
|
1
|
0
|
1352
|
my ( $class, $attr ) = @_; |
41
|
1
|
50
|
|
|
|
5
|
return $drh if $drh; # already created - return same one |
42
|
1
|
|
|
|
|
17
|
$drh = $class->SUPER::driver( |
43
|
|
|
|
|
|
|
{ |
44
|
|
|
|
|
|
|
'Name' => 'AnyData', |
45
|
|
|
|
|
|
|
'Version' => $VERSION, |
46
|
|
|
|
|
|
|
'Err' => \$DBD::AnyData::err, |
47
|
|
|
|
|
|
|
'Errstr' => \$DBD::AnyData::errstr, |
48
|
|
|
|
|
|
|
'State' => \$DBD::AnyData::sqlstate, |
49
|
|
|
|
|
|
|
'Attribution' => 'DBD::AnyData by Jens Rehsack', |
50
|
|
|
|
|
|
|
} |
51
|
|
|
|
|
|
|
); |
52
|
|
|
|
|
|
|
|
53
|
1
|
50
|
|
|
|
550
|
unless ( $methods_already_installed++ ) |
54
|
|
|
|
|
|
|
{ |
55
|
1
|
|
|
|
|
4
|
DBD::AnyData::db->install_method('ad_import'); |
56
|
1
|
|
|
|
|
25
|
DBD::AnyData::db->install_method('ad_catalog'); |
57
|
1
|
|
|
|
|
26
|
DBD::AnyData::db->install_method('ad_convert'); |
58
|
1
|
|
|
|
|
24
|
DBD::AnyData::db->install_method('ad_export'); |
59
|
1
|
|
|
|
|
24
|
DBD::AnyData::db->install_method('ad_clear'); |
60
|
1
|
|
|
|
|
24
|
DBD::AnyData::db->install_method('ad_dump'); |
61
|
|
|
|
|
|
|
} |
62
|
|
|
|
|
|
|
|
63
|
1
|
|
|
|
|
33
|
return $drh; |
64
|
|
|
|
|
|
|
} |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
sub CLONE |
67
|
|
|
|
|
|
|
{ |
68
|
0
|
|
|
0
|
|
0
|
undef $drh; |
69
|
|
|
|
|
|
|
} |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
package DBD::AnyData::dr; # ====== DRIVER ====== |
72
|
|
|
|
|
|
|
|
73
|
2
|
|
|
2
|
|
11
|
use strict; |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
68
|
|
74
|
2
|
|
|
2
|
|
10
|
use warnings; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
68
|
|
75
|
|
|
|
|
|
|
|
76
|
2
|
|
|
2
|
|
11
|
use vars qw($imp_data_size); |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
194
|
|
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
$DBD::AnyData::dr::imp_data_size = 0; |
79
|
|
|
|
|
|
|
@DBD::AnyData::dr::ISA = qw(DBI::DBD::SqlEngine::dr); |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
sub disconnect_all |
82
|
|
|
|
|
|
|
{ |
83
|
1
|
|
|
1
|
|
325
|
shift->{ad_tables} = {}; |
84
|
|
|
|
|
|
|
} |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
sub DESTROY |
87
|
|
|
|
|
|
|
{ |
88
|
0
|
|
|
0
|
|
0
|
shift->{ad_tables} = {}; |
89
|
|
|
|
|
|
|
} |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
package DBD::AnyData::db; # ====== DATABASE ====== |
92
|
|
|
|
|
|
|
|
93
|
2
|
|
|
2
|
|
11
|
use strict; |
|
2
|
|
|
|
|
2
|
|
|
2
|
|
|
|
|
70
|
|
94
|
2
|
|
|
2
|
|
10
|
use warnings; |
|
2
|
|
|
|
|
2
|
|
|
2
|
|
|
|
|
52
|
|
95
|
|
|
|
|
|
|
|
96
|
2
|
|
|
2
|
|
8
|
use vars qw($imp_data_size); |
|
2
|
|
|
|
|
9
|
|
|
2
|
|
|
|
|
5069
|
|
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
require Cwd; |
99
|
|
|
|
|
|
|
require File::Spec; |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
$DBD::AnyData::db::imp_data_size = 0; |
102
|
|
|
|
|
|
|
@DBD::AnyData::db::ISA = qw(DBI::DBD::SqlEngine::db); |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
sub init_default_attributes |
105
|
|
|
|
|
|
|
{ |
106
|
1
|
|
|
1
|
|
123
|
my $dbh = shift; |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
# must be done first, because setting flags implicitly calls $dbdname::db->STORE |
109
|
1
|
|
|
|
|
8
|
$dbh->SUPER::init_default_attributes(); |
110
|
|
|
|
|
|
|
|
111
|
1
|
|
|
|
|
82
|
$dbh->{f_dir} = Cwd::abs_path( File::Spec->curdir() ); |
112
|
|
|
|
|
|
|
|
113
|
1
|
|
|
|
|
3
|
return $dbh; |
114
|
|
|
|
|
|
|
} |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
sub set_versions |
117
|
|
|
|
|
|
|
{ |
118
|
1
|
|
|
1
|
|
56
|
my $this = $_[0]; |
119
|
1
|
|
|
|
|
4
|
$this->{ad_version} = $DBD::AnyData::VERSION; |
120
|
1
|
|
|
|
|
7
|
return $this->SUPER::set_versions(); |
121
|
|
|
|
|
|
|
} |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
sub disconnect |
124
|
|
|
|
|
|
|
{ |
125
|
0
|
|
|
0
|
|
0
|
my $dbh = $_[0]; |
126
|
0
|
|
|
|
|
0
|
$dbh->SUPER::disconnect(); |
127
|
0
|
|
|
|
|
0
|
$dbh->{ad_tables} = {}; |
128
|
0
|
|
|
|
|
0
|
$dbh->STORE( 'Active', 0 ); |
129
|
0
|
|
|
|
|
0
|
return 1; |
130
|
|
|
|
|
|
|
} |
131
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
sub validate_STORE_attr |
133
|
|
|
|
|
|
|
{ |
134
|
2
|
|
|
2
|
|
258
|
my ( $dbh, $attrib, $value ) = @_; |
135
|
|
|
|
|
|
|
|
136
|
2
|
100
|
|
|
|
9
|
if ( $attrib eq "f_dir" ) |
137
|
|
|
|
|
|
|
{ |
138
|
1
|
50
|
|
|
|
33
|
-d $value |
139
|
|
|
|
|
|
|
or return $dbh->set_err( $DBI::stderr, "No such directory '$value'" ); |
140
|
1
|
50
|
|
|
|
9
|
File::Spec->file_name_is_absolute($value) |
141
|
|
|
|
|
|
|
or $value = Cwd::abs_path($value); |
142
|
|
|
|
|
|
|
} |
143
|
|
|
|
|
|
|
|
144
|
2
|
|
|
|
|
11
|
return $dbh->SUPER::validate_STORE_attr( $attrib, $value ); |
145
|
|
|
|
|
|
|
} |
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
sub get_ad_versions |
148
|
|
|
|
|
|
|
{ |
149
|
0
|
|
|
0
|
|
0
|
my ( $dbh, $table ) = @_; |
150
|
|
|
|
|
|
|
|
151
|
0
|
|
|
|
|
0
|
my $dver; |
152
|
|
|
|
|
|
|
my $eval_str; |
153
|
0
|
|
|
|
|
0
|
$eval_str = sprintf( '$dver = $%s::VERSION', "AnyData" ); |
154
|
0
|
|
|
|
|
0
|
eval $eval_str; |
155
|
0
|
|
|
|
|
0
|
my $dtype = "AnyData"; |
156
|
0
|
0
|
|
|
|
0
|
$dtype .= ' (' . $dver . ')' if $dver; |
157
|
|
|
|
|
|
|
|
158
|
0
|
|
|
|
|
0
|
return sprintf( "%s using %s", $dbh->{ad_version}, $dtype ); |
159
|
|
|
|
|
|
|
} |
160
|
|
|
|
|
|
|
# |
161
|
|
|
|
|
|
|
# DRIVER PRIVATE METHODS |
162
|
|
|
|
|
|
|
# |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
sub ad_mod_catalog |
165
|
|
|
|
|
|
|
{ |
166
|
0
|
|
|
0
|
|
0
|
my ( $self, $tname, $key, $value ) = @_; |
167
|
0
|
|
|
|
|
0
|
$self->{ad_tables}->{$tname}->{$key} = $value; |
168
|
|
|
|
|
|
|
} |
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
sub ad_clear |
171
|
|
|
|
|
|
|
{ |
172
|
1
|
|
|
1
|
|
2511
|
my $self = shift; |
173
|
1
|
|
|
|
|
4
|
my $tname = shift; |
174
|
1
|
50
|
33
|
|
|
10
|
if ( $tname eq 'all' or $tname eq '' ) |
175
|
|
|
|
|
|
|
{ |
176
|
0
|
|
|
|
|
0
|
$self->{ad_tables} = {}; |
177
|
|
|
|
|
|
|
} |
178
|
|
|
|
|
|
|
else |
179
|
|
|
|
|
|
|
{ |
180
|
1
|
|
|
|
|
6
|
delete $self->{ad_tables}->{$tname}; |
181
|
|
|
|
|
|
|
} |
182
|
|
|
|
|
|
|
} |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
sub ad_get_catalog |
185
|
|
|
|
|
|
|
{ |
186
|
8
|
|
|
8
|
|
14
|
my $self = shift; |
187
|
8
|
|
|
|
|
11
|
my $tname = shift; |
188
|
|
|
|
|
|
|
################################################################# |
189
|
|
|
|
|
|
|
# Patch from Wes Hardaker |
190
|
|
|
|
|
|
|
################################################################# |
191
|
8
|
50
|
|
|
|
25
|
if ($tname) |
192
|
|
|
|
|
|
|
{ |
193
|
8
|
100
|
|
|
|
43
|
return $self->{ad_tables}->{$tname} |
194
|
|
|
|
|
|
|
if ( $self->{ad_tables}->{$tname} ); |
195
|
1
|
|
|
|
|
4
|
return $self->{ad_tables}->{__default}; |
196
|
|
|
|
|
|
|
} |
197
|
|
|
|
|
|
|
################################################################# |
198
|
0
|
|
|
|
|
0
|
return $self->{ad_tables}; |
199
|
|
|
|
|
|
|
} |
200
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
sub ad_export |
202
|
|
|
|
|
|
|
{ |
203
|
0
|
|
|
0
|
|
0
|
my $dbh = shift; |
204
|
0
|
|
|
|
|
0
|
my $table_name = shift; |
205
|
0
|
|
|
|
|
0
|
my $format = shift; |
206
|
0
|
|
|
|
|
0
|
my $file_name = shift; |
207
|
0
|
|
|
|
|
0
|
my $flags = shift; |
208
|
0
|
|
|
|
|
0
|
my $data; |
209
|
0
|
|
|
|
|
0
|
my $catalog = $dbh->func( $table_name, 'ad_get_catalog' ); |
210
|
|
|
|
|
|
|
#use Data::Dumper; print Dumper $catalog; |
211
|
0
|
0
|
0
|
|
|
0
|
if ( $catalog->{format} && 'XML HTMLtable' =~ /$catalog->{format}/ ) |
212
|
|
|
|
|
|
|
{ |
213
|
|
|
|
|
|
|
#use Data::Dumper; print "!",Dumper $catalog; exit; |
214
|
0
|
0
|
|
|
|
0
|
my $sth = $dbh->prepare("SELECT 1 FROM $table_name") or die DBI->errstr; |
215
|
0
|
|
|
|
|
0
|
$sth->execute; # or die DBI->errstr; |
216
|
|
|
|
|
|
|
###z return $catalog->{ad}->export($format,$file_name,$flags) if 'XML HTMLtable' =~ /$format/; |
217
|
0
|
0
|
|
|
|
0
|
return $catalog->{ad}->export( $file_name, $flags ) if 'XML HTMLtable' =~ /$format/; |
218
|
0
|
|
|
|
|
0
|
$data = $dbh->selectall_arrayref("SELECT * FROM $table_name"); |
219
|
|
|
|
|
|
|
#my $sth = $dbh->prepare("SELECT * FROM $table_name"); |
220
|
|
|
|
|
|
|
#$sth->execute; |
221
|
|
|
|
|
|
|
#unshift @$data, $sth->{NAME}; |
222
|
|
|
|
|
|
|
} |
223
|
|
|
|
|
|
|
else |
224
|
|
|
|
|
|
|
{ |
225
|
|
|
|
|
|
|
#z $data = $dbh->func($table_name,'ad_get_catalog')->{records}; |
226
|
0
|
|
|
|
|
0
|
my $sth = $dbh->prepare("SELECT * FROM $table_name WHERE 1=0"); |
227
|
0
|
|
|
|
|
0
|
$sth->execute; |
228
|
0
|
|
|
|
|
0
|
$data = $catalog->{ad}->{storage}->{records}; |
229
|
|
|
|
|
|
|
} |
230
|
0
|
0
|
|
|
|
0
|
$data = $dbh->selectall_arrayref("SELECT * FROM $table_name") |
231
|
|
|
|
|
|
|
if $format =~ /XML|HTMLtable/; |
232
|
|
|
|
|
|
|
#use Data::Dumper; |
233
|
|
|
|
|
|
|
#die Dumper $data; |
234
|
|
|
|
|
|
|
# print Dumper $dbh->func( $table_name,'ad_get_catalog'); |
235
|
|
|
|
|
|
|
|
236
|
0
|
|
|
|
|
0
|
my $newcols = $dbh->func( $table_name, 'ad_get_catalog' )->{ad}->{storage}->{col_names}; |
237
|
0
|
0
|
|
|
|
0
|
unshift @$data, $newcols if $newcols; |
238
|
0
|
|
|
|
|
0
|
return AnyData::adConvert( 'Base', $data, $format, $file_name, undef, $flags ); |
239
|
|
|
|
|
|
|
# return AnyData::adExport({},$format,$data,$file_name,undef,$flags); |
240
|
|
|
|
|
|
|
} |
241
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
sub ad_convert |
243
|
|
|
|
|
|
|
{ |
244
|
0
|
|
|
0
|
|
0
|
my $dbh = shift; |
245
|
0
|
|
|
|
|
0
|
my $format = shift; |
246
|
0
|
0
|
|
|
|
0
|
if ( $format eq 'DBI' ) |
247
|
|
|
|
|
|
|
{ |
248
|
0
|
|
|
|
|
0
|
my $data = shift; |
249
|
0
|
|
|
|
|
0
|
my $newformat = shift; |
250
|
0
|
0
|
0
|
|
|
0
|
die "table_name required to convert DBI" |
251
|
|
|
|
|
|
|
unless $_[1] and $_[1]->{table_name}; |
252
|
0
|
|
|
|
|
0
|
my $table_name = $_[1]->{table_name}; |
253
|
0
|
|
|
|
|
0
|
$dbh->func( $table_name, 'DBI', $data, 'ad_import' ); |
254
|
0
|
|
|
|
|
0
|
my $rv = $dbh->func( $table_name, $newformat, 'ad_export' ); |
255
|
0
|
|
|
|
|
0
|
$dbh->func( $table_name, 'ad_clear' ); |
256
|
0
|
|
|
|
|
0
|
return $rv; |
257
|
|
|
|
|
|
|
} |
258
|
0
|
|
|
|
|
0
|
return AnyData::adConvert( $format, @_ ); |
259
|
|
|
|
|
|
|
} |
260
|
|
|
|
|
|
|
|
261
|
|
|
|
|
|
|
sub ad_import |
262
|
|
|
|
|
|
|
{ |
263
|
1
|
|
|
1
|
|
10
|
my $dbh = shift; |
264
|
1
|
|
|
|
|
3
|
my ( $table_name, $format, $file_name, $flags ) = @_; |
265
|
1
|
50
|
|
|
|
4
|
$format = 'CSV' if $format eq 'ARRAY'; |
266
|
1
|
|
|
|
|
6
|
my $old_catalog = $dbh->func( $table_name, 'ad_get_catalog' ); |
267
|
1
|
|
|
|
|
3
|
my $old_columns; |
268
|
|
|
|
|
|
|
my $old_records; |
269
|
1
|
50
|
|
|
|
4
|
if ($old_catalog) |
270
|
|
|
|
|
|
|
{ |
271
|
0
|
|
|
|
|
0
|
my $sth = $dbh->prepare("SELECT * FROM $table_name"); |
272
|
0
|
|
|
|
|
0
|
$sth->execute; |
273
|
0
|
|
|
|
|
0
|
$old_records = $sth->fetchall_arrayref; |
274
|
0
|
|
|
|
|
0
|
$old_columns = $sth->{NAME}; |
275
|
|
|
|
|
|
|
} |
276
|
1
|
|
33
|
|
|
7
|
my $sql = $flags->{sql} || "SELECT * FROM $table_name"; |
277
|
|
|
|
|
|
|
# die $sql; |
278
|
1
|
|
33
|
|
|
8
|
my @params = $flags->{params} || (); |
279
|
1
|
50
|
|
|
|
23
|
if ( 'XML HTMLtable' =~ /$format/ ) |
|
|
50
|
|
|
|
|
|
280
|
|
|
|
|
|
|
{ |
281
|
0
|
|
|
|
|
0
|
$dbh->func( $table_name, $format, $file_name, $flags, 'ad_catalog' ); |
282
|
0
|
|
|
|
|
0
|
my $sth = $dbh->prepare("SELECT * FROM $table_name WHERE 1=0"); |
283
|
0
|
|
|
|
|
0
|
$sth->execute; |
284
|
0
|
|
|
|
|
0
|
$sth->finish; |
285
|
0
|
0
|
|
|
|
0
|
return unless $old_catalog; |
286
|
|
|
|
|
|
|
} |
287
|
|
|
|
|
|
|
elsif ( ref($file_name) ) |
288
|
|
|
|
|
|
|
{ |
289
|
0
|
|
|
|
|
0
|
$flags->{recs} = $file_name; |
290
|
0
|
|
|
|
|
0
|
$flags->{storage} = 'RAM'; |
291
|
|
|
|
|
|
|
#$flags->{col_names} =$old_columns if $old_columns; |
292
|
0
|
|
|
|
|
0
|
$dbh->func( $table_name, $format, '', $flags, 'ad_catalog' ); |
293
|
|
|
|
|
|
|
} |
294
|
|
|
|
|
|
|
else |
295
|
|
|
|
|
|
|
{ |
296
|
1
|
|
|
|
|
7
|
$dbh->func( $table_name, $format, $file_name, $flags, 'ad_catalog' ); |
297
|
|
|
|
|
|
|
#$dbh->func(@_,'ad_catalog'); |
298
|
|
|
|
|
|
|
} |
299
|
1
|
|
|
|
|
4
|
my $dbh2 = $dbh; |
300
|
1
|
50
|
|
|
|
5
|
$dbh2 = $file_name if $format eq 'DBI'; |
301
|
1
|
50
|
|
|
|
8
|
my $sth = $dbh2->prepare($sql) or die DBI->errstr; |
302
|
|
|
|
|
|
|
# die "$sql"; |
303
|
1
|
50
|
|
|
|
826
|
$sth->execute(@params) or die DBI->errstr; |
304
|
0
|
0
|
|
|
|
0
|
my $cols = $sth->{NAME} or die DBI->errstr; |
305
|
|
|
|
|
|
|
# die @$cols; |
306
|
0
|
|
|
|
|
0
|
my $records; |
307
|
0
|
0
|
|
|
|
0
|
if ($old_records) |
308
|
|
|
|
|
|
|
{ |
309
|
0
|
|
|
|
|
0
|
my $colstr = join ',', @$old_columns; |
310
|
0
|
|
|
|
|
0
|
my $cr = join " TEXT,", @$old_columns; |
311
|
0
|
|
|
|
|
0
|
$cr = "CREATE TABLE temp__ ($cr TEXT)"; |
312
|
0
|
0
|
|
|
|
0
|
$dbh->do($cr) or die DBI->errstr; |
313
|
0
|
|
|
|
|
0
|
while ( my $row = $sth->fetchrow_hashref ) |
314
|
|
|
|
|
|
|
{ |
315
|
0
|
|
|
|
|
0
|
my $old_row; |
316
|
0
|
0
|
|
|
|
0
|
if ( $flags->{lookup_key} ) |
317
|
|
|
|
|
|
|
{ |
318
|
0
|
|
0
|
|
|
0
|
my $lookup = $flags->{lookup_key} || $sth->{NAME}->[0]; |
319
|
0
|
|
0
|
|
|
0
|
my $val = $row->{$lookup} || next; |
320
|
0
|
|
|
|
|
0
|
my $oldsth = $dbh->prepare( |
321
|
|
|
|
|
|
|
qq{ |
322
|
|
|
|
|
|
|
SELECT * FROM temp__ WHERE $lookup = '$val' |
323
|
|
|
|
|
|
|
} |
324
|
|
|
|
|
|
|
); |
325
|
0
|
|
|
|
|
0
|
$oldsth->execute; |
326
|
0
|
|
|
|
|
0
|
$old_row = $oldsth->fetchrow_hashref; |
327
|
0
|
|
|
|
|
0
|
my @tmp = $dbh->selectrow_array("SELECT * FROM temp__ WHERE $lookup = $val"); |
328
|
0
|
|
|
|
|
0
|
my $dup; |
329
|
|
|
|
|
|
|
|
330
|
0
|
|
|
|
|
0
|
for my $x (@tmp) |
331
|
|
|
|
|
|
|
{ |
332
|
0
|
0
|
|
|
|
0
|
if ( !defined $x ) |
333
|
|
|
|
|
|
|
{ |
334
|
0
|
|
|
|
|
0
|
$dup++; |
335
|
0
|
|
|
|
|
0
|
last; |
336
|
|
|
|
|
|
|
} |
337
|
|
|
|
|
|
|
} |
338
|
0
|
0
|
|
|
|
0
|
if ($dup) |
339
|
|
|
|
|
|
|
{ |
340
|
|
|
|
|
|
|
#print "@tmp"; |
341
|
0
|
0
|
|
|
|
0
|
$dbh->do("DELETE FROM temp__ WHERE $lookup = $val") |
342
|
|
|
|
|
|
|
or die DBI->errstr; |
343
|
|
|
|
|
|
|
} |
344
|
|
|
|
|
|
|
} |
345
|
0
|
|
|
|
|
0
|
my @params; |
346
|
0
|
|
|
|
|
0
|
for (@$old_columns) |
347
|
|
|
|
|
|
|
{ |
348
|
0
|
|
|
|
|
0
|
my $newval = $row->{$_}; |
349
|
0
|
|
0
|
|
|
0
|
$newval ||= $old_row->{$_}; |
350
|
0
|
|
|
|
|
0
|
push @params, $newval; |
351
|
|
|
|
|
|
|
} |
352
|
0
|
|
|
|
|
0
|
my $paramStr = ( join ",", ("?") x @$old_columns ); |
353
|
0
|
|
|
|
|
0
|
my $ins_sql = "INSERT INTO temp__ ($colstr) VALUES ($paramStr)"; |
354
|
0
|
0
|
|
|
|
0
|
$dbh->do( $ins_sql, undef, @params ) or die DBI->errstr; |
355
|
|
|
|
|
|
|
} |
356
|
0
|
|
0
|
|
|
0
|
$records ||= $dbh->selectall_arrayref($sql); |
357
|
|
|
|
|
|
|
} |
358
|
|
|
|
|
|
|
else |
359
|
|
|
|
|
|
|
{ |
360
|
0
|
|
|
|
|
0
|
$records = $sth->fetchall_arrayref; |
361
|
|
|
|
|
|
|
} |
362
|
0
|
0
|
|
|
|
0
|
$cols = $old_columns if $old_columns; |
363
|
0
|
0
|
|
|
|
0
|
unshift @$records, $cols unless $flags->{col_names}; |
364
|
0
|
0
|
0
|
|
|
0
|
$dbh2->disconnect if $format eq 'DBI' and !$flags->{keep_connection}; |
365
|
0
|
0
|
|
|
|
0
|
$file_name = '' if ref($file_name) eq 'ARRAY'; |
366
|
0
|
|
|
|
|
0
|
delete $flags->{recs}; |
367
|
0
|
|
|
|
|
0
|
delete $flags->{storage}; |
368
|
0
|
|
|
|
|
0
|
delete $flags->{format}; |
369
|
|
|
|
|
|
|
#$flags = {} if 'XML HTMLtable' =~ /$format/; |
370
|
0
|
0
|
|
|
|
0
|
if ( 'XML HTMLtable' =~ /$format/ ) |
371
|
|
|
|
|
|
|
{ |
372
|
0
|
|
|
|
|
0
|
delete $flags->{ad}; |
373
|
0
|
|
|
|
|
0
|
$flags->{file_name} = ''; |
374
|
|
|
|
|
|
|
} |
375
|
|
|
|
|
|
|
# use Data::Dumper; print Dumper $flags; |
376
|
0
|
|
0
|
|
|
0
|
$flags->{records} ||= $records; |
377
|
0
|
|
|
|
|
0
|
$dbh->func( $table_name, 'ad_clear' ); |
378
|
0
|
|
|
|
|
0
|
$dbh->func( $table_name, 'Base', $file_name, $flags, 'ad_catalog' ); |
379
|
0
|
|
|
|
|
0
|
my $firstrow = {}; |
380
|
0
|
0
|
|
|
|
0
|
return unless $records->[1]; |
381
|
0
|
|
|
|
|
0
|
@{$firstrow}{@$cols} = @{ $records->[1] }; |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
382
|
0
|
|
|
|
|
0
|
return $firstrow; |
383
|
|
|
|
|
|
|
} |
384
|
|
|
|
|
|
|
|
385
|
|
|
|
|
|
|
sub ad_catalog |
386
|
|
|
|
|
|
|
{ |
387
|
2
|
|
|
2
|
|
503
|
my $dbh = shift; |
388
|
2
|
|
|
|
|
6
|
my @specs = @_; |
389
|
2
|
50
|
|
|
|
9
|
my $table_info = |
390
|
|
|
|
|
|
|
( ref $specs[0] ) eq 'ARRAY' |
391
|
|
|
|
|
|
|
? shift @specs |
392
|
|
|
|
|
|
|
: [ \@specs ]; |
393
|
2
|
|
|
|
|
3
|
for my $one_table ( @{$table_info} ) |
|
2
|
|
|
|
|
5
|
|
394
|
|
|
|
|
|
|
{ |
395
|
2
|
|
|
|
|
2
|
my ( $table_name, $format, $file_name, $flags ); |
396
|
2
|
50
|
|
|
|
8
|
if ( ref $one_table eq 'ARRAY' ) |
397
|
|
|
|
|
|
|
{ |
398
|
2
|
|
|
|
|
3
|
( $table_name, $format, $file_name, $flags ) = @{$one_table}; |
|
2
|
|
|
|
|
5
|
|
399
|
2
|
50
|
|
|
|
5
|
$flags = {} unless $flags; |
400
|
2
|
|
|
|
|
5
|
$flags->{table_name} = $table_name; |
401
|
2
|
50
|
|
|
|
5
|
if ( ref $format eq 'HASH' ) |
402
|
|
|
|
|
|
|
{ |
403
|
0
|
|
|
|
|
0
|
$flags->{data} = $format->{data}; |
404
|
0
|
|
|
|
|
0
|
$format = 'Base'; |
405
|
|
|
|
|
|
|
} |
406
|
2
|
|
|
|
|
4
|
$flags->{format} = $format; |
407
|
2
|
|
|
|
|
4
|
$flags->{file_name} = $file_name; |
408
|
|
|
|
|
|
|
} |
409
|
2
|
50
|
|
|
|
13
|
if ( ref $one_table eq 'HASH' ) |
410
|
|
|
|
|
|
|
{ |
411
|
0
|
|
|
|
|
0
|
$flags = $one_table; |
412
|
|
|
|
|
|
|
} |
413
|
2
|
50
|
|
|
|
9
|
die "ERROR: ad_catalog requires a table name!" |
414
|
|
|
|
|
|
|
unless $flags->{table_name}; |
415
|
2
|
|
|
|
|
4
|
$table_name = $flags->{table_name}; |
416
|
2
|
|
50
|
|
|
6
|
$flags->{format} ||= 'Base'; |
417
|
2
|
|
50
|
|
|
5
|
$flags->{file_name} ||= ''; |
418
|
2
|
|
100
|
|
|
10
|
$flags->{eol} ||= "\n"; |
419
|
2
|
|
66
|
|
|
9
|
$flags->{f_dir} ||= $dbh->{f_dir}; |
420
|
2
|
|
|
|
|
13
|
$dbh->{ad_tables}->{$table_name} = $flags; |
421
|
|
|
|
|
|
|
} |
422
|
|
|
|
|
|
|
} |
423
|
|
|
|
|
|
|
|
424
|
|
|
|
|
|
|
sub ad_dump |
425
|
|
|
|
|
|
|
{ |
426
|
0
|
|
|
0
|
|
0
|
my $dbh = shift; |
427
|
0
|
|
|
|
|
0
|
my $sql = shift; |
428
|
0
|
0
|
|
|
|
0
|
if ( !$sql ) |
429
|
|
|
|
|
|
|
{ |
430
|
0
|
|
|
|
|
0
|
require Data::Dumper; |
431
|
0
|
|
|
|
|
0
|
$Data::Dumper::Indent = 1; |
432
|
0
|
|
|
|
|
0
|
return Data::Dumper::Dumper $dbh->func('ad_get_catalog'); |
433
|
|
|
|
|
|
|
} |
434
|
0
|
|
|
|
|
0
|
my $txt; |
435
|
0
|
0
|
|
|
|
0
|
my $sth = $dbh->prepare($sql) or die $dbh->errstr; |
436
|
0
|
0
|
|
|
|
0
|
$sth->execute or die $sth->errstr; |
437
|
0
|
|
|
|
|
0
|
my @col_names = @{ $sth->{NAME} }; |
|
0
|
|
|
|
|
0
|
|
438
|
0
|
|
|
|
|
0
|
$txt .= "<$_> " for @col_names; |
439
|
0
|
|
|
|
|
0
|
$txt .= "\n"; |
440
|
0
|
|
|
|
|
0
|
while ( my @row = $sth->fetchrow_array ) |
441
|
|
|
|
|
|
|
{ |
442
|
0
|
|
|
|
|
0
|
for (@row) |
443
|
|
|
|
|
|
|
{ |
444
|
0
|
|
0
|
|
|
0
|
$_ ||= ''; |
445
|
0
|
|
|
|
|
0
|
s/^\s*//; |
446
|
0
|
|
|
|
|
0
|
s/\s*$//; |
447
|
0
|
|
|
|
|
0
|
$txt .= "[$_] "; |
448
|
|
|
|
|
|
|
} |
449
|
0
|
|
|
|
|
0
|
$txt .= "\n"; |
450
|
|
|
|
|
|
|
} |
451
|
0
|
|
|
|
|
0
|
return $txt; |
452
|
|
|
|
|
|
|
} |
453
|
|
|
|
|
|
|
|
454
|
|
|
|
|
|
|
# END OF DRIVER PRIVATE METHODS |
455
|
|
|
|
|
|
|
|
456
|
|
|
|
|
|
|
sub get_avail_tables |
457
|
|
|
|
|
|
|
{ |
458
|
0
|
|
|
0
|
|
0
|
my $dbh = $_[0]; |
459
|
|
|
|
|
|
|
|
460
|
0
|
|
|
|
|
0
|
my @tables = $dbh->SUPER::get_avail_tables(); |
461
|
|
|
|
|
|
|
|
462
|
0
|
|
|
|
|
0
|
my $catalog = $dbh->func( '', 'ad_get_catalog' ); |
463
|
0
|
0
|
|
|
|
0
|
if ($catalog) |
464
|
|
|
|
|
|
|
{ |
465
|
0
|
|
|
|
|
0
|
for ( keys %{$catalog} ) |
|
0
|
|
|
|
|
0
|
|
466
|
|
|
|
|
|
|
{ |
467
|
0
|
|
|
|
|
0
|
push( @tables, [ undef, undef, $_, "TABLE", "AnyData" ] ); |
468
|
|
|
|
|
|
|
} |
469
|
|
|
|
|
|
|
} |
470
|
|
|
|
|
|
|
|
471
|
0
|
|
|
|
|
0
|
return @tables; |
472
|
|
|
|
|
|
|
} |
473
|
|
|
|
|
|
|
|
474
|
|
|
|
|
|
|
sub DESTROY |
475
|
|
|
|
|
|
|
{ |
476
|
1
|
|
|
1
|
|
931
|
my $dbh = shift; |
477
|
1
|
|
|
|
|
4
|
$dbh->{ad_tables} = {}; |
478
|
1
|
|
|
|
|
13
|
$dbh->STORE( 'Active', 0 ); |
479
|
|
|
|
|
|
|
} |
480
|
|
|
|
|
|
|
|
481
|
|
|
|
|
|
|
package DBD::AnyData::st; # ====== STATEMENT ====== |
482
|
|
|
|
|
|
|
|
483
|
2
|
|
|
2
|
|
16
|
use strict; |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
73
|
|
484
|
2
|
|
|
2
|
|
12
|
use warnings; |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
66
|
|
485
|
|
|
|
|
|
|
|
486
|
2
|
|
|
2
|
|
25
|
use vars qw($imp_data_size); |
|
2
|
|
|
|
|
5
|
|
|
2
|
|
|
|
|
153
|
|
487
|
|
|
|
|
|
|
|
488
|
|
|
|
|
|
|
$DBD::AnyData::st::imp_data_size = 0; |
489
|
|
|
|
|
|
|
@DBD::AnyData::st::ISA = qw(DBI::DBD::SqlEngine::st); |
490
|
|
|
|
|
|
|
|
491
|
|
|
|
|
|
|
# sub DESTROY ($) { undef; } |
492
|
|
|
|
|
|
|
|
493
|
|
|
|
|
|
|
# sub finish ($) {} |
494
|
|
|
|
|
|
|
|
495
|
|
|
|
|
|
|
package DBD::AnyData::Statement; |
496
|
|
|
|
|
|
|
|
497
|
2
|
|
|
2
|
|
10
|
use strict; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
53
|
|
498
|
2
|
|
|
2
|
|
10
|
use warnings; |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
770
|
|
499
|
|
|
|
|
|
|
|
500
|
|
|
|
|
|
|
@DBD::AnyData::Statement::ISA = qw(DBI::DBD::SqlEngine::Statement); |
501
|
|
|
|
|
|
|
|
502
|
|
|
|
|
|
|
sub open_table ($$$$$) |
503
|
|
|
|
|
|
|
{ |
504
|
7
|
|
|
7
|
|
37609
|
my ( $self, $data, $tname, $createMode, $lockMode ) = @_; |
505
|
7
|
|
|
|
|
16
|
my $dbh = $data->{Database}; |
506
|
7
|
|
|
|
|
49
|
my $catalog = $dbh->func( $tname, 'ad_get_catalog' ); |
507
|
7
|
50
|
|
|
|
19
|
if ( !$catalog ) |
508
|
|
|
|
|
|
|
{ |
509
|
0
|
|
|
|
|
0
|
$dbh->func( [ [ $tname, 'Base', '' ] ], 'ad_catalog' ); |
510
|
0
|
|
|
|
|
0
|
$catalog = $dbh->func( $tname, 'ad_get_catalog' ); |
511
|
0
|
|
|
|
|
0
|
$createMode = 'o'; |
512
|
0
|
|
|
|
|
0
|
$lockMode = undef; |
513
|
|
|
|
|
|
|
} |
514
|
7
|
|
|
|
|
14
|
my $format = $catalog->{format}; |
515
|
7
|
|
|
|
|
20
|
my $file = $catalog->{file_name}; |
516
|
7
|
|
33
|
|
|
53
|
my $ad = $catalog->{ad} |
517
|
|
|
|
|
|
|
################################################################# |
518
|
|
|
|
|
|
|
# Patch from Wes Hardaker |
519
|
|
|
|
|
|
|
################################################################# |
520
|
|
|
|
|
|
|
# || AnyData::adTable( $format, $file, $createMode, $lockMode, |
521
|
|
|
|
|
|
|
# $catalog ); |
522
|
|
|
|
|
|
|
|| AnyData::adTable( $format, $file, $createMode, $lockMode, $catalog, $tname ); |
523
|
|
|
|
|
|
|
#print join("\n", $format,@$file,$createMode), "\n"; |
524
|
|
|
|
|
|
|
#use Data::Dumper; print Dumper $catalog; |
525
|
|
|
|
|
|
|
################################################################# |
526
|
7
|
|
|
|
|
24566
|
my $table = $ad->prep_dbd_table( $tname, $createMode ); |
527
|
7
|
|
|
|
|
943
|
my $cols = $table->{col_names}; |
528
|
7
|
50
|
66
|
|
|
52
|
if ( $cols and ref $cols ne 'ARRAY' ) |
529
|
|
|
|
|
|
|
{ |
530
|
|
|
|
|
|
|
#$dbh->DBI::set_err(99, "\n $cols\n "); |
531
|
0
|
|
|
|
|
0
|
print "\n $cols\n "; |
532
|
0
|
|
|
|
|
0
|
exit; |
533
|
|
|
|
|
|
|
} |
534
|
7
|
50
|
33
|
|
|
2485
|
if ( 'Base XML HTMLtable' =~ /$catalog->{format}/ |
|
|
|
33
|
|
|
|
|
535
|
|
|
|
|
|
|
or $file =~ /http:|ftp:/ |
536
|
|
|
|
|
|
|
or ref($file) eq 'ARRAY' ) |
537
|
|
|
|
|
|
|
{ |
538
|
0
|
|
|
|
|
0
|
$ad->seek_first_record(); |
539
|
0
|
|
|
|
|
0
|
$dbh->func( $tname, 'ad', $ad, 'ad_mod_catalog' ); |
540
|
|
|
|
|
|
|
} |
541
|
|
|
|
|
|
|
|
542
|
7
|
|
|
|
|
65
|
return DBD::AnyData::Table->new($table); |
543
|
|
|
|
|
|
|
} |
544
|
|
|
|
|
|
|
|
545
|
|
|
|
|
|
|
package DBD::AnyData::Table; |
546
|
|
|
|
|
|
|
|
547
|
2
|
|
|
2
|
|
11
|
use strict; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
68
|
|
548
|
2
|
|
|
2
|
|
10
|
use warnings; |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
96
|
|
549
|
|
|
|
|
|
|
|
550
|
2
|
|
|
2
|
|
12
|
use Params::Util qw(_HASH0); |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
1990
|
|
551
|
|
|
|
|
|
|
|
552
|
|
|
|
|
|
|
@DBD::AnyData::Table::ISA = qw(DBI::DBD::SqlEngine::Table); |
553
|
|
|
|
|
|
|
|
554
|
|
|
|
|
|
|
sub new |
555
|
|
|
|
|
|
|
{ |
556
|
7
|
|
|
7
|
|
14
|
my ( $proto, $attr ) = @_; |
557
|
7
|
|
|
|
|
25
|
$attr->{col_names} = $attr->{ad}->{storage}->{col_names}; |
558
|
7
|
|
|
|
|
20
|
$attr->{col_nums} = $attr->{ad}->{storage}->{col_nums}; |
559
|
7
|
50
|
33
|
|
|
57
|
delete $attr->{col_nums} unless ( defined( $attr->{col_nums} ) and defined( _HASH0( $attr->{col_nums} ) ) ); |
560
|
7
|
|
|
|
|
49
|
return $proto->SUPER::new($attr); |
561
|
|
|
|
|
|
|
} |
562
|
|
|
|
|
|
|
|
563
|
|
|
|
|
|
|
sub trim |
564
|
|
|
|
|
|
|
{ |
565
|
0
|
|
|
0
|
|
|
my $x = $_[0]; |
566
|
0
|
|
|
|
|
|
$x =~ s/^\s+//; |
567
|
0
|
|
|
|
|
|
$x =~ s/\s+$//; |
568
|
0
|
|
|
|
|
|
return $x; |
569
|
|
|
|
|
|
|
} |
570
|
|
|
|
|
|
|
|
571
|
|
|
|
|
|
|
sub fetch_row ($$$) |
572
|
|
|
|
|
|
|
{ |
573
|
0
|
|
|
0
|
|
|
my ( $self, $data, $row ) = @_; |
574
|
0
|
|
|
|
|
|
my $requested_cols = $data->{sql_stmt}->{NAME}; |
575
|
0
|
|
|
|
|
|
my $dbh = $data->{Database}; |
576
|
0
|
|
|
|
|
|
my $fields = $self->{ad}->fetch_row($requested_cols); |
577
|
0
|
0
|
|
|
|
|
if ( $dbh->{ChopBlanks} ) |
578
|
|
|
|
|
|
|
{ |
579
|
0
|
|
|
|
|
|
@$fields = map( $_ = &trim($_), @$fields ); |
580
|
|
|
|
|
|
|
} |
581
|
0
|
|
|
|
|
|
$self->{row} = $fields; |
582
|
0
|
|
|
|
|
|
return $self->{row}; |
583
|
|
|
|
|
|
|
} |
584
|
|
|
|
|
|
|
|
585
|
|
|
|
|
|
|
sub push_names ($$$) |
586
|
|
|
|
|
|
|
{ |
587
|
0
|
|
|
0
|
|
|
my ( $self, $data, $names ) = @_; |
588
|
|
|
|
|
|
|
#print @$names; |
589
|
0
|
|
|
|
|
|
$self->{ad}->push_names($names); |
590
|
|
|
|
|
|
|
} |
591
|
|
|
|
|
|
|
|
592
|
|
|
|
|
|
|
sub push_row ($$$) |
593
|
|
|
|
|
|
|
{ |
594
|
0
|
|
|
0
|
|
|
my ( $self, $data, $fields ) = @_; |
595
|
0
|
|
|
|
|
|
my $requested_cols = []; |
596
|
0
|
|
|
|
|
|
my @rc = $data->{sql_stmt}->columns(); |
597
|
0
|
|
|
|
|
|
push @$requested_cols, $_->{column} for @rc; |
598
|
0
|
|
|
|
|
|
unshift @$fields, $requested_cols; |
599
|
0
|
|
|
|
|
|
$self->{ad}->push_row(@$fields); |
600
|
0
|
|
|
|
|
|
1; |
601
|
|
|
|
|
|
|
} |
602
|
|
|
|
|
|
|
|
603
|
|
|
|
|
|
|
sub seek ($$$$) |
604
|
|
|
|
|
|
|
{ |
605
|
0
|
|
|
0
|
|
|
my ( $self, $data, $pos, $whence ) = @_; |
606
|
0
|
|
|
|
|
|
$self->{ad}->seek( $pos, $whence ); |
607
|
|
|
|
|
|
|
} |
608
|
|
|
|
|
|
|
|
609
|
|
|
|
|
|
|
sub drop ($$) |
610
|
|
|
|
|
|
|
{ |
611
|
0
|
|
|
0
|
|
|
my ( $self, $data ) = @_; |
612
|
0
|
|
|
|
|
|
return $self->{ad}->drop(); |
613
|
|
|
|
|
|
|
} |
614
|
|
|
|
|
|
|
|
615
|
|
|
|
|
|
|
sub truncate ($$) |
616
|
|
|
|
|
|
|
{ |
617
|
0
|
|
|
0
|
|
|
my ( $self, $data ) = @_; |
618
|
0
|
|
|
|
|
|
$self->{ad}->truncate($data); |
619
|
|
|
|
|
|
|
} |
620
|
|
|
|
|
|
|
|
621
|
|
|
|
|
|
|
sub DESTROY |
622
|
|
|
|
|
|
|
{ |
623
|
|
|
|
|
|
|
# wierd: this is needed to close file handle ??? |
624
|
0
|
|
|
0
|
|
|
my $self = shift; |
625
|
|
|
|
|
|
|
#print "CLOSING" if $self->{ad}->{storage}->{fh}; |
626
|
0
|
0
|
|
|
|
|
my $fh = $self->{ad}->{storage}->{fh} or return; |
627
|
0
|
|
|
|
|
|
$self->{ad}->DESTROY; |
628
|
0
|
|
|
|
|
|
undef $self->{ad}->{storage}->{fh}; |
629
|
|
|
|
|
|
|
} |
630
|
|
|
|
|
|
|
|
631
|
|
|
|
|
|
|
=head1 NAME |
632
|
|
|
|
|
|
|
|
633
|
|
|
|
|
|
|
DBD::AnyData - DBI access to XML, CSV and other formats |
634
|
|
|
|
|
|
|
|
635
|
|
|
|
|
|
|
=head1 SYNOPSIS |
636
|
|
|
|
|
|
|
|
637
|
|
|
|
|
|
|
use DBI; |
638
|
|
|
|
|
|
|
my $dbh = DBI->connect('dbi:AnyData(RaiseError=>1):'); |
639
|
|
|
|
|
|
|
$dbh->func( 'trains', 'CSV', '/users/joe/cars.csv', 'ad_catalog'); |
640
|
|
|
|
|
|
|
$dbh->func( 'bikes', 'XML', [$xml_str], 'ad_import'); |
641
|
|
|
|
|
|
|
$dbh->func( 'cars', 'DBI', $mysql_dbh, 'ad_import'); |
642
|
|
|
|
|
|
|
# |
643
|
|
|
|
|
|
|
# ... DBI/SQL methods to access/modify the tables 'cars','bikes','trains' |
644
|
|
|
|
|
|
|
# |
645
|
|
|
|
|
|
|
print $dbh->func( 'cars', 'HTMLtable', 'ad_export'); |
646
|
|
|
|
|
|
|
|
647
|
|
|
|
|
|
|
or |
648
|
|
|
|
|
|
|
|
649
|
|
|
|
|
|
|
use DBI; |
650
|
|
|
|
|
|
|
my $dbh = DBI->connect('dbi:AnyData(RaiseError=>1):'); |
651
|
|
|
|
|
|
|
$dbh->func( 'Pipe', 'data.pipe', 'XML', 'data.xml', 'ad_convert'); |
652
|
|
|
|
|
|
|
|
653
|
|
|
|
|
|
|
or |
654
|
|
|
|
|
|
|
|
655
|
|
|
|
|
|
|
(many combinations of a dozen other data formats, see below) |
656
|
|
|
|
|
|
|
|
657
|
|
|
|
|
|
|
=head1 DESCRIPTION |
658
|
|
|
|
|
|
|
|
659
|
|
|
|
|
|
|
The DBD::AnyData module provides a DBI/SQL interface to data in many |
660
|
|
|
|
|
|
|
formats and from many sources. |
661
|
|
|
|
|
|
|
|
662
|
|
|
|
|
|
|
Currently supported formats include general format flatfiles (CSV, Fixed |
663
|
|
|
|
|
|
|
Length, Tab or Pipe "delimited", etc.), specific formats (passwd files, |
664
|
|
|
|
|
|
|
web logs, etc.), a variety of other kinds of formats (XML, Mp3, HTML |
665
|
|
|
|
|
|
|
tables), and, for some operations, any DBI accessible database. The |
666
|
|
|
|
|
|
|
number of supported formats will continue to grow rapidly since there |
667
|
|
|
|
|
|
|
is an open API making it easy for any author to create additional format |
668
|
|
|
|
|
|
|
parsers which can be plugged in to AnyData. |
669
|
|
|
|
|
|
|
|
670
|
|
|
|
|
|
|
Data in these various formats can come from local files, from remote files, |
671
|
|
|
|
|
|
|
or from perl data structures such as strings and arrays. |
672
|
|
|
|
|
|
|
|
673
|
|
|
|
|
|
|
Regardless of the format or source of the data, it may be accessed and/or |
674
|
|
|
|
|
|
|
modified using all standard DBI methods and a subset of SQL syntax. |
675
|
|
|
|
|
|
|
|
676
|
|
|
|
|
|
|
In addition to standard database access to files, the module also supports |
677
|
|
|
|
|
|
|
in-memory tables which allow you to create temporary views; to combine data |
678
|
|
|
|
|
|
|
from a number of sources; to quickly prototype database systems; and to |
679
|
|
|
|
|
|
|
display or save the data in any of the supported formats (e.g. to display |
680
|
|
|
|
|
|
|
data in a CSV file as an HTML table). These in-memory tables can be |
681
|
|
|
|
|
|
|
created from any combination of DBI databases or files of any format. |
682
|
|
|
|
|
|
|
They may also be created from perl data structures which means it's |
683
|
|
|
|
|
|
|
possible to quickly prototype a database system without any file access |
684
|
|
|
|
|
|
|
or rdbms backend. |
685
|
|
|
|
|
|
|
|
686
|
|
|
|
|
|
|
The module also supports converting files between any of the supported |
687
|
|
|
|
|
|
|
formats (e.g. save selected data from MySQL or Oracle to an XML file). |
688
|
|
|
|
|
|
|
|
689
|
|
|
|
|
|
|
Here a just a few examples of the capabilities: |
690
|
|
|
|
|
|
|
|
691
|
|
|
|
|
|
|
# SELECT DATA FROM A PASSWD FILE |
692
|
|
|
|
|
|
|
# |
693
|
|
|
|
|
|
|
$dbh->func( 'users', 'Passwd', '/etc/passwd', 'ad_catalog'); |
694
|
|
|
|
|
|
|
my $sth = $dbh->prepare("SELECT username,homedir,GID FROM users'); |
695
|
|
|
|
|
|
|
|
696
|
|
|
|
|
|
|
# INSERT A NEW ROW INTO A CSV FILE |
697
|
|
|
|
|
|
|
# |
698
|
|
|
|
|
|
|
$dbh->func( 'cars', 'CSV', 'cars.csv', 'ad_catalog'); |
699
|
|
|
|
|
|
|
$dbh->do("INSERT INTO cars VALUES ('Honda','Odyssey')"); |
700
|
|
|
|
|
|
|
|
701
|
|
|
|
|
|
|
# READ A REMOTE XML FILE AND PRINT IT AS AN HTML TABLE |
702
|
|
|
|
|
|
|
# |
703
|
|
|
|
|
|
|
print $dbh->func( 'XML', $url, 'HTMLtable', 'ad_convert'); |
704
|
|
|
|
|
|
|
|
705
|
|
|
|
|
|
|
# CONVERT A MYSQL DATABASE INTO XML AND SAVE IT IN A NEW FILE |
706
|
|
|
|
|
|
|
# |
707
|
|
|
|
|
|
|
$dbh->func( 'DBI', $mysql_dbh, 'XML', 'data.xml', 'ad_convert'); |
708
|
|
|
|
|
|
|
|
709
|
|
|
|
|
|
|
# CREATE AND ACCESS A VIEW CONTAINING DATA FROM AN ORACLE DATABASE |
710
|
|
|
|
|
|
|
# AND A TAB DELIMITED FILE |
711
|
|
|
|
|
|
|
# |
712
|
|
|
|
|
|
|
$dbh->func( 'combo', 'DBI', $oracle_dbh, 'ad_import'); |
713
|
|
|
|
|
|
|
$dbh->func( 'combo', 'Tab', 'data.tab', 'ad_import'); |
714
|
|
|
|
|
|
|
my $sth = $dbh->prepare("SELECT * FROM combo"); |
715
|
|
|
|
|
|
|
|
716
|
|
|
|
|
|
|
|
717
|
|
|
|
|
|
|
=head1 INSTALLATION |
718
|
|
|
|
|
|
|
|
719
|
|
|
|
|
|
|
To use DBD::AnyData you will need to install these modules, |
720
|
|
|
|
|
|
|
all available from CPAN and most available from activeState. |
721
|
|
|
|
|
|
|
|
722
|
|
|
|
|
|
|
* DBI |
723
|
|
|
|
|
|
|
* DBI::DBD::SqlEngine |
724
|
|
|
|
|
|
|
* SQL::Statement |
725
|
|
|
|
|
|
|
* AnyData |
726
|
|
|
|
|
|
|
* DBD::AnyData |
727
|
|
|
|
|
|
|
|
728
|
|
|
|
|
|
|
Note: DBI::DBD::SqlEngine is part of the DBI distribution |
729
|
|
|
|
|
|
|
|
730
|
|
|
|
|
|
|
Some advanced features require additional modules: |
731
|
|
|
|
|
|
|
|
732
|
|
|
|
|
|
|
=over 4 |
733
|
|
|
|
|
|
|
|
734
|
|
|
|
|
|
|
=item remote file access |
735
|
|
|
|
|
|
|
|
736
|
|
|
|
|
|
|
requires L (the libwww bundle) |
737
|
|
|
|
|
|
|
|
738
|
|
|
|
|
|
|
=item XML access |
739
|
|
|
|
|
|
|
|
740
|
|
|
|
|
|
|
requires L and L |
741
|
|
|
|
|
|
|
|
742
|
|
|
|
|
|
|
=item HTML table |
743
|
|
|
|
|
|
|
|
744
|
|
|
|
|
|
|
access requires L and L |
745
|
|
|
|
|
|
|
|
746
|
|
|
|
|
|
|
=item HTML table writing |
747
|
|
|
|
|
|
|
|
748
|
|
|
|
|
|
|
requires L |
749
|
|
|
|
|
|
|
|
750
|
|
|
|
|
|
|
=back |
751
|
|
|
|
|
|
|
|
752
|
|
|
|
|
|
|
AnyData and DBD::AnyData themselves can either be installed via cpan, |
753
|
|
|
|
|
|
|
cpanplus or cpanminus, using the distributed Build.PL manually with |
754
|
|
|
|
|
|
|
|
755
|
|
|
|
|
|
|
perl Build.PL |
756
|
|
|
|
|
|
|
./Build |
757
|
|
|
|
|
|
|
./Build test |
758
|
|
|
|
|
|
|
./Build install |
759
|
|
|
|
|
|
|
|
760
|
|
|
|
|
|
|
or by copying the AnyData.pm file manually to it's right place within |
761
|
|
|
|
|
|
|
your perl library path. |
762
|
|
|
|
|
|
|
|
763
|
|
|
|
|
|
|
=head1 QUICK START |
764
|
|
|
|
|
|
|
|
765
|
|
|
|
|
|
|
=head2 The Basics |
766
|
|
|
|
|
|
|
|
767
|
|
|
|
|
|
|
=over 1 |
768
|
|
|
|
|
|
|
|
769
|
|
|
|
|
|
|
=item There are four main steps in using DBD::AnyData in a script: |
770
|
|
|
|
|
|
|
|
771
|
|
|
|
|
|
|
1. Specify that you want to use the DBI module |
772
|
|
|
|
|
|
|
2. Create a database handle |
773
|
|
|
|
|
|
|
3. Specify the tables, files, and formats you want |
774
|
|
|
|
|
|
|
4. Use DBI/SQL commands to access and/or modify the data |
775
|
|
|
|
|
|
|
|
776
|
|
|
|
|
|
|
Steps #1, #2, and #3 can be as little as a single line of code each. |
777
|
|
|
|
|
|
|
|
778
|
|
|
|
|
|
|
Steps #3 and #4 can be omitted in some situations, see the sections |
779
|
|
|
|
|
|
|
below on "Working with In-Memory Data" and "Converting Data" |
780
|
|
|
|
|
|
|
|
781
|
|
|
|
|
|
|
=item Step #1 : Specify that you want to use the DBI module |
782
|
|
|
|
|
|
|
|
783
|
|
|
|
|
|
|
This step is always the same: just put this at the top of your script: |
784
|
|
|
|
|
|
|
|
785
|
|
|
|
|
|
|
use DBI; |
786
|
|
|
|
|
|
|
|
787
|
|
|
|
|
|
|
=item Step #2 Create a Database Handle |
788
|
|
|
|
|
|
|
|
789
|
|
|
|
|
|
|
This step can vary slightly depending on your needs but is usually this: |
790
|
|
|
|
|
|
|
|
791
|
|
|
|
|
|
|
my $dbh = DBI->connect('dbi:AnyData(RaiseError=>1):'); |
792
|
|
|
|
|
|
|
|
793
|
|
|
|
|
|
|
See the section below on "Connection Options" for other forms of |
794
|
|
|
|
|
|
|
connecting. See the section below on "Using Multiple Databases" for |
795
|
|
|
|
|
|
|
cases in which you may be creating more than one database handle. |
796
|
|
|
|
|
|
|
|
797
|
|
|
|
|
|
|
=item Step #3 : Specify the tables, files, and formats |
798
|
|
|
|
|
|
|
|
799
|
|
|
|
|
|
|
This step makes use of one of several methods unique to DBD::AnyData. |
800
|
|
|
|
|
|
|
These methods use the database handle created in step #2 to make a |
801
|
|
|
|
|
|
|
func() call and specify the name of the method as the last parameter. |
802
|
|
|
|
|
|
|
For example the 'ad_catalog' method would be called like this: |
803
|
|
|
|
|
|
|
|
804
|
|
|
|
|
|
|
$dbh->func( ..., 'ad_catalog') |
805
|
|
|
|
|
|
|
|
806
|
|
|
|
|
|
|
The ad_catalog() method takes three required parameters and one |
807
|
|
|
|
|
|
|
optional parameter: |
808
|
|
|
|
|
|
|
|
809
|
|
|
|
|
|
|
# $table = the name you will use to refer to the table in SQL commands |
810
|
|
|
|
|
|
|
# $format = the format of the data ('XML', 'CSV', 'Fixed', etc.) |
811
|
|
|
|
|
|
|
# $file = the name of a local or remote file holding the data |
812
|
|
|
|
|
|
|
# $flags = an optional hash of flags required by some data formats |
813
|
|
|
|
|
|
|
$dbh->func( $table, $format, $file, $flags, 'ad_catalog') |
814
|
|
|
|
|
|
|
|
815
|
|
|
|
|
|
|
# For example: |
816
|
|
|
|
|
|
|
$dbh->func( 'cars', 'XML', 'cars.xml', 'ad_catalog' ) |
817
|
|
|
|
|
|
|
|
818
|
|
|
|
|
|
|
This specifies that the table name 'cars' will be used to |
819
|
|
|
|
|
|
|
access XML data stored in the file 'cars.xml'. |
820
|
|
|
|
|
|
|
|
821
|
|
|
|
|
|
|
Once you have issued a catalog command, you can use the name $table |
822
|
|
|
|
|
|
|
in SQL commands to access or modify the data in $file. The catalog |
823
|
|
|
|
|
|
|
only needs to be specified once for a table/file/format combination |
824
|
|
|
|
|
|
|
and can then be used for an unlimited number of processing commands. |
825
|
|
|
|
|
|
|
|
826
|
|
|
|
|
|
|
=item Step #4 : Use DBI/SQL commands to access and/or modify data |
827
|
|
|
|
|
|
|
|
828
|
|
|
|
|
|
|
DBD::AnyData supports all standard DBI methods and a subset of SQL |
829
|
|
|
|
|
|
|
syntax. See the section below "SQL Syntax" for a description of the |
830
|
|
|
|
|
|
|
supported SQL commands. See the DBI documentation for detailed |
831
|
|
|
|
|
|
|
description of DBI commands. |
832
|
|
|
|
|
|
|
|
833
|
|
|
|
|
|
|
The do() method can be used to create or drop a table and insert, delete, |
834
|
|
|
|
|
|
|
or update rows: |
835
|
|
|
|
|
|
|
|
836
|
|
|
|
|
|
|
$dbh->do("CREATE TABLE ... ) |
837
|
|
|
|
|
|
|
$dbh->do("DROP TABLE ... ) |
838
|
|
|
|
|
|
|
$dbh->do("INSERT INTO ... ) |
839
|
|
|
|
|
|
|
$dbh->do("UPDATE ... ) |
840
|
|
|
|
|
|
|
$dbh->do("DELETE ... ) |
841
|
|
|
|
|
|
|
|
842
|
|
|
|
|
|
|
A combination of the prepare(), execute(), and fetch() methods can be |
843
|
|
|
|
|
|
|
used to access data: |
844
|
|
|
|
|
|
|
|
845
|
|
|
|
|
|
|
my $sth = $dbh->prepare("SELECT * FROM cars WHERE make = 'Honda'"); |
846
|
|
|
|
|
|
|
$sth->execute(); |
847
|
|
|
|
|
|
|
while (my $row = $sth->fetchrow_hashref){ |
848
|
|
|
|
|
|
|
print $row->{model}; |
849
|
|
|
|
|
|
|
} |
850
|
|
|
|
|
|
|
|
851
|
|
|
|
|
|
|
=item Putting it all together |
852
|
|
|
|
|
|
|
|
853
|
|
|
|
|
|
|
This is the complete script needed to access data stored in |
854
|
|
|
|
|
|
|
CSV format in a file called "cars.csv". It prints all data |
855
|
|
|
|
|
|
|
from the "make" and "model" columns of the database. |
856
|
|
|
|
|
|
|
|
857
|
|
|
|
|
|
|
# specifies that you will use the DBI module. |
858
|
|
|
|
|
|
|
use DBI; |
859
|
|
|
|
|
|
|
# creates a database handle |
860
|
|
|
|
|
|
|
my $dbh = DBI->connect('dbi:AnyData(RaiseError=>1):'); |
861
|
|
|
|
|
|
|
# specifies the table, format, and file holding the data |
862
|
|
|
|
|
|
|
$dbh->func( 'cars', 'CSV', 'cars.csv' 'ad_catalog'); |
863
|
|
|
|
|
|
|
# through 8 use DBI and SQL to access data in the file |
864
|
|
|
|
|
|
|
my $sth = $dbh->prepare("SELECT make, model FROM cars"); |
865
|
|
|
|
|
|
|
$sth->execute(); |
866
|
|
|
|
|
|
|
while (my $row = $sth->fetch) { |
867
|
|
|
|
|
|
|
print "@$row\n"; |
868
|
|
|
|
|
|
|
} |
869
|
|
|
|
|
|
|
|
870
|
|
|
|
|
|
|
=back |
871
|
|
|
|
|
|
|
|
872
|
|
|
|
|
|
|
=head2 Customizing table structure |
873
|
|
|
|
|
|
|
|
874
|
|
|
|
|
|
|
DBD::AnyData uses a number of defaults when it decides how to read data |
875
|
|
|
|
|
|
|
from a database and in many cases these defaults are all you will need. |
876
|
|
|
|
|
|
|
However, depending on the format and database you are using, you may need |
877
|
|
|
|
|
|
|
to specify other features such as column names, record separators, etc. |
878
|
|
|
|
|
|
|
|
879
|
|
|
|
|
|
|
You can specify this additional information in the $flags parameter of the |
880
|
|
|
|
|
|
|
ad_catalog and other DBD::AnyData methods. $flags is always a reference |
881
|
|
|
|
|
|
|
to a hash, i.e. one or more key value pairs joined with a =>, separated by |
882
|
|
|
|
|
|
|
commas, and delimited by curly braces: |
883
|
|
|
|
|
|
|
|
884
|
|
|
|
|
|
|
$flags = { key1 => value1, key2 => value2 ... } |
885
|
|
|
|
|
|
|
|
886
|
|
|
|
|
|
|
# or in the method call: |
887
|
|
|
|
|
|
|
$dbh->func( $table, $format, $file, { key1=>,val1 ... }, 'ad_catalog'); |
888
|
|
|
|
|
|
|
|
889
|
|
|
|
|
|
|
=over 2 |
890
|
|
|
|
|
|
|
|
891
|
|
|
|
|
|
|
=item Column Names |
892
|
|
|
|
|
|
|
|
893
|
|
|
|
|
|
|
Some formats have pre-defined column names: |
894
|
|
|
|
|
|
|
|
895
|
|
|
|
|
|
|
Passwd username |
896
|
|
|
|
|
|
|
passwd |
897
|
|
|
|
|
|
|
UID |
898
|
|
|
|
|
|
|
GID |
899
|
|
|
|
|
|
|
fullname |
900
|
|
|
|
|
|
|
homedir |
901
|
|
|
|
|
|
|
shell |
902
|
|
|
|
|
|
|
|
903
|
|
|
|
|
|
|
Weblog remotehost |
904
|
|
|
|
|
|
|
usernname |
905
|
|
|
|
|
|
|
authuser |
906
|
|
|
|
|
|
|
date |
907
|
|
|
|
|
|
|
request |
908
|
|
|
|
|
|
|
status |
909
|
|
|
|
|
|
|
bytes |
910
|
|
|
|
|
|
|
referer |
911
|
|
|
|
|
|
|
client |
912
|
|
|
|
|
|
|
|
913
|
|
|
|
|
|
|
Mp3 song |
914
|
|
|
|
|
|
|
artist |
915
|
|
|
|
|
|
|
album |
916
|
|
|
|
|
|
|
year |
917
|
|
|
|
|
|
|
genre |
918
|
|
|
|
|
|
|
filename |
919
|
|
|
|
|
|
|
filesize |
920
|
|
|
|
|
|
|
|
921
|
|
|
|
|
|
|
Column names for the other formats can either be specified in the database |
922
|
|
|
|
|
|
|
itself or supplied by you in the $flags parameter. |
923
|
|
|
|
|
|
|
|
924
|
|
|
|
|
|
|
If the column names are specified in the database, they are taken from |
925
|
|
|
|
|
|
|
the first record in the database. For example in a CSV (Comma |
926
|
|
|
|
|
|
|
Separated Values) file or a Fixed Length file, the default is to treat |
927
|
|
|
|
|
|
|
the first line of the table as the list of column names. In an |
928
|
|
|
|
|
|
|
HTMLtable file, the default is to look for the first |
in the first
929
|
|
|
|
|
|
|
table. In an XML file, the default is to use the names of all |
930
|
|
|
|
|
|
|
attributes and all CDATA and PCDATA elements contained within the first |
931
|
|
|
|
|
|
|
non-initial tag. |
932
|
|
|
|
|
|
|
|
933
|
|
|
|
|
|
|
In most cases, this first record that defines the column names is in |
934
|
|
|
|
|
|
|
the same format as the rest of the table e.g. a CSV string in a CSV |
935
|
|
|
|
|
|
|
file, a tab delimited string in a Tab delimited file, etc. The one |
936
|
|
|
|
|
|
|
exception to this is that in a Fixed Length file the first row of the |
937
|
|
|
|
|
|
|
file can contain a *comma-separated* list of column names, not a fixed |
938
|
|
|
|
|
|
|
length list. HTMLtable and XML also use other flags to select the |
939
|
|
|
|
|
|
|
column names (e.g. the number of the table or the depth in the tree to |
940
|
|
|
|
|
|
|
examine). Please see the documentation for these formats for further |
941
|
|
|
|
|
|
|
details of how defaults are selected. |
942
|
|
|
|
|
|
|
|
943
|
|
|
|
|
|
|
For most formats, if the column names are not contained in the first |
944
|
|
|
|
|
|
|
record in the file, then you can specify them as a comma separated |
945
|
|
|
|
|
|
|
list in the $flags parameter, for example: |
946
|
|
|
|
|
|
|
|
947
|
|
|
|
|
|
|
$dbh->func( |
948
|
|
|
|
|
|
|
'cars', |
949
|
|
|
|
|
|
|
'Tab', |
950
|
|
|
|
|
|
|
'data.tab', |
951
|
|
|
|
|
|
|
{ col_names => 'make,model,year' }, |
952
|
|
|
|
|
|
|
'ad_catalog') |
953
|
|
|
|
|
|
|
|
954
|
|
|
|
|
|
|
=back |
955
|
|
|
|
|
|
|
|
956
|
|
|
|
|
|
|
=head1 SUPPORTED FORMATS |
957
|
|
|
|
|
|
|
|
958
|
|
|
|
|
|
|
=head2 CSV, Tab, Pipe, Ini, Paragraph |
959
|
|
|
|
|
|
|
|
960
|
|
|
|
|
|
|
=head2 Fixed |
961
|
|
|
|
|
|
|
|
962
|
|
|
|
|
|
|
Fixed Length format files (where each column is a specified length) |
963
|
|
|
|
|
|
|
are unique in several respects. First, as mentioned above, if you |
964
|
|
|
|
|
|
|
wish to include the column names in the file itself, they should be on |
965
|
|
|
|
|
|
|
the first line of the file as a *comma separated* string. |
966
|
|
|
|
|
|
|
|
967
|
|
|
|
|
|
|
Secondly, there is a mandatory flag called 'pattern' that you must use |
968
|
|
|
|
|
|
|
whenever you use the Fixed length format. This flag specifies the |
969
|
|
|
|
|
|
|
widths of the columns. It uses the standard Perl pack/unpack syntax |
970
|
|
|
|
|
|
|
to specify the pattern. See the Perl documentation for those commands |
971
|
|
|
|
|
|
|
for further details. In most cases simply using a capital 'A' |
972
|
|
|
|
|
|
|
followed by the length of the field suffices: |
973
|
|
|
|
|
|
|
|
974
|
|
|
|
|
|
|
{ pattern => 'A10 A12 A4' } |
975
|
|
|
|
|
|
|
|
976
|
|
|
|
|
|
|
This specifies that the table contains three fields with widths of 10, |
977
|
|
|
|
|
|
|
12, and 14 characters. |
978
|
|
|
|
|
|
|
|
979
|
|
|
|
|
|
|
=head2 XML |
980
|
|
|
|
|
|
|
|
981
|
|
|
|
|
|
|
=head2 HTMLtable |
982
|
|
|
|
|
|
|
|
983
|
|
|
|
|
|
|
=head2 DBI |
984
|
|
|
|
|
|
|
|
985
|
|
|
|
|
|
|
DBD::AnyData supports importing any DBI database into memory and can |
986
|
|
|
|
|
|
|
also convert any DBI database into any of the other AnyData formats. |
987
|
|
|
|
|
|
|
|
988
|
|
|
|
|
|
|
Use the format name 'DBI', and instead of a filename, pass the |
989
|
|
|
|
|
|
|
ad_import call a connection in whatever database you are using, and |
990
|
|
|
|
|
|
|
specify a SQL SELECT statement: |
991
|
|
|
|
|
|
|
|
992
|
|
|
|
|
|
|
my $dbh = DBI->connect('dbi:AnyData:(RaiseError=>1)'); |
993
|
|
|
|
|
|
|
$dbh->func( |
994
|
|
|
|
|
|
|
'table1', |
995
|
|
|
|
|
|
|
'DBI', |
996
|
|
|
|
|
|
|
DBI->connect('dbi:mysql:database=test:(RaiseError=>1)'), |
997
|
|
|
|
|
|
|
{sql=>"SELECT make, model FROM cars WHERE make = 'honda'"}, |
998
|
|
|
|
|
|
|
'ad_import'); |
999
|
|
|
|
|
|
|
|
1000
|
|
|
|
|
|
|
That snippet imports a view from a MySQL database (selecting only the |
1001
|
|
|
|
|
|
|
named columns and the selected rows) into an AnyData in-memory table. |
1002
|
|
|
|
|
|
|
It can then be queried and/or modified in memory and then either |
1003
|
|
|
|
|
|
|
displayed or stored to a file in some other format such as XML. |
1004
|
|
|
|
|
|
|
|
1005
|
|
|
|
|
|
|
You may also use a bind_parameters form for the SQL call by passing an |
1006
|
|
|
|
|
|
|
additional flag with an arrayref of the parameters: |
1007
|
|
|
|
|
|
|
|
1008
|
|
|
|
|
|
|
{ |
1009
|
|
|
|
|
|
|
sql => "SELECT make,model FROM CARS WHERE make = ?" |
1010
|
|
|
|
|
|
|
params => ['honda'] |
1011
|
|
|
|
|
|
|
} |
1012
|
|
|
|
|
|
|
|
1013
|
|
|
|
|
|
|
To convert from a DBI accessible database such as ORACLE or MySQL to |
1014
|
|
|
|
|
|
|
one of the AnyData formats such as XML you must also include a flag |
1015
|
|
|
|
|
|
|
with the table_name within the database: |
1016
|
|
|
|
|
|
|
|
1017
|
|
|
|
|
|
|
my $dbh = DBI->connect('dbi:AnyData:(RaiseError=>1)'); |
1018
|
|
|
|
|
|
|
$dbh->func( |
1019
|
|
|
|
|
|
|
'DBI', |
1020
|
|
|
|
|
|
|
DBI->connect('dbi:mysql:database=test:(RaiseError=>1)'), |
1021
|
|
|
|
|
|
|
'XML', |
1022
|
|
|
|
|
|
|
'cars.xml', |
1023
|
|
|
|
|
|
|
{table_name=>'cars'}, |
1024
|
|
|
|
|
|
|
'ad_convert'); |
1025
|
|
|
|
|
|
|
|
1026
|
|
|
|
|
|
|
Or to print out the same data as an HTML table without storing it: |
1027
|
|
|
|
|
|
|
|
1028
|
|
|
|
|
|
|
my $dbh = DBI->connect('dbi:AnyData:(RaiseError=>1)'); |
1029
|
|
|
|
|
|
|
print $dbh->func( |
1030
|
|
|
|
|
|
|
'DBI', |
1031
|
|
|
|
|
|
|
DBI->connect('dbi:mysql:database=test:(RaiseError=>1)'), |
1032
|
|
|
|
|
|
|
'HTMLtable', |
1033
|
|
|
|
|
|
|
undef, |
1034
|
|
|
|
|
|
|
{table_name=>'cars'}, |
1035
|
|
|
|
|
|
|
'ad_convert'); |
1036
|
|
|
|
|
|
|
|
1037
|
|
|
|
|
|
|
The ad_convert() method works on the entire database. If you need to |
1038
|
|
|
|
|
|
|
convert only a selected portion of the databse, use ad_import() with |
1039
|
|
|
|
|
|
|
a SELECT clause and then ad_export() it to the new format. |
1040
|
|
|
|
|
|
|
|
1041
|
|
|
|
|
|
|
The ad_import method by default closes the connection for the imported |
1042
|
|
|
|
|
|
|
database. If you need to continue using the handle for the other datbase, |
1043
|
|
|
|
|
|
|
pass the flag {keep_connection=>1}: |
1044
|
|
|
|
|
|
|
|
1045
|
|
|
|
|
|
|
my $dbh = DBI->connect('dbi:AnyData:(RaiseError=>1)'); |
1046
|
|
|
|
|
|
|
my $mysql_dbh = DBI->connect('dbi:mysql:database=test:(RaiseError=>1)'), |
1047
|
|
|
|
|
|
|
$dbh->func( |
1048
|
|
|
|
|
|
|
'cars', |
1049
|
|
|
|
|
|
|
'DBI', |
1050
|
|
|
|
|
|
|
$mysql_dbh, |
1051
|
|
|
|
|
|
|
{ keep_connection=>1 }, |
1052
|
|
|
|
|
|
|
'ad_import'); |
1053
|
|
|
|
|
|
|
#... |
1054
|
|
|
|
|
|
|
$mysql_dbh->disconnect; |
1055
|
|
|
|
|
|
|
|
1056
|
|
|
|
|
|
|
=head2 Passwd, Weblog, Mp3 |
1057
|
|
|
|
|
|
|
|
1058
|
|
|
|
|
|
|
=head2 Other Formats |
1059
|
|
|
|
|
|
|
|
1060
|
|
|
|
|
|
|
DBD::AnyData supports an open API that allows other authors to build support |
1061
|
|
|
|
|
|
|
for other formats. This means that the list of supported formats will |
1062
|
|
|
|
|
|
|
continually grow. At the moment Wes Hardaker is working on |
1063
|
|
|
|
|
|
|
AnyData::Format::SNMP and Earl Cahill is working on |
1064
|
|
|
|
|
|
|
AnyData::Format::Storable. Anyone who is interested in working on a new |
1065
|
|
|
|
|
|
|
format module, please open a ticket with an appropriate patch or |
1066
|
|
|
|
|
|
|
write to dbi-dev@perl.org. |
1067
|
|
|
|
|
|
|
|
1068
|
|
|
|
|
|
|
=head1 FURTHER DETAILS |
1069
|
|
|
|
|
|
|
|
1070
|
|
|
|
|
|
|
=head2 Converting between formats |
1071
|
|
|
|
|
|
|
|
1072
|
|
|
|
|
|
|
The $dbh->func(...,'ad_convert') method provides a one-step way to |
1073
|
|
|
|
|
|
|
convert between any of the data formats supported by DBD::AnyData. |
1074
|
|
|
|
|
|
|
For example: read a CSV file and save it as an XML file or vice versa. |
1075
|
|
|
|
|
|
|
See the section below on "convert" for details. See the section on |
1076
|
|
|
|
|
|
|
"Working with other DBI databases" for information on converting data |
1077
|
|
|
|
|
|
|
from ORACLE, or MySQL or almost any other database into XML, CSV, or |
1078
|
|
|
|
|
|
|
any of the DBD::AnyData formats. |
1079
|
|
|
|
|
|
|
|
1080
|
|
|
|
|
|
|
=head2 Using remote files |
1081
|
|
|
|
|
|
|
|
1082
|
|
|
|
|
|
|
You can import remote files accessible by FTP or HTTP directly into a |
1083
|
|
|
|
|
|
|
DBD::AnyData in memory database using 'ad_import' or you can use ad_convert |
1084
|
|
|
|
|
|
|
to print the remote files as strings or save them to a local file. |
1085
|
|
|
|
|
|
|
If the $file parameter of ad_import or ad_convert starts with "ftp" or |
1086
|
|
|
|
|
|
|
"http", DBD::AnyData will call LWP behind the scenes and fetch the file. |
1087
|
|
|
|
|
|
|
|
1088
|
|
|
|
|
|
|
This will fetch the remote file, parse its XML, and provide you with |
1089
|
|
|
|
|
|
|
an in-memory table which you can query with DBI/SQL or save to a local |
1090
|
|
|
|
|
|
|
file: |
1091
|
|
|
|
|
|
|
|
1092
|
|
|
|
|
|
|
$dbh->func( |
1093
|
|
|
|
|
|
|
'news', |
1094
|
|
|
|
|
|
|
'XML', |
1095
|
|
|
|
|
|
|
'http://www.somewhere.org/files/news.xml', |
1096
|
|
|
|
|
|
|
'ad_import'); |
1097
|
|
|
|
|
|
|
|
1098
|
|
|
|
|
|
|
This will fetch the remote file, parse its XML, and print it out |
1099
|
|
|
|
|
|
|
as an HTML table: |
1100
|
|
|
|
|
|
|
|
1101
|
|
|
|
|
|
|
print $dbh->func( |
1102
|
|
|
|
|
|
|
'XML', |
1103
|
|
|
|
|
|
|
'http://www.somewhere.org/files/news.xml', |
1104
|
|
|
|
|
|
|
'HTMLtable', |
1105
|
|
|
|
|
|
|
'ad_convert'); |
1106
|
|
|
|
|
|
|
|
1107
|
|
|
|
|
|
|
If the remote file requires authorization, you can include values for |
1108
|
|
|
|
|
|
|
"user" and "pass" in the $flags parameter: |
1109
|
|
|
|
|
|
|
|
1110
|
|
|
|
|
|
|
$dbh->func( |
1111
|
|
|
|
|
|
|
'news', |
1112
|
|
|
|
|
|
|
'XML', |
1113
|
|
|
|
|
|
|
'http://www.somewhere.org/news.xml', |
1114
|
|
|
|
|
|
|
{ user => 'fred', passwd => 'x9y77d' }, |
1115
|
|
|
|
|
|
|
'ad_import'); |
1116
|
|
|
|
|
|
|
|
1117
|
|
|
|
|
|
|
=head2 Working with in-memory tables |
1118
|
|
|
|
|
|
|
|
1119
|
|
|
|
|
|
|
In addition to normal file storage databases, DBD::AnyData supports |
1120
|
|
|
|
|
|
|
databases that are stored and modified in-memory. You may either simply |
1121
|
|
|
|
|
|
|
query the databases and then close them, or you can use the ad_export |
1122
|
|
|
|
|
|
|
method to display data to the screen or save it to a file. There are a |
1123
|
|
|
|
|
|
|
variety of reasons you might want to work with in-memory databases, |
1124
|
|
|
|
|
|
|
including: |
1125
|
|
|
|
|
|
|
|
1126
|
|
|
|
|
|
|
=over 4 |
1127
|
|
|
|
|
|
|
|
1128
|
|
|
|
|
|
|
=item Prototyping |
1129
|
|
|
|
|
|
|
|
1130
|
|
|
|
|
|
|
quickly create a database from a string, an array, or the DATA section of |
1131
|
|
|
|
|
|
|
a script without needing any file access or rdbms. |
1132
|
|
|
|
|
|
|
|
1133
|
|
|
|
|
|
|
=item Creating Views |
1134
|
|
|
|
|
|
|
|
1135
|
|
|
|
|
|
|
pull selected columns and selected rows from an ORACLE or MySQL database |
1136
|
|
|
|
|
|
|
en masse and work with them in memory rather than having to use the full |
1137
|
|
|
|
|
|
|
database. |
1138
|
|
|
|
|
|
|
|
1139
|
|
|
|
|
|
|
=item Combining Data from multiple formats |
1140
|
|
|
|
|
|
|
|
1141
|
|
|
|
|
|
|
create a single in-memory table by importing selected columns and rows |
1142
|
|
|
|
|
|
|
from e.g. an XML file, an Oracle database, and a CSV file. |
1143
|
|
|
|
|
|
|
|
1144
|
|
|
|
|
|
|
=item Rollback/Commit |
1145
|
|
|
|
|
|
|
|
1146
|
|
|
|
|
|
|
You can make multiple changes to the in-memory database and then, |
1147
|
|
|
|
|
|
|
depending on the sucess or failure of those changes either commit by using |
1148
|
|
|
|
|
|
|
export to save the changes to disk or skip export which effectively rolls |
1149
|
|
|
|
|
|
|
back the database to its state before the import. |
1150
|
|
|
|
|
|
|
|
1151
|
|
|
|
|
|
|
=back |
1152
|
|
|
|
|
|
|
|
1153
|
|
|
|
|
|
|
In-memory tables may be modified with DBI/SQL commands and can then be |
1154
|
|
|
|
|
|
|
either printed to the screen or saved as a file in any of the AnyData |
1155
|
|
|
|
|
|
|
formats. (see the ad_export method below) |
1156
|
|
|
|
|
|
|
|
1157
|
|
|
|
|
|
|
In-memory tables may be created in several ways: |
1158
|
|
|
|
|
|
|
|
1159
|
|
|
|
|
|
|
1. Create and populate the table from one or more local or remote files |
1160
|
|
|
|
|
|
|
2. Create and populate the table from a string |
1161
|
|
|
|
|
|
|
3. Create and populate the table from an array |
1162
|
|
|
|
|
|
|
4. Use DBI/SQL commands to create & populate the table |
1163
|
|
|
|
|
|
|
|
1164
|
|
|
|
|
|
|
=over 4 |
1165
|
|
|
|
|
|
|
|
1166
|
|
|
|
|
|
|
=item Creating in-memory tables from local or remote files |
1167
|
|
|
|
|
|
|
|
1168
|
|
|
|
|
|
|
You can create an in-memory table from a string in a specified format, |
1169
|
|
|
|
|
|
|
Note: the string should be enclosed in square brackets. |
1170
|
|
|
|
|
|
|
|
1171
|
|
|
|
|
|
|
This reads a CSV file into an in-memory table. Further access and |
1172
|
|
|
|
|
|
|
modification takes place in-memory without further file access unless |
1173
|
|
|
|
|
|
|
you specifically use ad_export to save the table to a file. |
1174
|
|
|
|
|
|
|
|
1175
|
|
|
|
|
|
|
# CREATE A TABLE FROM A LOCAL FILE |
1176
|
|
|
|
|
|
|
$dbh->func( 'test2', 'CSV', $filename, 'ad_import'); |
1177
|
|
|
|
|
|
|
|
1178
|
|
|
|
|
|
|
# CREATE A TABLE FROM A REMOTE FILE |
1179
|
|
|
|
|
|
|
$dbh->func( 'test2', 'CSV', $url, 'ad_import'); |
1180
|
|
|
|
|
|
|
|
1181
|
|
|
|
|
|
|
See the section on "Remote File Access" for further details of using |
1182
|
|
|
|
|
|
|
remote Files. |
1183
|
|
|
|
|
|
|
|
1184
|
|
|
|
|
|
|
=item Creating an in-memory table from Strings |
1185
|
|
|
|
|
|
|
|
1186
|
|
|
|
|
|
|
You can create an in-memory table from a string in a specified format, |
1187
|
|
|
|
|
|
|
Note: the string should be enclosed in square brackets. |
1188
|
|
|
|
|
|
|
|
1189
|
|
|
|
|
|
|
This example creates an in-memory table from a CSV string: |
1190
|
|
|
|
|
|
|
|
1191
|
|
|
|
|
|
|
# CREATE A TABLE FROM A CSV STRING |
1192
|
|
|
|
|
|
|
$dbh->func( 'test2', 'CSV', |
1193
|
|
|
|
|
|
|
["id,phrase\n1,foo\n2,bar"], |
1194
|
|
|
|
|
|
|
'ad_import'); |
1195
|
|
|
|
|
|
|
|
1196
|
|
|
|
|
|
|
=item Creating an in-memory table from the DATA section of a script |
1197
|
|
|
|
|
|
|
|
1198
|
|
|
|
|
|
|
Perl has the really cool feature that if you put text after the |
1199
|
|
|
|
|
|
|
marker __END__, you can access that text as if it were from a |
1200
|
|
|
|
|
|
|
file using the DATA array. This can be great for quick prototyping. |
1201
|
|
|
|
|
|
|
|
1202
|
|
|
|
|
|
|
For example this is a complete script to build and access a small |
1203
|
|
|
|
|
|
|
table and print out "Just Another Perl Hacker": |
1204
|
|
|
|
|
|
|
|
1205
|
|
|
|
|
|
|
use DBI; |
1206
|
|
|
|
|
|
|
my $dbh=DBI->connect('dbi:AnyData(RaiseError=>1):'); |
1207
|
|
|
|
|
|
|
$dbh->func( 'test', 'XML', [], 'ad_import'); |
1208
|
|
|
|
|
|
|
print $dbh->selectcol_arrayref(qq{ |
1209
|
|
|
|
|
|
|
SELECT phrase FROM test WHERE id = 2 |
1210
|
|
|
|
|
|
|
})->[0]; |
1211
|
|
|
|
|
|
|
__END__ |
1212
|
|
|
|
|
|
|
|
1213
|
|
|
|
|
|
|
Hello World! |
1214
|
|
|
|
|
|
|
Just Another Perl Hacker! |
1215
|
|
|
|
|
|
|
|
1216
|
|
|
|
|
|
|
|
1217
|
|
|
|
|
|
|
The same idea can be used with DATA sections of any size in any of |
1218
|
|
|
|
|
|
|
the supported formats. |
1219
|
|
|
|
|
|
|
|
1220
|
|
|
|
|
|
|
=item Creating an in-memory table from Arrays |
1221
|
|
|
|
|
|
|
|
1222
|
|
|
|
|
|
|
In-memory tables may also be created from arrays. Or, more technically, |
1223
|
|
|
|
|
|
|
from references to arrays. The array should consist of rows which are |
1224
|
|
|
|
|
|
|
themselves references to arrays of the row values. The first row should |
1225
|
|
|
|
|
|
|
be column names. |
1226
|
|
|
|
|
|
|
|
1227
|
|
|
|
|
|
|
For example: |
1228
|
|
|
|
|
|
|
|
1229
|
|
|
|
|
|
|
# CREATE A TABLE FROM AN ARRAY |
1230
|
|
|
|
|
|
|
$dbh->func( 'test3', 'ARRAY', |
1231
|
|
|
|
|
|
|
[ |
1232
|
|
|
|
|
|
|
['id','phrase'], |
1233
|
|
|
|
|
|
|
[1,'foo'], |
1234
|
|
|
|
|
|
|
[2,'bar'] |
1235
|
|
|
|
|
|
|
], |
1236
|
|
|
|
|
|
|
'ad_import'); |
1237
|
|
|
|
|
|
|
|
1238
|
|
|
|
|
|
|
=item Creating an in-memory table from DBI/SQL commands |
1239
|
|
|
|
|
|
|
|
1240
|
|
|
|
|
|
|
If you do not use ad_catalog or ad_import to associate a table |
1241
|
|
|
|
|
|
|
name with a file, then the table will be an in-memory table, so |
1242
|
|
|
|
|
|
|
you can just start right out by using it in DBI/SQL commands: |
1243
|
|
|
|
|
|
|
|
1244
|
|
|
|
|
|
|
# CREATE & POPULATE A TABLE FROM DBI/SQL COMMANDS |
1245
|
|
|
|
|
|
|
use DBI; |
1246
|
|
|
|
|
|
|
my $dbh = DBI->connect('dbi:AnyData(RaiseError=>1):'); |
1247
|
|
|
|
|
|
|
$dbh->do("CREATE TABLE test (id TEXT,phrase TEXT)"); |
1248
|
|
|
|
|
|
|
$dbh->do("INSERT INTO test VALUES (1,'foo')"); |
1249
|
|
|
|
|
|
|
$dbh->do("INSERT INTO test VALUES (2,'bar')"); |
1250
|
|
|
|
|
|
|
$dbh->do("UPDATE test SET phrase='baz' WHERE id = '2'"); |
1251
|
|
|
|
|
|
|
$dbh->do("DELETE FROM test WHERE id = '1'"); |
1252
|
|
|
|
|
|
|
|
1253
|
|
|
|
|
|
|
=back |
1254
|
|
|
|
|
|
|
|
1255
|
|
|
|
|
|
|
=head2 Using Multiple Databases, Simulating Joins |
1256
|
|
|
|
|
|
|
|
1257
|
|
|
|
|
|
|
You may access any number of databases within a single script and can mix |
1258
|
|
|
|
|
|
|
and match from the various data formats. |
1259
|
|
|
|
|
|
|
|
1260
|
|
|
|
|
|
|
For example, this creates two in-memory tables from two different data |
1261
|
|
|
|
|
|
|
formats |
1262
|
|
|
|
|
|
|
|
1263
|
|
|
|
|
|
|
$dbh->func( 'classes', 'CSV', 'classes.csv' 'ad_import'); |
1264
|
|
|
|
|
|
|
$dbh->func( 'profs', 'XML', 'profs.xml', 'ad_import'); |
1265
|
|
|
|
|
|
|
|
1266
|
|
|
|
|
|
|
You can also import columns from several different formats into a single |
1267
|
|
|
|
|
|
|
table. For example this imports data from an XML file, a CSV file and a |
1268
|
|
|
|
|
|
|
Pipe delimited file into a single in-memory database. Note that the |
1269
|
|
|
|
|
|
|
$table parameter is the same in each call so the data from each import |
1270
|
|
|
|
|
|
|
will be appended into that one table. |
1271
|
|
|
|
|
|
|
|
1272
|
|
|
|
|
|
|
$dbh->func( 'test', 'XML', [$xmlStr], 'ad_import'); |
1273
|
|
|
|
|
|
|
$dbh->func( 'test', 'CSV', [$csvStr], 'ad_import'); |
1274
|
|
|
|
|
|
|
$dbh->func( 'test', 'Pipe', [$pipeStr], 'ad_import'); |
1275
|
|
|
|
|
|
|
|
1276
|
|
|
|
|
|
|
When you import more than one table into a single table like this, the |
1277
|
|
|
|
|
|
|
resulting table will be a cross join unless you supply a lookup_key flag. |
1278
|
|
|
|
|
|
|
If a lookup_key is supplied, then a the resulting table will be a full |
1279
|
|
|
|
|
|
|
outer join on that key column. This feature is experimental for the time |
1280
|
|
|
|
|
|
|
being but should work as expected unless there are columns other than the |
1281
|
|
|
|
|
|
|
key column with the same names in the various tables. You can specify |
1282
|
|
|
|
|
|
|
that the joined table will only contain certain columns by creating a |
1283
|
|
|
|
|
|
|
blank empty table before doing the imports. You can specify only certain |
1284
|
|
|
|
|
|
|
rows with the sql flag. For example: |
1285
|
|
|
|
|
|
|
|
1286
|
|
|
|
|
|
|
$dbh->func('test','ARRAY',[],{col_names=>'foo,bar'baz'}, 'ad_import'); |
1287
|
|
|
|
|
|
|
$dbh->func('test','XML',$file1,{lookup_key=>'baz'},'ad_import'); |
1288
|
|
|
|
|
|
|
$dbh->func('test','CSV',$file1,{lookup_key=>'baz'},'ad_import'); |
1289
|
|
|
|
|
|
|
|
1290
|
|
|
|
|
|
|
DBD::AnyData does not currently support using multiple tables in a |
1291
|
|
|
|
|
|
|
single SQL statement. However it does support using multiple tables |
1292
|
|
|
|
|
|
|
and querying them separately with different SQL statements. This |
1293
|
|
|
|
|
|
|
means you can simulate joins by creating two statement handles and |
1294
|
|
|
|
|
|
|
using the values from the first handle as a lookup key for the second |
1295
|
|
|
|
|
|
|
handle. Like this: |
1296
|
|
|
|
|
|
|
|
1297
|
|
|
|
|
|
|
$dbh->func( 'classes', 'CSV', 'classes.csv' 'ad_import'); |
1298
|
|
|
|
|
|
|
$dbh->func( 'profs', 'XML', 'profs.xml', 'ad_import'); |
1299
|
|
|
|
|
|
|
my $classes_sth = $dbh->prepare( "SELECT pid,title FROM classes" ); |
1300
|
|
|
|
|
|
|
my $profs_sth = $dbh->prepare( "SELECT name FROM profs WHERE pid = ?" ); |
1301
|
|
|
|
|
|
|
$classes_sth->execute; |
1302
|
|
|
|
|
|
|
while (my($pid,$class_title) = $classes_sth->fetchrow_array) { |
1303
|
|
|
|
|
|
|
$profs_sth->execute($pid); |
1304
|
|
|
|
|
|
|
my $row = $profs_sth->fetchrow_arrayref; |
1305
|
|
|
|
|
|
|
my $prof_name = $row ? $row->[0] : ''; |
1306
|
|
|
|
|
|
|
print "$class_title : $prof_name\n"; |
1307
|
|
|
|
|
|
|
} |
1308
|
|
|
|
|
|
|
|
1309
|
|
|
|
|
|
|
# That will produce the same results as: |
1310
|
|
|
|
|
|
|
SELECT classes.title,profs.name FROM classes,profs WHERE pid = pid |
1311
|
|
|
|
|
|
|
|
1312
|
|
|
|
|
|
|
=head1 REFERENCE |
1313
|
|
|
|
|
|
|
|
1314
|
|
|
|
|
|
|
=head2 Overview of DBD::AnyData Methods |
1315
|
|
|
|
|
|
|
|
1316
|
|
|
|
|
|
|
DBD::AnyData makes use of five methods not found in other drivers: |
1317
|
|
|
|
|
|
|
|
1318
|
|
|
|
|
|
|
|
1319
|
|
|
|
|
|
|
=over 12 |
1320
|
|
|
|
|
|
|
|
1321
|
|
|
|
|
|
|
=item ad_catalog |
1322
|
|
|
|
|
|
|
|
1323
|
|
|
|
|
|
|
specifies a file to be used for DBI/SQL continuous file access |
1324
|
|
|
|
|
|
|
|
1325
|
|
|
|
|
|
|
=item ad_import |
1326
|
|
|
|
|
|
|
|
1327
|
|
|
|
|
|
|
imports data into an in-memory table |
1328
|
|
|
|
|
|
|
|
1329
|
|
|
|
|
|
|
=item ad_export |
1330
|
|
|
|
|
|
|
|
1331
|
|
|
|
|
|
|
exports data from an in-memory table to a file |
1332
|
|
|
|
|
|
|
|
1333
|
|
|
|
|
|
|
=item ad_clear |
1334
|
|
|
|
|
|
|
|
1335
|
|
|
|
|
|
|
clears an in-memory table (deletes it from memory) |
1336
|
|
|
|
|
|
|
|
1337
|
|
|
|
|
|
|
=item ad_convert |
1338
|
|
|
|
|
|
|
|
1339
|
|
|
|
|
|
|
converts data from one format to another and either saves it in a new file |
1340
|
|
|
|
|
|
|
or returns it as a string |
1341
|
|
|
|
|
|
|
|
1342
|
|
|
|
|
|
|
=back |
1343
|
|
|
|
|
|
|
|
1344
|
|
|
|
|
|
|
These methods are called using DBI func(), for example: |
1345
|
|
|
|
|
|
|
|
1346
|
|
|
|
|
|
|
$dbh->func( $table, $format, 'ad_export'); |
1347
|
|
|
|
|
|
|
|
1348
|
|
|
|
|
|
|
# Here are the parameters for the various methods: |
1349
|
|
|
|
|
|
|
$dbh->func( $table, $format, $file, $flags, 'ad_catalog'); |
1350
|
|
|
|
|
|
|
$dbh->func( $table, $format, $data, $flags, 'ad_import'); |
1351
|
|
|
|
|
|
|
|
1352
|
|
|
|
|
|
|
$dbh->func( $source_format, $source_data, |
1353
|
|
|
|
|
|
|
$target_format, $target_file, |
1354
|
|
|
|
|
|
|
$source_flags, $target_flags, |
1355
|
|
|
|
|
|
|
'ad_convert'); |
1356
|
|
|
|
|
|
|
|
1357
|
|
|
|
|
|
|
$dbh->func( $table, $format, $file, $flags, 'ad_export'); |
1358
|
|
|
|
|
|
|
$dbh->func( $table, 'ad_clear' ); |
1359
|
|
|
|
|
|
|
|
1360
|
|
|
|
|
|
|
# $table is a valid SQL table name |
1361
|
|
|
|
|
|
|
# $format is one of the AnyData formats ('XML','CSV',etc.) |
1362
|
|
|
|
|
|
|
# $file is a valid file name (relative or absolute) on the local computer |
1363
|
|
|
|
|
|
|
# $flags is a hashref containing key/value pairs, e.g. |
1364
|
|
|
|
|
|
|
{ col_names => 'make,model,year', pattern => 'A10 A12 A4' } |
1365
|
|
|
|
|
|
|
|
1366
|
|
|
|
|
|
|
# $data is one of: |
1367
|
|
|
|
|
|
|
# * a valid file name (relative or absolute) on the local computer |
1368
|
|
|
|
|
|
|
# * a valid absolute FTP or HTTP URL |
1369
|
|
|
|
|
|
|
# * an arrayref containing arrayrefs of rows with column names first |
1370
|
|
|
|
|
|
|
# [ |
1371
|
|
|
|
|
|
|
# ['make','model'], |
1372
|
|
|
|
|
|
|
# ['Honda','Odyssy'], |
1373
|
|
|
|
|
|
|
# ['Ford','Suburban'], |
1374
|
|
|
|
|
|
|
# ] |
1375
|
|
|
|
|
|
|
|
1376
|
|
|
|
|
|
|
# * an arrayref containing a string in a specified format |
1377
|
|
|
|
|
|
|
# CSV : ["id,phrase\n1,foo\n2,bar"] |
1378
|
|
|
|
|
|
|
# Pipe : ["id|phrase\n1|foo\n2|bar"] |
1379
|
|
|
|
|
|
|
|
1380
|
|
|
|
|
|
|
# * a reference to the DATA section of a file |
1381
|
|
|
|
|
|
|
# [] |
1382
|
|
|
|
|
|
|
|
1383
|
|
|
|
|
|
|
# * a DBI Database handle |
1384
|
|
|
|
|
|
|
# DBI->connect('dbi:mysql:database=...) |
1385
|
|
|
|
|
|
|
|
1386
|
|
|
|
|
|
|
The ad_catalog method is the standard way to treat files as databases. |
1387
|
|
|
|
|
|
|
Each time you access data, it is read from the file and each time you |
1388
|
|
|
|
|
|
|
modify data, it is written to the file. The entire file is never read |
1389
|
|
|
|
|
|
|
en masse into memory unless you explicitly request it. |
1390
|
|
|
|
|
|
|
|
1391
|
|
|
|
|
|
|
The ad_import method can import data from local or remote files, |
1392
|
|
|
|
|
|
|
from any other DBI accessible database, from perl data structures such |
1393
|
|
|
|
|
|
|
as arrays and strings. You may import an entire table or only the columns |
1394
|
|
|
|
|
|
|
and rows you specify. If the data is imported from a file, all of the |
1395
|
|
|
|
|
|
|
data you select is read into memory when you call ad_import so this should |
1396
|
|
|
|
|
|
|
not be done with selections larger than will fit in your memory. :-). |
1397
|
|
|
|
|
|
|
All accessing and modification is done in memory. If you want to save the |
1398
|
|
|
|
|
|
|
results of any changes, you will need to call ad_export explicitly. |
1399
|
|
|
|
|
|
|
|
1400
|
|
|
|
|
|
|
Not all formats and data sources will work with all methods. Here is a |
1401
|
|
|
|
|
|
|
summary of what will work. "all sources" includes local files, remote |
1402
|
|
|
|
|
|
|
files, any DBI accessible database, perl arrayrefs, perl strings. |
1403
|
|
|
|
|
|
|
|
1404
|
|
|
|
|
|
|
Import From all formats, all sources |
1405
|
|
|
|
|
|
|
Convert From all formats, all sources |
1406
|
|
|
|
|
|
|
Convert To all formats except DBI, local files, arrays or strings only |
1407
|
|
|
|
|
|
|
Export To all formats except DBI, local files, arrays or strings only |
1408
|
|
|
|
|
|
|
Catalog all formats except DBI, XML, HTMLtable, Mp3, ARRAY, |
1409
|
|
|
|
|
|
|
local files only |
1410
|
|
|
|
|
|
|
|
1411
|
|
|
|
|
|
|
=head2 connect |
1412
|
|
|
|
|
|
|
|
1413
|
|
|
|
|
|
|
The DBI->connect call |
1414
|
|
|
|
|
|
|
|
1415
|
|
|
|
|
|
|
=head2 ad_catalog |
1416
|
|
|
|
|
|
|
|
1417
|
|
|
|
|
|
|
PURPOSE: |
1418
|
|
|
|
|
|
|
|
1419
|
|
|
|
|
|
|
Creates an association betweeen a table name, a data format, and a file. |
1420
|
|
|
|
|
|
|
|
1421
|
|
|
|
|
|
|
SYNTAX: |
1422
|
|
|
|
|
|
|
|
1423
|
|
|
|
|
|
|
$dbh->func( $table, $format, $file, $flags, 'ad_catalog' ) |
1424
|
|
|
|
|
|
|
|
1425
|
|
|
|
|
|
|
PARAMETERS: |
1426
|
|
|
|
|
|
|
|
1427
|
|
|
|
|
|
|
$table = the name of the table to be used in SQL commands |
1428
|
|
|
|
|
|
|
|
1429
|
|
|
|
|
|
|
$format = an AnyData format ('XML','CSV', etc.) |
1430
|
|
|
|
|
|
|
|
1431
|
|
|
|
|
|
|
$file = the name of a local file (either full path or relative) |
1432
|
|
|
|
|
|
|
|
1433
|
|
|
|
|
|
|
$flags = a optional hashref of column names or other values |
1434
|
|
|
|
|
|
|
|
1435
|
|
|
|
|
|
|
EXAMPLE: |
1436
|
|
|
|
|
|
|
|
1437
|
|
|
|
|
|
|
This specifies that any DBI/SQL statements to the table |
1438
|
|
|
|
|
|
|
'cars' will access and/or modify XML data in the file |
1439
|
|
|
|
|
|
|
'/users/me/data.xml' |
1440
|
|
|
|
|
|
|
|
1441
|
|
|
|
|
|
|
$dbh->func( 'cars', 'XML', '/usrs/me/data.xml', 'ad_catalog' ) |
1442
|
|
|
|
|
|
|
|
1443
|
|
|
|
|
|
|
REMARKS: |
1444
|
|
|
|
|
|
|
|
1445
|
|
|
|
|
|
|
The format may be any AnyData format *except* DBI, XML, HTMLtable, |
1446
|
|
|
|
|
|
|
and MP3. |
1447
|
|
|
|
|
|
|
|
1448
|
|
|
|
|
|
|
=head2 ad_import |
1449
|
|
|
|
|
|
|
|
1450
|
|
|
|
|
|
|
PURPOSE: |
1451
|
|
|
|
|
|
|
|
1452
|
|
|
|
|
|
|
Imports data from any source and any format into an in-memory table. |
1453
|
|
|
|
|
|
|
|
1454
|
|
|
|
|
|
|
SYNTAX: |
1455
|
|
|
|
|
|
|
|
1456
|
|
|
|
|
|
|
$dbh->func( $table, $format, $data_source, $flags, 'ad_import' ) |
1457
|
|
|
|
|
|
|
|
1458
|
|
|
|
|
|
|
PARAMETERS: |
1459
|
|
|
|
|
|
|
|
1460
|
|
|
|
|
|
|
$table = the name of the table to be used in SQL commands |
1461
|
|
|
|
|
|
|
|
1462
|
|
|
|
|
|
|
$format = an AnyData format ('XML','CSV', etc.) |
1463
|
|
|
|
|
|
|
|
1464
|
|
|
|
|
|
|
$data_source = $file_name |
1465
|
|
|
|
|
|
|
or $url |
1466
|
|
|
|
|
|
|
or [$string] |
1467
|
|
|
|
|
|
|
or [] |
1468
|
|
|
|
|
|
|
or $reference_to_an array of arrays |
1469
|
|
|
|
|
|
|
or $DBI_database_handle |
1470
|
|
|
|
|
|
|
|
1471
|
|
|
|
|
|
|
(See section "Data Sources" for more specifics of $data_source) |
1472
|
|
|
|
|
|
|
|
1473
|
|
|
|
|
|
|
EXAMPLES: |
1474
|
|
|
|
|
|
|
|
1475
|
|
|
|
|
|
|
$dbh->func( 'cars', 'XML', '/usrs/me/data.xml', 'ad_import' ) |
1476
|
|
|
|
|
|
|
|
1477
|
|
|
|
|
|
|
For further examples, see sections on "In-Memory Tables", |
1478
|
|
|
|
|
|
|
"Remote Files", "DBI databases". |
1479
|
|
|
|
|
|
|
|
1480
|
|
|
|
|
|
|
|
1481
|
|
|
|
|
|
|
=head2 ad_export |
1482
|
|
|
|
|
|
|
|
1483
|
|
|
|
|
|
|
PURPOSE: |
1484
|
|
|
|
|
|
|
|
1485
|
|
|
|
|
|
|
Converts an in-memory table into a specified format and either saves |
1486
|
|
|
|
|
|
|
it to a file or returns it as a string. |
1487
|
|
|
|
|
|
|
|
1488
|
|
|
|
|
|
|
SYNTAX: |
1489
|
|
|
|
|
|
|
|
1490
|
|
|
|
|
|
|
$dbh->func( $table, $format, $file, $flags, 'ad_export' ) |
1491
|
|
|
|
|
|
|
|
1492
|
|
|
|
|
|
|
OR |
1493
|
|
|
|
|
|
|
|
1494
|
|
|
|
|
|
|
my $string = $dbh->func( $table, $format, $flags, 'ad_export' ) |
1495
|
|
|
|
|
|
|
|
1496
|
|
|
|
|
|
|
PARAMETERS: |
1497
|
|
|
|
|
|
|
|
1498
|
|
|
|
|
|
|
$table = the name of the in-memory table to export |
1499
|
|
|
|
|
|
|
|
1500
|
|
|
|
|
|
|
$format = an AnyData format ('XML','CSV', etc.) |
1501
|
|
|
|
|
|
|
|
1502
|
|
|
|
|
|
|
$file = the name of a local file (either full path or relative) |
1503
|
|
|
|
|
|
|
|
1504
|
|
|
|
|
|
|
EXAMPLES: |
1505
|
|
|
|
|
|
|
|
1506
|
|
|
|
|
|
|
Save a table as an XML file: |
1507
|
|
|
|
|
|
|
|
1508
|
|
|
|
|
|
|
$dbh->func( 'cars', 'XML', '/usrs/me/data.xml', 'ad_export' ) |
1509
|
|
|
|
|
|
|
|
1510
|
|
|
|
|
|
|
Print a table as an HTML table |
1511
|
|
|
|
|
|
|
|
1512
|
|
|
|
|
|
|
print $dbh->func( 'cars', 'HTMLtable', 'ad_export' ) |
1513
|
|
|
|
|
|
|
|
1514
|
|
|
|
|
|
|
=head2 ad_convert |
1515
|
|
|
|
|
|
|
|
1516
|
|
|
|
|
|
|
PURPOSE: |
1517
|
|
|
|
|
|
|
|
1518
|
|
|
|
|
|
|
Converts data from one format into another and either returns it |
1519
|
|
|
|
|
|
|
as a string in the new format or saves it to a file in the new |
1520
|
|
|
|
|
|
|
format. |
1521
|
|
|
|
|
|
|
|
1522
|
|
|
|
|
|
|
SYNTAX: |
1523
|
|
|
|
|
|
|
|
1524
|
|
|
|
|
|
|
my $str = $dbh->func( |
1525
|
|
|
|
|
|
|
$source_format, |
1526
|
|
|
|
|
|
|
$data_source |
1527
|
|
|
|
|
|
|
$target_format, |
1528
|
|
|
|
|
|
|
$source_flags, |
1529
|
|
|
|
|
|
|
$target_flags, |
1530
|
|
|
|
|
|
|
'ad_convert' ); |
1531
|
|
|
|
|
|
|
|
1532
|
|
|
|
|
|
|
OR |
1533
|
|
|
|
|
|
|
|
1534
|
|
|
|
|
|
|
$dbh->func( |
1535
|
|
|
|
|
|
|
$source_format, |
1536
|
|
|
|
|
|
|
$data_source |
1537
|
|
|
|
|
|
|
$target_format, |
1538
|
|
|
|
|
|
|
$target_file, |
1539
|
|
|
|
|
|
|
$source_flags, |
1540
|
|
|
|
|
|
|
$target_flags, |
1541
|
|
|
|
|
|
|
'ad_convert' ); |
1542
|
|
|
|
|
|
|
|
1543
|
|
|
|
|
|
|
PARAMETERS: |
1544
|
|
|
|
|
|
|
|
1545
|
|
|
|
|
|
|
$source_format = AnyData format ('XML','CSV', etc.) of the source db |
1546
|
|
|
|
|
|
|
|
1547
|
|
|
|
|
|
|
$target_format = AnyData format ('XML','CSV', etc.) of the target db |
1548
|
|
|
|
|
|
|
|
1549
|
|
|
|
|
|
|
$target_file = name of file to store converted data in |
1550
|
|
|
|
|
|
|
|
1551
|
|
|
|
|
|
|
$data_source = $file_name |
1552
|
|
|
|
|
|
|
or $url |
1553
|
|
|
|
|
|
|
or [$string] |
1554
|
|
|
|
|
|
|
or [] |
1555
|
|
|
|
|
|
|
or $reference_to_an array of arrays |
1556
|
|
|
|
|
|
|
or $DBI_database_handle |
1557
|
|
|
|
|
|
|
|
1558
|
|
|
|
|
|
|
(See section "Data Sources" for more specifics of $data_source) |
1559
|
|
|
|
|
|
|
|
1560
|
|
|
|
|
|
|
EXAMPLES: |
1561
|
|
|
|
|
|
|
|
1562
|
|
|
|
|
|
|
# CONVERT A CSV FILE TO AN XML FILE |
1563
|
|
|
|
|
|
|
# |
1564
|
|
|
|
|
|
|
$dbh->func( 'CSV', 'data.csv', 'XML', 'data.xml', 'ad_convert'); |
1565
|
|
|
|
|
|
|
|
1566
|
|
|
|
|
|
|
# CONVERT AN ARRAYREF TO AN HTML TABLE AND PRINT IT |
1567
|
|
|
|
|
|
|
# |
1568
|
|
|
|
|
|
|
print $dbh->func( 'ARRAY', $aryref, 'HTMLtable', 'ad_convert'); |
1569
|
|
|
|
|
|
|
|
1570
|
|
|
|
|
|
|
# CONVERT AN ARRAYREF TO XML AND SAVE IT IN A FILE |
1571
|
|
|
|
|
|
|
# |
1572
|
|
|
|
|
|
|
$dbh->func( 'ARRAY', $aryref, 'XML', 'data.xml', 'ad_convert'); |
1573
|
|
|
|
|
|
|
|
1574
|
|
|
|
|
|
|
# CONVERT A SELECTION FROM A MySQL DATABASE TO XML |
1575
|
|
|
|
|
|
|
# AND SAVE IT IN A FILE |
1576
|
|
|
|
|
|
|
# |
1577
|
|
|
|
|
|
|
$dbh->func( |
1578
|
|
|
|
|
|
|
'DBI', |
1579
|
|
|
|
|
|
|
$mysql_dbh, |
1580
|
|
|
|
|
|
|
'XML', |
1581
|
|
|
|
|
|
|
'data.xml', |
1582
|
|
|
|
|
|
|
{sql=>"SELECT make,model FROM CARS where year > 1996"} |
1583
|
|
|
|
|
|
|
'ad_convert'); |
1584
|
|
|
|
|
|
|
|
1585
|
|
|
|
|
|
|
REMARKS |
1586
|
|
|
|
|
|
|
|
1587
|
|
|
|
|
|
|
The format 'DBI' (any DBI accessible database) may be used as the |
1588
|
|
|
|
|
|
|
source of a conversion, but not as the target of a conversion. |
1589
|
|
|
|
|
|
|
|
1590
|
|
|
|
|
|
|
The format 'ARRAY' may be used to indicate that the source of the |
1591
|
|
|
|
|
|
|
conversion is a reference to an array. Or that the result of the |
1592
|
|
|
|
|
|
|
conversion should be returned as an array reference. (See above, |
1593
|
|
|
|
|
|
|
working with in-memory database for information on the structure of |
1594
|
|
|
|
|
|
|
the array reference). |
1595
|
|
|
|
|
|
|
|
1596
|
|
|
|
|
|
|
|
1597
|
|
|
|
|
|
|
=head2 Data Sources |
1598
|
|
|
|
|
|
|
|
1599
|
|
|
|
|
|
|
The ad_import and ad_convert methods can take data from many |
1600
|
|
|
|
|
|
|
sources, including local files, remote files, strings, arrays, |
1601
|
|
|
|
|
|
|
any DBI accessible database, the DATA section of a script. |
1602
|
|
|
|
|
|
|
|
1603
|
|
|
|
|
|
|
The $data_source parameter to ad_import and ad_convert will |
1604
|
|
|
|
|
|
|
vary depending on the specific data source, see below. |
1605
|
|
|
|
|
|
|
|
1606
|
|
|
|
|
|
|
Local Files |
1607
|
|
|
|
|
|
|
|
1608
|
|
|
|
|
|
|
A string containing the name of a local file. It may either |
1609
|
|
|
|
|
|
|
be a full path, or a path or file relative to the currently |
1610
|
|
|
|
|
|
|
defined f_dir (see ?); |
1611
|
|
|
|
|
|
|
|
1612
|
|
|
|
|
|
|
e.g. '/users/me/data.xml' |
1613
|
|
|
|
|
|
|
|
1614
|
|
|
|
|
|
|
Remote Files |
1615
|
|
|
|
|
|
|
|
1616
|
|
|
|
|
|
|
A string containing the url of the data. Must start with |
1617
|
|
|
|
|
|
|
'ftp://' or 'http://' |
1618
|
|
|
|
|
|
|
|
1619
|
|
|
|
|
|
|
e.g. 'http://www.somewhere.org/misc/news.xml' |
1620
|
|
|
|
|
|
|
|
1621
|
|
|
|
|
|
|
Arrays of Arrays |
1622
|
|
|
|
|
|
|
|
1623
|
|
|
|
|
|
|
A reference to an array of data. Each row of the data is |
1624
|
|
|
|
|
|
|
a reference to an array of values. The first row is the |
1625
|
|
|
|
|
|
|
column names. E.G.: |
1626
|
|
|
|
|
|
|
|
1627
|
|
|
|
|
|
|
[ |
1628
|
|
|
|
|
|
|
['make','model'], |
1629
|
|
|
|
|
|
|
['Honda','Odyssy'], |
1630
|
|
|
|
|
|
|
['Ford','Suburban'], |
1631
|
|
|
|
|
|
|
] |
1632
|
|
|
|
|
|
|
|
1633
|
|
|
|
|
|
|
Strings |
1634
|
|
|
|
|
|
|
|
1635
|
|
|
|
|
|
|
A string in the specified format including all field and record |
1636
|
|
|
|
|
|
|
separators. The string should be the only row in an array reference |
1637
|
|
|
|
|
|
|
(i.e. it should be enclosed in square brackets) |
1638
|
|
|
|
|
|
|
|
1639
|
|
|
|
|
|
|
e.g. a CSV string |
1640
|
|
|
|
|
|
|
|
1641
|
|
|
|
|
|
|
["id,phrase\n1,foo\n2,bar"] |
1642
|
|
|
|
|
|
|
|
1643
|
|
|
|
|
|
|
or in Pipe Delimited string |
1644
|
|
|
|
|
|
|
|
1645
|
|
|
|
|
|
|
["id|phrase\n1|foo\n2|bar"] |
1646
|
|
|
|
|
|
|
|
1647
|
|
|
|
|
|
|
The DATA section of a file |
1648
|
|
|
|
|
|
|
|
1649
|
|
|
|
|
|
|
A reference to the array obtained from the lines after |
1650
|
|
|
|
|
|
|
__END__ in a script. |
1651
|
|
|
|
|
|
|
|
1652
|
|
|
|
|
|
|
[] |
1653
|
|
|
|
|
|
|
|
1654
|
|
|
|
|
|
|
DBI Databases |
1655
|
|
|
|
|
|
|
|
1656
|
|
|
|
|
|
|
A database handle for a specified rdbms. |
1657
|
|
|
|
|
|
|
|
1658
|
|
|
|
|
|
|
DBI->connect('dbi:mysql:database=...) |
1659
|
|
|
|
|
|
|
|
1660
|
|
|
|
|
|
|
|
1661
|
|
|
|
|
|
|
=head2 ad_clear |
1662
|
|
|
|
|
|
|
|
1663
|
|
|
|
|
|
|
PURPOSE: |
1664
|
|
|
|
|
|
|
|
1665
|
|
|
|
|
|
|
Clears an in-memory table (deletes it from memory) |
1666
|
|
|
|
|
|
|
|
1667
|
|
|
|
|
|
|
SYNTAX: |
1668
|
|
|
|
|
|
|
|
1669
|
|
|
|
|
|
|
$dbh->func( $table, 'ad_clear' ) |
1670
|
|
|
|
|
|
|
|
1671
|
|
|
|
|
|
|
PARAMETERS: |
1672
|
|
|
|
|
|
|
|
1673
|
|
|
|
|
|
|
$table = the name of the in-memory table to clear |
1674
|
|
|
|
|
|
|
|
1675
|
|
|
|
|
|
|
REMARKS: |
1676
|
|
|
|
|
|
|
|
1677
|
|
|
|
|
|
|
In-memory tables will be deleted from memory automatically when the |
1678
|
|
|
|
|
|
|
database handle used to create them goes out of scope. They will also |
1679
|
|
|
|
|
|
|
be deleted if you call $dbh->disconnect() on the database handle |
1680
|
|
|
|
|
|
|
used to create them. The ad_clear method is a way to free up memory |
1681
|
|
|
|
|
|
|
if you intend to keep using the database handle but no longer need a |
1682
|
|
|
|
|
|
|
given table. As with other (all?) Perl memory operations, this frees |
1683
|
|
|
|
|
|
|
memory for the remainder of your perl script to use but does not decrease |
1684
|
|
|
|
|
|
|
the total amount of system memory used by the script. |
1685
|
|
|
|
|
|
|
|
1686
|
|
|
|
|
|
|
=head2 SQL Syntax |
1687
|
|
|
|
|
|
|
|
1688
|
|
|
|
|
|
|
Currently only a limited subset of SQL commands are supported. |
1689
|
|
|
|
|
|
|
Only a single table may be used in each command. This means |
1690
|
|
|
|
|
|
|
That there are *no joins*, but see the section above on simulating |
1691
|
|
|
|
|
|
|
joins. In coming months additional SQL capabilities will be added, |
1692
|
|
|
|
|
|
|
so keep your eyes out for ANNOUNCE message on usenet or the dbi-users |
1693
|
|
|
|
|
|
|
mailing list (see below "Getting More Help"). |
1694
|
|
|
|
|
|
|
|
1695
|
|
|
|
|
|
|
Here is a brief synopsis, please see the documentation for |
1696
|
|
|
|
|
|
|
SQL::Statement for a more complete description of these commands. |
1697
|
|
|
|
|
|
|
|
1698
|
|
|
|
|
|
|
CREATE TABLE $table |
1699
|
|
|
|
|
|
|
( $col1 $type1, ..., $colN $typeN, |
1700
|
|
|
|
|
|
|
[ PRIMARY KEY ($col1, ... $colM) ] ) |
1701
|
|
|
|
|
|
|
|
1702
|
|
|
|
|
|
|
DROP TABLE $table |
1703
|
|
|
|
|
|
|
|
1704
|
|
|
|
|
|
|
INSERT INTO $table |
1705
|
|
|
|
|
|
|
[ ( $col1, ..., $colN ) ] |
1706
|
|
|
|
|
|
|
VALUES ( $val1, ... $valN ) |
1707
|
|
|
|
|
|
|
|
1708
|
|
|
|
|
|
|
DELETE FROM $table |
1709
|
|
|
|
|
|
|
[ WHERE $wclause ] |
1710
|
|
|
|
|
|
|
|
1711
|
|
|
|
|
|
|
UPDATE $table |
1712
|
|
|
|
|
|
|
SET $col1 = $val1, ... $colN = $valN |
1713
|
|
|
|
|
|
|
[ WHERE $wclause ] |
1714
|
|
|
|
|
|
|
|
1715
|
|
|
|
|
|
|
SELECT [DISTINCT] $col1, ... $colN |
1716
|
|
|
|
|
|
|
FROM $table |
1717
|
|
|
|
|
|
|
[ WHERE $wclause ] |
1718
|
|
|
|
|
|
|
[ ORDER BY $ocol1 [ASC|DESC], ... $ocolM [ASC|DESC] ] |
1719
|
|
|
|
|
|
|
|
1720
|
|
|
|
|
|
|
$wclause [NOT] $col $op $val|$col |
1721
|
|
|
|
|
|
|
[ AND|OR $wclause2 ... AND|OR $wclauseN ] |
1722
|
|
|
|
|
|
|
|
1723
|
|
|
|
|
|
|
$op = | <> | < | > | <= | >= |
1724
|
|
|
|
|
|
|
| IS NULL | IS NOT NULL | LIKE | CLIKE |
1725
|
|
|
|
|
|
|
|
1726
|
|
|
|
|
|
|
The "CLIKE" operator works exactly like "LIKE" but is case insensitive. |
1727
|
|
|
|
|
|
|
|
1728
|
|
|
|
|
|
|
=head1 BUGS |
1729
|
|
|
|
|
|
|
|
1730
|
|
|
|
|
|
|
Please report any bugs or feature requests to |
1731
|
|
|
|
|
|
|
C, or through the web interface at |
1732
|
|
|
|
|
|
|
L. |
1733
|
|
|
|
|
|
|
I will be notified, and then you'll automatically be notified of |
1734
|
|
|
|
|
|
|
progress on your bug as I make changes. |
1735
|
|
|
|
|
|
|
|
1736
|
|
|
|
|
|
|
=head1 SUPPORT |
1737
|
|
|
|
|
|
|
|
1738
|
|
|
|
|
|
|
You can find documentation for this module with the perldoc command. |
1739
|
|
|
|
|
|
|
|
1740
|
|
|
|
|
|
|
perldoc DBD::AnyData |
1741
|
|
|
|
|
|
|
|
1742
|
|
|
|
|
|
|
You can also look for information at: |
1743
|
|
|
|
|
|
|
|
1744
|
|
|
|
|
|
|
=over 4 |
1745
|
|
|
|
|
|
|
|
1746
|
|
|
|
|
|
|
=item * RT: CPAN's request tracker |
1747
|
|
|
|
|
|
|
|
1748
|
|
|
|
|
|
|
L |
1749
|
|
|
|
|
|
|
|
1750
|
|
|
|
|
|
|
=item * AnnoCPAN: Annotated CPAN documentation |
1751
|
|
|
|
|
|
|
|
1752
|
|
|
|
|
|
|
L |
1753
|
|
|
|
|
|
|
|
1754
|
|
|
|
|
|
|
=item * CPAN Ratings |
1755
|
|
|
|
|
|
|
|
1756
|
|
|
|
|
|
|
L |
1757
|
|
|
|
|
|
|
|
1758
|
|
|
|
|
|
|
=item * Search CPAN |
1759
|
|
|
|
|
|
|
|
1760
|
|
|
|
|
|
|
L |
1761
|
|
|
|
|
|
|
|
1762
|
|
|
|
|
|
|
=back |
1763
|
|
|
|
|
|
|
|
1764
|
|
|
|
|
|
|
=head1 ACKNOWLEDGEMENTS |
1765
|
|
|
|
|
|
|
|
1766
|
|
|
|
|
|
|
Many people have contributed ideas and code, found bugs, and generally |
1767
|
|
|
|
|
|
|
been supportive including Tom Lowery, Andy Duncan, Randal Schwartz, Michel |
1768
|
|
|
|
|
|
|
Rodriguez, Wes Hardraker, Bob Starr, Earl Cahill, Bryan Fife, Matt Sisk, |
1769
|
|
|
|
|
|
|
Matthew Wickline, Wolfgang Weisseberg. Thanks to Jochen Weidmann for |
1770
|
|
|
|
|
|
|
DBD::File and SQL::Statement and of course Tim Bunce and Alligator |
1771
|
|
|
|
|
|
|
Descartes for DBI and its documentation. |
1772
|
|
|
|
|
|
|
|
1773
|
|
|
|
|
|
|
=head1 AUTHOR & COPYRIGHT |
1774
|
|
|
|
|
|
|
|
1775
|
|
|
|
|
|
|
Copyright 2000, Jeff Zucker |
1776
|
|
|
|
|
|
|
|
1777
|
|
|
|
|
|
|
Copyright 2010, Jens Rehsack |
1778
|
|
|
|
|
|
|
|
1779
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify it |
1780
|
|
|
|
|
|
|
under the terms of either: the GNU General Public License as published |
1781
|
|
|
|
|
|
|
by the Free Software Foundation; or the Artistic License. |
1782
|
|
|
|
|
|
|
|
1783
|
|
|
|
|
|
|
See http://dev.perl.org/licenses/ for more information. |
1784
|
|
|
|
|
|
|
|
1785
|
|
|
|
|
|
|
All rights reserved |
1786
|
|
|
|
|
|
|
|
1787
|
|
|
|
|
|
|
=cut |
1788
|
|
|
|
|
|
|
|
1789
|
|
|
|
|
|
|
1; # End of DBD::AnyData |