line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
10
|
|
|
10
|
|
26793
|
use Test::More; |
|
10
|
|
|
|
|
240552
|
|
|
10
|
|
|
|
|
109
|
|
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
package # Hide from PAUSE |
4
|
|
|
|
|
|
|
Test::DBO; |
5
|
|
|
|
|
|
|
|
6
|
10
|
|
|
10
|
|
3470
|
use 5.008; |
|
10
|
|
|
|
|
40
|
|
|
10
|
|
|
|
|
363
|
|
7
|
10
|
|
|
10
|
|
66
|
use strict; |
|
10
|
|
|
|
|
18
|
|
|
10
|
|
|
|
|
379
|
|
8
|
10
|
|
|
10
|
|
55
|
use warnings; |
|
10
|
|
|
|
|
18
|
|
|
10
|
|
|
|
|
351
|
|
9
|
10
|
|
|
10
|
|
20109
|
use sigtrap qw(die normal-signals); |
|
10
|
|
|
|
|
15157
|
|
|
10
|
|
|
|
|
75
|
|
10
|
|
|
|
|
|
|
|
11
|
10
|
|
|
10
|
|
1532
|
use Scalar::Util qw(blessed reftype); |
|
10
|
|
|
|
|
23
|
|
|
10
|
|
|
|
|
2129
|
|
12
|
10
|
|
|
10
|
|
58
|
use Test::More; |
|
10
|
|
|
|
|
19
|
|
|
10
|
|
|
|
|
70
|
|
13
|
10
|
|
|
10
|
|
10967
|
use DBIx::DBO; |
|
10
|
|
|
|
|
33
|
|
|
10
|
|
|
|
|
97
|
|
14
|
|
|
|
|
|
|
BEGIN { |
15
|
10
|
50
|
|
10
|
|
690
|
require Carp::Heavy if eval "$Carp::VERSION < 1.12"; |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
# If we are using a version of Test::More older than 0.82 ... |
18
|
10
|
50
|
|
|
|
57
|
unless (exists $Test::More::{note}) { |
19
|
0
|
|
|
|
|
0
|
eval q# |
20
|
|
|
|
|
|
|
sub Test::More::note { |
21
|
|
|
|
|
|
|
local $Test::Builder::{_print_diag} = $Test::Builder::{_print}; |
22
|
|
|
|
|
|
|
Test::More->builder->diag(@_); |
23
|
|
|
|
|
|
|
} |
24
|
|
|
|
|
|
|
*note = \&Test::More::note; |
25
|
|
|
|
|
|
|
no strict 'refs'; |
26
|
|
|
|
|
|
|
*{caller(2).'::note'} = \¬e; |
27
|
|
|
|
|
|
|
#; |
28
|
0
|
0
|
|
|
|
0
|
die $@ if $@; |
29
|
|
|
|
|
|
|
} |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
# Set up DebugSQL if requested |
32
|
10
|
50
|
|
|
|
48
|
if ($ENV{DBO_DEBUG_SQL}) { |
33
|
0
|
|
|
|
|
0
|
diag "DBO_DEBUG_SQL=$ENV{DBO_DEBUG_SQL}"; |
34
|
0
|
|
|
|
|
0
|
DBIx::DBO->config(DebugSQL => $ENV{DBO_DEBUG_SQL}); |
35
|
|
|
|
|
|
|
} |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
# Set up $Carp::Verbose if requested |
38
|
10
|
50
|
|
|
|
72
|
if ($ENV{DBO_CARP_VERBOSE}) { |
|
|
50
|
|
|
|
|
|
39
|
0
|
|
|
|
|
0
|
diag "DBO_CARP_VERBOSE=$ENV{DBO_CARP_VERBOSE}"; |
40
|
0
|
|
|
|
|
0
|
$Carp::Verbose = $ENV{DBO_CARP_VERBOSE}; |
41
|
|
|
|
|
|
|
} elsif ($ENV{AUTOMATED_TESTING}) { |
42
|
10
|
|
|
|
|
21
|
$Carp::Verbose = 1; |
43
|
|
|
|
|
|
|
} |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
# Store the last SQL executed, and show debug info |
46
|
|
|
|
|
|
|
DBIx::DBO->config(HookSQL => sub { |
47
|
86
|
|
|
|
|
113
|
my $me = shift; |
48
|
86
|
|
|
|
|
18931
|
my $loc = Carp::short_error_loc(); |
49
|
86
|
|
|
|
|
4771
|
my %i = Carp::caller_info($loc); |
50
|
86
|
|
|
|
|
3958
|
$me->config(LastSQL => [$i{'sub'}, @_]); |
51
|
86
|
50
|
|
|
|
888
|
my $dbg = $ENV{DBO_DEBUG_SQL} or return; |
52
|
0
|
|
|
|
|
0
|
my $trace; |
53
|
0
|
0
|
|
|
|
0
|
if ($dbg > 1) { |
54
|
0
|
|
|
|
|
0
|
$trace = "\t$i{sub_name} called at $i{file} line $i{line}\n"; |
55
|
0
|
|
|
|
|
0
|
$trace .= "\t$i{sub_name} called at $i{file} line $i{line}\n" while %i = Carp::caller_info(++$loc); |
56
|
|
|
|
|
|
|
} else { |
57
|
0
|
|
|
|
|
0
|
$trace = "\t$i{sub} called at $i{file} line $i{line}\n"; |
58
|
|
|
|
|
|
|
} |
59
|
0
|
|
|
|
|
0
|
my $sql = shift; |
60
|
0
|
|
|
|
|
0
|
Test::More::diag "DEBUG_SQL: $sql\nDEBUG_SQL: (".join(', ', map $me->rdbh->quote($_), @_).")\n".$trace; |
61
|
10
|
|
|
|
|
83
|
}); |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
{ |
64
|
10
|
|
|
10
|
|
89
|
no warnings 'redefine'; |
|
10
|
|
|
|
|
18
|
|
|
10
|
|
|
|
|
1833
|
|
|
10
|
|
|
|
|
17
|
|
65
|
|
|
|
|
|
|
# Remove CARP_NOT during tests |
66
|
|
|
|
|
|
|
package # Hide from PAUSE |
67
|
|
|
|
|
|
|
DBIx::DBO; |
68
|
|
|
|
|
|
|
*DBIx::DBO::croak = |
69
|
|
|
|
|
|
|
*DBIx::DBO::Query::croak = |
70
|
|
|
|
|
|
|
*DBIx::DBO::Table::croak = |
71
|
|
|
|
|
|
|
*DBIx::DBO::Row::croak = sub { |
72
|
38
|
50
|
|
38
|
|
284
|
local @DBIx::DBO::DBD::CARP_NOT = () if $Carp::Verbose; |
73
|
38
|
50
|
|
|
|
103
|
local $Carp::CarpLevel = $Carp::CarpLevel + 1 if $Carp::Verbose; |
74
|
38
|
|
|
|
|
5147
|
&Carp::croak; |
75
|
10
|
|
|
|
|
74
|
}; |
76
|
|
|
|
|
|
|
# Fix SvREFCNT with Devel::Cover |
77
|
|
|
|
|
|
|
package # Hide from PAUSE |
78
|
|
|
|
|
|
|
DBIx::DBO::Query; |
79
|
|
|
|
|
|
|
*DBIx::DBO::Query::SvREFCNT = sub { |
80
|
48
|
|
|
48
|
|
345
|
return Devel::Peek::SvREFCNT($_[0]) - 1; |
81
|
10
|
50
|
|
|
|
15862
|
} if exists $INC{'Devel/Cover.pm'}; |
82
|
|
|
|
|
|
|
} |
83
|
|
|
|
|
|
|
} |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
our $dbd; |
86
|
|
|
|
|
|
|
our $dbd_name; |
87
|
|
|
|
|
|
|
(our $test_db = "DBO_${DBIx::DBO::VERSION}_test_db") =~ s/\W/_/g; |
88
|
|
|
|
|
|
|
(our $test_sch = "DBO_${DBIx::DBO::VERSION}_test_sch") =~ s/\W/_/g; |
89
|
|
|
|
|
|
|
(our $test_tbl = "DBO_${DBIx::DBO::VERSION}_test_tbl") =~ s/\W/_/g; |
90
|
|
|
|
|
|
|
our @_cleanup_sql; |
91
|
|
|
|
|
|
|
our $case_sensitivity_sql = 'SELECT ? LIKE ?'; |
92
|
|
|
|
|
|
|
our %can; |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
sub import { |
95
|
11
|
|
|
11
|
|
126
|
my $class = shift; |
96
|
11
|
50
|
|
|
|
56
|
$dbd = shift or return; |
97
|
11
|
|
|
|
|
18
|
$dbd_name = shift; |
98
|
11
|
|
|
|
|
49
|
my %opt = splice @_; |
99
|
|
|
|
|
|
|
|
100
|
11
|
100
|
|
|
|
95
|
grep $_ eq $dbd, DBI->available_drivers |
101
|
|
|
|
|
|
|
or plan skip_all => "No $dbd driver available!"; |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
# Catch install_driver errors |
104
|
8
|
|
|
|
|
4362
|
eval { DBI->install_driver($dbd) }; |
|
8
|
|
|
|
|
59
|
|
105
|
8
|
50
|
|
|
|
105768
|
if ($@) { |
106
|
0
|
0
|
|
|
|
0
|
die $@ if $@ !~ /\binstall_driver\b/; |
107
|
0
|
|
|
|
|
0
|
plan skip_all => $@; |
108
|
|
|
|
|
|
|
} |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
# Skip tests with missing module requirements |
111
|
8
|
100
|
|
|
|
16
|
unless (eval { DBIx::DBO::DBD->_require_dbd_class($dbd) }) { |
|
8
|
|
|
|
|
88
|
|
112
|
1
|
50
|
|
|
|
41
|
if ($@ =~ /^Can't locate ([\w\/]+)\.pm in \@INC /m) { |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
113
|
|
|
|
|
|
|
# Module is not installed |
114
|
0
|
|
|
|
|
0
|
($_ = "$1 is required") =~ s'/'::'g; |
115
|
|
|
|
|
|
|
} elsif ($@ =~ /^([\w:]+ version [\d\.]+ required.*?) at /m) { |
116
|
|
|
|
|
|
|
# Module is not correct version |
117
|
0
|
|
|
|
|
0
|
($_ = $1); |
118
|
|
|
|
|
|
|
} elsif ($@ =~ /^(\Q$dbd_name\E is not yet supported)/m) { |
119
|
|
|
|
|
|
|
# DBM is not yet supported |
120
|
1
|
|
|
|
|
3
|
($_ = $1); |
121
|
|
|
|
|
|
|
} else { |
122
|
0
|
|
|
|
|
0
|
die $@; |
123
|
|
|
|
|
|
|
} |
124
|
1
|
|
|
|
|
11
|
plan skip_all => "Can't load $dbd driver: $_"; |
125
|
|
|
|
|
|
|
} |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
{ |
128
|
10
|
|
|
10
|
|
84
|
no strict 'refs'; |
|
10
|
|
|
|
|
17
|
|
|
10
|
|
|
|
|
66606
|
|
|
7
|
|
|
|
|
12
|
|
129
|
7
|
|
|
|
|
15
|
*{caller().'::sql_err'} = \&sql_err; |
|
7
|
|
|
|
|
36
|
|
130
|
|
|
|
|
|
|
} |
131
|
|
|
|
|
|
|
|
132
|
7
|
100
|
|
|
|
28
|
if (exists $opt{tempdir}) { |
133
|
1
|
|
|
|
|
1187
|
require File::Temp; |
134
|
1
|
|
|
|
|
31437
|
my $dir = File::Temp::tempdir('tmp_XXXX', CLEANUP => 1); |
135
|
1
|
50
|
|
|
|
541
|
if (ref $opt{tempdir}) { |
136
|
0
|
|
|
|
|
0
|
${$opt{tempdir}} = $dir; |
|
0
|
|
|
|
|
0
|
|
137
|
|
|
|
|
|
|
} else { |
138
|
1
|
50
|
|
|
|
15
|
chdir $dir or die "Can't cd to $dir: $!\n"; |
139
|
1
|
|
|
1
|
|
64
|
eval "END { chdir '..' }"; |
|
1
|
|
|
|
|
536
|
|
140
|
|
|
|
|
|
|
} |
141
|
|
|
|
|
|
|
} |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
# Query tests must produce the same result regardless of caching |
144
|
7
|
50
|
|
|
|
280
|
DBIx::DBO->config(CacheQuery => defined $ENV{DBO_CACHE_QUERY} ? $ENV{DBO_CACHE_QUERY} : int rand 2); |
145
|
|
|
|
|
|
|
|
146
|
7
|
50
|
|
|
|
32
|
if (exists $opt{try_connect}) { |
147
|
0
|
|
|
|
|
0
|
try_to_connect($opt{try_connect}); |
148
|
|
|
|
|
|
|
} |
149
|
|
|
|
|
|
|
|
150
|
7
|
100
|
66
|
|
|
72
|
note "DBD::$dbd ".${ $::DBD::{$dbd.'::'}{VERSION} } if exists $opt{try_connect} or exists $opt{connect_ok}; |
|
2
|
|
|
|
|
23
|
|
151
|
|
|
|
|
|
|
|
152
|
7
|
100
|
|
|
|
709
|
return unless exists $opt{tests}; |
153
|
|
|
|
|
|
|
|
154
|
6
|
100
|
|
|
|
63
|
if (exists $opt{connect_ok}) { |
155
|
2
|
50
|
|
|
|
4
|
my $dbo = connect_ok(@{$opt{connect_ok}}) or plan skip_all => "Can't connect: $DBI::errstr"; |
|
2
|
|
|
|
|
11
|
|
156
|
|
|
|
|
|
|
|
157
|
2
|
|
|
|
|
14
|
plan tests => $opt{tests}; |
158
|
2
|
|
|
|
|
462
|
pass "Connect to $dbd_name"; |
159
|
2
|
|
|
|
|
1027
|
isa_ok $dbo, 'DBIx::DBO', '$dbo'; |
160
|
|
|
|
|
|
|
} else { |
161
|
4
|
|
|
|
|
27
|
plan tests => $opt{tests}; |
162
|
|
|
|
|
|
|
} |
163
|
|
|
|
|
|
|
} |
164
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
sub sql_err { |
166
|
0
|
|
|
0
|
0
|
0
|
my $me = shift; |
167
|
0
|
|
|
|
|
0
|
my($cmd, $sql, @bind) = @{$me->config('LastSQL')}; |
|
0
|
|
|
|
|
0
|
|
168
|
0
|
|
|
|
|
0
|
$sql =~ s/^/ /mg; |
169
|
0
|
|
0
|
|
|
0
|
my @err = ($DBI::errstr || $me->rdbh->errstr || '???'); |
170
|
0
|
0
|
|
|
|
0
|
unshift @err, 'Bind Values: ('.join(', ', map $me->rdbh->quote($_), @bind).')' if @bind; |
171
|
0
|
|
|
|
|
0
|
unshift @err, "SQL command failed: $cmd", $sql.';'; |
172
|
0
|
|
|
|
|
0
|
$err[-1] =~ s/ at line \d+$//; |
173
|
0
|
|
|
|
|
0
|
join "\n", @err; |
174
|
|
|
|
|
|
|
} |
175
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
sub connect_dbo { |
177
|
2
|
|
|
2
|
0
|
4
|
my($dsn, $user, $pass) = @_; |
178
|
2
|
50
|
|
|
|
8
|
defined $dsn or $dsn = ''; |
179
|
2
|
|
|
|
|
22
|
DBIx::DBO->connect("DBI:$dbd:$dsn", $user, $pass, {RaiseError => 0}); |
180
|
|
|
|
|
|
|
} |
181
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
sub try_to_connect { |
183
|
2
|
|
|
2
|
0
|
5
|
my $dbo_ref = shift; |
184
|
2
|
|
|
|
|
19
|
my @env = map $ENV{"DBO_TEST_\U$dbd\E_$_"}, qw(DSN USER PASS); |
185
|
2
|
50
|
|
|
|
14
|
if (grep defined, @env) { |
186
|
0
|
0
|
|
|
|
0
|
return $$dbo_ref if $$dbo_ref = connect_dbo(@env); |
187
|
0
|
|
|
|
|
0
|
plan skip_all => "Can't connect: $DBI::errstr"; |
188
|
|
|
|
|
|
|
} |
189
|
2
|
|
|
|
|
20
|
return undef; |
190
|
|
|
|
|
|
|
} |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
sub connect_ok { |
193
|
2
|
|
|
2
|
0
|
7
|
my $dbo_ref = shift; |
194
|
2
|
|
33
|
|
|
10
|
return try_to_connect($dbo_ref) || ($$dbo_ref = connect_dbo(@_)); |
195
|
|
|
|
|
|
|
} |
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
sub basic_methods { |
198
|
1
|
|
|
1
|
0
|
18
|
my $dbo = shift; |
199
|
|
|
|
|
|
|
|
200
|
1
|
|
|
|
|
13
|
note 'Testing with: CacheQuery => '.DBIx::DBO->config('CacheQuery'); |
201
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
# Create a DBO from DBI handles |
203
|
1
|
|
|
|
|
403
|
isa_ok(DBIx::DBO->new($dbo->{dbh}, $dbo->{rdbh}), 'DBIx::DBO', 'Method DBIx::DBO->new, $dbo'); |
204
|
|
|
|
|
|
|
|
205
|
1
|
|
|
|
|
589
|
my $quoted_table = $dbo->{dbd_class}->_qi($dbo, $test_sch, $test_tbl); |
206
|
1
|
|
|
|
|
81
|
my @quoted_cols = map $dbo->{dbd_class}->_qi($dbo, $_), qw(type id name); |
207
|
1
|
|
|
|
|
22
|
my $t; |
208
|
1
|
50
|
50
|
|
|
21
|
my $create_table = "CREATE TABLE $quoted_table ($quoted_cols[1] ". |
209
|
|
|
|
|
|
|
($can{auto_increment_id} || 'INT NOT NULL').", $quoted_cols[2] VARCHAR(20)". |
210
|
|
|
|
|
|
|
($can{auto_increment_id} ? '' : ", PRIMARY KEY ($quoted_cols[1])").')'; |
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
# Create a test table with a multi-column primary key |
213
|
1
|
50
|
|
|
|
10
|
if ($dbo->do("CREATE TABLE $quoted_table ($quoted_cols[2] VARCHAR(20), $quoted_cols[1] INT, $quoted_cols[0] VARCHAR(8), PRIMARY KEY ($quoted_cols[0], $quoted_cols[1]))")) { |
214
|
1
|
|
|
|
|
1158
|
pass 'Create the test table: '.$quoted_table; |
215
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
# Create a table object |
217
|
1
|
|
|
|
|
515
|
$t = $dbo->table([undef, $test_tbl]); |
218
|
1
|
|
|
|
|
9
|
isa_ok $t, 'DBIx::DBO::Table', '$t'; |
219
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
# Check the Primary Keys |
221
|
1
|
50
|
|
|
|
763
|
is_deeply $t->{PrimaryKeys}, ['type', 'id'], 'Check PrimaryKeys' |
222
|
|
|
|
|
|
|
or diag Test::DBO::Dump($t); |
223
|
|
|
|
|
|
|
|
224
|
|
|
|
|
|
|
# Recreate our test table |
225
|
1
|
50
|
33
|
|
|
649
|
$dbo->do("DROP TABLE $quoted_table") && $dbo->do($create_table) |
|
|
|
33
|
|
|
|
|
226
|
|
|
|
|
|
|
or diag sql_err($dbo) or die "Can't recreate the test table!\n"; |
227
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
# Remove the created table during cleanup |
229
|
1
|
|
|
|
|
400
|
todo_cleanup("DROP TABLE $quoted_table"); |
230
|
|
|
|
|
|
|
|
231
|
1
|
|
|
|
|
7
|
$dbo->{dbd_class}->_get_table_info($dbo, $t->{Schema}, $t->{Name}); |
232
|
1
|
|
|
|
|
9
|
$t = $t->new($dbo, [$test_sch, $test_tbl]); |
233
|
|
|
|
|
|
|
} |
234
|
|
|
|
|
|
|
else { |
235
|
0
|
|
|
|
|
0
|
diag sql_err($dbo); |
236
|
0
|
|
|
|
|
0
|
SKIP: { |
237
|
0
|
|
|
|
|
0
|
skip "Can't create a multi-column primary key", 1; |
238
|
|
|
|
|
|
|
} |
239
|
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
# Create the test table |
241
|
0
|
0
|
0
|
|
|
0
|
ok $dbo->do($create_table), 'Create the test table' |
242
|
|
|
|
|
|
|
or diag sql_err($dbo) or die "Can't create the test table!\n"; |
243
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
# Remove the created table during cleanup |
245
|
0
|
|
|
|
|
0
|
todo_cleanup("DROP TABLE $quoted_table"); |
246
|
|
|
|
|
|
|
|
247
|
|
|
|
|
|
|
# Create a table object |
248
|
0
|
|
|
|
|
0
|
$t = $dbo->table([$test_sch, $test_tbl]); |
249
|
0
|
|
|
|
|
0
|
isa_ok $t, 'DBIx::DBO::Table', '$t'; |
250
|
|
|
|
|
|
|
} |
251
|
1
|
50
|
|
|
|
5
|
die "Couldn't create the DBIx::DBO::Table object!" unless $t; |
252
|
|
|
|
|
|
|
|
253
|
1
|
|
|
|
|
6
|
is $t->dbo, $dbo, 'Method DBIx::DBO::Table->dbo'; |
254
|
|
|
|
|
|
|
|
255
|
1
|
|
|
|
|
525
|
pass 'Method DBIx::DBO->do'; |
256
|
|
|
|
|
|
|
|
257
|
1
|
|
|
|
|
373
|
ok my $table_info = $dbo->table_info([$test_sch, $test_tbl]), 'Method DBIx::DBO->table_info'; |
258
|
1
|
|
|
|
|
445
|
is $table_info, $dbo->table_info($quoted_table), 'Method DBIx::DBO->table_info (quoted)'; |
259
|
1
|
50
|
|
|
|
443
|
is $table_info, $dbo->table_info(defined $test_sch ? "$test_sch.$test_tbl" : $test_tbl), |
260
|
|
|
|
|
|
|
'Method DBIx::DBO->table_info (unquoted)'; |
261
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
# Insert data |
263
|
1
|
50
|
|
|
|
407
|
$dbo->do("INSERT INTO $quoted_table VALUES (1, 'John Doe')") or diag sql_err($dbo); |
264
|
1
|
50
|
|
|
|
211
|
$dbo->do("INSERT INTO $quoted_table VALUES (?, ?)", undef, 2, 'Jane Smith') or diag sql_err($dbo); |
265
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
# Check the DBO select* methods |
267
|
1
|
|
|
|
|
174
|
my $rv = []; |
268
|
1
|
50
|
|
|
|
8
|
@$rv = $dbo->selectrow_array("SELECT * FROM $quoted_table") or diag sql_err($dbo); |
269
|
1
|
|
|
|
|
83
|
is_deeply $rv, [1,'John Doe'], 'Method DBIx::DBO->selectrow_array'; |
270
|
|
|
|
|
|
|
|
271
|
1
|
50
|
|
|
|
665
|
$rv = $dbo->selectrow_arrayref("SELECT * FROM $quoted_table") or diag sql_err($dbo); |
272
|
1
|
|
|
|
|
88
|
is_deeply $rv, [1,'John Doe'], 'Method DBIx::DBO->selectrow_arrayref'; |
273
|
|
|
|
|
|
|
|
274
|
1
|
50
|
|
|
|
664
|
$rv = $dbo->selectall_arrayref("SELECT * FROM $quoted_table") or diag sql_err($dbo); |
275
|
1
|
|
|
|
|
105
|
is_deeply $rv, [[1,'John Doe'],[2,'Jane Smith']], 'Method DBIx::DBO->selectall_arrayref'; |
276
|
|
|
|
|
|
|
|
277
|
|
|
|
|
|
|
# Insert via table object |
278
|
1
|
50
|
|
|
|
1119
|
$rv = $t->insert(id => 3, name => 'Uncle Arnie') or diag sql_err($t); |
279
|
1
|
|
|
|
|
6
|
ok $rv, 'Method DBIx::DBO::Table->insert'; |
280
|
|
|
|
|
|
|
|
281
|
1
|
|
|
|
|
452
|
is_deeply [$t->columns], [qw(id name)], 'Method DBIx::DBO::Table->columns'; |
282
|
|
|
|
|
|
|
|
283
|
|
|
|
|
|
|
# Create a column object |
284
|
1
|
|
|
|
|
750
|
my $c = $t->column('id'); |
285
|
1
|
|
|
|
|
7
|
isa_ok $c, 'DBIx::DBO::Column', '$c'; |
286
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
# Fetch one value from the Table |
288
|
1
|
|
|
|
|
556
|
is $t->fetch_value($t ** 'name', id => 3), 'Uncle Arnie', 'Method DBIx::DBO::Table->fetch_value'; |
289
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
# Fetch one value from the Table |
291
|
1
|
|
|
|
|
438
|
is_deeply $t->fetch_hash(id => \3), {id=>3,name=>'Uncle Arnie'}, 'Method DBIx::DBO::Table->fetch_hash'; |
292
|
|
|
|
|
|
|
|
293
|
|
|
|
|
|
|
# Fetch one value from the Table |
294
|
1
|
|
|
|
|
870
|
my $r = $t->fetch_row(id => 3, name => \'NOT NULL'); |
295
|
1
|
|
|
|
|
5
|
is $r->{name}, 'Uncle Arnie', 'Method DBIx::DBO::Table->fetch_row'; |
296
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
# Fetch a column arrayref from the Table |
298
|
1
|
|
|
|
|
599
|
is_deeply $t->fetch_column($t ** 'name', id => 3), ['Uncle Arnie'], 'Method DBIx::DBO::Table->fetch_column'; |
299
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
# Advanced insert using a column object |
301
|
1
|
50
|
|
|
|
903
|
$rv = $t->insert($c => {FUNC => '4'}, name => 'NotUsed', name => \"'James Bond'") or diag sql_err($t); |
302
|
1
|
|
|
|
|
7
|
ok $rv, 'Method DBIx::DBO::Table->insert (complex values)'; |
303
|
1
|
|
|
|
|
459
|
is $t->fetch_value('name', id => 4), 'James Bond', 'Method DBIx::DBO::Table->insert (remove duplicate cols)'; |
304
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
# Delete via table object |
306
|
1
|
50
|
|
|
|
432
|
$rv = $t->delete(id => 3) or diag sql_err($t); |
307
|
1
|
|
|
|
|
189
|
is $rv, 1, 'Method DBIx::DBO::Table->delete'; |
308
|
|
|
|
|
|
|
|
309
|
1
|
50
|
|
|
|
417
|
if ($can{auto_increment_id}) { |
310
|
1
|
50
|
|
|
|
5
|
$t->insert(name => 'Vernon Lyon') or diag sql_err($t); |
311
|
|
|
|
|
|
|
} else { |
312
|
0
|
0
|
|
|
|
0
|
$t->insert(id => 5, name => 'Vernon Lyon') or diag sql_err($t); |
313
|
|
|
|
|
|
|
} |
314
|
|
|
|
|
|
|
|
315
|
1
|
50
|
|
|
|
7
|
SKIP: { |
316
|
1
|
|
|
|
|
3
|
skip "No auto-increment $quoted_cols[1] column", 1 unless $can{auto_increment_id}; |
317
|
1
|
50
|
|
|
|
6
|
is $t->last_insert_id, 5, 'Method DBIx::DBO::Table->last_insert_id' |
318
|
|
|
|
|
|
|
or $t->delete(name => 'Vernon Lyon'), $t->insert(id => 5, name => 'Vernon Lyon'); |
319
|
|
|
|
|
|
|
} |
320
|
|
|
|
|
|
|
|
321
|
1
|
|
|
|
|
463
|
my $bulk_data = $dbo->query($t)->arrayref({ Slice => {} }); |
322
|
|
|
|
|
|
|
SKIP: { |
323
|
1
|
50
|
|
|
|
304
|
unless ($can{truncate}) { |
|
1
|
|
|
|
|
6
|
|
324
|
1
|
50
|
|
|
|
7
|
$t->delete or diag sql_err($t); |
325
|
1
|
|
|
|
|
185
|
skip 'TRUNCATE TABLE is not supported', 1; |
326
|
|
|
|
|
|
|
} |
327
|
0
|
0
|
|
|
|
0
|
$t->truncate or diag sql_err($t); |
328
|
0
|
|
|
|
|
0
|
is $t->fetch_value('id'), undef, 'Method DBIx::DBO::Table->truncate'; |
329
|
|
|
|
|
|
|
} |
330
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
# Bulk insert |
332
|
1
|
50
|
|
|
|
457
|
$rv = $t->bulk_insert(rows => [map [@$_{qw(id name)}], @$bulk_data]) or diag sql_err($t); |
333
|
1
|
|
|
|
|
45
|
is $rv, 4, 'Method DBIx::DBO::Table->bulk_insert (ARRAY)'; |
334
|
1
|
50
|
|
|
|
472
|
$t->delete or diag sql_err($t); |
335
|
|
|
|
|
|
|
|
336
|
1
|
50
|
|
|
|
168
|
$rv = $t->bulk_insert(rows => \@$bulk_data) or diag sql_err($t); |
337
|
1
|
|
|
|
|
12
|
is $rv, 4, 'Method DBIx::DBO::Table->bulk_insert (HASH)'; |
338
|
1
|
50
|
|
|
|
2881
|
$t->delete or diag sql_err($t); |
339
|
|
|
|
|
|
|
|
340
|
1
|
50
|
|
|
|
1446
|
$rv = $t->bulk_insert(columns => [qw(name id)], rows => [map [@$_{qw(name id)}], @$bulk_data]) or diag sql_err($t); |
341
|
1
|
|
|
|
|
12
|
is $rv, 4, 'Method DBIx::DBO::Table->bulk_insert (ARRAY)'; |
342
|
1
|
50
|
|
|
|
848
|
$t->delete or diag sql_err($t); |
343
|
|
|
|
|
|
|
|
344
|
1
|
50
|
|
|
|
354
|
$rv = $t->bulk_insert(columns => [qw(name id)], rows => \@$bulk_data) or diag sql_err($t); |
345
|
1
|
|
|
|
|
8
|
is $rv, 4, 'Method DBIx::DBO::Table->bulk_insert (HASH)'; |
346
|
|
|
|
|
|
|
|
347
|
1
|
|
|
|
|
1024
|
return $t; |
348
|
|
|
|
|
|
|
} |
349
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
sub advanced_table_methods { |
351
|
1
|
|
|
1
|
0
|
9
|
my $dbo = shift; |
352
|
1
|
|
|
|
|
5
|
my $t = shift; |
353
|
|
|
|
|
|
|
|
354
|
1
|
50
|
|
|
|
11
|
SKIP: { |
355
|
1
|
|
|
|
|
4
|
skip "No test table for advanced table tests", 2 unless $t; |
356
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
# Advanced insert |
358
|
1
|
50
|
|
|
|
16
|
my $rv = $t->insert(id => { FUNC => '? + 3', VAL => 3 }, name => \"'Harry Harrelson'") or diag sql_err($t); |
359
|
1
|
|
|
|
|
11
|
ok $rv, 'Method DBIx::DBO::Table->insert (advanced)'; |
360
|
|
|
|
|
|
|
|
361
|
1
|
50
|
|
|
|
1107
|
$t->insert(id => 7, name => 'Amanda Huggenkiss') or diag sql_err($t); |
362
|
1
|
50
|
|
|
|
8
|
$t->insert(id => 8, name => undef) or diag sql_err($t); |
363
|
|
|
|
|
|
|
|
364
|
|
|
|
|
|
|
# Advanced delete |
365
|
1
|
50
|
|
|
|
9
|
$rv = $t->delete(id => \'NOT NULL', name => undef) or diag sql_err($t); |
366
|
1
|
|
|
|
|
321
|
ok $rv, 'Method DBIx::DBO::Table->delete (advanced)'; |
367
|
|
|
|
|
|
|
} |
368
|
|
|
|
|
|
|
} |
369
|
|
|
|
|
|
|
|
370
|
|
|
|
|
|
|
sub skip_advanced_table_methods { |
371
|
0
|
|
|
0
|
0
|
0
|
my $dbo = shift; |
372
|
0
|
|
|
|
|
0
|
my $t = shift; |
373
|
|
|
|
|
|
|
|
374
|
0
|
|
|
|
|
0
|
note "No advanced table tests for $dbd_name"; |
375
|
0
|
0
|
|
|
|
0
|
$t->insert(id => 6, name => 'Harry Harrelson') or diag sql_err($t); |
376
|
0
|
0
|
|
|
|
0
|
$t->insert(id => 7, name => 'Amanda Huggenkiss') or diag sql_err($t); |
377
|
|
|
|
|
|
|
} |
378
|
|
|
|
|
|
|
|
379
|
|
|
|
|
|
|
sub row_methods { |
380
|
1
|
|
|
1
|
0
|
969
|
my $dbo = shift; |
381
|
1
|
|
|
|
|
4
|
my $t = shift; |
382
|
|
|
|
|
|
|
|
383
|
1
|
|
|
|
|
9
|
my $r = DBIx::DBO::Row->new($dbo, $t->_from); |
384
|
1
|
|
|
|
|
9
|
isa_ok $r, 'DBIx::DBO::Row', '$r (using quoted table name)'; |
385
|
|
|
|
|
|
|
|
386
|
1
|
|
|
|
|
695
|
$r = $dbo->row([ @$t{qw(Schema Name)} ]); |
387
|
1
|
|
|
|
|
7
|
isa_ok $r, 'DBIx::DBO::Row', '$r (using table name array)'; |
388
|
|
|
|
|
|
|
|
389
|
1
|
|
|
|
|
632
|
$r = $dbo->row($t); |
390
|
1
|
|
|
|
|
5
|
isa_ok $r, 'DBIx::DBO::Row', '$r (using Table object)'; |
391
|
|
|
|
|
|
|
|
392
|
1
|
|
|
|
|
522
|
is $r->dbo, $dbo, 'Method DBIx::DBO::Row->dbo'; |
393
|
|
|
|
|
|
|
|
394
|
1
|
|
|
|
|
593
|
ok $r->is_empty, 'Method DBIx::DBO::Row->is_empty'; |
395
|
1
|
|
|
|
|
366
|
is_deeply [$r->columns], [qw(id name)], 'Method DBIx::DBO::Row->columns'; |
396
|
|
|
|
|
|
|
|
397
|
1
|
50
|
|
|
|
636
|
ok $r->load(id => [2, 3], name => 'Jane Smith'), 'Method DBIx::DBO::Row->load' or diag sql_err($r); |
398
|
1
|
|
|
|
|
442
|
is_deeply $$r->{array}, [ 2, 'Jane Smith' ], 'Row loaded correctly'; |
399
|
|
|
|
|
|
|
|
400
|
|
|
|
|
|
|
# Access methods |
401
|
1
|
|
|
|
|
588
|
is $r->[1], 'Jane Smith', 'Access row as an arrayref'; |
402
|
1
|
|
|
|
|
349
|
is $r->{name}, 'Jane Smith', 'Access row as a hashref'; |
403
|
1
|
|
|
|
|
354
|
is $r->value('name'), 'Jane Smith', 'Method DBIx::DBO::Row->value'; |
404
|
1
|
|
|
|
|
378
|
is $r->value($t->column('name')), 'Jane Smith', 'Method DBIx::DBO::Row->value (using Table->column)'; |
405
|
|
|
|
|
|
|
|
406
|
1
|
50
|
|
|
|
397
|
is $r->update(name => 'Someone Else'), 1, 'Method DBIx::DBO::Row->update' or diag sql_err($r); |
407
|
1
|
50
|
|
|
|
558
|
is_deeply \@$r, [ 2, 'Someone Else' ], 'Row updated correctly (internal)' or diag Test::DBO::Dump($r); |
408
|
1
|
50
|
|
|
|
653
|
$r->load(id => 2) or diag sql_err($r); |
409
|
1
|
50
|
|
|
|
8
|
is_deeply \@$r, [ 2, 'Someone Else' ], 'Row updated correctly (external)' or diag Test::DBO::Dump($r); |
410
|
|
|
|
|
|
|
|
411
|
1
|
50
|
|
|
|
954
|
$r->update(name => 'Nobody', $t ** 'name' => 'Anybody') or diag sql_err($r); |
412
|
1
|
50
|
|
|
|
3
|
is_deeply \@{$r->load(id => 2)}, [ 2, 'Anybody' ], 'Row update removes duplicates' or diag sql_err($r); |
|
1
|
|
|
|
|
5
|
|
413
|
|
|
|
|
|
|
|
414
|
|
|
|
|
|
|
# UPDATE the primary key and a complex expression, requiring a reload |
415
|
1
|
|
|
|
|
864
|
$r->config(OnRowUpdate => 'reload'); |
416
|
1
|
50
|
|
|
|
6
|
$r->update(id => 3, name => \"'Uncle Arnie'") or diag sql_err($r); |
417
|
1
|
50
|
33
|
|
|
8
|
ok !$r->is_empty, 'Row reloaded on update' or $r->load(id => [2, 3]) or diag sql_err($r); |
418
|
|
|
|
|
|
|
|
419
|
1
|
50
|
|
|
|
659
|
ok $r->delete, 'Method DBIx::DBO::Row->delete' or diag sql_err($r); |
420
|
1
|
|
|
|
|
659
|
$t->insert(id => 2, name => 'Jane Smith'); |
421
|
|
|
|
|
|
|
|
422
|
1
|
|
|
|
|
7
|
is $r->load(name => 'non-existent'), undef, 'Load non-existent row'; |
423
|
1
|
|
|
|
|
617
|
is_deeply $$r->{array}, undef, 'Row is empty again'; |
424
|
|
|
|
|
|
|
} |
425
|
|
|
|
|
|
|
|
426
|
|
|
|
|
|
|
sub query_methods { |
427
|
1
|
|
|
1
|
0
|
8
|
my $dbo = shift; |
428
|
1
|
|
|
|
|
3
|
my $t = shift; |
429
|
1
|
|
|
|
|
7
|
my $quoted_table = $t->_from; |
430
|
|
|
|
|
|
|
|
431
|
|
|
|
|
|
|
# Create a query object |
432
|
1
|
|
|
|
|
6
|
my $q = $dbo->query($t); |
433
|
1
|
|
|
|
|
7
|
isa_ok $q, 'DBIx::DBO::Query', '$q'; |
434
|
|
|
|
|
|
|
|
435
|
1
|
|
|
|
|
534
|
is $q->dbo, $dbo, 'Method DBIx::DBO::Query->dbo'; |
436
|
|
|
|
|
|
|
|
437
|
|
|
|
|
|
|
# Default sql = select everything |
438
|
1
|
|
|
|
|
427
|
is_deeply [$q->columns], [qw(id name)], 'Method DBIx::DBO::Query->columns'; |
439
|
1
|
|
|
|
|
658
|
my $sql = $q->sql; |
440
|
1
|
|
|
|
|
7
|
is $sql, "SELECT * FROM $quoted_table", 'Method DBIx::DBO::Query->sql'; |
441
|
|
|
|
|
|
|
|
442
|
|
|
|
|
|
|
# Sort the result |
443
|
1
|
|
|
|
|
360
|
$q->order_by('id'); |
444
|
1
|
|
|
|
|
6
|
pass 'Method DBIx::DBO::Query->order_by'; |
445
|
|
|
|
|
|
|
|
446
|
|
|
|
|
|
|
# Get a valid sth |
447
|
1
|
50
|
|
|
|
418
|
isa_ok $q->_sth, 'DBI::st', '$q->_sth' or diag "SQL command failed: _sth\n $q->{sql}\n".$q->rdbh->errstr; |
448
|
|
|
|
|
|
|
|
449
|
|
|
|
|
|
|
# Get a Row object |
450
|
1
|
|
|
|
|
673
|
my $r = $q->row; |
451
|
1
|
|
|
|
|
4
|
isa_ok $r, 'DBIx::DBO::Row', '$q->row'; |
452
|
1
|
|
|
|
|
440
|
my $r_str = "$r"; |
453
|
|
|
|
|
|
|
|
454
|
1
|
|
|
|
|
6
|
$q->config(Testing => 123); |
455
|
1
|
|
|
|
|
6
|
is $r->config('Testing'), 123, 'Row gets config from parent Query'; |
456
|
|
|
|
|
|
|
|
457
|
|
|
|
|
|
|
# Alter the SQL to ensure the row is detached and rebuilt |
458
|
1
|
|
|
|
|
490
|
$q->order_by('id'); |
459
|
1
|
|
|
|
|
5
|
$r = $q->row; |
460
|
1
|
|
|
|
|
9
|
isnt $r_str, "$r", 'Row rebuilds SQL and detaches when a ref still exists'; |
461
|
1
|
|
|
|
|
1335
|
$r_str = "$r"; |
462
|
|
|
|
|
|
|
|
463
|
|
|
|
|
|
|
# Remove the reference so that the row wont detach |
464
|
1
|
|
|
|
|
3
|
undef $r; |
465
|
|
|
|
|
|
|
|
466
|
|
|
|
|
|
|
# Fetch the first row |
467
|
1
|
|
|
|
|
5
|
$r = $q->fetch; |
468
|
1
|
|
|
|
|
75
|
ok $r->isa('DBIx::DBO::Row'), 'Method DBIx::DBO::Query->fetch'; |
469
|
1
|
|
|
|
|
528
|
is $r_str, "$r", 'Re-use the same row object'; |
470
|
1
|
|
|
|
|
397
|
is_deeply [$q->columns], [qw(id name)], 'Method DBIx::DBO::Query->columns (after fetch)'; |
471
|
|
|
|
|
|
|
|
472
|
|
|
|
|
|
|
# Fetch another row |
473
|
1
|
|
|
|
|
783
|
$r_str = "$r"; |
474
|
1
|
|
|
|
|
8
|
$r = $q->fetch; |
475
|
1
|
|
|
|
|
6
|
isnt $r_str, "$r", 'Row detaches during fetch when a ref still exists'; |
476
|
|
|
|
|
|
|
|
477
|
|
|
|
|
|
|
# Re-run the query |
478
|
1
|
50
|
|
|
|
1183
|
$q->run or diag sql_err($q); |
479
|
1
|
|
|
|
|
6
|
is $q->fetch->{name}, 'John Doe', 'Method DBIx::DBO::Query->run'; |
480
|
1
|
|
|
|
|
488
|
$q->finish; |
481
|
1
|
|
|
|
|
5
|
is $q->fetch->{name}, 'John Doe', 'Method DBIx::DBO::Query->finish'; |
482
|
|
|
|
|
|
|
|
483
|
|
|
|
|
|
|
# Count the number of rows |
484
|
1
|
|
|
|
|
690
|
1 while $q->fetch; |
485
|
1
|
|
|
|
|
6
|
is $q->rows, 6, 'Row count is 6'; |
486
|
|
|
|
|
|
|
|
487
|
|
|
|
|
|
|
# WHERE clause |
488
|
1
|
50
|
|
|
|
490
|
ok $q->where('name', 'LIKE', \"'%o%'"), 'Method DBIx::DBO::Query->where' or diag sql_err($q); |
489
|
|
|
|
|
|
|
|
490
|
|
|
|
|
|
|
# Parentheses |
491
|
1
|
|
|
|
|
430
|
$q->open_bracket('OR'); |
492
|
1
|
|
|
|
|
7
|
$q->where('name', 'LIKE', \"'%a%'"); |
493
|
1
|
|
|
|
|
4
|
$q->where('id', '!=', \1); |
494
|
1
|
|
|
|
|
4
|
$q->where('id', '=', undef); |
495
|
1
|
|
|
|
|
5
|
$q->open_bracket('AND'); |
496
|
1
|
|
|
|
|
6
|
$q->where('id', '<>', 12345); |
497
|
1
|
|
|
|
|
4
|
$q->where('id', '!=', undef); |
498
|
1
|
|
|
|
|
5
|
$q->where('id', 'NOT IN', [1,22,333]); |
499
|
1
|
|
|
|
|
6
|
$q->where('id', 'NOT BETWEEN', [123,456]); |
500
|
1
|
|
|
|
|
8
|
my $got = $q->col_arrayref({ Columns => [1] }); |
501
|
1
|
50
|
|
|
|
162
|
is_deeply $got, [4,5,6], 'Method DBIx::DBO::Query->open_bracket' or diag sql_err($q); |
502
|
|
|
|
|
|
|
|
503
|
1
|
|
|
|
|
918
|
$q->where('id', 'NOT IN', 4444); |
504
|
1
|
|
|
|
|
6
|
ok scalar(() = $q->sql =~ / NOT IN /g) == 1, 'Group multiple IN & NOT IN clauses together'; |
505
|
|
|
|
|
|
|
|
506
|
1
|
|
|
|
|
708
|
$q->order_by; |
507
|
1
|
50
|
|
|
|
10
|
is $q->update(id => { FUNC => '? + 10', COL => 'id' }), 3, 'Method DBIx::DBO::Query->update' or diag sql_err($q); |
508
|
1
|
|
|
|
|
517
|
$q->order_by('id'); |
509
|
|
|
|
|
|
|
|
510
|
1
|
|
|
|
|
5
|
my $old_sql = $q->sql; |
511
|
1
|
|
|
|
|
7
|
$q->unwhere('name'); |
512
|
1
|
|
|
|
|
6
|
is $q->sql, $old_sql, 'Method DBIx::DBO::Query->unwhere (before close_bracket)'; |
513
|
|
|
|
|
|
|
|
514
|
1
|
|
|
|
|
729
|
$q->close_bracket; |
515
|
1
|
|
|
|
|
6
|
$q->close_bracket; |
516
|
1
|
|
|
|
|
7
|
$q->unwhere('name'); |
517
|
1
|
|
|
|
|
8
|
isnt $q->sql, $old_sql, 'Method DBIx::DBO::Query->close_bracket'; |
518
|
|
|
|
|
|
|
|
519
|
1
|
|
|
|
|
667
|
$got = $q->col_arrayref({ Columns => [1] }); |
520
|
1
|
|
|
|
|
157
|
is_deeply $got, [2,7,14,15,16], 'Method DBIx::DBO::Query->unwhere'; |
521
|
|
|
|
|
|
|
|
522
|
|
|
|
|
|
|
# Reset the Query |
523
|
1
|
|
|
|
|
824
|
$q->reset; |
524
|
1
|
|
|
|
|
5
|
is $q->sql, $dbo->query($t)->sql, 'Method DBIx::DBO::Query->reset'; |
525
|
|
|
|
|
|
|
|
526
|
|
|
|
|
|
|
# Group by the first initial |
527
|
1
|
|
|
|
|
445
|
$q->show(\'COUNT(*)'); |
528
|
1
|
50
|
|
|
|
7
|
ok(($q->group_by({FUNC => 'SUBSTR(?, 1, 1)', COL => 'name'}), $q->run), |
529
|
|
|
|
|
|
|
'Method DBIx::DBO::Query->group_by') or diag sql_err($q); |
530
|
|
|
|
|
|
|
|
531
|
|
|
|
|
|
|
# Update & Load a Row with aliased columns |
532
|
1
|
|
|
|
|
649
|
$q->show($t, {COL => 'id', AS => 'key'}); |
533
|
1
|
|
|
|
|
8
|
$q->group_by; |
534
|
1
|
|
|
|
|
6
|
is_deeply [$q->columns], [qw(id name key)], 'Method DBIx::DBO::Query->columns (with aliases)'; |
535
|
1
|
|
|
|
|
745
|
$r = $q->fetch; |
536
|
1
|
|
|
|
|
4
|
is_deeply [$q->columns], [qw(id name key)], 'Method DBIx::DBO::Query->columns (after fetch)'; |
537
|
1
|
50
|
|
|
|
710
|
ok $r->update(id => $r->{key}), 'Can update a Row despite using aliases' or diag sql_err($r); |
538
|
1
|
50
|
|
|
|
450
|
ok $r->load(id => 15), 'Can load a Row despite using aliases' or diag sql_err($r); |
539
|
|
|
|
|
|
|
|
540
|
1
|
|
|
|
|
431
|
isa_ok $q ** 'key', 'DBIx::DBO::Column', q{$q ** $alias}; |
541
|
|
|
|
|
|
|
|
542
|
|
|
|
|
|
|
# Limit & limit with Offset |
543
|
1
|
|
|
|
|
474
|
$q->show('id'); |
544
|
1
|
|
|
|
|
5
|
$q->order_by('id'); |
545
|
|
|
|
|
|
|
|
546
|
1
|
|
|
|
|
4
|
$q->limit(3); |
547
|
1
|
|
|
|
|
3
|
$got = []; |
548
|
1
|
|
|
|
|
8
|
for (my $row; $row = $q->fetch; push @$got, $row->[0]) {} |
549
|
1
|
|
|
|
|
7
|
is_deeply $got, [1,2,7], 'Method DBIx::DBO::Query->limit'; |
550
|
|
|
|
|
|
|
|
551
|
1
|
|
|
|
|
948
|
$q->limit(3, 2); |
552
|
1
|
|
|
|
|
3
|
$got = []; |
553
|
1
|
|
|
|
|
5
|
for (my $row; $row = $q->fetch; push @$got, $row->[0]) {} |
554
|
1
|
|
|
|
|
6
|
is_deeply $got, [7,14,15], 'Method DBIx::DBO::Query->limit (with offset)'; |
555
|
|
|
|
|
|
|
|
556
|
1
|
|
|
|
|
871
|
$q->finish; |
557
|
1
|
|
|
|
|
8
|
return $q; |
558
|
|
|
|
|
|
|
} |
559
|
|
|
|
|
|
|
|
560
|
|
|
|
|
|
|
sub advanced_query_methods { |
561
|
1
|
|
|
1
|
0
|
6
|
my $dbo = shift; |
562
|
1
|
|
|
|
|
3
|
my $t = shift; |
563
|
1
|
|
|
|
|
2
|
my $q = shift; |
564
|
1
|
|
|
|
|
8
|
$q->reset; |
565
|
|
|
|
|
|
|
|
566
|
|
|
|
|
|
|
# Show specific columns only |
567
|
1
|
50
|
|
|
|
6
|
SKIP: { |
568
|
1
|
|
|
|
|
2
|
skip 'COLLATE is not supported', 1 unless $can{collate}; |
569
|
1
|
|
|
|
|
8
|
$q->order_by({ COL => 'name', COLLATE => $can{collate} }); |
570
|
1
|
50
|
|
|
|
6
|
ok $q->run, 'Method DBIx::DBO::Query->order_by COLLATE' or diag sql_err($q); |
571
|
|
|
|
|
|
|
} |
572
|
1
|
|
|
|
|
459
|
$q->order_by('id'); |
573
|
1
|
|
|
|
|
7
|
$q->show({ FUNC => 'UPPER(?)', COL => 'name', AS => 'name' }, 'id', 'name'); |
574
|
1
|
50
|
33
|
|
|
5
|
ok $q->run && $q->fetch->{name} eq 'JOHN DOE', 'Method DBIx::DBO::Query->show' or diag sql_err($q); |
575
|
|
|
|
|
|
|
|
576
|
1
|
|
|
|
|
516
|
is $q->row->value($t ** 'name'), 'John Doe', 'Access specific column'; |
577
|
1
|
|
|
|
|
398
|
is_deeply [$q->row->columns], [qw(name id name)], 'Method DBIx::DBO::Row->columns (aliased)'; |
578
|
1
|
|
|
|
|
806
|
is_deeply [$q->columns], [qw(name id name)], 'Method DBIx::DBO::Query->columns (aliased)'; |
579
|
|
|
|
|
|
|
|
580
|
|
|
|
|
|
|
# Show whole tables |
581
|
1
|
|
|
|
|
577
|
$q->show({ FUNC => "'who?'", AS => 'name' }, $t); |
582
|
1
|
|
|
|
|
5
|
is $q->fetch->value($t ** 'name'), 'John Doe', 'Access specific column from a shown table'; |
583
|
|
|
|
|
|
|
|
584
|
|
|
|
|
|
|
# Check case sensitivity of LIKE |
585
|
1
|
50
|
|
|
|
478
|
my $case_sensitive = $dbo->selectrow_arrayref($case_sensitivity_sql, undef, 'a', 'A') or diag sql_err($dbo); |
586
|
1
|
|
|
|
|
97
|
$case_sensitive = not $case_sensitive->[0]; |
587
|
1
|
50
|
|
|
|
12
|
note "$dbd_name 'LIKE' is".($case_sensitive ? '' : ' NOT').' case sensitive'; |
588
|
|
|
|
|
|
|
|
589
|
|
|
|
|
|
|
# WHERE clause |
590
|
1
|
|
|
|
|
520
|
$q->show('id'); |
591
|
1
|
|
|
|
|
39
|
ok $q->where('name', 'LIKE', '%a%'), 'Method DBIx::DBO::Query->where LIKE'; |
592
|
1
|
50
|
|
|
|
682
|
my $a = $q->col_arrayref or diag sql_err($q); |
593
|
1
|
|
|
|
|
124
|
is_deeply $a, [2,7,14,16], 'Method DBIx::DBO::Query->col_arrayref'; |
594
|
1
|
|
|
|
|
779
|
ok $q->where('id', 'BETWEEN', [6, \16]), 'Method DBIx::DBO::Query->where BETWEEN'; |
595
|
1
|
50
|
|
|
|
445
|
$a = $q->arrayref or diag sql_err($q); |
596
|
1
|
|
|
|
|
227
|
is_deeply $a, [[7],[14],[16]], 'Method DBIx::DBO::Query->arrayref'; |
597
|
1
|
|
|
|
|
1072
|
ok $q->where('name', 'IN', ['Harry Harrelson', 'James Bond']), 'Method DBIx::DBO::Query->where IN'; |
598
|
1
|
50
|
|
|
|
385
|
$a = $q->hashref('id') or diag sql_err($q); |
599
|
1
|
|
|
|
|
364
|
is_deeply $a, {14 => {id => 14},16 => {id => 16}}, 'Method DBIx::DBO::Query->hashref'; |
600
|
|
|
|
|
|
|
|
601
|
|
|
|
|
|
|
# HAVING clause |
602
|
1
|
50
|
|
|
|
1143
|
my $concat = $dbd eq 'SQLite' ? '? || ?' : 'CONCAT(?, ?)'; |
603
|
1
|
|
|
|
|
6
|
my %concat_col = (FUNC => $concat, COL => [qw(id name)]); |
604
|
1
|
50
|
|
|
|
7
|
my $having_col = $dbo->{dbd_class}->_alias_preference($q, 'having') ? 'combo' : \%concat_col; |
605
|
1
|
|
|
|
|
10
|
$q->show('id', 'name', { %concat_col, AS => 'combo'}); |
606
|
1
|
|
|
|
|
8
|
$q->group_by('id', 'name'); |
607
|
1
|
|
|
|
|
5
|
$q->having($having_col, '=', '14James Bond'); |
608
|
1
|
|
|
|
|
3
|
$q->having($having_col, '=', 'ABC-XYZ'); |
609
|
1
|
|
|
|
|
5
|
$q->having($having_col, '=', 'XYZ-ABC'); |
610
|
1
|
|
|
|
|
2
|
is_deeply [@{$q->fetch}], [14, 'James Bond', '14James Bond'], 'Method DBIx::DBO::Query->having'; |
|
1
|
|
|
|
|
6
|
|
611
|
|
|
|
|
|
|
|
612
|
1
|
|
|
|
|
1043
|
$q->unhaving($having_col, '=', '14James Bond'); |
613
|
1
|
|
|
|
|
5
|
is $q->fetch, undef, 'Method DBIx::DBO::Query->unhaving'; |
614
|
1
|
|
|
|
|
770
|
$q->unhaving($having_col); |
615
|
1
|
|
|
|
|
1
|
is_deeply [@{$q->fetch}], [14, 'James Bond', '14James Bond'], 'Method DBIx::DBO::Query->unhaving (whole column)'; |
|
1
|
|
|
|
|
5
|
|
616
|
|
|
|
|
|
|
|
617
|
1
|
|
|
|
|
988
|
$q->finish; |
618
|
|
|
|
|
|
|
} |
619
|
|
|
|
|
|
|
|
620
|
|
|
|
|
|
|
sub skip_advanced_query_methods { |
621
|
0
|
|
|
0
|
0
|
0
|
note "No advanced query tests for $dbd_name"; |
622
|
|
|
|
|
|
|
} |
623
|
|
|
|
|
|
|
|
624
|
|
|
|
|
|
|
sub join_methods { |
625
|
1
|
|
|
1
|
0
|
8
|
my $dbo = shift; |
626
|
1
|
|
|
|
|
3
|
my $table = shift; |
627
|
|
|
|
|
|
|
|
628
|
1
|
|
|
|
|
7
|
my($q, $t1, $t2) = $dbo->query($table, $table); |
629
|
|
|
|
|
|
|
|
630
|
|
|
|
|
|
|
# DISTINCT clause |
631
|
1
|
|
|
|
|
5
|
$q->order_by('id'); |
632
|
1
|
|
|
|
|
4
|
$q->show('id'); |
633
|
1
|
|
|
|
|
7
|
$q->distinct(1); |
634
|
1
|
|
|
|
|
5
|
is_deeply $q->arrayref, [[1],[2],[7],[14],[15],[16]], 'Method DBIx::DBO::Query->distinct'; |
635
|
1
|
|
|
|
|
1739
|
$q->distinct(0); |
636
|
1
|
|
|
|
|
4
|
$q->show($t1, $t2); |
637
|
|
|
|
|
|
|
|
638
|
|
|
|
|
|
|
# Counting rows |
639
|
1
|
|
|
|
|
4
|
$q->limit(3); |
640
|
1
|
|
|
|
|
4
|
$q->config(CalcFoundRows => 1); |
641
|
1
|
|
|
|
|
6
|
ok $q, 'Comma JOIN'; |
642
|
1
|
50
|
|
|
|
420
|
is $q->count_rows, 3, 'Method DBIx::DBO::Query->count_rows' or diag sql_err($q); |
643
|
1
|
50
|
|
|
|
541
|
is $q->found_rows, 36, 'Method DBIx::DBO::Query->found_rows' or diag sql_err($q); |
644
|
|
|
|
|
|
|
|
645
|
|
|
|
|
|
|
# JOIN |
646
|
1
|
|
|
|
|
404
|
$q->join_on($t2, $t1 ** 'id', '=', { FUNC => '?/7.0', VAL => $t2 ** 'id' }); |
647
|
1
|
|
|
|
|
5
|
$q->order_by({ COL => $t1 ** 'name', ORDER => 'DESC' }); |
648
|
1
|
|
|
|
|
4
|
$q->where($t1 ** 'name', '<', $t2 ** 'name', FORCE => 'OR'); |
649
|
1
|
|
|
|
|
4
|
$q->where($t1 ** 'name', '>', $t2 ** 'name', FORCE => 'OR'); |
650
|
1
|
|
|
|
|
4
|
$q->where($t1 ** 'name', 'LIKE', '%'); |
651
|
1
|
|
|
|
|
3
|
my $r; |
652
|
|
|
|
|
|
|
# Oracle Can't do a SELECT * from a subquery that has "ambiguous" columns (two columns with the same name) |
653
|
1
|
50
|
|
|
|
4
|
$q->show() if $dbd eq 'Oracle'; |
654
|
1
|
0
|
33
|
|
|
6
|
SKIP: { |
|
|
|
33
|
|
|
|
|
655
|
1
|
|
|
|
|
3
|
$q->run or fail 'JOIN ON' or diag sql_err($q) or skip 'No Left Join', 1; |
656
|
1
|
50
|
33
|
|
|
8
|
$r = $q->fetch or fail 'JOIN ON' or skip 'No Left Join', 1; |
657
|
|
|
|
|
|
|
|
658
|
1
|
|
|
|
|
6
|
is_deeply \@$r, [ 1, 'John Doe', 7, 'Amanda Huggenkiss' ], 'JOIN ON'; |
659
|
1
|
50
|
|
|
|
1067
|
$r->load($t1 ** id => 2) or diag sql_err($r); |
660
|
1
|
|
|
|
|
4
|
is_deeply \@$r, [ 2, 'Jane Smith', 14, 'James Bond' ], 'Method DBIx::DBO::Row->load'; |
661
|
|
|
|
|
|
|
} |
662
|
|
|
|
|
|
|
|
663
|
|
|
|
|
|
|
# LEFT JOIN |
664
|
1
|
|
|
|
|
854
|
($q, $t1) = $dbo->query($table); |
665
|
|
|
|
|
|
|
# ... "t1" LEFT JOIN ... "t2" |
666
|
1
|
|
|
|
|
6
|
$t2 = $q->join_table($table, 'left'); |
667
|
|
|
|
|
|
|
# ... "t1" LEFT JOIN ... "t2" ON "t1"."id" = "t2"."id"/2.0 |
668
|
1
|
|
|
|
|
5
|
$q->join_on($t2, $t1 ** 'id', '=', { FUNC => '?/2.0', COL => $t2 ** 'id' }); |
669
|
1
|
|
|
|
|
8
|
ok $q->open_join_on_bracket($t2, 'OR'), 'Method DBIx::DBO::Query->open_join_on_bracket'; |
670
|
|
|
|
|
|
|
# ... "t1" LEFT JOIN ... "t2" ON "t1"."id" = "t2"."id"/2.0 AND 1 = 2 |
671
|
1
|
|
|
|
|
619
|
$q->join_on($t2, \1, '=', \2); |
672
|
|
|
|
|
|
|
# ... "t1" LEFT JOIN ... "t2" ON "t1"."id" = "t2"."id"/2.0 AND (1 = 2 OR 3 = 3) |
673
|
1
|
|
|
|
|
6
|
$q->join_on($t2, \3, '=', \3); |
674
|
1
|
|
|
|
|
7
|
ok $q->close_join_on_bracket($t2), 'Method DBIx::DBO::Query->close_join_on_bracket'; |
675
|
|
|
|
|
|
|
|
676
|
1
|
|
|
|
|
515
|
$q->order_by({ COL => $t1 ** 'name', ORDER => 'DESC' }); |
677
|
1
|
|
|
|
|
6
|
$q->limit(1, 3); |
678
|
|
|
|
|
|
|
|
679
|
1
|
0
|
33
|
|
|
9
|
SKIP: { |
|
|
|
33
|
|
|
|
|
680
|
1
|
|
|
|
|
1
|
$q->_sth or diag sql_err($q) or fail 'LEFT JOIN' or skip 'No Left Join', 3; |
681
|
1
|
50
|
33
|
|
|
179
|
$r = $q->fetch or fail 'LEFT JOIN' or skip 'No Left Join', 3; |
682
|
|
|
|
|
|
|
|
683
|
1
|
|
|
|
|
5
|
is_deeply [@$r[0..3]], [14, 'James Bond', undef, undef], 'LEFT JOIN'; |
684
|
1
|
|
|
|
|
904
|
is $r->_column_idx($t2 ** 'id'), 2, 'Method DBIx::DBO::Row->_column_idx'; |
685
|
1
|
|
|
|
|
380
|
is $r->value($t2 ** 'id'), undef, 'Method DBIx::DBO::Row->value'; |
686
|
|
|
|
|
|
|
|
687
|
|
|
|
|
|
|
# Update the LEFT JOINed row |
688
|
1
|
50
|
|
|
|
11
|
SKIP: { |
689
|
1
|
|
|
|
|
383
|
skip "Multi-table UPDATE is not supported by $dbd_name", 1 unless $can{multi_table_update}; |
690
|
0
|
0
|
|
|
|
0
|
ok $r->update($t1 ** 'name' => 'Vernon Wayne Lyon'), 'Method DBIx::DBO::Row->update' or diag sql_err($r); |
691
|
|
|
|
|
|
|
} |
692
|
|
|
|
|
|
|
} |
693
|
|
|
|
|
|
|
|
694
|
1
|
|
|
|
|
306
|
$q->finish; |
695
|
|
|
|
|
|
|
} |
696
|
|
|
|
|
|
|
|
697
|
|
|
|
|
|
|
sub todo_cleanup { |
698
|
1
|
|
|
1
|
0
|
3
|
my $sql = shift; |
699
|
1
|
|
|
|
|
5
|
unshift @_cleanup_sql, $sql; |
700
|
|
|
|
|
|
|
} |
701
|
|
|
|
|
|
|
|
702
|
|
|
|
|
|
|
sub cleanup { |
703
|
1
|
|
|
1
|
0
|
7
|
my $dbo = shift; |
704
|
|
|
|
|
|
|
|
705
|
1
|
|
|
|
|
5
|
note 'Doing cleanup'; |
706
|
1
|
|
|
|
|
197
|
for my $sql (@_cleanup_sql) { |
707
|
1
|
50
|
|
|
|
6
|
$dbo->do($sql) or diag sql_err($dbo); |
708
|
|
|
|
|
|
|
} |
709
|
|
|
|
|
|
|
|
710
|
1
|
|
|
|
|
453
|
$dbo->disconnect; |
711
|
1
|
|
33
|
|
|
11
|
ok !defined $dbo->{dbh} && !defined $dbo->{rdbh}, 'Method DBIx::DBO->disconnect'; |
712
|
|
|
|
|
|
|
} |
713
|
|
|
|
|
|
|
|
714
|
|
|
|
|
|
|
sub Dump { |
715
|
0
|
|
|
0
|
0
|
0
|
my($val, $var) = @_; |
716
|
0
|
0
|
0
|
|
|
0
|
if (blessed $val and !defined $var) { |
717
|
0
|
0
|
|
|
|
0
|
if ($val->isa('DBIx::DBO')) { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
718
|
0
|
|
|
|
|
0
|
$var = 'dbo'; |
719
|
|
|
|
|
|
|
} elsif ($val->isa('DBIx::DBO::Table')) { |
720
|
0
|
|
|
|
|
0
|
$var = 't'; |
721
|
|
|
|
|
|
|
} elsif ($val->isa('DBIx::DBO::Query')) { |
722
|
0
|
|
|
|
|
0
|
$var = 'q'; |
723
|
|
|
|
|
|
|
} elsif ($val->isa('DBIx::DBO::Row')) { |
724
|
0
|
|
|
|
|
0
|
$var = 'r'; |
725
|
|
|
|
|
|
|
} |
726
|
|
|
|
|
|
|
} |
727
|
0
|
0
|
|
|
|
0
|
$var = 'dump' unless defined $var; |
728
|
0
|
|
|
|
|
0
|
require Data::Dumper; |
729
|
0
|
|
|
|
|
0
|
local $Data::Dumper::Sortkeys = 1; |
730
|
0
|
|
|
|
|
0
|
local $Data::Dumper::Quotekeys = 0; |
731
|
0
|
|
|
|
|
0
|
my $d = Data::Dumper->new([$val], [$var]); |
732
|
0
|
0
|
|
|
|
0
|
if (ref $val) { |
733
|
0
|
|
|
|
|
0
|
my %seen; |
734
|
0
|
|
|
|
|
0
|
my @_no_recursion = ($val); |
735
|
0
|
0
|
|
|
|
0
|
if (reftype $val eq 'ARRAY') { _Find_Seen(\%seen, \@_no_recursion, $_) for @$val } |
|
0
|
0
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
|
736
|
0
|
|
|
|
|
0
|
elsif (reftype $val eq 'HASH') { _Find_Seen(\%seen, \@_no_recursion, $_) for values %$val } |
737
|
0
|
|
|
|
|
0
|
elsif (reftype $val eq 'REF') { _Find_Seen(\%seen, \@_no_recursion, $$val) } |
738
|
0
|
|
|
|
|
0
|
$d->Seen(\%seen); |
739
|
|
|
|
|
|
|
} |
740
|
0
|
0
|
|
|
|
0
|
defined wantarray ? return $d->Dump : print $d->Dump; |
741
|
|
|
|
|
|
|
} |
742
|
|
|
|
|
|
|
|
743
|
|
|
|
|
|
|
sub _Find_Seen { |
744
|
0
|
|
|
0
|
|
0
|
my($seen, $_no_recursion, $val) = @_; |
745
|
0
|
0
|
|
|
|
0
|
return unless ref $val; |
746
|
0
|
|
|
|
|
0
|
for (@$_no_recursion) { |
747
|
0
|
0
|
|
|
|
0
|
return if $val == $_; |
748
|
|
|
|
|
|
|
} |
749
|
0
|
|
|
|
|
0
|
push @$_no_recursion, $val; |
750
|
|
|
|
|
|
|
|
751
|
0
|
0
|
|
|
|
0
|
if (blessed $val) { |
752
|
0
|
0
|
|
|
|
0
|
if ($val->isa('DBIx::DBO')) { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
753
|
0
|
|
|
|
|
0
|
$seen->{dbo} = $val; |
754
|
0
|
|
|
|
|
0
|
return; |
755
|
|
|
|
|
|
|
} elsif ($val->isa('DBIx::DBO::Table')) { |
756
|
0
|
|
|
|
|
0
|
my $t = 1; |
757
|
0
|
|
|
|
|
0
|
while (my($k, $v) = each %$seen) { |
758
|
0
|
0
|
|
|
|
0
|
next if $k !~ /^t\d+$/; |
759
|
0
|
0
|
|
|
|
0
|
return if $val == $v; |
760
|
0
|
|
|
|
|
0
|
$t++; |
761
|
|
|
|
|
|
|
} |
762
|
0
|
|
|
|
|
0
|
$seen->{"t$t"} = $val; |
763
|
0
|
|
|
|
|
0
|
return; |
764
|
|
|
|
|
|
|
} elsif ($val->isa('DBIx::DBO::Query')) { |
765
|
0
|
|
|
|
|
0
|
$seen->{q} = $val; |
766
|
0
|
|
|
|
|
0
|
return; |
767
|
|
|
|
|
|
|
} elsif ($val->isa('DBIx::DBO::Row')) { |
768
|
0
|
|
|
|
|
0
|
$seen->{r} = $val; |
769
|
0
|
|
|
|
|
0
|
return; |
770
|
|
|
|
|
|
|
} |
771
|
|
|
|
|
|
|
} |
772
|
0
|
0
|
|
|
|
0
|
if (reftype $val eq 'ARRAY') { _Find_Seen($seen, $_no_recursion, $_) for @$val } |
|
0
|
0
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
|
773
|
0
|
|
|
|
|
0
|
elsif (reftype $val eq 'HASH') { _Find_Seen($seen, $_no_recursion, $_) for values %$val } |
774
|
0
|
|
|
|
|
0
|
elsif (reftype $val eq 'REF') { _Find_Seen($seen, $_no_recursion, $$val) } |
775
|
|
|
|
|
|
|
} |
776
|
|
|
|
|
|
|
|
777
|
|
|
|
|
|
|
# When testing via Sponge, use fake tables |
778
|
|
|
|
|
|
|
package # Hide from PAUSE |
779
|
|
|
|
|
|
|
DBIx::DBO::DBD::Sponge; |
780
|
|
|
|
|
|
|
sub _get_table_schema { |
781
|
11
|
|
|
11
|
|
26
|
return; |
782
|
|
|
|
|
|
|
} |
783
|
|
|
|
|
|
|
my $fake_table_info = { |
784
|
|
|
|
|
|
|
PrimaryKeys => [], |
785
|
|
|
|
|
|
|
Columns => [ 'id', 'name', 'age' ], |
786
|
|
|
|
|
|
|
Column_Idx => { id => 1, name => 2, age => 3 }, |
787
|
|
|
|
|
|
|
}; |
788
|
|
|
|
|
|
|
sub _get_table_info { |
789
|
5
|
|
|
5
|
|
13
|
my($class, $me, $schema, $table) = @_; |
790
|
5
|
100
|
|
|
|
38
|
return $class->SUPER::_get_table_info($me, $schema, $table) if $table ne $Test::DBO::test_tbl; |
791
|
|
|
|
|
|
|
# Fake table info |
792
|
4
|
|
33
|
|
|
39
|
return $me->{TableInfo}{''}{$table} ||= $fake_table_info; |
793
|
|
|
|
|
|
|
} |
794
|
|
|
|
|
|
|
|
795
|
|
|
|
|
|
|
# When testing via MySponge, fake table contents |
796
|
|
|
|
|
|
|
package # Hide from PAUSE |
797
|
|
|
|
|
|
|
MySponge::db; |
798
|
|
|
|
|
|
|
@MySponge::ISA = ('DBI'); |
799
|
|
|
|
|
|
|
@MySponge::db::ISA = ('DBI::db'); |
800
|
|
|
|
|
|
|
@MySponge::st::ISA = ('DBI::st'); |
801
|
|
|
|
|
|
|
my @cols; |
802
|
|
|
|
|
|
|
my @rows; |
803
|
|
|
|
|
|
|
sub setup { |
804
|
3
|
|
|
3
|
|
23
|
@cols = @{shift()}; |
|
3
|
|
|
|
|
13
|
|
805
|
3
|
|
|
|
|
11
|
@rows = @_; |
806
|
|
|
|
|
|
|
} |
807
|
|
|
|
|
|
|
sub prepare { |
808
|
6
|
|
|
6
|
|
39
|
my($dbh, $sql, $attr) = @_; |
809
|
6
|
|
50
|
|
|
29
|
$attr ||= {}; |
810
|
6
|
|
50
|
|
|
35
|
$attr->{NAME} ||= \@cols; |
811
|
6
|
|
50
|
|
|
29
|
$attr->{rows} ||= \@rows; |
812
|
6
|
|
|
|
|
80
|
$dbh->SUPER::prepare($sql, $attr); |
813
|
|
|
|
|
|
|
} |
814
|
|
|
|
|
|
|
|
815
|
|
|
|
|
|
|
1; |