add dbh_maker option to connect_info hash
[dbsrgits/DBIx-Class.git] / t / storage / base.t
1 use strict;
2 use warnings;  
3
4 use Test::More;
5 use lib qw(t/lib);
6 use DBICTest;
7 use Data::Dumper;
8
9 {
10     package DBICTest::ExplodingStorage::Sth;
11     use strict;
12     use warnings;
13
14     sub execute { die "Kablammo!" }
15
16     sub bind_param {}
17
18     package DBICTest::ExplodingStorage;
19     use strict;
20     use warnings;
21     use base 'DBIx::Class::Storage::DBI::SQLite';
22
23     my $count = 0;
24     sub sth {
25       my ($self, $sql) = @_;
26       return bless {},  "DBICTest::ExplodingStorage::Sth" unless $count++;
27       return $self->next::method($sql);
28     }
29
30     sub connected {
31       return 0 if $count == 1;
32       return shift->next::method(@_);
33     }
34 }
35
36 plan tests => 21;
37
38 my $schema = DBICTest->init_schema( sqlite_use_file => 1 );
39
40 is( ref($schema->storage), 'DBIx::Class::Storage::DBI::SQLite',
41     'Storage reblessed correctly into DBIx::Class::Storage::DBI::SQLite' );
42
43 my $storage = $schema->storage;
44 $storage->ensure_connected;
45
46 eval {
47     $schema->storage->throw_exception('test_exception_42');
48 };
49 like($@, qr/\btest_exception_42\b/, 'basic exception');
50
51 eval {
52     $schema->resultset('CD')->search_literal('broken +%$#$1')->all;
53 };
54 like($@, qr/prepare_cached failed/, 'exception via DBI->HandleError, etc');
55
56 bless $storage, "DBICTest::ExplodingStorage";
57 $schema->storage($storage);
58
59 eval { 
60     $schema->resultset('Artist')->create({ name => "Exploding Sheep" });
61 };
62
63 is($@, "", "Exploding \$sth->execute was caught");
64
65 is(1, $schema->resultset('Artist')->search({name => "Exploding Sheep" })->count,
66   "And the STH was retired");
67
68
69 # testing various invocations of connect_info ([ ... ])
70
71 my $coderef = sub { 42 };
72 my $invocations = {
73   'connect_info ([ $d, $u, $p, \%attr, \%extra_attr])' => {
74       args => [
75           'foo',
76           'bar',
77           undef,
78           {
79             on_connect_do => [qw/a b c/],
80             PrintError => 0,
81           },
82           {
83             AutoCommit => 1,
84             on_disconnect_do => [qw/d e f/],
85           },
86           {
87             unsafe => 1,
88             auto_savepoint => 1,
89           },
90         ],
91       dbi_connect_info => [
92           'foo',
93           'bar',
94           undef,
95           {
96             %{$storage->_default_dbi_connect_attributes || {} },
97             PrintError => 0,
98             AutoCommit => 1,
99           },
100       ],
101   },
102
103   'connect_info ([ \%code, \%extra_attr ])' => {
104       args => [
105           $coderef,
106           {
107             on_connect_do => [qw/a b c/],
108             PrintError => 0,
109             AutoCommit => 1,
110             on_disconnect_do => [qw/d e f/],
111           },
112           {
113             unsafe => 1,
114             auto_savepoint => 1,
115           },
116         ],
117       dbi_connect_info => [
118           $coderef,
119       ],
120   },
121
122   'connect_info ([ \%attr ])' => {
123       args => [
124           {
125             on_connect_do => [qw/a b c/],
126             PrintError => 1,
127             AutoCommit => 0,
128             on_disconnect_do => [qw/d e f/],
129             user => 'bar',
130             dsn => 'foo',
131           },
132           {
133             unsafe => 1,
134             auto_savepoint => 1,
135           },
136       ],
137       dbi_connect_info => [
138           'foo',
139           'bar',
140           undef,
141           {
142             %{$storage->_default_dbi_connect_attributes || {} },
143             PrintError => 1,
144             AutoCommit => 0,
145           },
146       ],
147   },
148   'connect_info ([ \%attr_with_coderef ])' => {
149       args => [ {
150         dbh_maker => $coderef,
151         on_connect_do => [qw/a b c/],
152         on_disconnect_do => [qw/d e f/],
153       } ],
154       dbi_connect_info => [
155         $coderef
156       ],
157   },
158 };
159
160 for my $type (keys %$invocations) {
161
162   # we can not use a cloner portably because of the coderef
163   # so compare dumps instead
164   local $Data::Dumper::Sortkeys = 1;
165   my $arg_dump = Dumper ($invocations->{$type}{args});
166
167   $storage->connect_info ($invocations->{$type}{args});
168
169   is ($arg_dump, Dumper ($invocations->{$type}{args}), "$type didn't modify passed arguments");
170
171
172   is_deeply ($storage->_dbi_connect_info, $invocations->{$type}{dbi_connect_info}, "$type produced correct _dbi_connect_info");
173   ok ( (not $storage->auto_savepoint and not $storage->unsafe), "$type correctly ignored extra hashref");
174
175   is_deeply (
176     [$storage->on_connect_do, $storage->on_disconnect_do ],
177     [ [qw/a b c/], [qw/d e f/] ],
178     "$type correctly parsed DBIC specific on_[dis]connect_do",
179   );
180 }
181
182 1;