File Coverage

blib/lib/DBomb/Query/Insert.pm
Criterion Covered Total %
statement 21 201 10.4
branch 0 50 0.0
condition 0 9 0.0
subroutine 7 35 20.0
pod 0 28 0.0
total 28 323 8.6


line stmt bran cond sub pod time code
1             package DBomb::Query::Insert;
2              
3             =head1 NAME
4              
5             DBomb::Query::Insert - An SQL INSERT wrapper.
6              
7             =cut
8              
9 6     6   23719 use strict;
  6         17  
  6         221  
10 6     6   32 use warnings;
  6         10  
  6         308  
11             our $VERSION = '$Revision: 1.14 $';
12              
13 6     6   32 use Carp::Assert;
  6         11  
  6         50  
14 6     6   944 use DBomb::Util qw(ctx_0);
  6         10  
  6         377  
15 6     6   32 use DBomb::Query;
  6         14  
  6         119  
16 6     6   40 use DBomb::Conf;
  6         16  
  6         311  
17              
18             use Class::MethodMaker
19 6         63 'new_with_init' => 'new',
20             'get_set' => [qw(_column_names), ## [names]
21             qw(_table), ## [name]
22             qw(_values), ## [values or Values]
23             qw(_sql_values), ## [ PlaceHolder,...,Expr,...]
24             qw(_query), ## Query object for INSERT ... SELECT
25             qw(dbh sth)],
26 6     6   32 ;
  6         10  
27              
28             ## new Insert()
29             ## new Insert(@columns)
30             ## new Insert($dbh,[@columns])
31             sub init
32             {
33 0     0 0   my $self = shift;
34 0           $self->_column_names([]);
35 0           $self->_values([]);
36 0           $self->_sql_values([]);
37 0           $self->_table();
38              
39             ## Check for a dbh
40 0 0         for ( map{ UNIVERSAL::isa($_, 'ARRAY') ? (@$_) : $_ } @_){
  0            
41 0 0         if (UNIVERSAL::isa($_,'DBI::db')){
    0          
42 0           $self->dbh($_)
43             }
44             elsif (UNIVERSAL::isa($_,'DBomb::Meta::TableInfo')){
45 0           $self->into($_);
46             }
47             else{
48 0           $self->columns($_);
49             }
50             }
51             }
52              
53             ## Same as prepare->execute
54             ## insert()
55             ## insert(@bind_values)
56             ## insert($dbh,@bind_values)
57             sub insert
58             {
59 0     0 0   my $self = shift;
60 0           my @bv;
61              
62 0           for (@_){
63 0 0         if (UNIVERSAL::isa($_,'DBI::db')){ $self->dbh($_) }
  0            
64 0           else { push @bv, $_ }
65             }
66 0           assert(defined($self->dbh), 'insert requires a dbh');
67              
68 0 0         $self->prepare unless $self->sth;
69 0           return $self->execute(@bv);
70             }
71              
72             ## Note: ValuesObjects are automatically added to values() list
73             ## columns(names or infos or values)
74             ## columns([names or infos or values])
75             sub columns
76             {
77 0     0 0   my $self = shift;
78 0           assert(@_);
79              
80             ## allow listrefs
81 0 0         my @a = map {UNIVERSAL::isa($_,'ARRAY')? (@$_) : $_ } @_;
  0            
82              
83 0           for (@a){
84 0 0         if (UNIVERSAL::isa($_,'DBomb::Value::Column')){
    0          
85 0           $self->_table($_->column_info->table_info->name);
86 0           push @{$self->_column_names}, $_->column_info->name;
  0            
87 0           push @{$self->_values}, $_;
  0            
88             }
89             elsif (UNIVERSAL::isa($_,'DBomb::Meta::ColumnInfo')){
90 0           $self->_table($_->table_info->name);
91 0           push @{$self->_column_names}, $_->name;
  0            
92             }
93             else{
94 0           push @{$self->_column_names}, $_;
  0            
95             }
96 0           push @{$self->_sql_values}, DBomb::Query::PlaceHolder();
  0            
97             }
98 0           return $self;
99             }
100              
101              
102             ## into($table_name)
103             ## into($table_info)
104             sub into
105             {
106 0     0 0   my $self = shift;
107 0   0       assert(@_ == 1 && defined($_[0]), 'valid parameters');
108              
109 0           my $table = shift;
110              
111 0 0         if (UNIVERSAL::isa($table,'DBomb::Meta::TableInfo')){
    0          
112 0           $self->_table($table->name);
113             }
114             elsif(ref($table)){
115 0           croak("invalid parameter. expected TableInfo or table_name");
116             }
117             else {
118 0           $self->_table($table);
119             }
120              
121 0           return $self;
122             }
123              
124             ## values($values..)
125             ## values(Value objects....)
126             sub values
127             {
128 0     0 0   my $self = shift;
129              
130 0 0         my @a = map {UNIVERSAL::isa($_, 'ARRAY')? (@$_) : $_ } @_;
  0            
131 0           assert(@a, 'valid parameters');
132              
133 0           my $ix = 0;
134 0           for (@a){
135 0   0       assert( (not defined $_)
136             || !ref($_)
137             || UNIVERSAL::isa($_,'DBomb::Value')
138             || UNIVERSAL::isa($_,'DBomb::Query::Expr')
139             || UNIVERSAL::isa($_,'DBomb::Query')
140             || $_ eq DBomb::Query::PlaceHolder(),
141             'values() must be scalars, PlaceHolders, Values, or Expr objects');
142              
143 0 0 0       next if (defined($_) && $_ eq DBomb::Query::PlaceHolder());
144 0 0         if (UNIVERSAL::isa($_, 'DBomb::Query::Expr')){
145 0           $self->_sql_values->[$ix] = $_; ## expressions go in the sql...
146             }
147 0           push @{$self->_values}, $_;
  0            
148              
149 0           }continue{ $ix++ }
150              
151 0           return $self;
152             }
153              
154             sub select
155             {
156 0     0 0   my $self = shift;
157 0           $self->_query(new DBomb::Query(@_));
158 0           $self
159             }
160              
161             sub sql
162             {
163 0     0 0   my ($self, $dbh) = @_;
164 0 0         $self->dbh($dbh) if defined $dbh;
165 0           $dbh = $self->dbh;
166              
167 0           assert(defined($dbh), 'DBomb::Query::Insert::sql method requires a dbh');
168              
169 0           my $sql = "INSERT INTO " . $self->_table;
170              
171 0           my $names = $self->_column_names;
172 0 0         $sql .= " ( " . CORE::join(', ', @$names) . ")" if @$names;
173              
174              
175 0           my $sql_values = $self->_sql_values;
176              
177 0 0         if (defined $self->_query){
178 0           $sql .= $self->_query->sql($self->dbh);
179             }
180             else{
181 0 0         $sql .= (" VALUES (" . CORE::join(',', map{
182 0 0         UNIVERSAL::isa($_,'DBomb::Query::Expr')
183             ? $_->sql($self->dbh)
184             : '?'
185             } @$sql_values) . ')') if @$sql_values;
186             }
187              
188              
189 0 0         return ctx_0($sql,wantarray?@{$self->bind_values} : ());
  0            
190             }
191              
192             sub bind_values
193             {
194 0     0 0   my $self = shift;
195 0           my $bv = [];
196 0           assert(!@_, 'bind_values takes no parameters');
197              
198 0           for (@{$self->_values}){
  0            
199 0 0         if (UNIVERSAL::isa($_,'DBomb::Value::Column')) { push @$bv, $_->get_value_for_update; }
  0 0          
200 0           elsif (UNIVERSAL::isa($_,'DBomb::Query::Expr')) { push @$bv, @{$_->bind_values} }
  0            
201 0           else { push @$bv, $_ }
202             }
203            
204 0 0         if ($self->_query){
205 0           push @$bv, @{$self->_query->bind_values};
  0            
206             }
207 0           return $bv;
208             }
209              
210             ## prepare()
211             ## prepare($dbh)
212             sub prepare
213             {
214 0     0 0   my ($self,$dbh) = @_;
215              
216 0 0         $self->dbh($dbh) if defined $dbh;
217 0           assert(defined($self->dbh), 'insert prepare requires a dbh');
218 0           assert(defined($self->_table), 'insert prepare requires a table');
219              
220 0 0         if ($DBomb::Conf::prepare_cached){
221 0           $self->sth($self->dbh->prepare_cached(scalar $self->sql));
222             }else{
223 0           $self->sth($self->dbh->prepare(scalar $self->sql));
224             }
225 0           return $self;
226             }
227              
228             ## execute(@bind_values)
229             ## execute($dbh,@bind_values)
230             sub execute
231             {
232 0     0 0   my ($self, @bind_values) = @_;
233              
234 0 0         $self->dbh(shift @bind_values) if UNIVERSAL::isa($bind_values[0],'DBI::db');
235 0           assert(defined($self->dbh), 'execute requires a dbh');
236              
237 0           $self->sth->execute((@{$self->bind_values},@bind_values));
  0            
238 0           return $self;
239             }
240              
241             ## returns a deep copy.
242             ## @note The database handle will be shared by the clone, and
243             ## the internal statement handle will set to undef in the clone.
244             ## clone ()
245             sub clone
246             {
247 0     0 0   die "Not implemented";
248 0           my $self = shift;
249              
250 0           assert(UNIVERSAL::isa($self,__PACKAGE__));
251 0           assert(@_ == 0);
252              
253 0           my $clone = __PACKAGE__->new();
254              
255 0           return $clone;
256             }
257              
258             ## Grabs the last auto_increment column
259             ## last_insert_id
260             sub last_insert_id
261             {
262 0     0 0   my $self = shift;
263 0           assert(@_ == 0, "last_insert_id takes no arguments");
264 0           assert($self->dbh, "last_insert_id requires a valid dbh");
265              
266             ## DANGER!! MYSQL-SPECIFIC!
267             ## DANGER!! dbh must return the same (if from a pool)
268 0           return $self->dbh->{'mysql_insertid'};
269             }
270              
271              
272              
273             ## Wrappers around _query for INSERT...SELECT
274             ##
275 0     0 0   sub from { my $self = shift; assert($self->_query); $self->_query->from(@_) ; $self }
  0            
  0            
  0            
276 0     0 0   sub join { my $self = shift; assert($self->_query); $self->_query->join(@_) ; $self }
  0            
  0            
  0            
277 0     0 0   sub right_join { my $self = shift; assert($self->_query); $self->_query->right_join(@_) ; $self }
  0            
  0            
  0            
278 0     0 0   sub left_join { my $self = shift; assert($self->_query); $self->_query->left_join(@_) ; $self }
  0            
  0            
  0            
279 0     0 0   sub on { my $self = shift; assert($self->_query); $self->_query->on(@_) ; $self }
  0            
  0            
  0            
280 0     0 0   sub using { my $self = shift; assert($self->_query); $self->_query->using(@_) ; $self }
  0            
  0            
  0            
281 0     0 0   sub where { my $self = shift; assert($self->_query); $self->_query->where(@_) ; $self }
  0            
  0            
  0            
282 0     0 0   sub and { my $self = shift; assert($self->_query); $self->_query->and(@_) ; $self }
  0            
  0            
  0            
283 0     0 0   sub or { my $self = shift; assert($self->_query); $self->_query->or(@_) ; $self }
  0            
  0            
  0            
284 0     0 0   sub group_by { my $self = shift; assert($self->_query); $self->_query->group_by(@_) ; $self }
  0            
  0            
  0            
285 0     0 0   sub having { my $self = shift; assert($self->_query); $self->_query->having(@_) ; $self }
  0            
  0            
  0            
286 0     0 0   sub order_by { my $self = shift; assert($self->_query); $self->_query->order_by(@_) ; $self }
  0            
  0            
  0            
287 0     0 0   sub asc { my $self = shift; assert($self->_query); $self->_query->asc(@_) ; $self }
  0            
  0            
  0            
288 0     0 0   sub desc { my $self = shift; assert($self->_query); $self->_query->desc(@_) ; $self }
  0            
  0            
  0            
289 0     0 0   sub limit { my $self = shift; assert($self->_query); $self->_query->limit(@_) ; $self }
  0            
  0            
  0            
290 0     0 0   sub sql_small_result { my $self = shift; assert($self->_query); $self->_query->sql_small_result(@_) ; $self }
  0            
  0            
  0            
291              
292              
293             1;
294             __END__