File Coverage

blib/lib/SQL/Maker/SelectSet.pm
Criterion Covered Total %
statement 71 74 95.9
branch 9 16 56.2
condition 1 3 33.3
subroutine 17 17 100.0
pod 4 6 66.6
total 102 116 87.9


line stmt bran cond sub pod time code
1             use strict;
2 1     1   5214 use warnings;
  1         3  
  1         28  
3 1     1   7 use parent qw(Exporter);
  1         2  
  1         38  
4 1     1   6 use Scalar::Util ();
  1         2  
  1         5  
5 1     1   58 use Carp ();
  1         2  
  1         16  
6 1     1   4 use SQL::Maker::Util;
  1         1  
  1         26  
7 1     1   5 use Class::Accessor::Lite (
  1         4  
  1         25  
8             ro => [qw/new_line operator/],
9 1         16 );
10 1     1   5  
  1         1  
11             our @EXPORT_OK = qw(union union_all intersect intersect_all except except_all);
12              
13             # Functions
14             BEGIN {
15             for (qw/union union_all intersect intersect_all except except_all/) {
16 1     1   5 my $method = $_;
17 6         11 (my $operator = uc $_) =~ s/_/ /;
18 6         22  
19             no strict 'refs';
20 1     1   174 *{__PACKAGE__ . '::' . $method} = sub {
  1         2  
  1         104  
21 6         615 my $stmt = SQL::Maker::SelectSet->new(
22 33     33   20225 operator => $operator,
23             new_line => $_[0]->new_line,
24             );
25             $stmt->add_statement($_) for @_;
26 30         83 return $stmt;
27 30         102 };
28 6         28 }
29             }
30              
31             #
32             # Methods
33             #
34              
35             my $class = shift;
36             my %args = @_==1 ? %{$_[0]} : @_;
37 30     30 1 206 Carp::croak("Missing mandatory parameter 'operator' for SQL::Maker::SelectSet->new") unless exists $args{operator};
38 30 50       101  
  0         0  
39 30 50       77 my $set = bless {
40             new_line => qq{\n},
41 30         103 %args,
42             }, $class;
43              
44             return $set;
45             }
46 30         69  
47             my ($self, $statement) = @_;
48              
49             unless ( Scalar::Util::blessed($statement) and $statement->can('as_sql') ) {
50 60     60 1 104 Carp::croak( "'$statement' doesn't have 'as_sql' method.");
51             }
52 60 50 33     309 push @{$self->{statements}}, $statement;
53 0         0 return $self; # method chain
54             }
55 60         88  
  60         137  
56 60         107 my ($self) = @_;
57              
58             my @attrs = @{$self->{order_by}};
59             return '' unless @attrs;
60 3     3 0 13  
61             return 'ORDER BY '
62 3         4 . join(', ', map {
  3         9  
63 3 50       9 my ($col, $type) = @$_;
64             if (ref $col) {
65             $$col
66             } else {
67 3         8 $type ? $self->_quote($col) . " $type" : $self->_quote($col)
  3         9  
68 3 50       7 }
69 0         0 } @attrs);
70             }
71 3 50       11  
72             my ($self, $label) = @_;
73              
74             return $$label if ref $label eq 'SCALAR';
75             SQL::Maker::Util::quote_identifier($label, $self->{quote_char}, $self->{name_sep})
76             }
77 3     3   7  
78             my ($self) = @_;
79 3 50       9  
80             my $new_line = $self->new_line;
81 3         11 my $operator = $self->operator;
82              
83             my $sql = join(
84 36     36 1 122 $new_line . $operator . $new_line,
85             map { $_->as_sql } @{ $self->{statements} }
86 36         71 );
87 36         216 $sql .= ' ' . $self->as_sql_order_by() if $self->{order_by};
88             return $sql;
89             }
90              
91 36         195 my ($self) = @_;
  72         161  
  36         70  
92             my @binds;
93 36 100       115 for my $select ( @{ $self->{statements} } ) {
94 36         153 push @binds, $select->bind;
95             }
96             return @binds;
97             }
98 36     36 1 78  
99 36         51 my ($self, $col, $type) = @_;
100 36         47 push @{$self->{order_by}}, [$col, $type];
  36         72  
101 72         158 return $self;
102             }
103 36         203  
104             1;
105              
106             =head1 NAME
107 3     3 0 11  
108 3         5 SQL::Maker::SelectSet - provides set functions
  3         10  
109 3         7  
110             =head1 SYNOPSIS
111              
112             use SQL::Maker::SelectSet qw(union_all except);
113             my $s1 = SQL::Maker::Select ->new()
114             ->add_select('foo')
115             ->add_from('t1');
116             my $s2 = SQL::Maker::Select ->new()
117             ->add_select('bar')
118             ->add_from('t2');
119             union_all( $s1, $s2 )->as_sql;
120             # =>
121             # SQL::Maker::SelectSet->new_set(
122             # operator => 'UNION ALL',
123             # new_line => $s1->new_line
124             # )->add_statement($s1)
125             # ->add_statement($s2)
126             # ->as_sql;
127             # => "SELECT foo FROM t1 UNION ALL SELECT bar FROM t2"
128             except( $s1, $s2 )->as_sql;
129             # => SQL::Maker::SelectSet->new_set( operator => 'EXCEPT', new_line => $s1->new_line )
130             # ->add_statement( $s1 )
131             # ->add_statement( $s2 )
132             # ->as_sql;
133             # => "SELECT foo FROM t1 EXCEPT SELECT bar FROM t2"
134              
135             =head1 DESCRIPTION
136              
137             This module provides some set functions which return a SQL::Maker::SelectSet object
138             inherited from L<SQL::Maker::Select>.
139              
140             =head1 FUNCTION
141              
142             =over 4
143              
144             =item C<< union($select :SQL::Maker::Select | $set :SQL::Maker::SelectSet) : SQL::Maker::SelectSet >>
145              
146             Tow statements are combined by C<UNION>.
147              
148             =item C<< union_all($select :SQL::Maker::Select | $set :SQL::Maker::SelectSet) : SQL::Maker::SelectSet >>
149              
150             Tow statements are combined by C<UNION ALL>.
151              
152             =item C<< intersect($select :SQL::Maker::Select | $set :SQL::Maker::SelectSet) : SQL::Maker::SelectSet >>
153              
154             Tow statements are combined by C<INTERSECT>.
155              
156             =item C<< intersect_all($select :SQL::Maker::Select | $set :SQL::Maker::SelectSet) : SQL::Maker::SelectSet >>
157              
158             Tow statements are combined by C<INTERSECT ALL>.
159              
160             =item C<< except($select :SQL::Maker::Select | $set :SQL::Maker::SelectSet) : SQL::Maker::SelectSet >>
161              
162             Tow statements are combined by C<EXCEPT>.
163              
164             =item C<< except($select :SQL::Maker::Select | $set :SQL::Maker::SelectSet) : SQL::Maker::SelectSet >>
165              
166             Tow statements are combined by C<EXCEPT ALL>.
167              
168             =back
169              
170             =head1 Class Method
171              
172             =over 4
173              
174             =item my $stmt = SQL::Maker::SelectSet->new( %args )
175              
176             $opretaor is a set operator (ex. C<UNION>).
177             $one and $another are SQL::Maker::Select object or SQL::Maker::SelectSet object.
178             It returns a SQL::Maker::SelectSet object.
179              
180             The parameters are:
181              
182             =over 4
183              
184             =item $new_line
185              
186             Default values is "\n".
187              
188             =item $operator : Str
189              
190             The operator. This parameter is required.
191              
192             =back
193              
194             =back
195              
196             =head1 Instance Methods
197              
198             =over 4
199              
200             =item C<< my $sql = $set->as_sql() : Str >>
201              
202             Returns a new select statement.
203              
204             =item C<< my @binds = $set->bind() : Array[Str] >>
205              
206             Returns bind variables.
207              
208             =item C<< $set->add_statement($stmt : $stmt->can('as_sql')) : SQL::Maker::SelectSet >>
209              
210             This method adds new statement object. C<< $stmt >> must provides 'as_sql' method.
211              
212             I<Return Value> is the $set itself.
213              
214             =back
215              
216             =head1 SEE ALSO
217              
218             L<SQL::Maker::Select>
219