Institute a central "load this first in testing" package
[dbsrgits/DBIx-Class.git] / t / search / stack_cond.t
1 BEGIN { do "./t/lib/ANFANG.pm" or die ( $@ || $! ) }
2
3 use strict;
4 use warnings;
5
6 use Test::More;
7
8 use DBICTest ':DiffSQL';
9 use SQL::Abstract qw(is_plain_value is_literal_value);
10 use List::Util 'shuffle';
11 use Data::Dumper;
12 $Data::Dumper::Terse = 1;
13 $Data::Dumper::Useqq = 1;
14 $Data::Dumper::Indent = 0;
15
16 my $schema = DBICTest->init_schema();
17
18 for my $c (
19   { cond => undef, sql => 'IS NULL' },
20   { cond => { -value => undef }, sql => 'IS NULL' },
21   { cond => \'foo', sql => '= foo' },
22   { cond => 'foo', sql => '= ?', bind => [
23     [ { dbic_colname => "title", sqlt_datatype => "varchar", sqlt_size => 100 } => 'foo' ],
24     [ { dbic_colname => "year", sqlt_datatype => "varchar", sqlt_size => 100 } => 'foo' ],
25   ]},
26   { cond => { -value => 'foo' }, sql => '= ?', bind => [
27     [ { dbic_colname => "title", sqlt_datatype => "varchar", sqlt_size => 100 } => 'foo' ],
28     [ { dbic_colname => "year", sqlt_datatype => "varchar", sqlt_size => 100 } => 'foo' ],
29   ]},
30   { cond => \[ '?', "foo" ], sql => '= ?', bind => [
31     [ {} => 'foo' ],
32     [ {} => 'foo' ],
33   ]},
34 ) {
35   my $rs = $schema->resultset('CD')->search({}, { columns => 'title' });
36
37   my $bare_cond = is_literal_value($c->{cond}) ? { '=', $c->{cond} } : $c->{cond};
38
39   my @query_steps = (
40     # these are monkey-wrenches, always there
41     { title => { '!=', [ -and => \'bar' ] }, year => { '!=', [ -and => 'bar' ] } },
42     { -or => [ genreid => undef, genreid => { '!=' => \42 } ] },
43     { -or => [ genreid => undef, genreid => { '!=' => \42 } ] },
44
45     { title => $bare_cond, year => { '=', $c->{cond} } },
46     { -and => [ year => $bare_cond, { title => { '=', $c->{cond} } } ] },
47     [ year => $bare_cond ],
48     [ title => $bare_cond ],
49     { -and => [ { year => { '=', $c->{cond} } }, { title => { '=', $c->{cond} } } ] },
50     { -and => { -or => { year => { '=', $c->{cond} } } }, -or => { title => $bare_cond } },
51   );
52
53   if (my $v = is_plain_value($c->{cond})) {
54     push @query_steps,
55       { year => $$v },
56       { title => $$v },
57       { -and => [ year => $$v, title => $$v ] },
58     ;
59   }
60
61   @query_steps = shuffle @query_steps;
62
63   $rs = $rs->search($_) for @query_steps;
64
65   my @bind = @{$c->{bind} || []};
66   {
67     no warnings 'misc';
68     splice @bind, 1, 0, [ { dbic_colname => "year", sqlt_datatype => "varchar", sqlt_size => 100 } => 'bar' ];
69   }
70
71   is_same_sql_bind (
72     $rs->as_query,
73     "(
74       SELECT me.title
75         FROM cd me
76       WHERE
77         ( genreid != 42 OR genreid IS NULL )
78           AND
79         ( genreid != 42 OR genreid IS NULL )
80           AND
81         title != bar
82           AND
83         title $c->{sql}
84           AND
85         year != ?
86           AND
87         year $c->{sql}
88     )",
89     \@bind,
90     'Double condition correctly collapsed for steps' . Dumper \@query_steps,
91   );
92 }
93
94 done_testing;