expand alias
[dbsrgits/SQL-Abstract.git] / t / 08special_ops.t
1 use strict;
2 use warnings;
3 use Test::More;
4
5 use SQL::Abstract::Test import => ['is_same_sql_bind'];
6
7 use SQL::Abstract;
8
9 my $sqlmaker = SQL::Abstract->new(special_ops => [
10
11   # special op for MySql MATCH (field) AGAINST(word1, word2, ...)
12   {regex => qr/^match$/i,
13    handler => sub {
14      my ($self, $field, $op, $arg) = @_;
15      $arg = [$arg] if not ref $arg;
16      my $label         = $self->_quote($field);
17      my ($placeholder) = $self->_convert('?');
18      my $placeholders  = join ", ", (($placeholder) x @$arg);
19      my $sql           = $self->_sqlcase('match') . " ($label) "
20                        . $self->_sqlcase('against') . " ($placeholders) ";
21      my @bind = $self->_bindtype($field, @$arg);
22      return ($sql, @bind);
23      }
24    },
25
26   # special op for Basis+ NATIVE
27   {regex => qr/^native$/i,
28    handler => sub {
29      my ($self, $field, $op, $arg) = @_;
30      $arg =~ s/'/''/g;
31      my $sql = "NATIVE (' $field $arg ')";
32      return ($sql);
33      }
34    },
35
36   # PRIOR op from DBIx::Class::SQLMaker::Oracle
37
38   {
39     regex => qr/^prior$/i,
40     handler => sub {
41       my ($self, $lhs, $op, $rhs) = @_;
42       my ($sql, @bind) = $self->_recurse_where ($rhs);
43
44       $sql = sprintf ('%s = %s %s ',
45         $self->_convert($self->_quote($lhs)),
46         $self->_sqlcase ($op),
47         $sql
48       );
49
50       return ($sql, @bind);
51     },
52   },
53
54 ], unary_ops => [
55   # unary op from Mojo::Pg
56   {regex => qr/^json$/i,
57    handler => sub { '?', { json => $_[2] } }
58   },
59 ]);
60
61 my @tests = (
62
63   #1
64   { where => {foo => {-match => 'foo'},
65               bar => {-match => [qw/foo bar/]}},
66     stmt  => " WHERE ( MATCH (bar) AGAINST (?, ?) AND MATCH (foo) AGAINST (?) )",
67     bind  => [qw/foo bar foo/],
68   },
69
70   #2
71   { where => {foo => {-native => "PH IS 'bar'"}},
72     stmt  => " WHERE ( NATIVE (' foo PH IS ''bar'' ') )",
73     bind  => [],
74   },
75
76   #3
77   { where => { foo => { -json => { bar => 'baz' } } },
78     stmt => "WHERE foo = ?",
79     bind => [ { json => { bar => 'baz' } } ],
80   },
81
82   #4
83   { where => { foo => { '@>' => { -json => { bar => 'baz' } } } },
84     stmt => "WHERE foo @> ?",
85     bind => [ { json => { bar => 'baz' } } ],
86   },
87
88   # Verify inconsistent behaviour from DBIx::Class:SQLMaker::Oracle works
89   # (unary use of special op is not equivalent to special op + =)
90   {
91     where => {
92       foo_id => { '=' => { '-prior' => { -ident => 'bar_id' } } },
93       baz_id => { '-prior' => { -ident => 'quux_id' } },
94     },
95     stmt        => ' WHERE ( baz_id = PRIOR quux_id AND foo_id = ( PRIOR bar_id ) )',
96     bind        => [],
97   },
98 );
99
100 for (@tests) {
101
102   my($stmt, @bind) = $sqlmaker->where($_->{where}, $_->{order});
103   is_same_sql_bind($stmt, \@bind, $_->{stmt}, $_->{bind});
104 }
105
106 done_testing;