File Coverage

blib/lib/Class/ReluctantORM/SQL/Expression/Criterion.pm
Criterion Covered Total %
statement 27 53 50.9
branch 0 4 0.0
condition 0 2 0.0
subroutine 9 16 56.2
pod 5 5 100.0
total 41 80 51.2


line stmt bran cond sub pod time code
1             package Class::ReluctantORM::SQL::Expression::Criterion;
2              
3             =head1 NAME
4              
5             Class::ReluctantORM::SQL::Expression::Criterion - Represent WHERE and JOIN criteria
6              
7             =head1 SYNOPSIS
8              
9             # Save yourself some typing
10             use Class::ReluctantORM::SQL::Aliases;
11              
12             # This creates an "always true" criteria
13             my $crit = Criterion->new_tautology();
14              
15             # This creates '1=1'
16             my $crit1 = Criterion->new('=', 1, 1);
17              
18             # This creates 'my_column = ?'
19             my $crit2 = Criterion->new(
20             '=',
21             Column->new(column =>'my_column',
22             Param->new(),
23             );
24              
25             # Wrap $crit2 in NOT ( 'NOT my_column = ?' )
26             my $crit3 = Criterion->new('NOT', $crit2);
27              
28             # Make '(1=1) AND (NOT (my_column = ?))'
29             my $crit4 = Criterion->new('AND', $crit1, $crit3);
30              
31             # Make a where clause with this as its root
32             my $where = Where->new($crit4);
33              
34             # Or AND it to an existing one
35             $where2->and($crit4);
36              
37             # Dump a Criterion as a string (for diagnostics only - NOT RBMS safe)
38             my $str = $crit->pretty_print(); # Verbose
39             my $str = $crit->pretty_print(one_line => 1);
40              
41              
42             =head1 DESCRIPTION
43              
44             Represents a boolean-return predicate call, as needed in JOIN criteria and WHERE clauses.
45              
46             This is a specialized subclass of a FunctionCall.
47              
48             =cut
49              
50 1     1   4 use strict;
  1         1  
  1         25  
51 1     1   4 use warnings;
  1         1  
  1         19  
52              
53 1     1   4 use Data::Dumper;
  1         1  
  1         35  
54 1     1   4 use Class::ReluctantORM::Exception;
  1         1  
  1         18  
55 1     1   9 use Class::ReluctantORM::Utilities qw(install_method);
  1         2  
  1         43  
56             our $DEBUG = 0;
57              
58 1     1   5 use base 'Class::ReluctantORM::SQL::Expression::FunctionCall';
  1         2  
  1         657  
59              
60 1     1   8 use Class::ReluctantORM::SQL::Aliases;
  1         2  
  1         142  
61 1     1   7 use Class::ReluctantORM::SQL::Expression::Literal;
  1         2  
  1         11  
62 1     1   27 use Class::ReluctantORM::SQL::Expression;
  1         3  
  1         6  
63              
64              
65              
66              
67             =head1 CONSTRUCTORS
68              
69             =cut
70              
71             =head2 $crit = SQL::Expression::Criterion->new();
72              
73             =head2 $crit = SQL::Expression::Criterion->new($op_name, $exp1, [$exp2, ...]);
74              
75             =head2 $crit = SQL::Expression::Criterion->new($function, $exp1, [$exp2, ...]);
76              
77             Creates a new criterion.
78              
79             In the first form, returns an always true criterion.
80              
81             In the second and third form, creates a new criterion using the
82             specified operator and argument(s). An exception
83             will be thrown if the number of arguments does not
84             match the operator's arity.
85              
86             $op is a string name of a Function. Case is ignored.
87              
88             $expN is either a Class::ReluctantORM::SQL::Expression
89             subclass, or a plain scalar, or undef. Scalars and undefs will
90             be "autoboxed" into being Class::ReluctantORM::SQL::Expression::Literal
91             objects, with undefs becoming NULLs.
92              
93             =cut
94              
95             sub new {
96 0     0 1   my $class = shift;
97 0           my $op = shift;
98 0           my @args = @_;
99 0 0         unless ($op) {
100 0           return $class->new_tautology();
101             }
102              
103             # Otherwise use FunctionCall constructor
104 0           $class->SUPER::new($op, @args);
105              
106             }
107              
108             # clone() inherited from function call
109              
110             =head2 $crit = SQL::Expression::Criterion->new_tautology();
111              
112             Returns an 'always true' criterion.
113              
114             =cut
115              
116             sub new_tautology {
117 0     0 1   my $class = shift;
118 0           return $class->new('=', 1 , 1);
119             }
120              
121             =head1 ACCESSORS
122              
123             =cut
124              
125              
126             =head2 @args = $crit->arguments();
127              
128             Returns the arguments of the criterion.
129              
130             =cut
131              
132             # From FunctionCall
133              
134             =head2 @args = $crit->child_expressions();
135              
136             Returns the child nodes of this node (same as arguments()). Required by the Expression interface.
137              
138             =cut
139              
140             # From FunctionCall
141              
142             =head2 $bool = $arg->is_criterion();
143              
144             All objects of this class return true. The class adds this method to Expression, making all other subclasses of it return false.
145              
146             =cut
147              
148 0     0     install_method('Class::ReluctantORM::SQL::Expression', 'is_criterion', sub { return 0; });
149 0     0 1   sub is_criterion { return 1; }
150              
151             =head2 $bool = $crit->is_leaf_expression();
152              
153             Always returns false for this class. Required by the Expression interface.
154              
155             =cut
156              
157 0     0 1   sub is_leaf_expression { return 0; }
158              
159              
160             =head2 $func = $crit->function();
161              
162             Returns the Function that represents the operator.
163              
164             =cut
165              
166             # From FunctionCall
167              
168             =head2 $str = $crit->pretty_print();
169              
170             Renders a human-readable representation of the Criterion.
171              
172             =cut
173              
174             # From FunctionCall
175              
176             sub __pp_verbose {
177 0     0     my $self = shift;
178 0           my %args = @_;
179 0   0       my $prefix = $args{prefix} || '';
180 0           my $str = $prefix . "CRITERION '" . $self->function->name() . "'\n";
181 0           my @args = $self->arguments;
182 0           my $last_arg = pop @args;
183 0           foreach my $arg (@args) {
184 0           $str .= $arg->pretty_print(%args, prefix => $prefix . ' | ');
185             }
186 0           $str .= $last_arg->pretty_print(%args, prefix => $prefix . ' ` ');
187 0           return $str;
188             }
189              
190             =head2 $bool = $crit->is_equivalent($other_crit);
191              
192             Returns true if the two criteria are certainly equivalent (does not check table or column aliases).
193              
194             Returns false otherwise.
195              
196             =cut
197              
198             sub is_equivalent {
199 0     0 1   my $left = shift;
200 0           my $right = shift;
201              
202 0 0         unless ($right->is_criterion) { return 0; }
  0            
203 0           return $left->Class::ReluctantORM::SQL::Expression::FunctionCall::is_equivalent($right);
204             }
205              
206              
207              
208             =head1 AUTHOR
209              
210             Clinton Wolfe January 2009, January 2010
211              
212             =cut
213              
214             1;