line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package DBIx::DBO; |
2
|
|
|
|
|
|
|
|
3
|
11
|
|
|
11
|
|
44412
|
use 5.008; |
|
11
|
|
|
|
|
42
|
|
|
11
|
|
|
|
|
478
|
|
4
|
11
|
|
|
11
|
|
64
|
use strict; |
|
11
|
|
|
|
|
19
|
|
|
11
|
|
|
|
|
1448
|
|
5
|
11
|
|
|
11
|
|
77
|
use warnings; |
|
11
|
|
|
|
|
26
|
|
|
11
|
|
|
|
|
369
|
|
6
|
11
|
|
|
11
|
|
1991863
|
use DBI; |
|
11
|
|
|
|
|
307610
|
|
|
11
|
|
|
|
|
936
|
|
7
|
11
|
|
|
11
|
|
132
|
use Carp qw(carp croak); |
|
11
|
|
|
|
|
24
|
|
|
11
|
|
|
|
|
1973
|
|
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
our $VERSION; |
10
|
|
|
|
|
|
|
our %Config = ( |
11
|
|
|
|
|
|
|
AutoReconnect => 0, |
12
|
|
|
|
|
|
|
CacheQuery => 0, |
13
|
|
|
|
|
|
|
DebugSQL => 0, |
14
|
|
|
|
|
|
|
OnRowUpdate => 'simple', |
15
|
|
|
|
|
|
|
QuoteIdentifier => 1, |
16
|
|
|
|
|
|
|
); |
17
|
|
|
|
|
|
|
my $need_c3_initialize; |
18
|
|
|
|
|
|
|
my @ConnectArgs; |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
BEGIN { |
21
|
11
|
|
|
11
|
|
23
|
$VERSION = '0.40'; |
22
|
|
|
|
|
|
|
# The C3 method resolution order is required. |
23
|
11
|
50
|
|
|
|
68
|
if ($] < 5.009_005) { |
24
|
0
|
|
|
|
|
0
|
require MRO::Compat; |
25
|
|
|
|
|
|
|
} else { |
26
|
11
|
|
|
|
|
14034
|
require mro; |
27
|
|
|
|
|
|
|
} |
28
|
|
|
|
|
|
|
} |
29
|
|
|
|
|
|
|
|
30
|
11
|
|
|
11
|
|
36261
|
use DBIx::DBO::DBD; |
|
11
|
|
|
|
|
38
|
|
|
11
|
|
|
|
|
431
|
|
31
|
11
|
|
|
11
|
|
9427
|
use DBIx::DBO::Table; |
|
11
|
|
|
|
|
35
|
|
|
11
|
|
|
|
|
410
|
|
32
|
11
|
|
|
11
|
|
15596
|
use DBIx::DBO::Query; |
|
11
|
|
|
|
|
35
|
|
|
11
|
|
|
|
|
402
|
|
33
|
11
|
|
|
11
|
|
7608
|
use DBIx::DBO::Row; |
|
11
|
|
|
|
|
38
|
|
|
11
|
|
|
|
|
27749
|
|
34
|
|
|
|
|
|
|
|
35
|
42
|
|
|
42
|
|
328
|
sub _dbd_class { 'DBIx::DBO::DBD' } |
36
|
14
|
|
|
14
|
|
100
|
sub _table_class { 'DBIx::DBO::Table' } |
37
|
9
|
|
|
9
|
|
76
|
sub _query_class { 'DBIx::DBO::Query' } |
38
|
17
|
|
|
17
|
|
127
|
sub _row_class { 'DBIx::DBO::Row' } |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
*_isa = \&DBIx::DBO::DBD::_isa; |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
=head1 NAME |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
DBIx::DBO - An OO interface to SQL queries and results. Easily constructs SQL queries, and simplifies processing of the returned data. |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
=head1 SYNOPSIS |
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
use DBIx::DBO; |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
# Create the DBO |
51
|
|
|
|
|
|
|
my $dbo = DBIx::DBO->connect('DBI:mysql:my_db', 'me', 'mypasswd') or die $DBI::errstr; |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
# Create a "read-only" connection (useful for a replicated database) |
54
|
|
|
|
|
|
|
$dbo->connect_readonly('DBI:mysql:my_db', 'me', 'mypasswd') or die $DBI::errstr; |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
# Start with a Query object |
57
|
|
|
|
|
|
|
my $query = $dbo->query('my_table'); |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
# Find records with an 'o' in the name |
60
|
|
|
|
|
|
|
$query->where('name', 'LIKE', '%o%'); |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
# And with an id that is less than 500 |
63
|
|
|
|
|
|
|
$query->where('id', '<', 500); |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
# Exluding those with an age range from 20 to 29 |
66
|
|
|
|
|
|
|
$query->where('age', 'NOT BETWEEN', [20, 29]); |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
# Return only the first 10 rows |
69
|
|
|
|
|
|
|
$query->limit(10); |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
# Fetch the rows |
72
|
|
|
|
|
|
|
while (my $row = $query->fetch) { |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
# Use the row as an array reference |
75
|
|
|
|
|
|
|
printf "id=%d name=%s status=%s\n", $row->[0], $row->[1], $row->[4]; |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
# Or as a hash reference |
78
|
|
|
|
|
|
|
print 'id=', $row->{id}, "\n", 'name=', $row->{name}; |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
# Update/delete rows |
81
|
|
|
|
|
|
|
$row->update(status => 'Fired!') if $row->{name} eq 'Harry'; |
82
|
|
|
|
|
|
|
$row->delete if $row->{id} == 27; |
83
|
|
|
|
|
|
|
} |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
=head1 DESCRIPTION |
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
This module provides a convenient and efficient way to access a database. It can construct queries for you and returns the results in easy to use methods. |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
Once you've created a C object using one or both of C or C, you can begin creating L objects. These are the "workhorse" objects, they encapsulate an entire query with JOINs, WHERE clauses, etc. You need not have to know about what created the C to be able to use or modify it. This makes it valuable in environments like mod_perl or large projects that prefer an object oriented approach to data. |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
The query is only automatically executed when the data is requested. This is to make it possible to minimise lookups that may not be needed or to delay them as late as possible. |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
The L object returned can be treated as both an arrayref or a hashref. The data is aliased for efficient use of memory. C objects can be updated or deleted, even when created by JOINs (If the DB supports it). |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
=head1 METHODS |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
=cut |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
sub import { |
100
|
14
|
|
|
14
|
|
5117
|
my $class = shift; |
101
|
14
|
100
|
|
|
|
94
|
if (@_ & 1) { |
102
|
1
|
|
|
|
|
3
|
my $opt = pop; |
103
|
1
|
|
|
|
|
322
|
carp "Import option '$opt' passed without a value"; |
104
|
|
|
|
|
|
|
} |
105
|
14
|
|
|
|
|
4369
|
while (my($opt, $val) = splice @_, 0, 2) { |
106
|
6
|
100
|
|
|
|
37
|
if (exists $Config{$opt}) { |
107
|
5
|
|
|
|
|
40
|
DBIx::DBO::DBD->_set_config(\%Config, $opt, $val); |
108
|
|
|
|
|
|
|
} else { |
109
|
1
|
|
|
|
|
300
|
carp "Unknown import option '$opt'"; |
110
|
|
|
|
|
|
|
} |
111
|
|
|
|
|
|
|
} |
112
|
|
|
|
|
|
|
} |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
=head3 C |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
DBIx::DBO->new($dbh); |
117
|
|
|
|
|
|
|
DBIx::DBO->new(undef, $readonly_dbh); |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
Create a new C object from existsing C handles. You must provide one or both of the I and I C handles. |
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
=head3 C |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
$dbo = DBIx::DBO->connect($data_source, $username, $password, \%attr) |
124
|
|
|
|
|
|
|
or die $DBI::errstr; |
125
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
Takes the same arguments as Lconnect|DBI/"connect"> for a I connection to a database. It returns the C object if the connection succeeds or undefined on failure. |
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
=head3 C |
129
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
Takes the same arguments as C for a I connection to a database. It returns the C object if the connection succeeds or undefined on failure. |
131
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
Both C & C can be called on a C object to add that respective connection to create a C with both I and I connections. |
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
my $dbo = DBIx::DBO->connect($master_dsn, $username, $password, \%attr) |
135
|
|
|
|
|
|
|
or die $DBI::errstr; |
136
|
|
|
|
|
|
|
$dbo->connect_readonly($slave_dsn, $username, $password, \%attr) |
137
|
|
|
|
|
|
|
or die $DBI::errstr; |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
=cut |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
sub new { |
142
|
19
|
|
|
19
|
1
|
7101
|
my $me = shift; |
143
|
19
|
100
|
|
|
|
84
|
croak 'Too many arguments for '.(caller(0))[3] if @_ > 3; |
144
|
18
|
|
|
|
|
35
|
my($dbh, $rdbh, $new) = @_; |
145
|
|
|
|
|
|
|
|
146
|
18
|
100
|
100
|
|
|
120
|
if (defined $new and not UNIVERSAL::isa($new, 'HASH')) { |
147
|
1
|
|
|
|
|
10
|
croak '3rd argument to '.(caller(0))[3].' is not a HASH reference'; |
148
|
|
|
|
|
|
|
} |
149
|
17
|
100
|
|
|
|
52
|
if (defined $dbh) { |
150
|
11
|
100
|
|
|
|
55
|
croak 'Invalid read-write database handle' unless _isa($dbh, 'DBI::db'); |
151
|
10
|
|
|
|
|
33
|
$new->{dbh} = $dbh; |
152
|
10
|
|
66
|
|
|
183
|
$new->{dbd} ||= $dbh->{Driver}{Name}; |
153
|
|
|
|
|
|
|
} |
154
|
16
|
100
|
|
|
|
174
|
if (defined $rdbh) { |
155
|
6
|
100
|
|
|
|
18
|
croak 'Invalid read-only database handle' unless _isa($rdbh, 'DBI::db'); |
156
|
5
|
100
|
100
|
|
|
30
|
croak 'The read-write and read-only connections must use the same DBI driver' |
157
|
|
|
|
|
|
|
if $dbh and $dbh->{Driver}{Name} ne $rdbh->{Driver}{Name}; |
158
|
4
|
|
|
|
|
44
|
$new->{rdbh} = $rdbh; |
159
|
4
|
|
66
|
|
|
35
|
$new->{dbd} ||= $rdbh->{Driver}{Name}; |
160
|
|
|
|
|
|
|
} |
161
|
14
|
100
|
|
|
|
91
|
croak "Can't create the DBO, unknown database driver" unless $new->{dbd}; |
162
|
13
|
|
|
|
|
58
|
$new->{dbd_class} = $me->_dbd_class->_require_dbd_class($new->{dbd}); |
163
|
13
|
|
|
|
|
64
|
$me->_init($new); |
164
|
|
|
|
|
|
|
} |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
sub _init { |
167
|
13
|
|
|
13
|
|
30
|
my($class, $me) = @_; |
168
|
13
|
|
|
|
|
29
|
bless $me, $class; |
169
|
13
|
|
|
|
|
191
|
$me->{dbd_class}->_init_dbo($me); |
170
|
|
|
|
|
|
|
} |
171
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
sub connect { |
173
|
8
|
|
|
8
|
1
|
2004
|
my $me = shift; |
174
|
8
|
|
|
|
|
13
|
my $conn; |
175
|
8
|
100
|
|
|
|
30
|
if (ref $me) { |
176
|
4
|
100
|
|
|
|
21
|
croak 'DBO is already connected' if $me->{dbh}; |
177
|
3
|
100
|
|
|
|
14
|
$me->_check_driver($_[0]) if @_; |
178
|
2
|
100
|
|
|
|
7
|
if ($me->config('AutoReconnect')) { |
179
|
1
|
50
|
|
|
|
5
|
$me->{ConnectArgs} = scalar @ConnectArgs unless defined $me->{ConnectArgs}; |
180
|
1
|
|
|
|
|
3
|
$conn = $me->{ConnectArgs}; |
181
|
|
|
|
|
|
|
} else { |
182
|
1
|
50
|
|
|
|
8
|
undef $ConnectArgs[$me->{ConnectArgs}] if defined $me->{ConnectArgs}; |
183
|
1
|
|
|
|
|
11
|
delete $me->{ConnectArgs}; |
184
|
|
|
|
|
|
|
} |
185
|
|
|
|
|
|
|
# $conn = $me->{ConnectArgs} //= scalar @ConnectArgs if $me->config('AutoReconnect'); |
186
|
2
|
50
|
|
|
|
7
|
$me->{dbh} = $me->_connect($conn, @_) or return; |
187
|
2
|
|
|
|
|
721
|
return $me; |
188
|
|
|
|
|
|
|
} |
189
|
4
|
|
|
|
|
9
|
my %new; |
190
|
4
|
100
|
|
|
|
22
|
$conn = $new{ConnectArgs} = scalar @ConnectArgs if $me->config('AutoReconnect'); |
191
|
4
|
50
|
|
|
|
43
|
my $dbh = $me->_connect($conn, @_) or return; |
192
|
4
|
|
|
|
|
1966
|
$me->new($dbh, undef, \%new); |
193
|
|
|
|
|
|
|
} |
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
sub connect_readonly { |
196
|
12
|
|
|
12
|
1
|
1150
|
my $me = shift; |
197
|
12
|
|
|
|
|
15
|
my $conn; |
198
|
12
|
100
|
|
|
|
64
|
if (ref $me) { |
199
|
11
|
|
|
|
|
18
|
undef $me->{rdbh}; |
200
|
11
|
100
|
|
|
|
154
|
$me->_check_driver($_[0]) if @_; |
201
|
9
|
100
|
|
|
|
22
|
if ($me->config('AutoReconnect')) { |
202
|
4
|
100
|
|
|
|
16
|
$me->{ConnectReadOnlyArgs} = scalar @ConnectArgs unless defined $me->{ConnectReadOnlyArgs}; |
203
|
4
|
|
|
|
|
8
|
$conn = $me->{ConnectReadOnlyArgs}; |
204
|
|
|
|
|
|
|
} else { |
205
|
5
|
100
|
|
|
|
20
|
undef $ConnectArgs[$me->{ConnectReadOnlyArgs}] if defined $me->{ConnectReadOnlyArgs}; |
206
|
5
|
|
|
|
|
16
|
delete $me->{ConnectReadOnlyArgs}; |
207
|
|
|
|
|
|
|
} |
208
|
|
|
|
|
|
|
# $conn = $me->{ConnectReadOnlyArgs} //= scalar @ConnectArgs if $me->config('AutoReconnect'); |
209
|
9
|
50
|
|
|
|
28
|
$me->{rdbh} = $me->_connect($conn, @_) or return; |
210
|
7
|
|
|
|
|
1490
|
return $me; |
211
|
|
|
|
|
|
|
} |
212
|
1
|
|
|
|
|
3
|
my %new; |
213
|
1
|
50
|
|
|
|
6
|
$conn = $new{ConnectReadOnlyArgs} = scalar @ConnectArgs if $me->config('AutoReconnect'); |
214
|
1
|
50
|
|
|
|
8
|
my $dbh = $me->_connect($conn, @_) or return; |
215
|
1
|
|
|
|
|
208
|
$me->new(undef, $dbh, \%new); |
216
|
|
|
|
|
|
|
} |
217
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
sub _check_driver { |
219
|
9
|
|
|
9
|
|
16
|
my($me, $dsn) = @_; |
220
|
|
|
|
|
|
|
|
221
|
9
|
100
|
|
|
|
42
|
my $driver = (DBI->parse_dsn($dsn))[1] or |
222
|
|
|
|
|
|
|
croak "Can't connect to data source '$dsn' because I can't work out what driver to use " . |
223
|
|
|
|
|
|
|
"(it doesn't seem to contain a 'dbi:driver:' prefix and the DBI_DRIVER env var is not set)"; |
224
|
|
|
|
|
|
|
|
225
|
8
|
100
|
66
|
|
|
269
|
ref($me) =~ /::DBD::\Q$driver\E$/ or |
226
|
|
|
|
|
|
|
$driver eq $me->{dbd} or |
227
|
|
|
|
|
|
|
croak "Can't connect to the data source '$dsn'\n" . |
228
|
|
|
|
|
|
|
"The read-write and read-only connections must use the same DBI driver"; |
229
|
|
|
|
|
|
|
} |
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
sub _connect { |
232
|
17
|
|
|
17
|
|
71
|
my $me = shift; |
233
|
17
|
|
|
|
|
24
|
my $conn_idx = shift; |
234
|
17
|
|
|
|
|
27
|
my @conn; |
235
|
|
|
|
|
|
|
|
236
|
17
|
100
|
66
|
|
|
69
|
if (@_) { |
|
|
100
|
|
|
|
|
|
237
|
11
|
|
|
|
|
22
|
my($dsn, $user, $auth, $attr) = @_; |
238
|
11
|
100
|
|
|
|
41
|
my %attr = %$attr if ref($attr) eq 'HASH'; |
239
|
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
# Add a stack trace to PrintError & RaiseError |
241
|
|
|
|
|
|
|
$attr{HandleError} = sub { |
242
|
0
|
0
|
|
0
|
|
0
|
if ($Config{DebugSQL} > 1) { |
243
|
0
|
|
|
|
|
0
|
$_[0] = Carp::longmess($_[0]); |
244
|
0
|
|
|
|
|
0
|
return 0; |
245
|
|
|
|
|
|
|
} |
246
|
0
|
0
|
|
|
|
0
|
carp $_[1]->errstr if $_[1]->{PrintError}; |
247
|
0
|
0
|
|
|
|
0
|
croak $_[1]->errstr if $_[1]->{RaiseError}; |
248
|
0
|
|
|
|
|
0
|
return 1; |
249
|
11
|
100
|
|
|
|
66
|
} unless exists $attr{HandleError}; |
250
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
# AutoCommit is always on |
252
|
11
|
|
|
|
|
95
|
%attr = (PrintError => 0, RaiseError => 1, %attr, AutoCommit => 1); |
253
|
11
|
|
|
|
|
83
|
@conn = ($dsn, $user, $auth, \%attr); |
254
|
|
|
|
|
|
|
|
255
|
|
|
|
|
|
|
# If a conn index is given then store the connection args |
256
|
11
|
100
|
|
|
|
52
|
$ConnectArgs[$conn_idx] = \@conn if defined $conn_idx; |
257
|
|
|
|
|
|
|
} elsif (defined $conn_idx and $ConnectArgs[$conn_idx]) { |
258
|
|
|
|
|
|
|
# If a conn index is given then retrieve the connection args |
259
|
4
|
|
|
|
|
7
|
@conn = @{$ConnectArgs[$conn_idx]}; |
|
4
|
|
|
|
|
14
|
|
260
|
|
|
|
|
|
|
} else { |
261
|
2
|
|
|
|
|
7
|
croak "Can't auto-connect as AutoReconnect was not set"; |
262
|
|
|
|
|
|
|
} |
263
|
|
|
|
|
|
|
|
264
|
15
|
|
|
|
|
43
|
local @DBIx::DBO::CARP_NOT = qw(DBI); |
265
|
15
|
|
|
|
|
74
|
DBI->connect(@conn); |
266
|
|
|
|
|
|
|
} |
267
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
=head3 C
269
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
$dbo->table($table); |
271
|
|
|
|
|
|
|
$dbo->table([$schema, $table]); |
272
|
|
|
|
|
|
|
$dbo->table($table_object); |
273
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
Create and return a new L object.
275
|
|
|
|
|
|
|
Tables can be specified by their name or an arrayref of schema and table name or another L object.
276
|
|
|
|
|
|
|
|
277
|
|
|
|
|
|
|
=cut |
278
|
|
|
|
|
|
|
|
279
|
|
|
|
|
|
|
sub table { |
280
|
7
|
|
|
7
|
1
|
626
|
$_[0]->_table_class->new(@_); |
281
|
|
|
|
|
|
|
} |
282
|
|
|
|
|
|
|
|
283
|
|
|
|
|
|
|
=head3 C |
284
|
|
|
|
|
|
|
|
285
|
|
|
|
|
|
|
$dbo->query($table, ...); |
286
|
|
|
|
|
|
|
$dbo->query([$schema, $table], ...); |
287
|
|
|
|
|
|
|
$dbo->query($table_object, ...); |
288
|
|
|
|
|
|
|
|
289
|
|
|
|
|
|
|
Create a new L object from the tables specified. |
290
|
|
|
|
|
|
|
In scalar context, just the C object will be returned. |
291
|
|
|
|
|
|
|
In list context, the C object and L objects will be returned for each table specified.
292
|
|
|
|
|
|
|
|
293
|
|
|
|
|
|
|
my($query, $table1, $table2) = $dbo->query(['my_schema', 'my_table'], 'my_other_table'); |
294
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
=cut |
296
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
sub query { |
298
|
10
|
|
|
10
|
1
|
3483
|
$_[0]->_query_class->new(@_); |
299
|
|
|
|
|
|
|
} |
300
|
|
|
|
|
|
|
|
301
|
|
|
|
|
|
|
=head3 C |
302
|
|
|
|
|
|
|
|
303
|
|
|
|
|
|
|
$dbo->row($table || $table_object || $query_object); |
304
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
Create and return a new L object. |
306
|
|
|
|
|
|
|
|
307
|
|
|
|
|
|
|
=cut |
308
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
sub row { |
310
|
5
|
|
|
5
|
1
|
1629
|
$_[0]->_row_class->new(@_); |
311
|
|
|
|
|
|
|
} |
312
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
=head3 C, C, C, C |
314
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
$dbo->selectrow_array($statement, \%attr, @bind_values); |
316
|
|
|
|
|
|
|
$dbo->selectrow_arrayref($statement, \%attr, @bind_values); |
317
|
|
|
|
|
|
|
$dbo->selectrow_hashref($statement, \%attr, @bind_values); |
318
|
|
|
|
|
|
|
$dbo->selectall_arrayref($statement, \%attr, @bind_values); |
319
|
|
|
|
|
|
|
|
320
|
|
|
|
|
|
|
These convenience methods provide access to Lselectrow_array|DBI/"selectrow_array">, Lselectrow_arrayref|DBI/"selectrow_arrayref">, Lselectrow_hashref|DBI/"selectrow_hashref">, Lselectall_arrayref|DBI/"selectall_arrayref"> methods. |
321
|
|
|
|
|
|
|
They default to using the I C handle. |
322
|
|
|
|
|
|
|
|
323
|
|
|
|
|
|
|
=cut |
324
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
sub selectrow_array { |
326
|
1
|
|
|
1
|
1
|
2
|
my $me = shift; |
327
|
1
|
|
|
|
|
13
|
$me->{dbd_class}->_selectrow_array($me, @_); |
328
|
|
|
|
|
|
|
} |
329
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
sub selectrow_arrayref { |
331
|
2
|
|
|
2
|
1
|
5
|
my $me = shift; |
332
|
2
|
|
|
|
|
18
|
$me->{dbd_class}->_selectrow_arrayref($me, @_); |
333
|
|
|
|
|
|
|
} |
334
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
sub selectrow_hashref { |
336
|
0
|
|
|
0
|
1
|
0
|
my $me = shift; |
337
|
0
|
|
|
|
|
0
|
$me->{dbd_class}->_selectrow_hashref($me, @_); |
338
|
|
|
|
|
|
|
} |
339
|
|
|
|
|
|
|
|
340
|
|
|
|
|
|
|
sub selectall_arrayref { |
341
|
1
|
|
|
1
|
1
|
3
|
my $me = shift; |
342
|
1
|
|
|
|
|
11
|
$me->{dbd_class}->_selectall_arrayref($me, @_); |
343
|
|
|
|
|
|
|
} |
344
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
=head3 C |
346
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
$dbo->do($statement) or die $dbo->dbh->errstr; |
348
|
|
|
|
|
|
|
$dbo->do($statement, \%attr) or die $dbo->dbh->errstr; |
349
|
|
|
|
|
|
|
$dbo->do($statement, \%attr, @bind_values) or die ... |
350
|
|
|
|
|
|
|
|
351
|
|
|
|
|
|
|
This provides access to the Ldo|DBI/"do"> method. It defaults to using the I C handle. |
352
|
|
|
|
|
|
|
|
353
|
|
|
|
|
|
|
=cut |
354
|
|
|
|
|
|
|
|
355
|
|
|
|
|
|
|
sub do { |
356
|
6
|
|
|
6
|
1
|
425
|
my $me = shift; |
357
|
6
|
|
|
|
|
34
|
$me->{dbd_class}->_do($me, @_); |
358
|
|
|
|
|
|
|
} |
359
|
|
|
|
|
|
|
|
360
|
|
|
|
|
|
|
=head3 C |
361
|
|
|
|
|
|
|
|
362
|
|
|
|
|
|
|
$dbo->table_info($table); |
363
|
|
|
|
|
|
|
$dbo->table_info([$schema, $table]); |
364
|
|
|
|
|
|
|
$dbo->table_info($table_object); |
365
|
|
|
|
|
|
|
|
366
|
|
|
|
|
|
|
Returns a hashref containing C, C and C for the table. |
367
|
|
|
|
|
|
|
Mainly for internal use. |
368
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
=cut |
370
|
|
|
|
|
|
|
|
371
|
|
|
|
|
|
|
sub table_info { |
372
|
24
|
|
|
24
|
1
|
47
|
my($me, $table) = @_; |
373
|
24
|
50
|
33
|
|
|
151
|
croak 'No table name supplied' unless defined $table and length $table; |
374
|
|
|
|
|
|
|
|
375
|
24
|
|
|
|
|
36
|
my $schema; |
376
|
24
|
100
|
|
|
|
129
|
if (_isa($table, 'DBIx::DBO::Table')) { |
377
|
2
|
100
|
|
|
|
11
|
croak 'This table is from a different DBO connection' if $table->{DBO} != $me; |
378
|
1
|
|
|
|
|
6
|
($schema, $table) = @$table{qw(Schema Name)}; |
379
|
|
|
|
|
|
|
} else { |
380
|
22
|
100
|
|
|
|
160
|
($schema, $table) = ref $table eq 'ARRAY' ? @$table : $me->{dbd_class}->_unquote_table($me, $table); |
381
|
22
|
100
|
|
|
|
160
|
defined $schema or $schema = $me->{dbd_class}->_get_table_schema($me, $schema, $table); |
382
|
|
|
|
|
|
|
|
383
|
22
|
100
|
|
|
|
163
|
$me->{dbd_class}->_get_table_info($me, $schema, $table) |
|
|
100
|
|
|
|
|
|
384
|
|
|
|
|
|
|
unless exists $me->{TableInfo}{defined $schema ? $schema : ''}{$table}; |
385
|
|
|
|
|
|
|
} |
386
|
22
|
100
|
|
|
|
224
|
return ($schema, $table, $me->{TableInfo}{defined $schema ? $schema : ''}{$table}); |
387
|
|
|
|
|
|
|
} |
388
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
=head3 C |
390
|
|
|
|
|
|
|
|
391
|
|
|
|
|
|
|
Disconnect both the I & I connections to the database. |
392
|
|
|
|
|
|
|
|
393
|
|
|
|
|
|
|
=cut |
394
|
|
|
|
|
|
|
|
395
|
|
|
|
|
|
|
sub disconnect { |
396
|
4
|
|
|
4
|
1
|
600
|
my $me = shift; |
397
|
4
|
100
|
|
|
|
22
|
if ($me->{dbh}) { |
398
|
3
|
|
|
|
|
204
|
$me->{dbh}->disconnect; |
399
|
3
|
|
|
|
|
6
|
undef $me->{dbh}; |
400
|
|
|
|
|
|
|
} |
401
|
4
|
100
|
|
|
|
70
|
if ($me->{rdbh}) { |
402
|
3
|
|
|
|
|
30
|
$me->{rdbh}->disconnect; |
403
|
3
|
|
|
|
|
5
|
undef $me->{rdbh}; |
404
|
|
|
|
|
|
|
} |
405
|
4
|
|
|
|
|
87
|
delete $me->{TableInfo}; |
406
|
4
|
|
|
|
|
15
|
return; |
407
|
|
|
|
|
|
|
} |
408
|
|
|
|
|
|
|
|
409
|
|
|
|
|
|
|
=head2 Common Methods |
410
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
These methods are accessible from all DBIx::DBO* objects. |
412
|
|
|
|
|
|
|
|
413
|
|
|
|
|
|
|
=head3 C |
414
|
|
|
|
|
|
|
|
415
|
|
|
|
|
|
|
This C object. |
416
|
|
|
|
|
|
|
|
417
|
|
|
|
|
|
|
=head3 C |
418
|
|
|
|
|
|
|
|
419
|
|
|
|
|
|
|
The I C handle. |
420
|
|
|
|
|
|
|
|
421
|
|
|
|
|
|
|
=head3 C |
422
|
|
|
|
|
|
|
|
423
|
|
|
|
|
|
|
The I C handle, or if there is no I connection, the I C handle. |
424
|
|
|
|
|
|
|
|
425
|
|
|
|
|
|
|
=cut |
426
|
|
|
|
|
|
|
|
427
|
2
|
|
|
2
|
1
|
449
|
sub dbo { $_[0] } |
428
|
|
|
|
|
|
|
|
429
|
|
|
|
|
|
|
sub _handle { |
430
|
302
|
|
|
302
|
|
488
|
my($me, $type) = @_; |
431
|
|
|
|
|
|
|
# $type can be 'read-only', 'read-write' or false (which means try read-only then read-write) |
432
|
302
|
100
|
66
|
|
|
1449
|
$type ||= defined $me->{rdbh} ? 'read-only' : 'read-write'; |
433
|
302
|
100
|
|
|
|
788
|
my($d, $c) = $type ne 'read-only' ? qw(dbh ConnectArgs) : qw(rdbh ConnectReadOnlyArgs); |
434
|
302
|
100
|
|
|
|
731
|
croak "No $type handle connected" unless defined $me->{$d}; |
435
|
|
|
|
|
|
|
# Automatically reconnect, but only if possible and needed |
436
|
300
|
100
|
100
|
|
|
870
|
$me->{$d} = $me->_connect($me->{$c}) if exists $me->{$c} and not $me->{$d}->ping; |
437
|
300
|
|
|
|
|
2659
|
$me->{$d}; |
438
|
|
|
|
|
|
|
} |
439
|
|
|
|
|
|
|
|
440
|
|
|
|
|
|
|
sub dbh { |
441
|
34
|
|
|
34
|
1
|
59
|
my $me = shift; |
442
|
34
|
|
50
|
|
|
91
|
$me->_handle($me->config('UseHandle') || 'read-write'); |
443
|
|
|
|
|
|
|
} |
444
|
|
|
|
|
|
|
|
445
|
|
|
|
|
|
|
sub rdbh { |
446
|
268
|
|
|
268
|
1
|
400
|
my $me = shift; |
447
|
268
|
|
|
|
|
667
|
$me->_handle($me->config('UseHandle')); |
448
|
|
|
|
|
|
|
} |
449
|
|
|
|
|
|
|
|
450
|
|
|
|
|
|
|
=head3 C |
451
|
|
|
|
|
|
|
|
452
|
|
|
|
|
|
|
$global_setting = DBIx::DBO->config($option); |
453
|
|
|
|
|
|
|
DBIx::DBO->config($option => $global_setting); |
454
|
|
|
|
|
|
|
$dbo_setting = $dbo->config($option); |
455
|
|
|
|
|
|
|
$dbo->config($option => $dbo_setting); |
456
|
|
|
|
|
|
|
|
457
|
|
|
|
|
|
|
Get or set the global or this C config settings. When setting an option, the previous value is returned. When getting an option's value, if the value is undefined, the global value is returned. |
458
|
|
|
|
|
|
|
|
459
|
|
|
|
|
|
|
=head2 Available C options |
460
|
|
|
|
|
|
|
|
461
|
|
|
|
|
|
|
=over |
462
|
|
|
|
|
|
|
|
463
|
|
|
|
|
|
|
=item C |
464
|
|
|
|
|
|
|
|
465
|
|
|
|
|
|
|
Boolean setting to store the connection details for re-use. |
466
|
|
|
|
|
|
|
Before every operation the connection will be tested via ping() and reconnected automatically if needed. |
467
|
|
|
|
|
|
|
Changing this has no effect after the connection has been made. |
468
|
|
|
|
|
|
|
Defaults to C. |
469
|
|
|
|
|
|
|
|
470
|
|
|
|
|
|
|
=item C |
471
|
|
|
|
|
|
|
|
472
|
|
|
|
|
|
|
Boolean setting to cause C objects to cache their entire result for re-use. |
473
|
|
|
|
|
|
|
The query will only be executed automatically once. |
474
|
|
|
|
|
|
|
To rerun the query, either explicitly call L or alter the query. |
475
|
|
|
|
|
|
|
Defaults to C. |
476
|
|
|
|
|
|
|
|
477
|
|
|
|
|
|
|
=item C |
478
|
|
|
|
|
|
|
|
479
|
|
|
|
|
|
|
Set to C<1> or C<2> to warn about each SQL command executed. C<2> adds a full stack trace. |
480
|
|
|
|
|
|
|
Defaults to C<0> (silent). |
481
|
|
|
|
|
|
|
|
482
|
|
|
|
|
|
|
=item C |
483
|
|
|
|
|
|
|
|
484
|
|
|
|
|
|
|
Set to C<'empty'>, C<'simple'> or C<'reload'> to define the behaviour of a C after an L. |
485
|
|
|
|
|
|
|
C<'empty'> will simply leave the C empty after every update. |
486
|
|
|
|
|
|
|
C<'simple'> will set the values in the C if they are not complex expressions, otherwise the C will be empty. |
487
|
|
|
|
|
|
|
C<'reload'> is the same as C<'simple'> except it also tries to reload the C if possible. |
488
|
|
|
|
|
|
|
Defaults to C<'simple'>. |
489
|
|
|
|
|
|
|
|
490
|
|
|
|
|
|
|
=item C |
491
|
|
|
|
|
|
|
|
492
|
|
|
|
|
|
|
Boolean setting to control quoting of SQL identifiers (schema, table and column names). |
493
|
|
|
|
|
|
|
|
494
|
|
|
|
|
|
|
=item C |
495
|
|
|
|
|
|
|
|
496
|
|
|
|
|
|
|
Set to C<'read-write'> or C<'read-only'> to force using only that handle for all operations. |
497
|
|
|
|
|
|
|
Defaults to C which chooses the I handle for reads and the I handle otherwise. |
498
|
|
|
|
|
|
|
|
499
|
|
|
|
|
|
|
=back |
500
|
|
|
|
|
|
|
|
501
|
|
|
|
|
|
|
Global options can also be set when C |
502
|
|
|
|
|
|
|
|
503
|
|
|
|
|
|
|
use DBIx::DBO QuoteIdentifier => 0, DebugSQL => 1; |
504
|
|
|
|
|
|
|
|
505
|
|
|
|
|
|
|
=cut |
506
|
|
|
|
|
|
|
|
507
|
|
|
|
|
|
|
sub config { |
508
|
399
|
|
|
399
|
1
|
7930
|
my($me, $opt) = @_; |
509
|
399
|
100
|
|
|
|
941
|
if (@_ > 2) { |
510
|
37
|
100
|
100
|
|
|
1472
|
return ref $me |
511
|
|
|
|
|
|
|
? $me->{dbd_class}->_set_config($me->{Config} ||= {}, $opt, $_[2]) |
512
|
|
|
|
|
|
|
: $me->_dbd_class->_set_config(\%Config, $opt, $_[2]); |
513
|
|
|
|
|
|
|
} |
514
|
362
|
100
|
100
|
|
|
2168
|
return ref $me |
515
|
|
|
|
|
|
|
? $me->{dbd_class}->_get_config($opt, $me->{Config} ||= {}, \%Config) |
516
|
|
|
|
|
|
|
: $me->_dbd_class->_get_config($opt, \%Config); |
517
|
|
|
|
|
|
|
} |
518
|
|
|
|
|
|
|
|
519
|
|
|
|
|
|
|
sub STORABLE_freeze { |
520
|
16
|
|
|
16
|
0
|
358
|
my $me = $_[0]; |
521
|
16
|
100
|
66
|
|
|
801
|
return unless ref $me->{dbh} or ref $me->{rdbh}; |
522
|
|
|
|
|
|
|
|
523
|
8
|
|
|
|
|
16
|
my %stash = map { $_ => delete $me->{$_} } qw(dbh rdbh ConnectArgs ConnectReadOnlyArgs); |
|
32
|
|
|
|
|
85
|
|
524
|
8
|
50
|
|
|
|
42
|
$me->{dbh} = "$stash{dbh}" if defined $stash{dbh}; |
525
|
8
|
50
|
|
|
|
19
|
$me->{rdbh} = "$stash{rdbh}" if defined $stash{rdbh}; |
526
|
8
|
|
|
|
|
14
|
for (qw(ConnectArgs ConnectReadOnlyArgs)) { |
527
|
16
|
50
|
|
|
|
42
|
$me->{$_} = $ConnectArgs[$stash{$_}] if defined $stash{$_}; |
528
|
|
|
|
|
|
|
} |
529
|
|
|
|
|
|
|
|
530
|
8
|
|
|
|
|
26
|
my $frozen = Storable::nfreeze($me); |
531
|
8
|
|
66
|
|
|
112
|
defined $stash{$_} and $me->{$_} = $stash{$_} for qw(dbh rdbh ConnectArgs ConnectReadOnlyArgs); |
532
|
8
|
|
|
|
|
370
|
return $frozen; |
533
|
|
|
|
|
|
|
} |
534
|
|
|
|
|
|
|
|
535
|
|
|
|
|
|
|
sub STORABLE_thaw { |
536
|
8
|
|
|
8
|
0
|
2428
|
my($me, $cloning, $frozen) = @_; |
537
|
8
|
|
|
|
|
9
|
%$me = %{ Storable::thaw($frozen) }; |
|
8
|
|
|
|
|
22
|
|
538
|
8
|
50
|
|
|
|
292
|
if ($me->config('AutoReconnect')) { |
539
|
0
|
|
|
|
|
0
|
for (qw(ConnectArgs ConnectReadOnlyArgs)) { |
540
|
0
|
0
|
|
|
|
0
|
$me->{$_} = push(@ConnectArgs, $me->{$_}) - 1 if $me->{$_}; |
541
|
|
|
|
|
|
|
} |
542
|
|
|
|
|
|
|
} else { |
543
|
8
|
|
|
|
|
197
|
delete $me->{$_} for qw(ConnectArgs ConnectReadOnlyArgs); |
544
|
|
|
|
|
|
|
} |
545
|
|
|
|
|
|
|
} |
546
|
|
|
|
|
|
|
|
547
|
|
|
|
|
|
|
sub DESTROY { |
548
|
17
|
|
|
17
|
|
1024
|
undef %{$_[0]}; |
|
17
|
|
|
|
|
316
|
|
549
|
|
|
|
|
|
|
} |
550
|
|
|
|
|
|
|
|
551
|
|
|
|
|
|
|
1; |
552
|
|
|
|
|
|
|
|
553
|
|
|
|
|
|
|
__END__ |
| | | |