File Coverage

blib/lib/JsonSQL/Param/Join.pm
Criterion Covered Total %
statement 48 59 81.3
branch 6 12 50.0
condition n/a
subroutine 7 7 100.0
pod 2 2 100.0
total 63 80 78.7


line stmt bran cond sub pod time code
1             # ABSTRACT: JsonSQL::Param::Join object. Stores a Perl representation of an SQL join expression for use in JsonSQL::Query objects.
2              
3              
4              
5 1     1   6 use strict;
  1         1  
  1         23  
6 1     1   4 use warnings;
  1         1  
  1         18  
7 1     1   12 use 5.014;
  1         2  
8              
9             package JsonSQL::Param::Join;
10              
11             our $VERSION = '0.4'; # VERSION
12              
13 1     1   29 use JsonSQL::Param::Table;
  1         3  
  1         34  
14 1     1   7 use JsonSQL::Error;
  1         3  
  1         230  
15              
16              
17              
18             sub new {
19 1     1 1 5 my ( $class, $joinhashref, $queryObj ) = @_;
20            
21 1         3 my $self = {};
22 1         2 my @join_errors;
23            
24             # The join FROM table is just a JsonSQL::Param::Table, so we can inherit the error handling.
25 1         10 my $joinFrom = JsonSQL::Param::Table->new($joinhashref->{from}, $queryObj);
26 1 50       3 if ( eval { $joinFrom->is_error } ) {
  1         12  
27 0         0 push(@join_errors, "Error creating join FROM table $joinhashref->{from}->{table}: $joinFrom->{message}");
28             } else {
29 1         30 $self->{_joinFrom} = $joinFrom;
30             }
31            
32             # Same with the join TO table.
33 1         5 my $joinTo = JsonSQL::Param::Table->new($joinhashref->{to}, $queryObj);
34 1 50       3 if ( eval { $joinTo->is_error } ) {
  1         12  
35 0         0 push(@join_errors, "Error creating join TO table $joinhashref->{to}->{table}: $joinTo->{message}");
36             } else {
37 1         29 $self->{_joinTo} = $joinTo;
38             }
39              
40             ## SMELL: more fixes to work around QueryMaker bugs
41 1         4 for ( $joinhashref->{jointype} ) {
42 1         5 when("outerleft") { $self->{_joinType} = "LEFT"; }
  0         0  
43 1         3 when("outerright") { $self->{_joinType} = "RIGHT"; }
  0         0  
44 1         3 when("outerfull") { $self->{_joinType} = "FULL"; }
  0         0  
45 1         3 when("inner") { $self->{_joinType} = "INNER"; }
  1         4  
46 0         0 when("cross") { $self->{_joinType} = "CROSS"; }
  0         0  
47             }
48            
49 1 50       5 if (defined $joinhashref->{on}) {
50 1         6 my $joinOn = JsonSQL::Param::ConditionDispatcher->parse($joinhashref->{on}, $queryObj);
51 1 50       2 if ( eval { $joinOn->is_error } ) {
  1         17  
52 0         0 push(@join_errors, "Error creating join ON condition: $joinOn->{message}");
53             } else {
54 1         31 $self->{_joinCondition} = $joinOn;
55             }
56             }
57            
58 1 50       5 if ( @join_errors ) {
59 0         0 my $err = "Error(s) constructing JOIN object: \n\t";
60 0         0 $err .= join("\n\t", @join_errors);
61 0         0 return JsonSQL::Error->new("invalid_joins", $err);
62             } else {
63 1         2 bless $self, $class;
64 1         4 return $self;
65             }
66             }
67              
68              
69             sub get_join {
70 1     1 1 4 my ( $self, $queryObj ) = @_;
71              
72 1         8 my $joinFrom = $self->{_joinFrom}->get_table_param($queryObj);
73             my $joinParams = {
74             type => $self->{_joinType},
75 1         6 table => $self->{_joinTo}->get_table_param($queryObj)
76             };
77            
78 1 50       5 if (defined $self->{_joinCondition}) {
79             ## SMELL: SQL::Maker doesn't support SQL::QueryMaker objects for JOIN ON
80             ## So, we build up the expression manually
81             ## Note: the JOIN condition is not parameterized, but this should be ok because the schema forces it to be based on
82             ## field identifiers, which are always quoted. It would be nice to do this in a cleaner way, but first have to
83             ## remove SQL::Maker dependency.
84 1         9 my ($sql, $bind) = $self->{_joinCondition}->get_cond($queryObj);
85 1         9 my $condition = $sql =~ s/\?/$bind->[0]/r;
86 1         4 $condition =~ s/`//g;
87 1         4 $joinParams->{condition} = $condition;
88             }
89            
90             ## Return join as a hash ref.
91 1         14 return { $joinFrom => $joinParams };
92             }
93              
94              
95             1;
96              
97             __END__
98              
99             =pod
100              
101             =encoding UTF-8
102              
103             =head1 NAME
104              
105             JsonSQL::Param::Join - JsonSQL::Param::Join object. Stores a Perl representation of an SQL join expression for use in JsonSQL::Query objects.
106              
107             =head1 VERSION
108              
109             version 0.4
110              
111             =head1 SYNOPSIS
112              
113             This module constructs a Perl object representing a JOIN parameter of an SQL SELECT statement and has methods for
114             extracting the parameters to generate the appropriate SQL string.
115              
116             =head1 DESCRIPTION
117              
118             =head3 Object properties:
119              
120             =over
121              
122             =item _joinFrom => L<JsonSQL::Param::Table>
123              
124             =item _joinTo => L<JsonSQL::Param::Table>
125              
126             =item _joinType => "inner" || "outerleft" || "outerright" || "outerfull" || "cross"
127              
128             =item _joinCondition => L<JsonSQL::Param::Condition>
129              
130             =back
131              
132             =head3 Generated parameters:
133              
134             =over
135              
136             =item { $joinFrom => $joinParams }
137              
138             =back
139              
140             =head1 METHODS
141              
142             =head2 Constructor new($joinhashref, $queryObj)
143              
144             Instantiates and returns a new JsonSQL::Param::Join object.
145              
146             $joinhashref => A hashref of fromtable/totable/jointype/joincondition properties used to construct the object.
147             $queryObj => A reference to the JsonSQL::Query object that will own this object.
148              
149             Returns a JsonSQL::Error object on failure.
150              
151             =head2 ObjectMethod get_join -> { $joinFrom => $joinParams }
152              
153             Generates parameters represented by the object for the SQL statement. Returns:
154              
155             $joinFrom => The table to JOIN from.
156             $joinParams => The parameters defining the join.
157              
158             =head1 AUTHOR
159              
160             Chris Hoefler <bhoefler@draper.com>
161              
162             =head1 COPYRIGHT AND LICENSE
163              
164             This software is copyright (c) 2017 by Chris Hoefler.
165              
166             This is free software; you can redistribute it and/or modify it under
167             the same terms as the Perl 5 programming language system itself.
168              
169             =cut