File Coverage

blib/lib/SQL/Wizard/Expr/Select.pm
Criterion Covered Total %
statement 70 71 98.5
branch 25 30 83.3
condition n/a
subroutine 18 18 100.0
pod 0 13 0.0
total 113 132 85.6


line stmt bran cond sub pod time code
1             package SQL::Wizard::Expr::Select;
2              
3 14     14   87 use strict;
  14         23  
  14         504  
4 14     14   61 use warnings;
  14         43  
  14         662  
5 14     14   8536 use Storable qw(dclone);
  14         64684  
  14         1161  
6 14     14   115 use parent 'SQL::Wizard::Expr';
  14         25  
  14         101  
7 14     14   10363 use SQL::Wizard::Expr::Compound;
  14         47  
  14         13136  
8              
9             sub new {
10 123     123 0 367 my ($class, %args) = @_;
11 123         581 $class->SUPER::new(%args);
12             }
13              
14             # Build a Select node from the standard -key => value API args.
15             # Accepts extra key/value pairs (e.g. _cte, _renderer) merged in.
16             sub from_args {
17 123     123 0 438 my ($class, %args) = @_;
18 123 50       421 Carp::confess("select requires -from") unless $args{'-from'};
19 123         187 my %node;
20 123 100       317 $node{distinct} = $args{'-distinct'} if $args{'-distinct'};
21 123 100       373 $node{columns} = $args{'-columns'} if $args{'-columns'};
22 123 50       384 $node{from} = $args{'-from'} if $args{'-from'};
23 123 100       326 $node{where} = $args{'-where'} if $args{'-where'};
24 123 100       286 $node{group_by} = $args{'-group_by'} if $args{'-group_by'};
25 123 100       293 $node{having} = $args{'-having'} if $args{'-having'};
26 123 100       286 $node{order_by} = $args{'-order_by'} if $args{'-order_by'};
27 123 100       302 $node{limit} = $args{'-limit'} if defined $args{'-limit'};
28 123 100       286 $node{offset} = $args{'-offset'} if defined $args{'-offset'};
29 123 100       286 $node{window} = $args{'-window'} if $args{'-window'};
30 123 100       299 $node{_cte} = $args{_cte} if $args{_cte};
31 123 50       348 $node{_renderer} = $args{_renderer} if $args{_renderer};
32 123         435 $class->new(%node);
33             }
34              
35             # Immutable modifiers — return cloned objects
36              
37             sub distinct {
38 1     1 0 8 my ($self) = @_;
39 1         186 my $clone = dclone($self);
40 1         5 $clone->{distinct} = 1;
41 1         8 return $clone;
42             }
43              
44             sub where {
45 2     2 0 2337 my ($self, $where) = @_;
46 2         253 my $clone = dclone($self);
47 2         7 $clone->{where} = $where;
48 2         5 return $clone;
49             }
50              
51             sub add_where {
52 2     2 0 1569 my ($self, $extra) = @_;
53 2         89 my $clone = dclone($self);
54 2 50       6 if ($clone->{where}) {
55 2         7 $clone->{where} = [-and => $clone->{where}, $extra];
56             } else {
57 0         0 $clone->{where} = $extra;
58             }
59 2         4 return $clone;
60             }
61              
62             sub columns {
63 1     1 0 3 my ($self, $cols) = @_;
64 1         70 my $clone = dclone($self);
65 1         3 $clone->{columns} = $cols;
66 1         3 return $clone;
67             }
68              
69             sub order_by {
70 2     2 0 1049 my ($self, @order) = @_;
71 2         95 my $clone = dclone($self);
72 2 50       10 $clone->{order_by} = @order == 1 ? $order[0] : \@order;
73 2         6 return $clone;
74             }
75              
76             sub limit {
77 3     3 0 1929 my ($self, $limit) = @_;
78 3         129 my $clone = dclone($self);
79 3         6 $clone->{limit} = $limit;
80 3         8 return $clone;
81             }
82              
83             sub offset {
84 2     2 0 4 my ($self, $offset) = @_;
85 2         43 my $clone = dclone($self);
86 2         4 $clone->{offset} = $offset;
87 2         4 return $clone;
88             }
89              
90             # Compound query methods
91              
92             sub union {
93 5     5 0 27 my ($self, $other) = @_;
94             SQL::Wizard::Expr::Compound->new(
95             queries => [{ type => undef, query => $self }, { type => 'UNION', query => $other }],
96             _renderer => $self->{_renderer},
97 5         90 );
98             }
99              
100             sub union_all {
101 1     1 0 7 my ($self, $other) = @_;
102             SQL::Wizard::Expr::Compound->new(
103             queries => [{ type => undef, query => $self }, { type => 'UNION ALL', query => $other }],
104             _renderer => $self->{_renderer},
105 1         9 );
106             }
107              
108             sub intersect {
109 1     1 0 9 my ($self, $other) = @_;
110             SQL::Wizard::Expr::Compound->new(
111             queries => [{ type => undef, query => $self }, { type => 'INTERSECT', query => $other }],
112             _renderer => $self->{_renderer},
113 1         9 );
114             }
115              
116             sub except {
117 1     1 0 8 my ($self, $other) = @_;
118             SQL::Wizard::Expr::Compound->new(
119             queries => [{ type => undef, query => $self }, { type => 'EXCEPT', query => $other }],
120             _renderer => $self->{_renderer},
121 1         9 );
122             }
123              
124             1;