Make sure Win32-like DBICTest checks are not tripped by repeated disconnects
[dbsrgits/DBIx-Class.git] / t / storage / base.t
CommitLineData
efe6365b 1use strict;
6b5e61af 2use warnings;
efe6365b 3
4use Test::More;
6b5e61af 5use Test::Warn;
f3d405dc 6use Test::Exception;
efe6365b 7use lib qw(t/lib);
8use DBICTest;
92fe2181 9use Data::Dumper;
efe6365b 10
fcf741b1 11my $schema = DBICTest->init_schema( sqlite_use_file => 1 );
efe6365b 12
13is( ref($schema->storage), 'DBIx::Class::Storage::DBI::SQLite',
14 'Storage reblessed correctly into DBIx::Class::Storage::DBI::SQLite' );
15
baa31d2f 16my $storage = $schema->storage;
17$storage->ensure_connected;
18
f3d405dc 19throws_ok {
19fb8520 20 $schema->storage->throw_exception('test_exception_42');
f3d405dc 21} qr/\btest_exception_42\b/, 'basic exception';
19fb8520 22
f3d405dc 23throws_ok {
19fb8520 24 $schema->resultset('CD')->search_literal('broken +%$#$1')->all;
f3d405dc 25} qr/prepare_cached failed/, 'exception via DBI->HandleError, etc';
19fb8520 26
9a0891be 27
97fc8d21 28# make sure repeated disconnection works
29{
30 my $fn = DBICTest->_sqlite_dbfilename;
31
32 lives_ok {
33 $schema->storage->ensure_connected;
34 my $dbh = $schema->storage->dbh;
35 $schema->storage->disconnect for 1,2;
36 unlink $fn;
37 $dbh->disconnect;
38 };
39
40 lives_ok {
41 $schema->storage->ensure_connected;
42 $schema->storage->disconnect for 1,2;
43 unlink $fn;
44 $schema->storage->disconnect for 1,2;
45 };
46
47 lives_ok {
48 $schema->storage->ensure_connected;
49 $schema->storage->_dbh->disconnect;
50 unlink $fn;
51 $schema->storage->disconnect for 1,2;
52 };
53}
54
55
92fe2181 56# testing various invocations of connect_info ([ ... ])
57
58my $coderef = sub { 42 };
59my $invocations = {
60 'connect_info ([ $d, $u, $p, \%attr, \%extra_attr])' => {
61 args => [
62 'foo',
63 'bar',
64 undef,
65 {
66 on_connect_do => [qw/a b c/],
67 PrintError => 0,
68 },
69 {
70 AutoCommit => 1,
71 on_disconnect_do => [qw/d e f/],
72 },
73 {
74 unsafe => 1,
75 auto_savepoint => 1,
76 },
77 ],
78 dbi_connect_info => [
79 'foo',
80 'bar',
81 undef,
82 {
3a4c1d89 83 %{$storage->_default_dbi_connect_attributes || {} },
92fe2181 84 PrintError => 0,
85 AutoCommit => 1,
86 },
87 ],
88 },
89
90 'connect_info ([ \%code, \%extra_attr ])' => {
91 args => [
92 $coderef,
93 {
94 on_connect_do => [qw/a b c/],
95 PrintError => 0,
96 AutoCommit => 1,
97 on_disconnect_do => [qw/d e f/],
98 },
99 {
100 unsafe => 1,
101 auto_savepoint => 1,
102 },
103 ],
104 dbi_connect_info => [
105 $coderef,
106 ],
107 },
108
109 'connect_info ([ \%attr ])' => {
110 args => [
111 {
112 on_connect_do => [qw/a b c/],
3a4c1d89 113 PrintError => 1,
114 AutoCommit => 0,
92fe2181 115 on_disconnect_do => [qw/d e f/],
116 user => 'bar',
117 dsn => 'foo',
118 },
119 {
120 unsafe => 1,
121 auto_savepoint => 1,
122 },
123 ],
124 dbi_connect_info => [
125 'foo',
126 'bar',
127 undef,
128 {
3a4c1d89 129 %{$storage->_default_dbi_connect_attributes || {} },
130 PrintError => 1,
131 AutoCommit => 0,
92fe2181 132 },
133 ],
6c925c72 134 warn => qr/\QYou provided explicit AutoCommit => 0 in your connection_info/,
92fe2181 135 },
8fd069b9 136 'connect_info ([ \%attr_with_coderef ])' => {
137 args => [ {
138 dbh_maker => $coderef,
6b5e61af 139 dsn => 'blah',
140 user => 'bleh',
8fd069b9 141 on_connect_do => [qw/a b c/],
142 on_disconnect_do => [qw/d e f/],
143 } ],
144 dbi_connect_info => [
145 $coderef
146 ],
6b5e61af 147 warn => qr/Attribute\(s\) 'dsn', 'user' in connect_info were ignored/,
8fd069b9 148 },
92fe2181 149};
150
151for my $type (keys %$invocations) {
eed5492f 152 local $ENV{DBIC_UNSAFE_AUTOCOMMIT_OK};
92fe2181 153
154 # we can not use a cloner portably because of the coderef
155 # so compare dumps instead
156 local $Data::Dumper::Sortkeys = 1;
157 my $arg_dump = Dumper ($invocations->{$type}{args});
158
6b5e61af 159 warnings_exist (
160 sub { $storage->connect_info ($invocations->{$type}{args}) },
eed5492f 161 $invocations->{$type}{warn} || [],
6b5e61af 162 'Warned about ignored attributes',
163 );
92fe2181 164
6b5e61af 165 is ($arg_dump, Dumper ($invocations->{$type}{args}), "$type didn't modify passed arguments");
92fe2181 166
167 is_deeply ($storage->_dbi_connect_info, $invocations->{$type}{dbi_connect_info}, "$type produced correct _dbi_connect_info");
168 ok ( (not $storage->auto_savepoint and not $storage->unsafe), "$type correctly ignored extra hashref");
169
170 is_deeply (
171 [$storage->on_connect_do, $storage->on_disconnect_do ],
172 [ [qw/a b c/], [qw/d e f/] ],
173 "$type correctly parsed DBIC specific on_[dis]connect_do",
174 );
175}
baa31d2f 176
d87929a4 177# make sure connection-less storages do not throw on _determine_driver
37b5ab51 178# but work with ENV at the same time
179SKIP: for my $env_dsn (undef, (DBICTest->_database)[0] ) {
180 skip 'Subtest relies on being connected to SQLite', 1
181 if $env_dsn and $env_dsn !~ /\:SQLite\:/;
444f799b 182
879ff8cb 183 local $ENV{DBI_DSN} = $env_dsn || '';
37b5ab51 184
185 my $s = DBICTest::Schema->connect();
d87929a4 186 is_deeply (
187 $s->storage->connect_info,
188 [],
37b5ab51 189 'Starting with no explicitly passed in connect info'
190 . ($env_dsn ? ' (with DBI_DSN)' : ''),
d87929a4 191 );
192
37b5ab51 193 my $sm = $s->storage->sql_maker;
194
879ff8cb 195 ok (! $s->storage->connected, 'Storage does not appear connected after SQLMaker instance is taken');
d87929a4 196
37b5ab51 197 if ($env_dsn) {
198 isa_ok($sm, 'DBIx::Class::SQLMaker');
d87929a4 199
37b5ab51 200 ok ( $s->storage->_driver_determined, 'Driver determined (with DBI_DSN)');
201 isa_ok ( $s->storage, 'DBIx::Class::Storage::DBI::SQLite' );
202 }
203 else {
204 isa_ok($sm, 'DBIx::Class::SQLMaker');
d87929a4 205
37b5ab51 206 ok (! $s->storage->_driver_determined, 'Driver undetermined');
207
208 throws_ok {
209 $s->storage->ensure_connected
210 } qr/You did not provide any connection_info/,
211 'sensible exception on empty conninfo connect';
212 }
d87929a4 213}
214
6b5e61af 215done_testing;