File Coverage

lib/DBIx/ActiveRecord/Arel/Query.pm
Criterion Covered Total %
statement 114 118 96.6
branch 15 16 93.7
condition 2 4 50.0
subroutine 26 28 92.8
pod 0 25 0.0
total 157 191 82.2


line stmt bran cond sub pod time code
1             package DBIx::ActiveRecord::Arel::Query;
2 2     2   12 use strict;
  2         4  
  2         79  
3 2     2   11 use warnings;
  2         2  
  2         2975  
4              
5             sub new {
6 7     7 0 10 my ($self, $main) = @_;
7 7         88 bless {
8             main => $main,
9             wheres => [],
10             joins => [],
11             binds => [],
12             selects => [],
13             group => [],
14             order => [],
15             limit => undef,
16             offset => undef,
17             lock => undef,
18             as => {},
19             }, $self;
20             }
21              
22 0     0   0 sub _to_sql { die 'implement!' }
23 85     85 0 608 sub main {shift->{main}}
24 37     37 0 36 sub binds {@{shift->{binds}}}
  37         206  
25              
26             sub add_as {
27 3     3 0 5 my ($self, $table, $as) = @_;
28 3         12 $self->{as}->{$table} = $as;
29             }
30              
31             sub add_join {
32 16     16 0 20 my ($self, $join) = @_;
33 16         17 push @{$self->{joins}}, $join;
  16         4379  
34             }
35              
36             sub add_where {
37 40     40 0 52 my ($self, $where) = @_;
38 40         29 push @{$self->{wheres}}, $where;
  40         114  
39             }
40              
41             sub add_select {
42 11     11 0 17 my ($self, $select) = @_;
43 11         8 push @{$self->{selects}}, $select;
  11         47  
44             }
45              
46             sub add_group {
47 5     5 0 7 my ($self, $group) = @_;
48 5         5 push @{$self->{group}}, $group;
  5         18  
49             }
50              
51             sub add_order {
52 7     7 0 8 my ($self, $order) = @_;
53 7         6 push @{$self->{order}}, $order;
  7         30  
54             }
55              
56             sub set_limit {
57 1     1 0 3 my ($self, $limit) = @_;
58 1         2 $self->{limit} = $limit;
59             }
60              
61             sub set_offset {
62 1     1 0 2 my ($self, $offset) = @_;
63 1         2 $self->{offset} = $offset;
64             }
65              
66             sub set_lock {
67 1     1 0 3 shift->{lock} = 1;
68             }
69              
70             sub reset_order {
71 1     1 0 3 shift->{order} = [];
72             }
73              
74             sub reverse_order {
75 0     0 0 0 my $self = shift;
76 0         0 $_->reverse for @{$self->{order}};
  0         0  
77             }
78              
79             sub merge {
80 12     12 0 17 my ($self, $query) = @_;
81 12         13 push @{$self->{wheres}}, @{$query->{wheres}};
  12         33  
  12         21  
82 12         14 push @{$self->{selects}}, @{$query->{selects}};
  12         13  
  12         15  
83 12         13 push @{$self->{group}}, @{$query->{group}};
  12         15  
  12         38  
84 12         12 push @{$self->{order}}, @{$query->{order}};
  12         13  
  12         14  
85 12         12 push @{$self->{joins}}, @{$query->{joins}};
  12         14  
  12         14  
86 12         32 $self->merge_as($query);
87             }
88              
89             sub merge_as {
90 28     28 0 33 my ($self, $query) = @_;
91 28         29 %{$self->{as}} = (%{$query->{as}}, %{$self->{as}});
  28         81  
  28         49  
  28         48  
92             }
93              
94             sub build_where {
95 38     38 0 43 my ($self) = @_;
96 38         30 my @binds;
97             my @where;
98              
99 38         37 foreach my $w (@{$self->{wheres}}) {
  38         80  
100 40         106 my ($where, $binds) = $w->build;
101 40         56 push @where, $where;
102 40 50       133 push @binds, @$binds if $binds;
103             }
104              
105 38         59 $self->{binds} = \@binds;
106 38         132 join(' AND ', @where);
107             }
108              
109             sub build_options {
110 35     35 0 37 my $self = shift;
111              
112 35         32 my @sql;
113              
114 35         61 my $group = $self->build_group;
115 35 100       64 push @sql, 'GROUP BY '.$group if $group;
116              
117 35         68 my $order = $self->build_order;
118 35 100       61 push @sql, 'ORDER BY '.$order if $order;
119              
120 35 100       67 if ($self->{limit}) {
121 1         2 push @sql, 'LIMIT ?';
122 1         1 push @{$self->{binds}}, $self->{limit};
  1         3  
123             }
124 35 100       55 if ($self->{offset}) {
125 1         1 push @sql, 'OFFSET ?';
126 1         2 push @{$self->{binds}}, $self->{offset};
  1         2  
127             }
128 35 100       63 push @sql, 'FOR UPDATE' if $self->{lock};
129 35         98 join (' ', @sql);
130             }
131              
132             sub build_group {
133 35     35 0 57 my $self = shift;
134 35   50     74 my $g = $self->{group} || return;
135 35         79 join(', ', map {$_->name} @$g);
  5         13  
136             }
137              
138             sub build_order {
139 35     35 0 38 my $self = shift;
140 35   50     66 my $order = $self->{order} || return;
141 35         71 join(', ', map {$_->build} @$order);
  5         14  
142             }
143              
144             sub build_select {
145 35     35 0 45 my ($self) = @_;
146 35         214 my @select = map {$_->name} @{$self->{selects}};
  11         27  
  35         64  
147 35 100       107 @select ? join(', ', @select) : $self->main->_col("*")->name;
148             }
149              
150             sub build_join {
151 36     36 0 39 my ($self) = @_;
152 36         39 my @join = map {$_->build} @{$self->{joins}};
  18         49  
  36         64  
153 36         112 join(" ", @join);
154             }
155              
156             sub has_join {
157 75     75 0 257 my $self = shift;
158 75         243 !!@{$self->{joins}};
  75         275  
159             }
160              
161             sub to_sql {
162 39     39 0 45 my $self = shift;
163              
164 39         41 my $org_use_full_name = $DBIx::ActiveRecord::Arel::Column::USE_FULL_NAME;
165 39         68 my $org_as = $DBIx::ActiveRecord::Arel::Column::AS;
166              
167 39         87 $DBIx::ActiveRecord::Arel::Column::USE_FULL_NAME = $self->has_join;
168 39         223 $DBIx::ActiveRecord::Arel::Column::AS = $self->{as};
169              
170 39         100 my $sql = $self->_to_sql(@_);
171              
172 39         49 $DBIx::ActiveRecord::Arel::Column::USE_FULL_NAME = $org_use_full_name;
173 39         49 $DBIx::ActiveRecord::Arel::Column::AS = $self->{as};
174              
175 39         155 $sql;
176             }
177              
178             sub main_table_with_alias {
179 16     16 0 21 my $self = shift;
180 16         17 my $as = $DBIx::ActiveRecord::Arel::Column::AS;
181 16 100       31 $as->{$self->main->table} ? $self->main->table." ".$as->{$self->main->table} : $self->main->table;
182             }
183              
184             1;