Some test suite corrections ahead of next commits
[dbsrgits/DBIx-Class.git] / t / 99dbic_sqlt_parser.t
CommitLineData
c0329273 1BEGIN { do "./t/lib/ANFANG.pm" or die ( $@ || $! ) }
cb551b07 2use DBIx::Class::Optional::Dependencies -skip_all_without => 'deploy';
3
0e2c6809 4use strict;
5use warnings;
206d1995 6
8b60b921 7BEGIN { $ENV{DBICTEST_VIA_REPLICATED} = 0 }
8
0e2c6809 9use Test::More;
a07ae2aa 10use Test::Warn;
8fd10683 11use Test::Exception;
06e15b8e 12use Scalar::Util ();
0e2c6809 13
4bea1fe7 14use DBICTest;
052a832c 15use DBIx::Class::_Util 'sigwarn_silencer';
4bea1fe7 16
06e15b8e 17# Test for SQLT-related leaks
18{
19 my $s = DBICTest::Schema->clone;
48775dd1 20
21 my @schemas = (
22 create_schema ({ schema => $s }),
a07ae2aa 23 create_schema ({ args => { parser_args => { dbic_schema => $s } } }),
48775dd1 24 );
25
a07ae2aa 26 for my $parser_args_key (qw(
27 DBIx::Class::Schema
28 DBIx::Schema
29 package
30 )) {
31 warnings_exist {
32 push @schemas, create_schema({
33 args => { parser_args => { $parser_args_key => $s } }
34 });
569b96bb 35 } qr/\Qparser_args => {\E.+?is deprecated.+\Q@{[__FILE__]}/,
a07ae2aa 36 "deprecated crazy parser_arg '$parser_args_key' warned";
37 }
38
06e15b8e 39 Scalar::Util::weaken ($s);
40
41 ok (!$s, 'Schema not leaked');
02730621 42
48775dd1 43 isa_ok ($_, 'SQL::Translator::Schema', "SQLT schema object $_ produced")
44 for @schemas;
06e15b8e 45}
46
02730621 47# make sure classname-style works
48lives_ok { isa_ok (create_schema ({ schema => 'DBICTest::Schema' }), 'SQL::Translator::Schema', 'SQLT schema object produced') };
49
31399b48 50# make sure a connected instance passed via $args does not get the $dbh improperly serialized
51SKIP: {
52
461e818a 53 DBIx::Class::Optional::Dependencies->skip_without( 'YAML>=0' );
31399b48 54
55 lives_ok {
56
57 my $s = DBICTest->init_schema(no_populate => 1);
58 ok ($s->storage->connected, '$schema instance connected');
59
60 # roundtrip through YAML
61 my $yaml_rt_schema = SQL::Translator->new(
62 parser => 'SQL::Translator::Parser::YAML'
63 )->translate(
64 data => SQL::Translator->new(
569b96bb 65 parser_args => { dbic_schema => $s },
31399b48 66 parser => 'SQL::Translator::Parser::DBIx::Class',
67 producer => 'SQL::Translator::Producer::YAML',
68 )->translate
69 );
70
71 isa_ok ( $yaml_rt_schema, 'SQL::Translator::Schema', 'SQLT schema object produced after YAML roundtrip');
72
73 ok ($s->storage->connected, '$schema instance still connected');
74 }
75
76 eval <<'EOE' or die $@;
77 END {
052a832c 78 # we are in END - everything remains global
79 #
31399b48 80 $^W = 1; # important, otherwise DBI won't trip the next fail()
81 $SIG{__WARN__} = sub {
82 fail "Unexpected global destruction warning"
83 if $_[0] =~ /is not a DBI/;
84 warn @_;
85 };
86 }
87EOE
88
89}
06e15b8e 90
6ddb4ac0 91my $schema = DBICTest->init_schema( no_deploy => 1 );
92
0fc7cd47 93# Dummy was yanked out by the sqlt hook test
8e8a8d91 94# CustomSql tests the horrific/deprecated ->name(\$sql) hack
e0cd97a4 95# YearXXXXCDs are views
8e8a8d91 96#
97my @sources = grep
d6c322f8 98 { $_ !~ /^ (?: Dummy | CustomSql | Year\d{4}CDs ) $/x }
8e8a8d91 99 $schema->sources
100;
0fc7cd47 101
f0ac764e 102my $idx_exceptions = {
103 'Artwork' => -1,
104 'ForceForeign' => -1,
105 'LinerNotes' => -1,
827a808f 106 'TwoKeys' => -1, # TwoKeys has the index turned off on the rel def
f0ac764e 107};
108
c49ff507 109{
206d1995 110 my $sqlt_schema = create_schema({ schema => $schema, args => { parser_args => { } } });
0e2c6809 111
620df7e8 112 foreach my $source_name (@sources) {
113 my $table = get_table($sqlt_schema, $schema, $source_name);
0e2c6809 114
206d1995 115 my $fk_count = scalar(grep { $_->type eq 'FOREIGN KEY' } $table->get_constraints);
f0ac764e 116 $fk_count += $idx_exceptions->{$source_name} || 0;
206d1995 117 my @indices = $table->get_indices;
620df7e8 118
206d1995 119 my $index_count = scalar(@indices);
620df7e8 120 is($index_count, $fk_count, "correct number of indices for $source_name with no args");
c49ff507 121
620df7e8 122 for my $index (@indices) {
123 my $source = $schema->source($source_name);
3eaae0f2 124 my $pk_test = join("\x00", $source->primary_columns);
125 my $idx_test = join("\x00", $index->fields);
c1092055 126 isnt ( $pk_test, $idx_test, "no additional index for the primary columns exists in $source_name");
620df7e8 127 }
206d1995 128 }
0e2c6809 129}
130
c49ff507 131{
206d1995 132 my $sqlt_schema = create_schema({ schema => $schema, args => { parser_args => { add_fk_index => 1 } } });
0e2c6809 133
f0ac764e 134 foreach my $source_name (@sources) {
135 my $table = get_table($sqlt_schema, $schema, $source_name);
0e2c6809 136
206d1995 137 my $fk_count = scalar(grep { $_->type eq 'FOREIGN KEY' } $table->get_constraints);
f0ac764e 138 $fk_count += $idx_exceptions->{$source_name} || 0;
206d1995 139 my @indices = $table->get_indices;
140 my $index_count = scalar(@indices);
f0ac764e 141 is($index_count, $fk_count, "correct number of indices for $source_name with add_fk_index => 1");
206d1995 142 }
0e2c6809 143}
144
c49ff507 145{
206d1995 146 my $sqlt_schema = create_schema({ schema => $schema, args => { parser_args => { add_fk_index => 0 } } });
0e2c6809 147
206d1995 148 foreach my $source (@sources) {
149 my $table = get_table($sqlt_schema, $schema, $source);
0e2c6809 150
206d1995 151 my @indices = $table->get_indices;
152 my $index_count = scalar(@indices);
153 is($index_count, 0, "correct number of indices for $source with add_fk_index => 0");
154 }
0e2c6809 155}
156
c49ff507 157{
ab7e74aa 158 {
159 package # hide from PAUSE
160 DBICTest::Schema::NoViewDefinition;
161
162 use base qw/DBICTest::BaseResult/;
8f1617e2 163
ab7e74aa 164 __PACKAGE__->table_class('DBIx::Class::ResultSource::View');
165 __PACKAGE__->table('noviewdefinition');
8f1617e2 166
ab7e74aa 167 1;
8f1617e2 168 }
169
ab7e74aa 170 my $schema_invalid_view = $schema->clone;
171 $schema_invalid_view->register_class('NoViewDefinition', 'DBICTest::Schema::NoViewDefinition');
8f1617e2 172
8fd10683 173 throws_ok { create_schema({ schema => $schema_invalid_view }) }
174 qr/view noviewdefinition is missing a view_definition/,
175 'parser detects views with a view_definition';
8f1617e2 176}
177
a7f4b74c 178lives_ok (sub {
179 my $sqlt_schema = create_schema ({
180 schema => $schema,
181 args => {
182 parser_args => {
183 sources => ['CD']
184 },
185 },
186 });
187
188 is_deeply (
189 [$sqlt_schema->get_tables ],
190 ['cd'],
191 'sources limitng with relationships works',
192 );
193
194});
195
5b9ecfcc 196{
197 package DBICTest::PartialSchema;
198
4c905568 199 use base qw/DBICTest::BaseSchema/;
5b9ecfcc 200
201 __PACKAGE__->load_classes(
202 { 'DBICTest::Schema' => [qw/
203 CD
204 Track
205 Tag
206 Producer
207 CD_to_Producer
208 /]}
209 );
210}
211
212{
213 my $partial_schema = DBICTest::PartialSchema->connect(DBICTest->_database);
214
215 lives_ok (sub {
216 my $sqlt_schema = do {
217
052a832c 218 local $SIG{__WARN__} = sigwarn_silencer(
219 qr/Ignoring relationship .+ related resultsource .+ is not registered with this schema/
220 );
5b9ecfcc 221
222 create_schema({ schema => $partial_schema });
223 };
224
225 my @tables = $sqlt_schema->get_tables;
226
227 is_deeply (
228 [sort map { $_->name } @tables],
229 [qw/cd cd_to_producer producer tags track/],
230 'partial dbic schema parsing ok',
231 );
232
233 # the primary key is currently unnamed in sqlt - adding below
234 my %constraints_for_table = (
235 producer => [qw/prod_name /],
236 tags => [qw/tagid_cd tagid_cd_tag tags_fk_cd tags_tagid_tag tags_tagid_tag_cd /],
237 track => [qw/track_cd_position track_cd_title track_fk_cd /],
238 cd => [qw/cd_artist_title cd_fk_single_track /],
239 cd_to_producer => [qw/cd_to_producer_fk_cd cd_to_producer_fk_producer /],
240 );
241
242 for my $table (@tables) {
243 my $tablename = $table->name;
244 my @constraints = $table->get_constraints;
245 is_deeply (
246 [ sort map { $_->name } @constraints ],
247
248 # the primary key (present on all loaded tables) is currently named '' in sqlt
249 # subject to future changes
250 [ '', @{$constraints_for_table{$tablename}} ],
251
252 "constraints of table '$tablename' ok",
253 );
254 }
255 }, 'partial schema tests successful');
256}
257
0e14d918 258{
259 my $cd_rsrc = $schema->source('CD');
260 $cd_rsrc->name(\'main.cd');
261
262 my $sqlt_schema = create_schema(
263 { schema => $schema },
264 args => { ignore_constraint_names => 0, ignore_index_names => 0 }
265 );
266
267 foreach my $source_name (qw(CD)) {
268 my $table = get_table($sqlt_schema, $schema, $source_name);
269 ok(
270 !(grep {$_->name =~ m/main\./} $table->get_indices),
271 'indices have periods stripped out'
272 );
273 ok(
274 !(grep {$_->name =~ m/main\./} $table->get_constraints),
275 'constraints have periods stripped out'
276 );
277 }
278}
279
7f6f5b69 280done_testing;
281
0e2c6809 282sub create_schema {
206d1995 283 my $args = shift;
0e2c6809 284
206d1995 285 my $additional_sqltargs = $args->{args} || {};
0e2c6809 286
206d1995 287 my $sqltargs = {
8273e845 288 add_drop_table => 1,
206d1995 289 ignore_constraint_names => 1,
290 ignore_index_names => 1,
291 %{$additional_sqltargs}
292 };
0e2c6809 293
206d1995 294 my $sqlt = SQL::Translator->new( $sqltargs );
0e2c6809 295
206d1995 296 $sqlt->parser('SQL::Translator::Parser::DBIx::Class');
a07ae2aa 297 return $sqlt->translate(
298 $args->{schema} ? ( data => $args->{schema} ) : ()
299 ) || die $sqlt->error;
0e2c6809 300}
c2b7c5dc 301
302sub get_table {
303 my ($sqlt_schema, $schema, $source) = @_;
304
305 my $table_name = $schema->source($source)->from;
306 $table_name = $$table_name if ref $table_name;
307
308 return $sqlt_schema->get_table($table_name);
309}