File: 08special_ops.t

package info (click to toggle)
libsql-abstract-perl 2.000001-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 744 kB
  • sloc: perl: 3,443; makefile: 8
file content (106 lines) | stat: -rw-r--r-- 2,694 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
use strict;
use warnings;
use Test::More;

use SQL::Abstract::Test import => ['is_same_sql_bind'];

use SQL::Abstract;

my $sqlmaker = SQL::Abstract->new(special_ops => [

  # special op for MySql MATCH (field) AGAINST(word1, word2, ...)
  {regex => qr/^match$/i,
   handler => sub {
     my ($self, $field, $op, $arg) = @_;
     $arg = [$arg] if not ref $arg;
     my $label         = $self->_quote($field);
     my ($placeholder) = $self->_convert('?');
     my $placeholders  = join ", ", (($placeholder) x @$arg);
     my $sql           = $self->_sqlcase('match') . " ($label) "
                       . $self->_sqlcase('against') . " ($placeholders) ";
     my @bind = $self->_bindtype($field, @$arg);
     return ($sql, @bind);
     }
   },

  # special op for Basis+ NATIVE
  {regex => qr/^native$/i,
   handler => sub {
     my ($self, $field, $op, $arg) = @_;
     $arg =~ s/'/''/g;
     my $sql = "NATIVE (' $field $arg ')";
     return ($sql);
     }
   },

  # PRIOR op from DBIx::Class::SQLMaker::Oracle

  {
    regex => qr/^prior$/i,
    handler => sub {
      my ($self, $lhs, $op, $rhs) = @_;
      my ($sql, @bind) = $self->_recurse_where ($rhs);

      $sql = sprintf ('%s = %s %s ',
        $self->_convert($self->_quote($lhs)),
        $self->_sqlcase ($op),
        $sql
      );

      return ($sql, @bind);
    },
  },

], unary_ops => [
  # unary op from Mojo::Pg
  {regex => qr/^json$/i,
   handler => sub { '?', { json => $_[2] } }
  },
]);

my @tests = (

  #1
  { where => {foo => {-match => 'foo'},
              bar => {-match => [qw/foo bar/]}},
    stmt  => " WHERE ( MATCH (bar) AGAINST (?, ?) AND MATCH (foo) AGAINST (?) )",
    bind  => [qw/foo bar foo/],
  },

  #2
  { where => {foo => {-native => "PH IS 'bar'"}},
    stmt  => " WHERE ( NATIVE (' foo PH IS ''bar'' ') )",
    bind  => [],
  },

  #3
  { where => { foo => { -json => { bar => 'baz' } } },
    stmt => "WHERE foo = ?",
    bind => [ { json => { bar => 'baz' } } ],
  },

  #4
  { where => { foo => { '@>' => { -json => { bar => 'baz' } } } },
    stmt => "WHERE foo @> ?",
    bind => [ { json => { bar => 'baz' } } ],
  },

  # Verify inconsistent behaviour from DBIx::Class:SQLMaker::Oracle works
  # (unary use of special op is not equivalent to special op + =)
  {
    where => {
      foo_id => { '=' => { '-prior' => { -ident => 'bar_id' } } },
      baz_id => { '-prior' => { -ident => 'quux_id' } },
    },
    stmt        => ' WHERE ( baz_id = PRIOR quux_id AND foo_id = ( PRIOR bar_id ) )',
    bind        => [],
  },
);

for (@tests) {

  my($stmt, @bind) = $sqlmaker->where($_->{where}, $_->{order});
  is_same_sql_bind($stmt, \@bind, $_->{stmt}, $_->{bind});
}

done_testing;