File Coverage

blib/lib/DBR/Query.pm
Criterion Covered Total %
statement 91 104 87.5
branch 27 52 51.9
condition 12 36 33.3
subroutine 19 25 76.0
pod 0 16 0.0
total 149 233 63.9


line stmt bran cond sub pod time code
1             # the contents of this file are Copyright (c) 2004-2010 Daniel Norman
2             # This program is free software; you can redistribute it and/or
3             # modify it under the terms of the GNU General Public License as
4             # published by the Free Software Foundation.
5              
6             package DBR::Query;
7 18     18   107 use base 'DBR::Common';
  18         38  
  18         10350  
8 18     18   242 use strict;
  18         2392  
  18         973  
9 18     18   117 use Carp;
  18         33  
  18         1203  
10 18     18   10838 use DBR::Query::Part;
  18         58  
  18         1293  
11 0     0   0 sub _params{ confess "Shouldn't get here" }
12 0     0   0 sub _reqparams{ confess "Shouldn't get here" }
13 18     18   123 use Scalar::Util 'blessed';
  18         29  
  18         36874  
14              
15             sub new {
16 1144     1144 0 7567 my( $package, %params ) = @_;
17              
18 1144 50       4321 $package ne __PACKAGE__ || croak "Can't create a query object directly, must create a subclass for the given query type";
19 1144         4770 my $self = bless({},$package);
20              
21 1144   33     6947 $self->{instance} = $params{instance} || croak "instance is required";
22 1144   33     16869 $self->{session} = $params{session} || croak "session is required";
23 1144         14444 $self->{scope} = $params{scope};
24 1144         2898 $self->{splitfield} = $params{splitfield};
25              
26 1144         6026 my %req = map {$_ => 1} $self->_reqparams;
  2275         9103  
27 1144         6098 for my $key ( $self->_params ){
28              
29 6853 100       27416 if( $params{$key} ){
    50          
30 2940         23528 $self->$key( $params{$key} );
31              
32             }elsif($req{$key}){
33 0         0 croak "$key is required";
34             }
35             }
36              
37 1144 50       12123 $self->validate() or croak "Object is not valid"; # HERE - not enough info as to why
38              
39 1143         24625 return $self;
40             }
41              
42             sub tables{
43 1144     1144 0 3394 my $self = shift;
44 1144 0 0     8776 exists( $_[0] ) or return wantarray?( @$self->{tables} ) : $self->{tables} || undef;
    50          
45 1144         4793 my @tables = $self->_arrayify(@_);
46              
47 1144 50       5556 scalar(@tables) || croak "must provide at least one table";
48              
49 1144         2208 my @tparts;
50             my %aliasmap;
51 1144         2619 foreach my $table (@tables){
52 1146 50       7018 croak('must specify table as a DBR::Config::Table object') unless ref($table) =~ /^DBR::Config::Table/; # Could also be ::Anon
53              
54 1146 50       11419 my $name = $table->name or confess 'failed to get table name';
55 1146         5928 my $alias = $table->alias;
56 1146 100       5595 $aliasmap{$alias} = $name if $alias;
57             }
58              
59 1144         3565 $self->{tables} = \@tables;
60 1144         3954 $self->{aliasmap} = \%aliasmap;
61              
62 1144         5132 return $self;
63             }
64              
65             sub check_table{
66 4     4 0 8 my $self = shift;
67 4         8 my $alias = shift;
68              
69 4 50       27 return $self->{aliasmap}->{$alias} ? 1 : 0;
70             }
71              
72             sub where{
73 613     613 0 2078 my $self = shift;
74 613 50 0     1943 exists( $_[0] ) or return $self->{where} || undef;
75 613   50     2945 my $part = shift || undef;
76              
77 613 50 33     9803 !$part || ref($part) =~ /^DBR::Query::Part::(And|Or|Compare|Subquery|Join)$/ ||
78             croak('param must be an AND/OR/COMPARE/SUBQUERY/JOIN object');
79              
80 613         2127 $self->{where} = $part;
81              
82 613         1585 return $self;
83             }
84              
85             sub builder{
86 12     12 0 24 my $self = shift;
87 12 50 0     60 exists( $_[0] ) or return $self->{builder} || undef;
88 12   50     49 my $builder = shift || undef;
89              
90 12 50 33     93 !$builder || ref($builder) eq 'DBR::Interface::Where' || croak('must specify a builder object');
91              
92 12         26 $self->{builder} = $builder;
93              
94 12         30 return $self;
95             }
96              
97             sub limit{
98 0     0 0 0 my $self = shift;
99 0 0 0     0 exists( $_[0] ) or return $self->{limit} || undef;
100 0   0     0 $self->{limit} = shift || undef;
101              
102 0         0 return $self;
103             }
104              
105             sub lock{
106 0     0 0 0 my $self = shift;
107 0 0 0     0 exists( $_[0] ) or return $self->{lock} || undef;
108 0 0       0 $self->{lock} = shift() ? 1 : 0;
109              
110 0         0 return $self;
111             }
112              
113             sub quiet_error{
114 598     598 0 1782 my $self = shift;
115 598 100 100     8061 exists( $_[0] ) or return $self->{quiet_error} || undef;
116 42 50       231 $self->{quiet_error} = shift() ? 1 : 0;
117              
118 42         142 return $self;
119             }
120              
121 501     501 0 4879 sub primary_table{ shift->{tables}[0] } # HERE HERE HERE - this is lame
122              
123             # Copy the guts of this query into a query of a different type
124             # For instance: transpose a Select into an Update.
125             sub transpose{
126 10     10 0 41 my $self = shift;
127 10         21 my $module = shift;
128              
129 10         32 my $class = __PACKAGE__ . '::' . $module;
130 10         18 my %params;
131 10 100       43 map { $params{ $_ } = $self->{$_} if $self->{$_} } (qw'instance session scope',$self->_params);
  100         425  
132            
133 10 0       106 return $class->new(
134             %params,
135             @_, # extra params
136             ) or croak "Failed to create new $class object";
137             }
138              
139             sub child_query{
140 10     10 0 15 my $self = shift;
141 10         14 my $where = shift;
142              
143 10   66     76 my $builder = $self->{builder} ||= DBR::Interface::Where->new(
144             session => $self->{session},
145             instance => $self->{instance},
146             primary_table => $self->primary_table,
147             );
148              
149 10         47 my $ident = $builder->digest( $where );
150              
151 10   66     99 return $self->{child_queries}{$ident} ||= $self->_new_child_query($where);
152             }
153              
154             sub _new_child_query{
155 6     6   9 my $self = shift;
156 6         16 my $where = shift;
157              
158             #HERE - I don't think this is the correct place to do this
159 6         27 my $qpart = $self->{builder}->build($where);
160              
161 6         9 my %child;
162              
163             # Copy everything over, including internal goodies # HERE HERE HERE - I'm uncertain if builder should be copied
164 6         29 map { $child{$_} = $self->{$_} } (qw'instance session scope splitfield last_idx', $self->_params);
  72         172  
165              
166 6 100       46 $child{where} = $self->{where} ? DBR::Query::Part::And->new( $self->{where}, $qpart ) : $qpart;
167              
168 6         29 my $class = blessed($self);
169 6         64 return bless(\%child, $class); # not even calling new
170             }
171              
172 2316     2316 0 20516 sub instance { $_[0]{instance} }
173 1140     1140   16750 sub _session { $_[0]{session} }
174 0     0 0 0 sub session { $_[0]{session} }
175 27     27 0 285 sub scope { $_[0]{scope} }
176              
177 0     0 0 0 sub can_be_subquery { 0 }
178              
179             sub validate{
180 1144     1144 0 1773 my $self = shift;
181              
182 1144 50       4305 return 0 unless $self->_validate_self; # make sure I'm sane
183              
184             # Now check my component objects
185 1143 100       3866 if($self->{where}){
186 613 50       3962 $self->{where}->validate( $self ) or croak "Invalid where clause";
187             }
188              
189 1143         7853 return 1;
190             }
191              
192             1;