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   73 use strict;
  14         20  
  14         427  
4 14     14   48 use warnings;
  14         31  
  14         576  
5 14     14   7317 use Storable qw(dclone);
  14         53365  
  14         1204  
6 14     14   95 use parent 'SQL::Wizard::Expr';
  14         18  
  14         67  
7 14     14   7128 use SQL::Wizard::Expr::Compound;
  14         40  
  14         10010  
8              
9             sub new {
10 129     129 0 260 my ($class, %args) = @_;
11 129         470 $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 129     129 0 370 my ($class, %args) = @_;
18 129 50       341 Carp::confess("select requires -from") unless $args{'-from'};
19 129         172 my %node;
20 129 100       261 $node{distinct} = $args{'-distinct'} if $args{'-distinct'};
21 129 100       304 $node{columns} = $args{'-columns'} if $args{'-columns'};
22 129 50       362 $node{from} = $args{'-from'} if $args{'-from'};
23 129 100       273 $node{where} = $args{'-where'} if $args{'-where'};
24 129 100       225 $node{group_by} = $args{'-group_by'} if $args{'-group_by'};
25 129 100       253 $node{having} = $args{'-having'} if $args{'-having'};
26 129 100       243 $node{order_by} = $args{'-order_by'} if $args{'-order_by'};
27 129 100       242 $node{limit} = $args{'-limit'} if defined $args{'-limit'};
28 129 100       203 $node{offset} = $args{'-offset'} if defined $args{'-offset'};
29 129 100       206 $node{window} = $args{'-window'} if $args{'-window'};
30 129 100       210 $node{_cte} = $args{_cte} if $args{_cte};
31 129 50       319 $node{_renderer} = $args{_renderer} if $args{_renderer};
32 129         347 $class->new(%node);
33             }
34              
35             # Immutable modifiers — return cloned objects
36              
37             sub distinct {
38 1     1 0 5 my ($self) = @_;
39 1         131 my $clone = dclone($self);
40 1         4 $clone->{distinct} = 1;
41 1         5 return $clone;
42             }
43              
44             sub where {
45 2     2 0 2239 my ($self, $where) = @_;
46 2         259 my $clone = dclone($self);
47 2         6 $clone->{where} = $where;
48 2         6 return $clone;
49             }
50              
51             sub add_where {
52 2     2 0 1909 my ($self, $extra) = @_;
53 2         75 my $clone = dclone($self);
54 2 50       7 if ($clone->{where}) {
55 2         5 $clone->{where} = [-and => $clone->{where}, $extra];
56             } else {
57 0         0 $clone->{where} = $extra;
58             }
59 2         5 return $clone;
60             }
61              
62             sub columns {
63 1     1 0 3 my ($self, $cols) = @_;
64 1         76 my $clone = dclone($self);
65 1         3 $clone->{columns} = $cols;
66 1         2 return $clone;
67             }
68              
69             sub order_by {
70 2     2 0 1077 my ($self, @order) = @_;
71 2         104 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 2279 my ($self, $limit) = @_;
78 3         132 my $clone = dclone($self);
79 3         7 $clone->{limit} = $limit;
80 3         8 return $clone;
81             }
82              
83             sub offset {
84 2     2 0 5 my ($self, $offset) = @_;
85 2         69 my $clone = dclone($self);
86 2         6 $clone->{offset} = $offset;
87 2         3 return $clone;
88             }
89              
90             # Compound query methods
91              
92             sub union {
93 5     5 0 21 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         58 );
98             }
99              
100             sub union_all {
101 1     1 0 5 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         21 );
106             }
107              
108             sub intersect {
109 1     1 0 5 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         6 );
114             }
115              
116             sub except {
117 1     1 0 5 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         6 );
122             }
123              
124             1;