File Coverage

lib/DB/Object/Query.pm
Criterion Covered Total %
statement 79 1040 7.6
branch 26 690 3.7
condition 0 432 0.0
subroutine 18 93 19.3
pod 57 57 100.0
total 180 2312 7.7


line stmt bran cond sub pod time code
1             # -*- perl -*-
2             ##----------------------------------------------------------------------------
3             ## Database Object Interface - ~/lib/DB/Object/Query.pm
4             ## Version v0.5.2
5             ## Copyright(c) 2023 DEGUEST Pte. Ltd.
6             ## Author: Jacques Deguest <jack@deguest.jp>
7             ## Created 2017/07/19
8             ## Modified 2023/06/13
9             ## All rights reserved
10             ##
11             ## This program is free software; you can redistribute it and/or modify it
12             ## under the same terms as Perl itself.
13             ##----------------------------------------------------------------------------
14             package DB::Object::Query;
15             BEGIN
16             {
17 2     2   2415 use strict;
  2         6  
  2         78  
18 2     2   11 use warnings;
  2         4  
  2         67  
19 2     2   9 use parent qw( DB::Object );
  2         3  
  2         10  
20 2     2   169 use vars qw( $VERSION $DEBUG $VERBOSE );
  2         4  
  2         122  
21 2     2   19 use Devel::Confess;
  2         5  
  2         24  
22 2     2   177 $VERSION = 'v0.5.2';
23 2         4 $DEBUG = 0;
24 2         34 $VERBOSE = 0;
25             };
26              
27 2     2   11 use strict;
  2         4  
  2         38  
28 2     2   9 use warnings;
  2         4  
  2         24732  
29              
30             sub init
31             {
32 1     1 1 5 my $self = shift( @_ );
33 1 50       93 $self->{alias} = {} unless( CORE::exists( $self->{alias} ) );
34 1 50       128 $self->{avoid} = [] unless( CORE::exists( $self->{avoid} ) );
35 1 50       7 $self->{binded} = [] unless( CORE::exists( $self->{binded} ) );
36 1 50       3 $self->{binded_group} = [] unless( CORE::exists( $self->{binded_group} ) );
37 1 50       7 $self->{binded_limit} = [] unless( CORE::exists( $self->{binded_limit} ) );
38 1 50       5 $self->{binded_order} = [] unless( CORE::exists( $self->{binded_order} ) );
39 1 50       105 $self->{binded_types} = [] unless( CORE::exists( $self->{binded_types} ) );
40 1 50       12 $self->{binded_values} = [] unless( CORE::exists( $self->{binded_values} ) );
41 1 50       5 $self->{binded_where} = [] unless( CORE::exists( $self->{binded_where} ) );
42 1 50       4 $self->{enhance} = 0 unless( CORE::exists( $self->{enhance} ) );
43 1 50       5 $self->{from_table} = [] unless( CORE::exists( $self->{from_table} ) );
44 1 50       4 $self->{from_unixtime} = [] unless( CORE::exists( $self->{from_unixtime} ) );
45 1 50       3 $self->{group_by} = '' unless( CORE::exists( $self->{group_by} ) );
46 1 50       3 $self->{join_fields} = '' unless( CORE::exists( $self->{join_fields} ) );
47 1 50       4 $self->{left_join} = {} unless( CORE::exists( $self->{left_join} ) );
48 1 50       6 $self->{limit} = [] unless( CORE::exists( $self->{limit} ) );
49 1 50       4 $self->{local} = {} unless( CORE::exists( $self->{local} ) );
50 1 50       5 $self->{order_by} = '' unless( CORE::exists( $self->{order_by} ) );
51 1 50       3 $self->{prepare_options}= {} unless( CORE::exists( $self->{prepare_options} ) );
52 1 50       4 $self->{reverse} = '' unless( CORE::exists( $self->{reverse} ) );
53 1 50       4 $self->{sorted} = [] unless( CORE::exists( $self->{sorted} ) );
54 1 50       4 $self->{table_alias} = '' unless( CORE::exists( $self->{table_alias} ) );
55 1 50       3 $self->{table_object} = '' unless( CORE::exists( $self->{table_object} ) );
56 1 50       4 $self->{unix_timestamp} = [] unless( CORE::exists( $self->{unix_timestamp} ) );
57 1 50       2 $self->{where} = '' unless( CORE::exists( $self->{where} ) );
58 1         2 $self->{_init_strict_use_sub} = 1;
59 1 50       23 $self->SUPER::init( @_ ) || return( $self->pass_error );
60 1         27 $self->{constant} = {};
61 1         17 $self->{query} = '';
62 1         12 $self->{query_reset} = 0;
63 1         20 $self->{query_reset_core_keys} = [qw( alias binded binded_group binded_limit binded_order binded_types binded_values binded_where from_unixtime group_by limit local order_by reverse sorted table_alias unix_timestamp where )];
64 1         9 $self->{selected_fields} = '';
65 1         13 $self->{table_object} = '';
66 1         10 $self->{tie_order} = [];
67 1         44 return( $self );
68             }
69              
70 0     0 1 0 sub alias { return( shift->_set_get_hash( 'alias', @_ ) ); }
71              
72 0     0 1 0 sub as_string { return( shift->{query} ); }
73              
74 0     0 1 0 sub avoid { return( shift->_set_get_array_as_object( 'avoid', @_ ) ); }
75              
76 0     0 1 0 sub binded { return( shift->_set_get_array_as_object( 'binded', @_ ) ); }
77              
78 0     0 1 0 sub binded_group { return( shift->group->bind->values ); }
79              
80 0     0 1 0 sub binded_limit { return( shift->limit->bind->values ); }
81              
82 0     0 1 0 sub binded_order { return( shift->order->bind->values ); }
83              
84 0     0 1 0 sub binded_types { return( shift->_set_get_array_as_object( 'binded_types', @_ ) ); }
85              
86             sub binded_types_as_param
87             {
88 0     0 1 0 my $self = shift( @_ );
89 0         0 return( $self->error( "The driver has not implemented th emethod binded_types_as_param." ) );
90             }
91              
92 0     0 1 0 sub binded_values { return( shift->_set_get_array_as_object( 'binded_values', @_ ) ); }
93              
94 0     0 1 0 sub binded_where { return( shift->_set_get_array_as_object( 'binded_where', @_ ) ); }
95              
96             sub constant
97             {
98 0     0 1 0 my $self = shift( @_ );
99 0 0       0 if( @_ )
100             {
101 0         0 my $def = shift( @_ );
102 0 0       0 return( $self->error( "I was expecting a hash reference, but got '$def' instead." ) ) if( !$self->_is_hash( $def ) );
103 0         0 foreach my $k (qw( pack file line ))
104             {
105 0 0       0 return( $self->error( "Parameter \"$k\" is missing in hash refernece provided." ) ) if( !$def->{ $k } );
106             }
107             ## sth may or may not be there
108 0 0 0     0 return( $self->error( "Statement handler provided is not a DB::Object::Statement object." ) ) if( $def->{sth} && ( !$self->_is_object( $def->{sth} ) && !$def->{sth}->isa( 'DB::Object::Statement' ) ) );
      0        
109 0         0 $self->{constant} = $def;
110             }
111 0         0 return( $self->{constant} );
112             }
113              
114 0     0 1 0 sub database_object { return( shift->table_object->database_object ) }
115              
116             sub delete
117             {
118 0     0 1 0 my $self = shift( @_ );
119 0         0 my $constant = $self->constant;
120 0 0       0 if( scalar( keys( %$constant ) ) )
121             {
122 0 0 0     0 return( $constant->{sth} ) if( $constant->{sth} && $self->_is_object( $constant->{sth} ) && $constant->{sth}->isa( 'DB::Object::Statement' ) );
      0        
123             }
124 0   0     0 my $tbl_o = $self->table_object || return( $self->error( "No table object is set." ) );
125 0   0     0 my $table = $tbl_o->name ||
126             return( $self->error( "No table to delete entries from was set." ) );
127 0         0 my $where = '';
128 0 0       0 $self->where( @_ ) if( @_ );
129             # if( !$where && $self->{ 'query_reset' } )
130 0 0       0 if( !$where )
131             {
132 0         0 $where = $self->where();
133             }
134 0 0       0 if( !$where )
135             {
136 0         0 return( $self->error( "You have provided no where clause. If you intend to delete all records from table '$table', you must do explicitly by preparing the statement yourself." ) );
137             }
138 0         0 my $clauses = $self->_query_components( 'delete' );
139 0         0 my @query = ( "DELETE FROM $table" );
140             # 'query_reset' condition to avoid catching parameters from pervious queries.
141 0 0       0 push( @query, @$clauses ) if( scalar( @$clauses ) );
142 0         0 my $query = $self->{query} = CORE::join( ' ', @query );
143 0 0 0     0 return( $self->error( "Refusing to do a bulk delete. Enable the allow_bulk_delete database object property if you want to do so. Original query was: $query" ) ) if( !$self->where && !$self->database_object->allow_bulk_delete );
144 0         0 $self->_save_bind();
145 0   0     0 my $sth = $tbl_o->_cache_this( $self ) ||
146             return( $self->error( "Error while preparing query to delete from table '$table':\n$query" ) );
147             # Routines such as as_string() expect an array on pupose so we do not have to commit the action
148             # but rather get the statement string. At the end, we write:
149             # $obj->delete() to really delete
150             # $obj->delete->as_string() to ONLY get the formatted statement
151             # wantarray returns undef in void context, i.e. $obj->delete()
152 0 0       0 if( !defined( wantarray() ) )
153             {
154 0 0       0 $sth->execute() ||
155             return( $self->error( "Error while executing query to delete from table '$table':\n$query" ) );
156             ## Will be destroyed anyway and permits the end user to manipulate the object if needed
157             ## $sth->finish();
158             }
159             # wantarray returns false but not undef() otherwise, i.e.
160             # $obj->delete->as_string();
161 0         0 return( $sth );
162             }
163              
164 1     1 1 47 sub enhance { return( shift->_set_get_boolean( 'enhance', @_ ) ); }
165              
166             # Used in conjonction with constant(), allows internally to know if the query has reached the end of the chain
167             # Such as $tbl->select->join( $tbl_object, $conditions )->join( $other_tbl_object, $other_conditions );
168             # final() enables to know the query reached the end, so that when constant is used, all the processing can be skipped
169 0     0 1 0 sub final { return( shift->_set_get_scalar( 'final', @_ ) ); }
170              
171             sub format_from_epoch
172             {
173 0     0 1 0 warn( "This method \"format_from_epoch\" was not superseded.\n" );
174             }
175              
176             sub format_to_epoch
177             {
178 0     0 1 0 warn( "This method \"format_to_epoch\" was not superseded.\n" );
179             }
180              
181             # For select or insert queries
182             sub format_statement
183             {
184 0     0 1 0 my $self = shift( @_ );
185 0         0 my $opts = {};
186 0 0       0 $opts = shift( @_ ) if( @_ );
187 0   0     0 my $tbl_o = $self->table_object || return( $self->error( "No table object is set." ) );
188             # Should we use bind statement?
189 0         0 my $bind = $tbl_o->database_object->use_bind;
190 0 0       0 $opts->{data} = $self->{_default} if( !$opts->{data} );
191 0 0       0 $opts->{order} = $self->{_fields} if( !$opts->{order} );
192 0 0       0 $opts->{table} = $tbl_o->qualified_name if( !$opts->{table} );
193 0         0 local $_;
194 0         0 my $data = $opts->{data};
195 0         0 my $order = $opts->{order};
196 0         0 my $table = $opts->{table};
197 0         0 my $prefix = $tbl_o->prefix;
198 0         0 my $from_unix = {};
199 0         0 my $unixtime = {};
200 0         0 my $args = $self->{_args};
201 0         0 my $fields = '';
202 0         0 my $values = '';
203 0         0 my $base_class = $self->base_class;
204 0         0 $from_unix = $self->{_from_unix};
205 0         0 my $tmp_ref = $self->from_unixtime();
206 0         0 map{ $from_unix->{ $_ }++ } @$tmp_ref;
  0         0  
207 0         0 $tmp_ref = $self->unix_timestamp();
208 0         0 map{ $unixtime->{ $_ }++ } @$tmp_ref;
  0         0  
209 0         0 my @format_fields = ();
210 0         0 my @format_values = ();
211 0         0 my $binded = $self->{binded_values} = [];
212 0         0 my $multi_db = $tbl_o->prefix_database;
213 0         0 my $db = $tbl_o->database;
214 0         0 my $fields_ref = $tbl_o->fields();
215 0         0 my $ok_list = CORE::join( '|', keys( %$fields_ref ) );
216 0         0 my $tables = CORE::join( '|', @{$tbl_o->database_object->tables} );
  0         0  
217 0         0 my $struct = $tbl_o->structure();
218 0         0 my $query_type = $self->{query_type};
219 0         0 my @sorted = ();
220 0 0 0     0 if( @$args && !( @$args % 2 ) )
221             {
222 0         0 for( my $i = 0; $i < @$args; $i++ )
223             {
224 0 0       0 push( @sorted, $args->[ $i ] ) if( exists( $order->{ $args->[ $i ] } ) );
225 0         0 $i++;
226             }
227             }
228 0 0       0 @sorted = sort{ $order->{ $a } <=> $order->{ $b } } keys( %$order ) if( !@sorted );
  0         0  
229             # Used for insert or update so that execute can take a hash of key => value pair and we would bind the values in the right order
230             # But or that we need to know the order of the fields.
231 0         0 $self->{sorted} = \@sorted;
232            
233 0         0 foreach( @sorted )
234             {
235             # next if( $struct->{ $_ } =~ /\b(AUTO_INCREMENT|SERIAL)\b/i );
236 0 0       0 if( exists( $data->{ $_ } ) )
237             {
238 0         0 my $value = $data->{ $_ };
239 0 0 0     0 if( $self->_is_a( $value => "${base_class}::Statement" ) )
    0 0        
    0 0        
    0 0        
    0          
    0          
    0          
    0          
    0          
    0          
240             {
241 0         0 push( @format_values, '(' . $value->as_string . ')' );
242 0         0 $self->binded_types->push( $value->query_object->binded_types_as_param );
243             }
244             # This is for insert or update statement types
245             elsif( exists( $from_unix->{ $_ } ) )
246             {
247 0 0       0 if( $bind )
248             {
249 0         0 push( @$binded, $value );
250 0         0 push( @format_values, $self->format_from_epoch({ value => $value, bind => 1 }) );
251             }
252             else
253             {
254 0         0 push( @format_values, $self->format_from_epoch({ value => $value, bind => 0 }) );
255             }
256 0         0 $self->binded_types->push( '' );
257             }
258             elsif( exists( $unixtime->{ $_ } ) )
259             {
260 0 0       0 if( $bind )
261             {
262 0         0 push( @$binded, $value );
263 0         0 push( @format_values, $self->format_to_epoch({ value => $value, bind => 1 }) );
264             }
265             else
266             {
267 0         0 push( @format_values, $self->format_to_epoch({ value => $value, bind => 0 }) );
268             }
269 0         0 $self->binded_types->push( '' );
270             }
271             elsif( ref( $value ) eq 'SCALAR' )
272             {
273 0         0 push( @format_values, $$value );
274             }
275             elsif( $value eq '?' )
276             {
277 0         0 push( @format_values, '?' );
278 0         0 $self->binded_types->push( '' );
279             }
280             elsif( $struct->{ $_ } =~ /^\s*\bBLOB\b/i )
281             {
282 0         0 push( @format_values, '?' );
283 0         0 push( @$binded, $value );
284 0         0 $self->binded_types->push( '' );
285             }
286             # If the value itself looks like a field name or like a SQL function
287             # or simply if bind option is inactive
288             # This stinks too much. It is way too complex to parse or guess a sql query
289             # use \( instead to pass a scalar reference
290             # elsif( $value =~ /(?:\.|\A)(?:$ok_list)\b/ ||
291             # $value =~ /[a-zA-Z_]{3,}\([^\)]*\)/ ||
292             # $value eq '?' )
293             # {
294             # push( @format_values, $value );
295             # }
296             elsif( !$bind )
297             {
298 0         0 push( @format_values, sprintf( "%s", $tbl_o->database_object->quote( $value ) ) );
299             }
300             # We do this before testing for param binding because DBI puts quotes around SET number :-(
301             elsif( $value =~ /^\d+$/ && $struct->{ $_ } =~ /\bSET\(/i )
302             {
303 0         0 push( @format_values, $value );
304             }
305             elsif( $value =~ /^\d+$/ &&
306             $struct->{ $_ } =~ /\bENUM\(/i &&
307             ( $query_type eq 'insert' || $query_type eq 'update' ) )
308             {
309 0         0 push( @format_values, "'$value'" );
310             }
311             # Otherwise, bind option is enabled, we bind parameter
312             elsif( $bind )
313             {
314 0         0 push( @format_values, '?' );
315 0         0 push( @$binded, $value );
316 0         0 $self->binded_types->push( '' );
317             }
318             # In last resort, we handle the formatting ourself
319             else
320             {
321 0         0 push( @format_values, $tbl_o->database_object->quote( $value ) );
322             }
323             }
324            
325 0 0       0 if( $prefix )
326             {
327 0         0 s{
328             (?<![\.\"])\b($ok_list)\b(\s*)?(?!\.)
329             }
330 0         0 {
331 0 0 0     0 my( $field, $spc ) = ( $1, $2 );
    0          
332             if( $` =~ /\s+(?:AS|FROM)\s+$/i )
333 0         0 {
334             "$field$spc";
335             }
336             elsif( $query_type eq 'select' && $prefix )
337 0         0 {
338             "$prefix.$field$spc";
339             }
340             else
341 0         0 {
342             "$field$spc";
343             }
344 0 0       0 }gex;
345 0         0 s/(?<!\.)($tables)(?:\.)/$db\.$1\./g if( $multi_db );
346             push( @format_fields, $_ );
347             }
348             else
349 0         0 {
350             push( @format_fields, $_ );
351             }
352 0 0 0     0 }
  0         0  
353             if( !wantarray() && scalar( @{$self->{_extra}} ) )
354 0         0 {
  0         0  
355             push( @format_fields, @{$self->{_extra}} );
356 0         0 }
357 0         0 $values = CORE::join( ', ', @format_values );
358 0 0       0 $fields = CORE::join( ', ', @format_fields );
359             wantarray ? return( $fields, $values ) : return( $fields );
360             }
361              
362             sub format_update($;%)
363 0     0 1 0 {
364 0 0 0     0 my $self = shift( @_ );
      0        
365 0         0 my $data = shift( @_ ) if( $self->_is_array( $_[0] ) || $self->_is_hash( $_[0] ) || @_ % 2 );
366 0 0 0     0 my @arg = @_;
367             if( !@arg && $data )
368 0 0       0 {
    0          
369             if( $self->_is_hash( $data ) )
370 0         0 {
371             @arg = %$data;
372             }
373             elsif( $self->_is_array( $data ) )
374 0         0 {
375             @arg = @$data;
376             }
377             }
378 0 0 0     0
379 0         0 return( $self->error( "Must provide key => value pairs. I received an odd number of arguments" ) ) if( @arg && ( scalar( @arg ) % 2 ) );
380 0   0     0 my %arg = ( @arg );
381 0   0     0 my $tbl_o = $self->table_object || return( $self->error( "No table object is set." ) );
382 0 0 0     0 $arg{default} ||= $self->{_default};
    0          
383             if( $arg{data} && !$data )
384 0         0 {
385 0         0 my $hash = $arg{data};
386 0         0 my @vals = %$hash;
387             $data = \@vals;
388             }
389             elsif( $self->_is_hash( $data ) )
390 0         0 {
391 0         0 my @vals = %$data;
392             $data = \@vals;
393 0   0     0 }
394             my $info = $data || \@arg;
395 0 0 0     0 # if( !%$info || !scalar( keys( %$info ) ) )
396             if( !$info || !scalar( @$info ) )
397 0         0 {
398             return( $self->error( "No data to update was provided to format update." ) );
399 0         0 }
400 0   0     0 my $bind = $tbl_o->database_object->use_bind;
401 0         0 my $def = $arg{default} || $self->{_default};
402 0         0 my $fields_ref = $tbl_o->fields();
403 0         0 my $fields_list = CORE::join( '|', keys( %$fields_ref ) );
404 0         0 my $struct = $tbl_o->structure();
405 0         0 my $types = $tbl_o->types;
406 0         0 my $from_unix = $self->from_unixtime();
  0         0  
407 0         0 my $from_unixtime = { map{ $_ => 1 } @$from_unix };
408 0         0 my @fields = ();
409 0         0 my @binded = ();
410             my @types = ();
411 0         0 # Get the constant has definition for each table fields
412             my $types_const = $tbl_o->types_const;
413             # Before we used to call getdefault supplying it our new values and the
414             # format_statement() that would take the default supplied values
415             # Now, this works differently since we use update() method and supply
416             # directly our value to update to it
417             # In this context, getting the default values is dangerous, since resetting
418             # the values to their default ones is not was we want, is it?
419             #foreach my $field ( keys( %$def ) )
420             #{
421             # if( exists( $info->{ $field } ) )
422             #{
423             # $def->{ $field } = $info->{ $field };
424             #}
425 0         0 #}
426 0         0 my( $field, $value );
427             while( @$info )
428 0         0 {
429             my( $field, $value ) = ( shift( @$info ), shift( @$info ) );
430 0 0       0 # Do not update a field that does not belong in this table
431             next if( !exists( $fields_ref->{ $field } ) );
432             # Make it a FROM_UNIXTIME field if this is what we need.
433             # $value = "FROM_UNIXTIME($value)" if( exists( $from_unixtime->{ $field } ) );
434             # $value = \"TO_TIMESTAMP($value)" if( exists( $from_unixtime->{ $field } ) );
435 0 0 0     0 # This is for insert or update statement types
    0          
    0          
    0          
    0          
436             if( exists( $from_unixtime->{ $field } ) )
437 0 0       0 {
438             if( $bind )
439 0         0 {
440 0         0 push( @binded, $value );
441 0         0 push( @fields, "$field=" . $self->format_from_epoch({ value => $value, bind => 1 }) );
442             CORE::push( @types, '' );
443             }
444             else
445 0         0 {
446 0 0       0 push( @fields, "$field=" . $self->format_from_epoch({ value => $value, bind => 0 }) );
447             CORE::push( @types, '' ) if( $value eq '?' );
448             }
449             }
450             elsif( ref( $value ) eq 'SCALAR' )
451 0         0 {
452             push( @fields, "$field=$$value" );
453             }
454             # Maybe $bind is not enabled, but the user may have manually provided a placeholder, i.e. '?'
455             elsif( !$bind )
456             {
457 0         0 # push( @fields, sprintf( "$field='%s'", quotemeta( $value ) ) );
458 0 0 0     0 my $const;
    0 0        
    0 0        
459             if( $value eq '?' )
460 0         0 {
461 0 0 0     0 push( @fields, "$field = ?" );
    0          
462             if( lc( $types->{ $field } ) eq 'bytea' && ( $const = $self->database_object->get_sql_type( 'bytea' ) ) )
463 0         0 {
464             CORE::push( @types, $const );
465             }
466             elsif( CORE::exists( $types_const->{ $field } ) )
467 0         0 {
468             CORE::push( @types, $types_const->{ $field }->{constant} );
469             }
470             else
471 0         0 {
472             CORE::push( @types, '' );
473             }
474             }
475             elsif( lc( $types->{ $field } ) eq 'bytea' && ( $const = $self->database_object->get_sql_type( 'bytea' ) ) )
476             {
477 0         0 # push( @fields, sprintf( "$field=%s", $tbl_o->database_object->quote( $value, DBD::Pg::PG_BYTEA ) ) );
478             push( @fields, sprintf( "$field=%s", $tbl_o->database_object->quote( $value, $const ) ) );
479             }
480             elsif( $self->_is_hash( $value ) &&
481             ( lc( $types->{ $field } ) eq 'jsonb' || lc( $types->{ $field } ) eq 'json' ) )
482 0         0 {
483 0 0       0 my $this_json = $self->_encode_json( $value );
484             push( @fields, sprintf( "$field=%s", $tbl_o->database_object->quote( $this_json, ( lc( $types->{ $field } ) eq 'jsonb' ? $self->database_object->get_sql_type( 'jsonb' ) : $self->database_object->get_sql_type( 'json' ) ) ) ) );
485             }
486             else
487 0         0 {
488             push( @fields, sprintf( "$field=%s", $tbl_o->database_object->quote( $value ) ) );
489             }
490             }
491             # if this is a SET field type and value is a number, treat it as a number and not as a string
492             # We do this before testing for param binding because DBI puts quotes around SET number :-(
493             elsif( $value =~ /^\d+$/ && $struct->{ $field } =~ /\bSET\(/i )
494 0         0 {
495             push( @fields, "$field=$value" );
496             }
497             elsif( $bind )
498 0         0 {
499 0         0 push( @fields, "$field=?" );
500 0         0 push( @binded, $value );
501 0 0 0     0 my $const;
    0          
502             if( lc( $types->{ $field } ) eq 'bytea' && ( $const = $self->database_object->get_sql_type( 'bytea' ) ) )
503             {
504 0         0 # CORE::push( @types, DBD::Pg::PG_BYTEA );
505             CORE::push( @types, $const );
506             }
507             elsif( CORE::exists( $types_const->{ $field } ) )
508 0         0 {
509             CORE::push( @types, $types_const->{ $field }->{constant} );
510             }
511             else
512 0         0 {
513             CORE::push( @types, '' );
514             }
515             }
516             else
517 0         0 {
518 0 0 0     0 my $const;
519             if( lc( $types->{ $field } ) eq 'bytea' && ( $const = $self->database_object->get_sql_type( 'bytea' ) ) )
520             {
521 0         0 # push( @fields, "$field=" . $tbl_o->database_object->quote( $value, DBD::Pg::PG_BYTEA ) );
522             push( @fields, "$field=" . $tbl_o->database_object->quote( $value, $const ) );
523             }
524             else
525 0         0 {
526             push( @fields, "$field=" . $tbl_o->database_object->quote( $value ) );
527             }
528             }
529 0         0 }
530 0 0       0 $self->{binded_values} = [ @binded ];
531 0         0 $self->binded_types->push( @types ) if( scalar( @types ) );
532             return( CORE::join( ', ', @fields ) );
533             }
534 0     0 1 0  
535             sub from_table { return( shift->_set_get_array_as_object( 'from_table', @_ ) ); }
536 0     0 1 0  
537             sub from_unixtime { return( shift->_set_get_array_as_object( 'from_unixtime', @_ ) ); }
538              
539             sub getdefault
540 0     0 1 0 {
541 0         0 my $self = shift( @_ );
542 0   0     0 my $opts = $self->_get_args_as_hash( @_ );
543 0   0     0 my $tbl_o = $self->table_object || return( $self->error( "No table object is set." ) );
544 0 0       0 my $table = $opts->{table} || $tbl_o->name;
545 0         0 my $prefix = $tbl_o->query_object->table_alias ? $tbl_o->query_object->table_alias : $tbl_o->prefix;
546 0 0       0 my $arg = [];
547             if( $opts->{arg} )
548 0 0       0 {
549 0         0 return( $self->error( "arg parameter provided, but is not an array reference." ) ) if( !$self->_is_array( $opts->{arg} ) );
550 0 0 0     0 $arg = $opts->{arg};
551             return( $self->error( "arg parameter provided is not a key => value pair. Its number of elements should be an even number." ) ) if( scalar( @$arg ) && ( @$arg % 2 ) );
552 0         0 }
553 0         0 my %arg = ();
554 0         0 my %default = ();
555 0         0 my %fields = ();
556 0         0 my %structure = ();
557             my $base_class = $self->base_class;
558             # Contains some extra parameters for SELECT queries only
559 0         0 # Right now a concatenation of 'last_name' and 'first_name' fields into field named 'name'
560 0 0       0 my @extra = ();
561 0         0 %arg = @$arg if( scalar( @$arg ) );
562 0 0       0 $opts->{table} = lc( $opts->{table} );
563 0         0 $opts->{time} = time() if( !defined( $opts->{time} ) );
564 0 0       0 my $time = '';
565 0   0     0 $time = $opts->{time} if( $opts->{time} =~ /^\d+$/ );
      0        
566 0         0 $time ||= $opts->{unixtime} || time();
567 0 0       0 my $query_type = $opts->{query_type};
568             if( !$query_type )
569 0         0 {
570 0         0 my( $pkg, $file, $line, $sub ) = caller( 1 );
571 0         0 $sub =~ s/(.*):://;
572             $query_type = $sub;
573 0         0 }
574 0 0 0     0 my $alias = '';
      0        
575             if( $query_type ne 'insert' && $query_type ne 'delete' && $query_type ne 'replace' )
576 0         0 {
577 0 0 0     0 $alias = $opts->{as};
578             $alias = $self->alias if( !$alias || !%$alias );
579 0   0     0 }
580 0   0     0 my $avoid = $opts->{avoid} || $self->avoid();
581 0   0     0 my $unix_time = $opts->{unix_timestamp} || $self->unix_timestamp();
582             my $from_unix = $opts->{from_unixtime} || $self->from_unixtime();
583 0         0  
584             my $enhance = $tbl_o->enhance;
585             ## my $table_name = $table;
586 0         0 ## Need to do hard copy of hashes
587 0         0 %default = $tbl_o->default();
588 0         0 %fields = $tbl_o->fields();
589             %structure = $tbl_o->structure();
590 0 0 0     0
591             if( !%default || !%fields )
592 0         0 {
593             return( $self->error( "No proper configuration file found for table \"$table\"." ) );
594             }
595 0 0 0     0
596             if( $query_type eq 'select' && $enhance )
597 0         0 {
  0         0  
598             my @sorted = sort{ $fields{ $a } <=> $fields{ $b } } keys( %fields );
599 0         0 ## foreach my $field ( keys( %structure ) )
600             foreach my $field ( @sorted )
601 0 0       0 {
602             if( $structure{ $field } =~ /^\s*(?:DATE(?:TIME)?|TIMESTAMP)\s*/i )
603             {
604             ## $fields{ "UNIX_TIMESTAMP( $field ) AS ${field}_unixtime" } = scalar( keys( %fields ) ) + 1;
605 0 0       0 ## $fields{ "${field}::ABSTIME::INTEGER AS ${field}_unixtime" } = scalar( keys( %fields ) ) + 1;
606             my $f = $self->format_to_epoch({
607             value => ( $prefix ? "${prefix}.${field}" : $field ),
608             bind => 0,
609             quote => 0,
610             });
611 0         0 ## $fields{ "EXTRACT( EPOCH FROM $f ) AS ${field}_unixtime" } = scalar( keys( %fields ) ) + 1;
612             $fields{ "$f AS ${field}_unixtime" } = scalar( keys( %fields ) ) + 1;
613             }
614             }
615             }
616 0         0
617 0 0       0 my %to_unixtime = ();
    0          
618             if( $self->_is_array( $unix_time ) )
619 0         0 {
  0         0  
620             %to_unixtime = map{ $_ => 1 } @$unix_time;
621             }
622             elsif( $self->_is_hash( $unix_time ) )
623 0         0 {
624             %to_unixtime = %$unix_time;
625             }
626 0 0 0     0
627             if( %to_unixtime && scalar( keys( %to_unixtime ) ) )
628 0         0 {
629             foreach my $field ( keys( %to_unixtime ) )
630 0 0       0 {
631             if( exists( $fields{ $field } ) )
632             {
633 0 0       0 ## $fields{ 'UNIX_TIMESTAMP(' . $field . ') AS ' . $field } = $fields{ $field };
634             my $func = $self->format_to_epoch({
635             value => ( $prefix ? "${prefix}.${field}" : $field ),
636             bind => 0,
637             quote => 0,
638 0         0 });
639 0         0 $fields{ $func . ' AS ' . $field } = $fields{ $field };
640             delete( $fields{ $field } );
641             }
642             }
643             }
644 0         0
645 0 0       0 my %avoid = ();
    0          
646             if( $self->_is_array( $avoid ) )
647 0         0 {
  0         0  
648             %avoid = map{ $_ => 1 } @$avoid;
649             }
650             elsif( $self->_is_hash( $avoid ) )
651 0         0 {
652             %avoid = %$avoid;
653             }
654 0 0 0     0
655             if( %avoid && scalar( keys( %avoid ) ) )
656 0         0 {
657             foreach my $field ( keys( %avoid ) )
658 0 0       0 {
659             if( exists( $fields{ $field } ) )
660 0         0 {
661 0         0 delete( $fields{ $field } );
662             delete( $default{ $field } );
663             }
664             }
665             }
666 0         0
667 0 0       0 my %as = ();
668             if( $self->_is_hash( $alias ) )
669 0         0 {
670 0         0 %as = %$alias;
671             foreach my $field ( keys( %as ) )
672 0 0       0 {
673             if( exists( $fields{ $field } ) )
674 0 0       0 {
675             my $f = $prefix
676             ? "${prefix}.${field}"
677 0         0 : $field;
678             $fields{ "$f AS \"$as{ $field }\"" } = $fields{ $field };
679             # delete( $fields{ $field } );
680             }
681             else
682 0         0 {
683             $fields{ "$field AS \"$as{ $field }\"" } = scalar( keys( %fields ) ) + 1;
684             }
685             }
686 0 0 0     0 }
      0        
687             if( exists( $fields{ 'last_name' } ) &&
688             exists( $fields{ 'first_name' } ) &&
689             !exists( $fields{ 'name' } ) )
690             {
691 0 0       0
692             my $f = $prefix
693             ? "CONCAT(${prefix}.first_name, ' ', ${prefix}.last_name)"
694 0         0 : "CONCAT(first_name, ' ', last_name)";
695             push( @extra, "$f AS name" );
696             }
697 0 0 0     0
      0        
698             if( ( exists( $default{ 'auth' } ) && !defined( $arg{ 'auth' } ) ) ||
699             defined( $arg{ 'auth' } ) )
700             {
701 0 0       0 $default{ 'auth' } = defined( $arg{ 'auth' } )
702             ? $arg{ 'auth' }
703             : 0;
704 0 0 0     0 }
      0        
705             if( ( exists( $default{ 'status' } ) && !defined( $default{ 'status' } ) ) ||
706             defined( $arg{ 'status' } ) )
707             {
708 0 0       0 $default{ 'status' } = defined( $arg{ 'status' } )
709             ? $arg{ 'status' }
710             : 1;
711 0         0 }
712             foreach my $data ( keys( %arg ) )
713 0 0       0 {
714             if( exists( $default{ $data } ) )
715 0         0 {
716             $default{ $data } = $arg{ $data };
717             }
718 0         0 }
719 0 0       0 my %from_unixtime = ();
    0          
720             if( $self->_is_array( $from_unix ) )
721 0         0 {
  0         0  
722             %from_unixtime = map{ $_ => 1 } @$from_unix;
723             }
724             elsif( $self->_is_hash( $from_unix ) )
725 0         0 {
726             %from_unixtime = %$from_unix;
727             }
728 0         0
729             $self->{_args} = $arg;
730 0         0 # $self->{ '_args' } = $opts->{arg};
731 0         0 $self->{_default} = \%default;
732 0         0 $self->{_fields} = \%fields;
733 0         0 $self->{_extra} = \@extra;
734 0         0 $self->{_structure} = \%structure;
735 0         0 $self->{_from_unix} = \%from_unixtime;
736 0         0 $self->{_to_unix} = \%to_unixtime;
737 0         0 $self->{query_type} = $query_type;
738 0         0 $self->{bind} = $tbl_o->database_object->use_bind;
739             return( $self );
740             }
741 0     0 1 0  
742             sub group { return( shift->_group_order( 'group', 'group_by', @_ ) ); }
743 0     0 1 0  
744             sub having { return( shift->error( "Having clause is not supported by this driver." ) ); }
745              
746             sub insert
747 0     0 1 0 {
748 0 0 0     0 my $self = shift( @_ );
749 0         0 my $data = shift( @_ ) if( @_ == 1 && ref( $_[ 0 ] ) );
750 0         0 my @arg = @_;
751 0 0       0 my $constant = $self->constant;
752             if( scalar( keys( %$constant ) ) )
753 0 0 0     0 {
      0        
754             return( $constant->{sth} ) if( $constant->{sth} && $self->_is_object( $constant->{sth} ) && $constant->{sth}->isa( 'DB::Object::Statement' ) );
755 0         0 }
756 0         0 my %arg = ();
757 0         0 my $select = '';
758 0 0 0     0 my $base_class = $self->base_class;
    0 0        
      0        
759             if( !@arg && $data && $self->_is_hash( $data ) )
760 0         0 {
761             @arg = %$data;
762             }
763             # insert into (field1, field2, field3) select field1, field2, field3 from some_table where some_id=12
764             elsif( $data && ref( $data ) eq "${base_class}::Statement" )
765 0         0 {
766             $select = $data->as_string();
767 0 0       0 }
768 0   0     0 %arg = @arg if( @arg );
769 0   0     0 my $tbl_o = $self->table_object || return( $self->error( "No table object is set." ) );
770             my $table = $tbl_o->name ||
771             return( $self->error( "No table was provided to insert data." ) );
772             # We do not decide of the value of AUTO_INCREMENT fields, so we do not use them in
773 0         0 # our INSERT statement.
774 0         0 my $structure = $tbl_o->structure();
775 0         0 my $null = $tbl_o->null();
776 0         0 my @avoid = ();
777 0 0       0 my( $fields, $values ) = ( '', '' );
778             unless( $select )
779 0         0 {
780             foreach my $field ( keys( %$structure ) )
781 0 0 0     0 {
782             push( @avoid, $field ) if( $structure->{ $field } =~ /\b(AUTO_INCREMENT|SERIAL|nextval)\b/i && !$arg{ $field } );
783             # It is useless to insert a blank data in a field whose default value is NULL.
784 0 0 0     0 # Especially since a test on a NULL field may be made specifically.
      0        
785             push( @avoid, $field ) if( scalar( @arg ) && !exists( $arg{ $field } ) && $null->{ $field } );
786             }
787 0 0       0 $self->getdefault({
788             table => $table,
789             arg => \@arg,
790             avoid => \@avoid,
791 0         0 }) || return;
792             ( $fields, $values ) = $self->format_statement();
793             }
794 0 0 0     0
      0        
795             if( $data && $self->_is_hash( $data ) && $self->binded_types->length )
796 0         0 {
797             warn( "You have passed arguments to this insert as hash reference, and you are using placeholders. Using placeholders requires fixed order of arguments which an hash reference cannot guarantee. This will potentially lead to error when executing the query. I recommend you switch to an array of arguments instead, i.e. from { field1 => value1, field2 => value2 } to ( field1 => value1, field2 => value2 )\n" );
798 0         0 }
799 0 0       0 my $clauses = $self->_query_components( 'insert' );
800 0 0       0 my @query = ( $select ? "INSERT INTO $table $select" : "INSERT INTO $table ($fields) VALUES($values)" );
801 0         0 push( @query, @$clauses ) if( scalar( @$clauses ) );
802             my $query = $self->{query} = CORE::join( ' ', @query );
803             # Everything meaningfull lies within the object
804 0         0 # If no bind should be done _save_bind does nothing
805             $self->_save_bind();
806             # Query string should lie within the object
807 0         0 # _cache_this sends back an object no matter what or unde() if an error occurs
808             my $sth = $tbl_o->_cache_this( $self );
809 0 0       0 # STOP! No need to go further
810             if( !defined( $sth ) )
811 0         0 {
812             return( $self->error( "Error '", $tbl_o->error, "' while preparing query to insert data into table '$table':\n$query" ) );
813 0 0       0 }
814             if( !defined( wantarray() ) )
815 0 0       0 {
816             $sth->execute() ||
817             return( $self->error( "Error while executing query to insert data to table '$table':\n$query" ) );
818 0         0 }
819             return( $sth );
820             }
821 0     0 1 0  
822             sub is_upsert { return( shift->_set_get_boolean( 'is_upsert', @_ ) ); }
823 0     0 1 0  
824             sub join_fields { return( shift->_set_get_scalar( 'join_fields', @_ ) ); }
825 0     0 1 0  
826             sub join_tables { return( shift->_set_get_object_array_object( 'join_tables', 'DB::Object::Tables', @_ ) ); }
827 0     0 1 0  
828             sub left_join { return( shift->_set_get_hash( 'left_join', @_ ) ); }
829              
830             sub limit
831 0     0 1 0 {
832 0         0 my $self = shift( @_ );
833 0 0       0 my $limit = $self->_process_limit( @_ );
834             if( CORE::length( $limit->metadata->limit ) )
835 0 0       0 {
836             $limit->generic( CORE::length( $limit->metadata->offset ) ? 'LIMIT ?, ?' : 'LIMIT ?' );
837 0 0 0     0 # User is managing the binding of value
      0        
838             if( (
839             $limit->metadata->offset eq '?' &&
840             $limit->metadata->limit eq '?'
841             ) || $limit->metadata->limit eq '?' )
842 0 0       0 {
843             $limit->value(
844             CORE::length( $limit->metadata->offset )
845             ? 'LIMIT ?, ?'
846             : 'LIMIT ?'
847             );
848             }
849             else
850 0 0       0 {
851             $limit->value(
852             CORE::length( $limit->metadata->offset )
853             ? CORE::sprintf( 'LIMIT %d, %d', $limit->metadata->offset, $limit->metadata->limit )
854             : CORE::sprintf( 'LIMIT %d', $limit->metadata->limit )
855             );
856             }
857 0         0 }
858             return( $limit );
859             }
860              
861             sub local
862 0     0 1 0 {
863 0   0     0 my $self = shift( @_ );
864 0         0 $self->{local} ||= {};
865 0 0       0 my $local = $self->{local};
866             if( @_ )
867 0         0 {
868 0         0 my $data = $self->_get_args_as_hash( @_ );
869 0 0       0 my $str = '';
870             if( scalar( keys( %$data ) ) )
871 0         0 {
872 0         0 my @keys = keys( %$data );
873             @$local{ @keys } = @$data{ @keys };
874             }
875 0 0 0     0 }
    0          
876 0 0       0 return( wantarray() ? () : undef() ) if( !$local || !%$local );
877 0         0 return( %$local ) if( wantarray() );
  0         0  
878             my $str = join( ', ', map{ "\@${_} = '" . $local->{ $_ } . "'" } keys( %$local ) );
879 0         0 ## return( "SET $str" );
880             return( $str );
881             }
882              
883             sub new_clause
884 0     0 1 0 {
885 0         0 my $self = shift( @_ );
886 0         0 my $opts = $self->_get_args_as_hash( @_ );
887 0         0 $opts->{debug} = $self->debug;
888 0 0       0 my $o = DB::Object::Query::Clause->new( $opts );
889 0 0       0 defined( $o ) || return( $self->error( "Unable to create a DB::Object::Query::Clause object: ", DB::Object::Query::Clause->error ) );
890             $o->query_object( $self ) || return( $self->error( "Error: ", $o->error ) );
891 0         0 # $o->debug( $self->debug );
892             return( $o );
893             }
894 0     0 1 0  
895             sub order { return( shift->_group_order( 'order', 'order_by', @_ ) ); }
896 0     0 1 0  
897             sub prepare_options { return( shift->_set_get_hash_as_mix_object( 'prepare_options', @_ ) ); }
898 0     0 1 0  
899             sub query { return( shift->_set_get_scalar( 'query', @_ ) ); }
900 0     0 1 0  
901             sub query_reset { return( shift->_set_get_boolean( 'query_reset', @_ ) ); }
902 0     0 1 0  
903             sub query_reset_core_keys { return( shift->_set_get_array_as_object( 'query_reset_core_keys', @_ ) ); }
904 0     0 1 0  
905             sub query_reset_keys { return( shift->_set_get_array_as_object( 'query_reset_keys', @_ ) ); }
906 0     0 1 0  
907             sub query_type { return( shift->_set_get_scalar( 'query_type', @_ ) ); }
908 0     0 1 0  
909             sub query_values { return( shift->_set_get( 'query_values', @_ ) ); }
910 0     0 1 0  
911             sub replace { return( shift->error( "The replace sql query is not supported by this driver." ) ); }
912              
913             sub reset
914 0     0 1 0 {
915 0 0       0 my $self = shift( @_ );
916             if( !$self->{query_reset} )
917 0         0 {
918 0         0 my $core_keys = $self->query_reset_core_keys;
919             my $keys = $self->query_reset_keys;
920 0 0       0 # Make sure the driver's list of keys for query reset is complete by merging this base class keys with the diver's one
921             unless( $core_keys == $keys )
922 0         0 {
923 0         0 my $new_keys = $keys->merge( $core_keys )->unique->sort;
924             $keys = $self->query_reset_keys( $new_keys );
925 0         0 }
926 0         0 CORE::delete( @$self{ @$keys } );
927 0         0 $self->{query_reset}++;
928             $self->{enhance} = 1;
929 0         0 }
930             return( $self );
931             }
932              
933             sub reset_bind
934 0     0 1 0 {
935 0         0 my $self = shift( @_ );
936 0         0 my @f = qw( binded binded_group binded_limit binded_order binded_types binded_where );
937             foreach my $field ( @f )
938 0         0 {
939             $self->{ $field } = [];
940 0         0 }
941             return( $self );
942             }
943 0     0 1 0  
944             sub returning { return( shift->error( "Returning clause is not supported by this driver" ) ); }
945              
946             sub reverse
947 0     0 1 0 {
948 0 0       0 my $self = shift( @_ );
949             if( @_ )
950 0         0 {
951             $self->{reverse}++;
952 0         0 }
953             return( $self->{reverse} );
954             }
955              
956             sub select
957 0     0 1 0 {
958 0         0 my $self = shift( @_ );
959 0 0       0 my $constant = $self->constant;
960             if( scalar( keys( %$constant ) ) )
961 0 0 0     0 {
      0        
962             return( $constant->{sth} ) if( $constant->{sth} && $self->_is_object( $constant->{sth} ) && $constant->{sth}->isa( 'DB::Object::Statement' ) );
963 0   0     0 }
964 0 0       0 my $tbl_o = $self->table_object || return( $self->error( "No table object is set." ) );
965 0   0     0 my $prefix = $tbl_o->query_object->table_alias ? $tbl_o->query_object->table_alias : $tbl_o->prefix;
966             my $table = $tbl_o->qualified_name ||
967 0         0 return( $self->error( "No table name provided to perform select statement." ) );
968 0         0 my $bind = $tbl_o->use_bind;
969             my $cache = $tbl_o->use_cache;
970 0         0 # my $multi_db = $tbl_o->param( 'multi_db' );
971 0         0 my $multi_db = $tbl_o->prefix_database;
972 0         0 my $db = $tbl_o->database();
973 0         0 my $fields = '';
974 0         0 my $ok_ref = $tbl_o->fields();
975 0         0 my $ok_list = CORE::join( '|', keys( %$ok_ref ) );
  0         0  
976 0 0       0 my $tables = CORE::join( '|', @{$tbl_o->database_object->tables} );
977             if( @_ )
978             {
979 0         0 # Get aliases
980 0 0 0     0 my $alias = $self->alias();
981 0 0       0 my $data = ( @_ == 1 && ref( $_[0] ) ) ? shift( @_ ) : [ @_ ];
    0          
982             if( ref( $data ) eq 'SCALAR' )
983 0         0 {
984             $fields = $$data;
985             }
986             elsif( $self->_is_array( $data ) )
987             {
988 0         0 # Remove from the provided list any name that are aliases
989             for( my $i = 0; $i < scalar( @$data ); $i++ )
990 0         0 {
991             foreach my $n ( keys( %$alias ) )
992 0 0       0 {
993             if( lc( $alias->{ $n } ) eq lc( $data->[$i] ) )
994 0         0 {
995 0         0 splice( @$data, $i, 1 );
996             $i--;
997             }
998             }
999             }
1000 0 0       0 # No fields provided after all? We fallback to use the magic '*' optimizer
    0          
    0          
1001             $fields = @$data
1002             ? CORE::join( ', ', @$data )
1003             : scalar( keys( %$alias ) )
1004             ? ''
1005             : ( $prefix ? "${prefix}.*" : '*' );
1006             }
1007             else
1008 0         0 {
1009             $fields = $data;
1010             }
1011 0 0       0
1012             if( length( $fields ) )
1013             {
1014 0         0 # Now, we eventually add the table and database specification to the fields
1015             $fields =~ s{
1016             (?<![\.\"])\b($ok_list)\b(\s*)?(?!\.)
1017 0         0 }
1018 0 0 0     0 {
    0          
1019             my( $field, $spc ) = ( $1, $2 );
1020 0         0 if( $` =~ /\s+(?:AS|FROM)\s+$/i || !$field )
1021             {
1022             "${field}${spc}";
1023             }
1024 0         0 elsif( $prefix )
1025             {
1026             "${prefix}.${field}${spc}";
1027             }
1028 0         0 else
1029             {
1030             "${field}${spc}";
1031 0 0       0 }
1032             }gex;
1033             $fields =~ s/(?<!\.)($tables)(?:\.)/$db\.$1\./g if( $multi_db );
1034 0         0 }
1035 0 0 0     0
1036             $self->messagef_colour( 3, "<green>%d</> aliases were provided: <red>%s</>", scalar( keys( %$alias ) ), join( ', ', keys( %$alias ) ) );
1037 0         0 if( $alias && %$alias )
1038 0         0 {
1039             my @aliases = ();
1040 0 0 0     0 foreach my $f ( keys( %$alias ) )
    0 0        
    0          
1041             {
1042 0         0 if( ref( $alias->{ $f } ) eq 'SCALAR' )
  0         0  
1043             {
1044             CORE::push( @aliases, "$f AS " . ${$alias->{ $f }} );
1045             }
1046 0         0 elsif( CORE::exists( $ok_ref->{ $f } ) && $prefix )
1047             {
1048             CORE::push( @aliases, "${prefix}.${f} AS \"" . $alias->{ $f } . "\"" );
1049             }
1050             elsif( $f =~ /\b(?:$ok_list)\b/ ||
1051 0 0       0 $f =~ /\w\([^\)]*\)/ )
1052             {
1053             $f =~ s{
1054 0         0 (?<![\.\"])\b($ok_list)\b(\s*)?(?!\.)
1055 0         0 }
1056             {
1057 0 0       0 my( $ok, $spc ) = ( $1, $2 );
1058 0         0 "${prefix}.${ok}${spc}";
1059             }gex if( $prefix );
1060             $f =~ s/(?<!\.)($tables)(?:\.)/$db\.$1\./g if( $multi_db );
1061             CORE::push( @aliases, "$f AS " . "\"" . $alias->{ $f } . "\"" );
1062 0         0 }
1063             else
1064             {
1065 0 0       0 CORE::push( @aliases, "$f AS " . "\"" . $alias->{ $f } . "\"" );
1066             }
1067             }
1068             $fields = length( $fields )
1069             ? join( ', ', $fields, @aliases )
1070             : join( ', ', @aliases );
1071             }
1072 0         0 }
1073 0         0 else
1074             {
1075             $self->getdefault({ table => $table });
1076 0         0 $fields = $self->format_statement();
1077 0         0 }
1078 0         0
1079             my $tie = $self->tie();
1080 0 0       0 my $clauses = $self->_query_components( 'select' );
    0          
1081             my $vars = $self->local();
1082             # You may not sort if there is no order clause
1083 0         0 my $sort = $self->reverse() ? 'DESC' : $self->sort() ? 'ASC' : '';
1084 0 0       0 # my @query = $multi_db ? ( "SELECT $fields FROM $db.$table" ) : ( "SELECT $fields FROM $table" );
1085             # $table comes from $tbl->qualified_name which automatically sets itself with the right prefixes based on the prefixed() settings
1086 0         0 my $table_alias = '';
1087             if( length( $table_alias = $self->table_alias ) )
1088 0         0 {
1089 0         0 $table_alias = " AS $table_alias";
1090 0         0 }
1091 0         0 my @query = ( "SELECT $fields FROM ${table}${table_alias}" );
1092             my $prev_fields = $self->{selected_fields};
1093 0 0 0     0 my $last_sth = '';
1094             my $queries = $self->_cache_queries;
1095             # A simple check to avoid to do this test on each query, but rather only on those who deserve it.
1096             if( $fields eq $prev_fields && @$queries )
1097 0   0     0 {
  0         0  
1098 0         0 my @last_query = grep
1099             {
1100 0   0     0 $_->{selected_fields} ||= '';
1101             $_->{selected_fields} eq $fields
1102             } @$queries;
1103             $last_sth = $last_query[ 0 ] || {};
1104             }
1105             # If the selected fields in the last query performed were the same than those ones and
1106             # that the last query object has the flag 'as_string' set to true, this would mean that
1107             # user has made a statement as string and is now really executing it
1108             # Now, if the special flag 'query_reset' is true, this means that the user has accessed the methods
1109             # where(), group(), order() or limit() and hence this is a brain new query for which we need
1110             # to get the clause conditions
1111 0 0       0 #if( $fields eq $$prev_fields && $last_sth->{ 'as_string' } )
1112             #{
1113             ## unshift( @query, "${vars};" ) if( $vars );
1114 0         0 push( @query, @$clauses ) if( @$clauses );
1115 0         0 #}
1116 0         0 # used by join()
1117 0 0 0     0 $self->{selected_fields} = $fields;
1118             my $query = $self->{query} = CORE::join( ' ', @query );
1119 0         0 my @tie_order = ();
1120             if( $tie && %$tie )
1121             {
1122             my $copy = $fields;
1123             # According to bind_col() specifications, we need to bind perl variable
1124 0         0 # in the right column order.
1125             # We make it easy for our user, to only provide the column name and its corresponding variable
1126 0         0 # We will do the job of matching
1127             while( $copy =~ s/^.*?\b([a-zA-Z0-9\_]+)\s*(?:\,|\Z)// )
1128 0         0 {
1129             push( @tie_order, $1 );
1130             }
1131             $self->{tie_order} = \@tie_order;
1132 0         0 }
1133             # Everything meaningfull lies within the object
1134             # If no bind should be done _save_bind does nothing
1135 0         0 $self->_save_bind();
1136            
1137             # Predeclare variables if any.
1138             $tbl_o->set();
1139 0         0
1140             # Query string should lie within the object
1141 0 0       0 # _cache_this sends back an object no matter what or undef() if an error occurs
1142             my $sth = $tbl_o->_cache_this( $self );
1143 0         0 ## STOP! No need to go further
1144             if( !defined( $sth ) )
1145             {
1146             return( $self->error( "Error while preparing query to select on table '$self->{ 'table' }':\n$query", $self->errstr() ) );
1147             }
1148             # Routines such as as_string() expect an array on pupose so we do not have to commit the action
1149             # but rather get the statement string. At the end, we write:
1150             # $obj->select() to really select
1151             # $obj->select->as_string() to ONLY get the formatted statement
1152 0 0       0 # wantarray() returns the undefined value in void context, which is typical use of a real select command
1153             # i.e. $obj->select();
1154 0 0       0 # Straight forward declaration: $obj->select(); or $obj->select->execute() || die( $obj->error() );
1155             if( !defined( wantarray() ) )
1156             {
1157 0         0 $sth->execute() ||
1158             return( $self->error( "Error while executing query to select:\n", $self->as_string(), $sth->errstr() ) );
1159             }
1160 0     0 1 0 return( $sth );
1161             }
1162              
1163             sub selected_fields { return( shift->_set_get( 'selected_fields', @_ ) ); }
1164 0     0 1 0  
1165 0 0       0 sub sort
1166             {
1167 0         0 my $self = shift( @_ );
1168             if( @_ )
1169 0         0 {
1170             $self->{reverse} = 0;
1171             }
1172             return( $self->{reverse} );
1173             }
1174 0     0 1 0  
1175             # The fields in their order of appearance in insert and update
1176 21     21 1 486 # so that following ->exec( $hash ) would be able to allocate the bind values in the right order
1177             sub sorted { return( shift->_set_get_array_as_object( 'sorted', @_ ) ); }
1178 1     1 1 37  
1179             sub table_alias { return( shift->_set_get_scalar( 'table_alias', @_ ) ); }
1180              
1181             sub table_object { return( shift->_set_get_object_without_init( 'table_object', 'DB::Object::Tables', @_ ) ); }
1182 0     0 1    
1183 0 0         sub tie
1184             {
1185 0           my $self = shift( @_ );
1186 0 0 0       if( @_ )
1187 0           {
1188 0   0       my $ref = '';
1189 0           $ref = shift( @_ ) if( @_ && @_ % 2 );
1190             my %hash = ( @_ );
1191 0 0         $ref ||= \%hash;
  0            
1192             $self->{tie} = $ref;
1193             }
1194             return( wantarray() ? %{$self->{tie}} : $self->{tie} );
1195             }
1196              
1197             # sub unix_timestamp
1198             # {
1199             # my $self = shift( @_ );
1200             # if( @_ )
1201             # {
1202             # my $ref = ( @_ == 1 && $self->_is_array( $_[0] ) ) ? shift( @_ ) : [ @_ ];
1203             # $self->{ 'unix_timestamp' } ||= [];
1204             # push( @{$self->{unix_timestamp}}, ref( $ref ) ? @$ref : $ref );
1205 0     0 1   # }
1206             # return( wantarray() ? @{ $self->{ 'unix_timestamp' } } : $self->{ 'unix_timestamp' } );
1207             # }
1208             sub unix_timestamp { return( shift->_set_get_array_as_object( 'unix_timestamp', @_ ) ); }
1209 0     0 1    
1210 0 0 0       sub update
1211 0           {
1212 0 0 0       my $self = shift( @_ );
1213             my $data = shift( @_ ) if( @_ == 1 && ref( $_[ 0 ] ) );
1214 0 0         my @arg = @_;
    0          
1215             if( !@arg && $data )
1216 0           {
1217             if( $self->_is_hash( $data ) )
1218             {
1219             @arg = %$data;
1220 0           }
1221             elsif( $self->_is_array( $data ) )
1222             {
1223 0           @arg = @$data;
1224 0 0         }
1225             }
1226 0 0 0       my $constant = $self->constant;
      0        
1227             if( scalar( keys( %$constant ) ) )
1228 0   0       {
1229 0   0       return( $constant->{sth} ) if( $constant->{sth} && $self->_is_object( $constant->{sth} ) && $constant->{sth}->isa( 'DB::Object::Statement' ) );
1230             }
1231 0 0         my $tbl_o = $self->table_object || return( $self->error( "No table object is set." ) );
1232             my $table = $tbl_o->name ||
1233 0           return( $self->error( "No table to update was provided." ) );
1234             if( !scalar( @arg ) )
1235 0   0       {
1236             return( $self->error( "No data to update was provided." ) );
1237 0           }
1238 0           my $values = $self->format_update( \@arg ) ||
1239 0 0         return( $self->error( "No data to update was provided." ) );
1240 0           my $clauses = $self->_query_components( 'update' );
1241 0           my @query = ( "UPDATE $table SET $values" );
1242 0           push( @query, @$clauses ) if( scalar( @$clauses ) );
1243 0 0 0       my $query = $self->{query} = CORE::join( ' ', @query );
1244 0           my( $p, $f, $l ) = caller();
1245 0           my $call_sub = ( caller( 1 ) )[3];
1246             return( $self->error( "Refusing to do a bulk update. Called from package $p in file $f at line $l from sub $call_sub. Enable the allow_bulk_update database object property if you want to do so. Original query was: $query" ) ) if( !$self->where && !$self->database_object->allow_bulk_update );
1247 0   0       $self->{query_values} = \$values;
1248             $self->_save_bind();
1249             # my $sth = $self->prepare( $self->{ 'query' } ) ||
1250             my $sth = $tbl_o->_cache_this( $self ) ||
1251             return( $self->error( "Error while preparing query to update table '$table':\n$query" ) );
1252             # $obj->update() to really delete
1253 0 0         # $obj->update->as_string() to ONLY get the formatted statement
1254             # wantarray() returns the undefined value in void context, which is typical use of a real update command
1255 0 0         # i.e. $obj->update();
1256             if( !defined( wantarray() ) )
1257             {
1258             $sth->execute() ||
1259             return( $self->error( "Error while executing query to update table '$table':\n$query" ) );
1260 0           ## $sth->finish();
1261             }
1262             # wantarray returns false but not undefined when $obj->update->as_string();
1263 0     0 1   return( $sth );
1264             }
1265              
1266             sub where { return( shift->_where_having( 'where', 'where', @_ ) ); }
1267 0     0      
1268             sub _group_order
1269 0   0       {
1270             my $self = shift( @_ );
1271 0   0       # This is the type, ie 'group', 'order' and used to initiate the DB::Object::Query::Clause
1272 0   0       my $type = shift( @_ ) || return( $self->error( "No clause type was provided." ) );
1273 0           # This is used to store the data in $self such as $self->{ $prop } = $clause;
1274 0           my $prop = shift( @_ ) || return( $self->error( "No object data property name was provided for clause type '$type'." ) );
1275 0 0 0       my $tbl_o = $self->table_object || return( $self->error( "No table object is set." ) );
1276 0           my $bind = $tbl_o->use_bind;
1277 0 0         my $table = $tbl_o->name;
1278             $self->{ $prop } = $self->new_clause if( !CORE::length( $self->{ $prop } ) && !ref( $self->{ $prop } ) );
1279 0           my $clause;
1280 0           if( @_ )
1281 0 0 0       {
1282             my $clause = '';
1283             my $fields_ref = $tbl_o->fields();
1284 0 0         my $data = ( @_ == 1 && ( !$self->_is_object( $_[0] ) || $self->_is_array( $_[0] ) ) && !exists( $fields_ref->{ "$_[0]" } ) )
1285             ? shift( @_ )
1286 0           : [ @_ ];
1287 0           if( $self->_is_array( $data ) )
1288 0           {
1289 0           my $prefix = $tbl_o->prefix;
  0            
1290 0           my $fields = join( '|', keys( %$fields_ref ) );
1291 0           my $db = $tbl_o->database();
1292 0           my $tables = CORE::join( '|', @{$tbl_o->database_object->tables} );
1293 0           my $multi_db = $tbl_o->prefix_database;
1294 0           my $values = Module::Generic::Array->new;
1295 0           my $components = Module::Generic::Array->new;
1296             my $types = Module::Generic::Array->new;
1297 0           my $fobjects = Module::Generic::Array->new;
1298             my $generic = Module::Generic::Array->new;
1299            
1300 0 0         foreach my $field ( @$data )
1301             {
1302 0 0         # Some garbage reached us
1303 0 0 0       next if( !CORE::length( $field ) );
    0 0        
    0 0        
    0          
1304             ## Transform a simple 'field' into a field object
1305 0           $field = $tbl_o->fo->$field if( CORE::exists( $fields_ref->{ $field } ) );
1306 0           if( $self->_is_a( $field => 'DB::Object::Fields::Field' ) )
1307 0           {
1308 0           $components->push( '%s' );
1309 0           $fobjects->push( $field );
1310             $generic->push( '?' );
1311             $types->push( '' );
1312             $values->push( $field );
1313 0           }
1314             elsif( $self->_is_a( $field => 'DB::Object::Fields::Unknown' ) )
1315             {
1316             next;
1317             }
1318 0           # i.e. GROUP BY width => GROUP BY table.width
1319             elsif( ref( $field ) eq 'SCALAR' )
1320             {
1321             $components->push( $$field );
1322             }
1323             elsif( $field =~ /\b(?:$fields)\b/ ||
1324             $field =~ /\w\([^\)]*\)/ ||
1325 0 0         $field eq '?' ||
1326             !$bind )
1327             {
1328 0           $field =~ s{
1329 0           (?<![\.\"])\b($fields)\b(\s*)?(?!\.)
1330             }
1331 0 0         {
1332 0           my( $ok, $spc ) = ( $1, $2 );
1333             "${prefix}.${ok}${spc}";
1334             }gex if( $prefix );
1335             $field =~ s/(?<!\.)($tables)(?:\.)/$db\.$1\./g if( $multi_db );
1336 0           $components->push( $field );
1337 0           }
1338 0           else
1339 0           {
1340             $components->push( $field );
1341             $values->push( $field );
1342 0           $types->push( '' );
1343             $generic->push( '?' );
1344             }
1345             }
1346             $clause = $self->new_clause({
1347             value => $components->join( ', ' ),
1348 0 0         type => $type,
1349 0 0         fields => $fobjects,
1350             generic => $generic->join( ', ' ),
1351             });
1352             $clause->bind->values( @$values ) if( $bind );
1353 0           $clause->bind->types( @$types ) if( $bind );
1354             }
1355             else
1356             {
1357 0           $clause = $self->new_clause({
1358 0 0         value => $data,
1359             type => $type,
1360 0           });
1361 0           my $ref = [];
1362 0           if( $bind )
1363             {
1364             $self->_value2bind( \$data, $ref );
1365 0           $clause->bind->values( $ref );
1366             $clause->bind->types( ( '' ) x scalar( @$ref ) );
1367             }
1368             }
1369 0           $self->{ $prop } = $clause;
1370             }
1371 0           else
1372             {
1373             $clause = $self->{ $prop };
1374             }
1375             return( $clause );
1376             }
1377              
1378 0     0     # Each driver can call on this private method like sub having { return( shift->_having( @_ ) ); }
1379 0   0       # to avoid recreating it themselve
1380 0           sub _having
1381 0           {
1382 0           my $self = shift( @_ );
1383 0   0       my $tbl_o = $self->table_object || return( $self->error( "No table object is set." ) );
1384 0           my $bind = $tbl_o->use_bind;
1385 0 0         my $table = $tbl_o->name;
1386             my $prefix = $tbl_o->prefix;
1387 0 0         $self->{having} ||= '';
1388 0 0         my $clause;
1389             if( @_ )
1390 0           {
1391 0           my $data = ( @_ == 1 ) ? shift( @_ ) : [ @_ ];
1392 0           if( $self->_is_array( $data ) )
1393 0           {
  0            
1394 0           my $fields_ref = $tbl_o->fields();
1395 0           my $fields = join( '|', keys( %$fields_ref ) );
1396 0           my $db = $tbl_o->database();
1397 0           my $tables = CORE::join( '|', @{$self->{tables}->{ $db }} );
1398 0           my $multi_db = $tbl_o->prefix_database;
1399             my @values = ();
1400             my @clause = ();
1401 0 0         my @types = ();
1402             foreach my $field ( @$data )
1403 0 0 0       {
    0 0        
    0 0        
1404             # In case we received some garbage
1405 0           next if( !CORE::length( $field ) );
1406             # i.e. HAVING width => HAVING table.width
1407             if( ref( $field ) eq 'SCALAR' )
1408             {
1409             push( @clause, $self->new_clause({
1410             value => $$field,
1411             type => 'having',
1412             }) );
1413             }
1414             elsif( $field =~ /\b(?:$fields)\b/ ||
1415 0 0         $field =~ /\w\([^\)]*\)/ ||
1416             $field eq '?' ||
1417             !$bind )
1418 0           {
1419 0           $field =~ s{
1420             (?<![\.\"])\b($fields)\b(\s*)?(?!\.)
1421 0 0         }
1422 0           {
1423             my( $ok, $spc ) = ( $1, $2 );
1424             "${prefix}.${ok}${spc}";
1425             }gex if( $prefix );
1426             $field =~ s/(?<!\.)($tables)(?:\.)/$db\.$1\./g if( $multi_db );
1427             push( @clause, $self->new_clause({
1428             value => $field,
1429 0           type => 'having',
1430             }) );
1431             }
1432             elsif( $bind )
1433             {
1434             CORE::push( @clause, $self->new_clause(
1435             {
1436             value => '?',
1437             type => 'having',
1438             bind =>
1439             {
1440             values => $field,
1441             types => [ '' ],
1442 0           }
1443             }) );
1444             }
1445             else
1446             {
1447             push( @clause, $self->new_clause({
1448 0           value => $field,
1449 0 0         type => 'having',
1450 0 0         }) );
1451             }
1452             }
1453             $clause = $self->new_clause->merge( $self->database_object->AND( @clause ) );
1454 0           $clause->bind->values( @values ) if( $bind );
1455             $clause->bind->types( @types ) if( $bind );
1456             }
1457             else
1458 0           {
1459 0 0         $clause = $self->new_clause({
1460             value => $data,
1461 0           type => 'having',
1462 0 0 0       });
1463 0 0         my $ref = [];
1464             if( $bind )
1465             {
1466 0           $self->_value2bind( \$clause, $ref );
1467             $clause->bind->values( @$ref ) if( $bind && scalar( @$ref ) );
1468             $clause->bind->types( ( '' ) x scalar( @$ref ) ) if( $bind );
1469             }
1470 0           }
1471             $self->{having} = $clause;
1472 0           }
1473             else
1474             {
1475             $clause = $self->{having};
1476             }
1477 0     0     return( $clause );
1478 0           }
1479              
1480             sub _initiate_clause_object
1481 0     0     {
1482             my $self = shift( @_ );
1483             return( DB::Object::Query::Clause->new( @_ ) );
1484             }
1485 0     0      
1486 0   0       sub _limit { return( shift->_set_get_object( 'limit', 'DB::Object::Query::Clause', @_ ) ); }
1487 0            
1488 0           sub _process_limit
1489 0 0 0       {
1490             my $self = shift( @_ );
1491 0           my $tbl_o = $self->table_object || return( $self->error( "No table object is set." ) );
1492             my $bind = $tbl_o->use_bind;
1493             my $limit;
1494             if( !$self->{limit} || !$self->_is_object( $self->{limit} ) )
1495 0           {
1496             $limit = $self->{limit} = $self->new_clause({ type => 'limit' });
1497 0 0         }
1498             else
1499 0           {
1500 0 0         $limit = $self->{limit};
1501             }
1502 0           if( @_ )
1503             {
1504             my( $start, $end ) = ( '', '' );
1505             if( @_ == 1 )
1506 0           {
1507             ( $start, $end ) = ( undef(), shift( @_ ) );
1508 0           }
1509 0           else
1510 0           {
1511 0           ( $start, $end ) = ( shift( @_ ), shift( @_ ) );
1512 0           }
1513             my @binded = ();
1514 0 0         my @list = ();
1515             my @types = ();
1516 0 0         my @generic = ();
    0          
1517             foreach my $value ( $start, $end )
1518 0           {
1519             next if( !CORE::length( $value ) );
1520             ## This is a raw parameter - being a ref to a SCALAR means we must not modify it
1521             if( ref( $value ) eq 'SCALAR' )
1522             {
1523             push( @list, $$value );
1524 0           }
1525 0           ## A value to be a place holder - forward it
1526 0           elsif( $value eq '?' )
1527 0           {
1528             # push( @list, $value );
1529             push( @list, '?' );
1530             push( @generic, '?' );
1531             push( @binded, $value );
1532             push( @types, '' );
1533 0           }
1534 0           ## Normal processing
1535 0           ## elsif( $bind )
1536 0           else
1537             {
1538             push( @list, $value );
1539             push( @generic, '?' );
1540 0 0         push( @binded, $value );
1541 0 0         push( @types, '' );
1542 0           }
1543 0           }
1544 0 0         ## $limit = $self->{limit} = [ @list ];
1545             $limit->value( CORE::join( ', ', @list ) ) if( scalar( @list ) );
1546 0 0         $limit->generic( CORE::join( ', ', @generic ) ) if( scalar( @generic ) );
1547             $limit->bind->values( \@binded );
1548 0 0         $limit->bind->types( \@types );
1549 0 0         if( scalar( @list ) )
1550             {
1551             if( scalar( @list ) > 1 )
1552             {
1553 0           $limit->metadata->offset( $list[0] ) if( CORE::length( $list[0] ) );
1554 0 0         $limit->metadata->limit( $list[1] ) if( CORE::length( $list[1] ) );
1555             }
1556             else
1557             {
1558             $limit->metadata->offset( '' );
1559             $limit->metadata->limit( $list[0] ) if( CORE::length( $list[0] ) );
1560 0           }
1561             }
1562 0           }
1563             else
1564             {
1565             $limit = $self->{limit};
1566             }
1567 0     0     return( $limit );
1568 0   0       }
1569 0            
1570 0           sub _query_components
1571 0 0         {
1572             my $self = shift( @_ );
1573 0           my $type = lc( shift( @_ ) ) || $self->_query_type() || return( $self->error( "You must specify a query type: select, insert, update or delete" ) );
1574 0 0         my( $where, $group, $sort, $order, $limit );
    0          
1575 0           $where = $self->where();
1576             if( $type eq "select" )
1577 0           {
1578 0           $group = $self->group();
1579 0 0 0       $sort = $self->reverse() ? 'DESC' : $self->sort() ? 'ASC' : '';
1580 0 0 0       $order = $self->order();
1581 0 0 0       }
1582 0 0 0       $limit = $self->limit();
      0        
1583 0 0 0       my @query = ();
1584 0           push( @query, "WHERE $where" ) if( $where && $type ne 'insert' );
1585             push( @query, "GROUP BY $group" ) if( $group && $type eq 'select' );
1586             push( @query, "ORDER BY $order" ) if( $order && $type eq 'select' );
1587             push( @query, $sort ) if( $sort && $order && $type eq 'select' );
1588             push( @query, "LIMIT $limit" ) if( $limit && $type ne 'insert' );
1589 0     0     return( \@query );
1590 0 0 0       }
1591              
1592 0           sub _query_type
1593             {
1594 0           my $self = shift( @_ );
1595             if( $self->{query} && length( $self->{query} ) )
1596             {
1597             return( lc( ( $self->{query} =~ /^[[:blank:]]*(ALTER|CREATE|DROP|GRANT|LISTEN|NOTIFY|INSERT|UPDATE|DELETE|SELECT|TRUNCATE)\b/i )[0] ) )
1598             }
1599 0     0     return;
1600 0           }
1601 0 0          
1602             sub _save_bind
1603 0           {
1604 0           my $self = shift( @_ );
1605 0           my $type = shift( @_ );
1606             if( !$type )
1607 0   0       {
1608 0           my( $pkg, $file, $line, $sub ) = caller( 1 );
1609 0           $sub =~ s/(.*):://;
1610 0           $type = $sub;
1611 0           }
1612 0           my $tbl_o = $self->table_object || return( $self->error( "No table object is set." ) );
1613             my $bind = $tbl_o->use_bind;
1614 0 0         my $where = $self->where();
1615             my $group = $self->group();
1616 0           my $order = $self->order();
1617             my $limit = $self->limit();
1618 0           ## This is used so upon execute, the saved binded parameters get sent to the DBI::execute method
1619 0           if( $bind )
1620 0           {
1621 0           my $binded = $self->binded;
1622 0           ## For update or insert
1623             my $binded_values = $self->binded_values;
1624 0 0 0       my $binded_where = $self->where->bind->values;
1625 0 0 0       my $binded_group = $self->group->bind->values;
1626 0 0 0       my $binded_order = $self->order->bind->values;
1627 0 0 0       my $binded_limit = $self->limit->bind->values;
1628 0 0 0       ## The order is important
1629             $binded->push( @$binded_values ) if( $type !~ /^(?:select|delete)$/ && $binded_values->length );
1630 0           $binded->push( @$binded_where ) if( $where->length && $binded_where->length );
1631 0 0         $binded->push( @$binded_group ) if( $group->length && $binded_group->length );
  0            
1632 0 0         $binded->push( @$binded_order ) if( $order->length && $binded_order->length );
  0            
1633 0 0         $binded->push( @$binded_limit ) if( $limit->length && $binded_limit->length );
  0            
1634 0 0        
  0            
1635             my $binded_types = $self->binded_types;
1636 0           $binded_types->push( @{$where->bind->types} ) if( $where->bind->types->length );
1637             $binded_types->push( @{$group->bind->types} ) if( $group->bind->types->length );
1638             $binded_types->push( @{$order->bind->types} ) if( $order->bind->types->length );
1639             $binded_types->push( @{$limit->bind->types} ) if( $limit->bind->types->length );
1640             }
1641 0     0     return( $self );
1642             }
1643              
1644 0           sub _value2bind
1645 0           {
1646 0   0       my $self = shift( @_ );
1647 0           ## If we are not suppose to bind any values, there is no point to go on.
1648 0           ## return( 1 ) if( !$self->{ 'bind' } );
1649 0           my $str = shift( @_ );
1650 0           my $ref = shift( @_ );
1651 0           my $tbl_o = $self->{table_object} || return( $self->error( "No table object is set." ) );
1652 0           my $table = $tbl_o->name;
1653 0           my $bind = $tbl_o->use_bind;
  0            
1654 0           my $db = $tbl_o->database();
1655 0           my $prefix = $tbl_o->prefix;
1656 0           my $fields_ref = $tbl_o->fields();
1657             my $fields = CORE::join( '|', keys( %$fields_ref ) );
1658             my $tables = CORE::join( '|', @{$tbl_o->database_object->tables} );
1659             my $multi_db = $tbl_o->param( 'multi_db' );
1660             my @binded = ();
1661 0           $$str =~ s
1662 0           {
1663             (([\w\_]+)(?:\.))?\b([a-zA-Z\_]+)\b\s*(=|\!=|LIKE)\s*['"]([^'"]+)['"]
1664             }
1665 0   0       {
1666 0           do
1667             {
1668 0 0 0       my( $this_table, $field, $equity, $value ) = ( $2, $3, $4, $5 );
    0 0        
1669             ## Add to the list of value to bind on execute() only if this is not already a place holder
1670             ## push( @binded, $value ) if( $bind && $value ne '?' );
1671             $this_table ||= $table;
1672             $this_table .= '.';
1673 0           ## $bind ? "${this_table}${field}=?" : "${this_table}${field}='$value'";
1674             if( $value !~ /[\r\n]+/ &&
1675             ( $value =~ /\b(?:$fields)\b/ ||
1676             $value =~ /\w\([^\)]*\)/ ||
1677 0           $value eq '?' ) )
1678 0           {
1679             "${this_table}${field} $equity $value";
1680             }
1681             elsif( $bind )
1682 0           {
1683             push( @binded, $value );
1684             "${this_table}${field} $equity ?";
1685             }
1686 0 0         else
1687             {
1688             "${this_table}${field} $equity '$value'";
1689             }
1690 0           };
1691 0           }geix;
1692             $$str =~ s
1693 0 0         {
1694 0 0         (?<![\.\"])\b($fields)\b(\s*)?(?!\.)
1695 0           }
1696             {
1697             my( $ok, $spc ) = ( $1, $2 );
1698             "$prefix.$ok$spc";
1699             }gex if( $prefix );
1700 0     0     $$str =~ s/(?<!\.)($tables)(?:\.)/$db\.$1\./g if( $multi_db );
1701             push( @$ref, @binded ) if( @binded );
1702 0   0       return( 1 );
1703             }
1704 0   0        
1705 0   0       sub _where_having
1706 0           {
1707 0           my $self = shift( @_ );
1708 0 0 0       # This is the type, ie 'group', 'order' and used to initiate the DB::Object::Query::Clause
1709 0           my $type = shift( @_ ) || return( $self->error( "No clause type was provided." ) );
1710 0 0         # This is used to store the data in $self such as $self->{ $prop } = $clause;
1711             my $prop = shift( @_ ) || return( $self->error( "No object data property name was provided for clause type '$type'." ) );
1712 0           my $tbl_o = $self->table_object || return( $self->error( "No table object is set." ) );
1713             my $base_class = $tbl_o->base_class;
1714             my $bind = $tbl_o->use_bind;
1715 0           $self->{ $prop } = $self->new_clause() if( !CORE::length( $self->{ $prop } ) || !$self->_is_object( $self->{ $prop } ) );
1716 0           my $where = $self->{ $prop };
1717 0           if( @_ )
1718 0           {
1719 0           my @params = @_;
1720 0           # This will change the belonging of the object $self to the class DB::Object::Prepare so method
1721 0           # such as select, insert, update, delete know there are some conditionning clause to be added
1722             my $table = $tbl_o->name;
1723 0           my $db = $tbl_o->database();
1724             my $multi_db = $tbl_o->prefix_database;
1725             my $prefix = $tbl_o->prefix;
1726             my $fields_ref = $tbl_o->fields();
1727 0 0 0 0     my $fields = CORE::join( '|', keys( %$fields_ref ) );
      0        
1728 0           my $fields_type = $tbl_o->types;
1729 0          
1730 0 0         my $process_where_condition;
1731             $process_where_condition = sub
1732 0 0         {
1733 0   0       # my @parameters = @_;
1734             my $data = shift( @_ ) if( @_ % 2 && !( scalar( @_ ) == 1 && $self->_is_object( $_[0] ) ) );
1735 0           my $agg_op = 'AND';
1736 0           my @arg = ();
1737             if( $self->_is_a( $_[0], 'DB::Object::Operator' ) )
1738             {
1739             return( $self->error( "I was expecting an operator object, but got \"", $_[0], "\" instead." ) ) if( !$_[0]->isa( 'DB::Object::Operator' ) );
1740 0           $agg_op = $_[0]->operator || return( $self->error( "Unknown operator for \"", $_[0], "\"." ) );
1741             # We filter out any unknown field
1742 0 0         my @and_values = $_[0]->value;
1743 0           ( @arg ) = grep( !$self->_is_a( $_ => 'DB::Object::Fields::Unknown' ), $_[0]->value );
1744 0           }
1745 0           else
1746 0           {
1747             @arg = @_;
1748 0 0         }
    0          
    0          
1749             $data = \@arg if( @arg );
1750 0           my $str = '';
1751             my @binded = ();
1752             my @types = ();
1753             my $clause;
1754 0           # A simple scalar
1755 0           if( ref( $data ) eq 'SCALAR' )
1756 0           {
1757             $str = $$data;
1758 0 0 0       }
    0 0        
    0 0        
    0 0        
    0 0        
    0 0        
    0          
    0          
1759             elsif( ref( $data ) )
1760 0           {
1761 0           my @list = ();
1762 0           my( $field, $value );
1763 0           while( @arg )
1764             {
1765             if( $self->_is_object( $arg[0] ) && $arg[0]->isa( 'DB::Object::Operator' ) )
1766             {
1767             my $op_object = shift( @arg );
1768 0           $clause = $process_where_condition->( $op_object );
1769 0           push( @list, $clause );
1770             next;
1771             }
1772             # This is an already formulated clause
1773             elsif( $self->_is_object( $arg[0] ) && $arg[0]->isa( 'DB::Object::Query::Clause' ) )
1774 0           {
1775 0           push( @list, shift( @arg ) );
1776             next;
1777             }
1778             # An expression
1779 0           elsif( $self->_is_a( $arg[0] => 'DB::Object::Expression' ) )
1780 0           {
1781             push( @list, shift( @arg ) );
1782             next;
1783             }
1784             elsif( $self->_is_object( $arg[0] ) && $arg[0]->isa( 'DB::Object::Fields::Field::Overloaded' ) )
1785 0 0         {
1786             my $f = shift( @arg );
1787 0           my $cl = $self->new_clause(
1788 0 0         value => $f,
1789             type => 'where',
1790 0           );
1791             # $cl->bind->types->push( '' ) if( $f->binded );
1792             if( $f->binded )
1793             {
1794 0           my $const = $f->field->constant->constant;
1795             if( $const )
1796             {
1797 0           $cl->bind->types->push( $const );
1798             }
1799             else
1800             {
1801 0 0 0       $cl->bind->types->push( '' );
1802             }
1803             }
1804 0           push( @list, $cl );
1805            
1806 0           # If this field value assignment is followed (as a pair) by just a regular field, this is likely a typo.
1807             # Catching some typical typo errors for the benefit of the coder (from experience)
1808             if( scalar( @arg ) &&
1809             $self->_is_a( $arg[0], 'DB::Object::Fields::Field' ) )
1810             {
1811 0           warn( "Warning only: found a (proper) field value assignment ($f) followed by a field object '$arg[0]' (never mind the surrounding quotes) (", overload::StrVal( $arg[0] ), "). Did you forget to assign a value such as \$tbl->fo->$arg[0] == 'something' ?\n" );
1812             }
1813             next;
1814             }
1815             # Ignore it
1816 0           elsif( $self->_is_a( $arg[0] => 'DB::Object::Fields::Unknown' ) )
1817 0           {
1818             next;
1819             }
1820             # Case where there is a litteral query component, e.g. "LENGTH(lang) = 2" and the number of arguments is odd which means there is no second argument such as: ->where( "LENGTH(lang) = 2", $tbl->fo->user_id => "something );
1821 0           elsif( ( scalar( @arg ) % 2 ) && !ref( $arg[0] ) )
1822 0           {
1823 0           push( @list, $self->new_clause({ value => shift( @arg ), type => 'where' }) );
1824             next;
1825             }
1826             elsif( ( scalar( @arg ) % 2 ) && ref( $arg[0] ) eq 'SCALAR' )
1827             {
1828             my $scalar = shift( @arg );
1829 0           push( @list, $self->new_clause({ value => $$scalar, type => 'where' }) );
1830             next;
1831             }
1832 0           # Catching some typical typo errors for the benefit of the coder (from experience)
1833             # The coder provided a field object without associated value and there are no other argument passed to the where clause. He/she probably forget the assignment like $tbl->fo->field == 'something'
1834 0 0 0       elsif( $self->_is_a( $arg[0], 'DB::Object::Fields::Field' ) && scalar( @arg ) == 1 )
1835             {
1836             warn( "Warning only: found a field object '$arg[0]' (never mind the surrounding quotes) (", overload::StrVal( $arg[0] ), ") followed by no other argument. Did you forget to assign a value such as \$tbl->fo->$arg[0] == 'something' ?\n" );
1837 0           }
1838            
1839             my( $field, $value ) = ( shift( @arg ), shift( @arg ) );
1840 0 0         # Catching some typical typo errors for the benefit of the coder (from experience)
1841             if( $self->_is_a( $field, 'DB::Object::Fields::Field' ) &&
1842 0 0         $self->_is_a( $value, 'DB::Object::Fields::Field::Overloaded' ) )
1843             {
1844 0           warn( "Warning only: found a field object '$field' (never mind the surrounding quotes) (", overload::StrVal( $field ), ") followed by an another (proper) field value assignment ($value). Did you forget to assign a value such as \$tbl->fo->$field == 'something' ?\n" );
1845 0 0 0       }
    0          
1846            
1847 0           unless( $self->_is_a( $field => 'DB::Object::Fields::Field' ) )
1848 0 0         {
1849             $field =~ s/\b(?<![\.\"])($fields)\b/$prefix.$1/gs if( $prefix );
1850 0 0         }
1851             my $i_am_negative = 0;
1852             if( $self->_is_a( $value, 'DB::Object::NOT' ) )
1853 0           {
1854             ( $value ) = $value->value;
1855             $value = $self->database_object->NULL if( !defined( $value ) );
1856             # https://www.postgresql.org/docs/8.3/functions-comparison.html
1857             if( lc( $value ) eq 'null' )
1858 0           {
1859             # If e do not first copy the value to a separate variable, we would end up with a circular reference (type REF)
1860 0           push( @list, $self->new_clause({
1861             value => "$field IS NOT NULL",
1862             type => 'where',
1863             })
1864             );
1865 0           next;
1866             }
1867             $i_am_negative++;
1868             }
1869             # When value is undef() or explicitly set to NULL, we need to write this as IS NULL to be sql compliant
1870 0           elsif( !defined( $value ) || lc( $value ) eq 'null' )
1871             {
1872             push( @list, $self->new_clause({
1873 0           value => "$field IS NULL",
1874 0 0         type => 'where',
1875             })
1876 0           );
1877             next;
1878             }
1879            
1880 0 0         my $f;
1881             if( $self->_is_a( $field => 'DB::Object::Fields::Field' ) )
1882             {
1883 0 0 0       $f = '%s';
    0 0        
    0          
    0          
1884             }
1885 0 0         else
1886             {
1887             $f = $prefix ? "$prefix.$field" : $field;
1888             }
1889            
1890             if( ref( $value ) eq 'SCALAR' )
1891             {
1892             push( @list, $self->new_clause({
1893             value => $i_am_negative ? "$field != $$value" : "$field = $$value",
1894             type => 'where' })
1895             );
1896             }
1897 0           # If this is a sub-select - i.e.
1898 0 0         # SELECT article, dealer, price
    0          
1899             # FROM shop
1900             # WHERE price=(SELECT MAX(price) FROM shop)
1901             # By default we get the value and use it in our clause, but sub classes like DB::Object::Postgres::Query would use the statement as is to form a native sub-query
1902             elsif( ref( $value ) eq "${base_class}::Statement" )
1903 0           {
1904 0           my $res = $value->fetchrow();
1905 0 0         my $cl = $self->new_clause({
1906 0           value => $i_am_negative ? "$f != '$res'" : "$f = '$res'",
1907             generic => $i_am_negative ? "$f != ?" : "$f = ?",
1908             type => 'where',
1909             });
1910             $cl->bind->values( $res );
1911 0 0         $cl->bind->types( '' );
1912             $cl->fields( $field ) if( $self->_is_a( $field => 'DB::Object::Fields::Field' ) );
1913 0           push( @list, $cl );
1914             }
1915 0           elsif( ref( $value ) eq 'Regexp' )
1916 0 0 0       {
    0          
1917             # (?^:^want-(.*?)) => ^want-(.*?)
1918 0 0         if( $value =~ s/^\(\?\^\:// )
    0          
1919             {
1920             $value =~ s/\)$//;
1921             }
1922             my $cl;
1923             if( $self->database_object->driver eq 'Pg' )
1924             {
1925             $cl = $self->new_clause({
1926             value => $i_am_negative ? "$f !~ '$value'" : "$f ~ '$value'",
1927 0 0         generic => $i_am_negative ? "$f !~ ?" : "$f ~ ?",
    0          
1928             type => 'where',
1929             });
1930             }
1931             elsif( $self->database_object->driver eq 'SQLite' ||
1932             $self->database_object->driver eq 'mysql' )
1933 0           {
1934 0           $cl = $self->new_clause({
1935 0 0         value => $i_am_negative ? "$f NOT REGEXP('$value')" : "$f REGEXP('$value')",
1936 0           generic => $i_am_negative ? "$f NOT REGEXP(?)" : "$f REGEXP(?)",
1937             type => 'where',
1938             });
1939             }
1940             $cl->bind->values( $value );
1941             $cl->bind->types( '' );
1942             $cl->fields( $field ) if( $self->_is_a( $field => 'DB::Object::Fields::Field' ) );
1943 0 0         push( @list, $cl );
1944             }
1945             elsif( $value =~ /[\s\(\)\.\'\"]+(?:$fields)[\s\(\)\.\'\"]+/ ||
1946             $value =~ /\w\([^\)]*\)/ ||
1947 0 0         $value eq '?' )
1948 0 0         {
1949 0           # Nothing fancy, as is. Even with binding option on, it will still return the clause without placeholder, because we don't know what $value is
1950             my $cl = $self->new_clause({
1951             value => $i_am_negative ? "$f != $value" : "$f = $value",
1952             type => 'where',
1953 0           });
1954             $cl->bind->types( '' ) if( $value eq '?' );
1955 0 0 0       $cl->fields( $field ) if( $self->_is_a( $field => 'DB::Object::Fields::Field' ) );
1956             push( @list, $cl );
1957 0 0         }
1958             else
1959             {
1960             my $cl;
1961             my $const;
1962             if( lc( $fields_type->{ $field } ) eq 'bytea' && ( $const = $self->database_object->get_sql_type( 'bytea' ) ) )
1963             {
1964             $cl = $self->new_clause({
1965 0 0         # value => "$f" . ( $i_am_negative ? '!=' : '=' ) . $tbl_o->database_object->quote( $value, DBD::Pg::PG_BYTEA ),
    0          
1966             value => "$f" . ( $i_am_negative ? '!=' : '=' ) . $tbl_o->database_object->quote( $value, $const ),
1967             type => 'where',
1968             });
1969             }
1970 0           else
1971             {
1972 0 0         $cl = $self->new_clause({
1973 0 0 0       value => "$f" . ( $i_am_negative ? '!=' : '=' ) . $tbl_o->database_object->quote( $value ),
1974             generic => $i_am_negative ? "$f != ?" : "$f = ?",
1975             type => 'where',
1976             });
1977             $cl->bind->values( $value );
1978 0           }
1979             $cl->fields( $field ) if( $self->_is_a( $field => 'DB::Object::Fields::Field' ) );
1980             if( lc( $fields_type->{ $field } ) eq 'bytea' &&
1981             ( $const = $self->database_object->get_sql_type( 'bytea' ) ) )
1982 0 0         {
1983             # TODO Really need to fix this !!
1984 0           # $cl->bind->types( DBD::Pg::PG_BYTEA );
1985             $cl->bind->types( $const );
1986             }
1987             else
1988 0           {
1989             $cl->bind->types( '' ) if( $value eq '?' );
1990             }
1991             CORE::push( @list, $cl );
1992 0 0         }
1993 0           }
1994 0           # End while @arg loop
1995 0           $clause = $self->new_clause->merge( $tbl_o->database_object->$agg_op( @list ) );
1996             }
1997             elsif( $data )
1998             {
1999             $self->_value2bind( \$data, \@binded ) if( $bind );
2000             $str = $data;
2001             @types = ( '' ) x scalar( @binded );
2002             $clause = $self->new_clause({
2003             value => $str,
2004 0           bind =>
2005 0           {
2006 0           values => \@binded,
2007 0           types => \@types,
2008             }
2009             });
2010             }
2011 0           return( $clause );
2012             };
2013 0           $where = $self->{ $prop } = $process_where_condition->( @params );
2014             return( $where );
2015             }
2016             else
2017             {
2018             $where = $self->{ $prop };
2019             }
2020 2     2   28 return( $where );
  2         3  
  2         63  
2021 2     2   10 }
  2         5  
  2         21  
2022 2     2   171  
  2         4  
  2         9  
2023 2     2   167 # NOTE: package DB::Object::Query::Clause
  2         5  
  2         9  
2024             package DB::Object::Query::Clause;
2025 2         14 BEGIN
2026             {
2027 2     2   179 use strict;
  2         5  
2028 2     2   2056 use common::sense;
2029             use parent qw( Module::Generic );
2030             use Devel::Confess;
2031             use overload (
2032             '""' => 'as_string',
2033 0     0     fallback => 1,
2034 0           );
2035 0           our( $VERSION ) = '0.1';
2036 0           };
2037 0            
2038 0           sub init
2039 0 0         {
2040             my $self = shift( @_ );
2041 0           my @copy = @_;
2042             $self->{value} = '';
2043             $self->{generic} = '';
2044             $self->{_init_strict_use_sub} = 1;
2045             $self->{fields} = [];
2046             defined( $self->SUPER::init( @copy ) ) || return( $self->pass_error );
2047 0     0     # return( $self->error( "No sql clause was provided." ) ) if( !$self->{value} );
2048 0           return( $self );
2049 0 0 0       }
2050              
2051 0 0         sub as_string
2052 0           {
2053             # no overloading;
2054 0           my $self = shift( @_ );
2055 0 0         my $fields = $self->fields;
2056             if( $self->generic->length && $self->query_object->table_object->use_bind )
2057 0           {
2058             return( $self->generic ) if( !$fields->length );
2059             return( Module::Generic::Scalar->new( CORE::sprintf( $self->generic, @$fields ) ) );
2060             }
2061             my $str = $self->value;
2062             return( $str ) if( !$fields->length );
2063 0     0     # Stringification of the fields will automatically format them properly, ie with a table prefix, schema prefix, database prefix as necessary
2064             return( Module::Generic::Scalar->new( CORE::sprintf( $str, @$fields ) ) );
2065             # return( CORE::sprintf( $str, @$fields ) );
2066             }
2067              
2068             sub bind
2069             {
2070             return( shift->_set_get_class( 'bind',
2071             {
2072 0     0     # The sql types of the value bound to the placeholders
2073             types => { type => 'array_as_object' },
2074 0     0     # The values bound to the placeholders in the sql clause
2075             values => { type => 'array_as_object' },
2076 0     0     }, @_ ) );
2077             }
2078 0     0      
2079             sub fields { return( shift->_set_get_array_as_object( 'fields', @_ ) ); }
2080              
2081             sub generic { return( shift->_set_get_scalar_as_object( 'generic', @_ ) ); }
2082 0     0      
2083 0 0         sub length { return( shift->value->length ); }
2084              
2085             sub metadata { return( shift->_set_get_hash_as_object( 'metadata', @_ ) ); }
2086 0            
2087 0           sub merge
2088             {
2089             my $self = shift( @_ );
2090             if( @_ )
2091 0 0 0       {
2092             # By default
2093 0           my $op = 'AND';
2094 0 0 0       my @params = ();
      0        
2095 0           # $clause->merge( $dbh->OR( $clause1, $clause2, $clause3 ) );
2096 0           # or just
2097             # $clause->merge( $clause1, $clause2, $clause3 );
2098             if( $self->_is_object( $_[0] ) && $_[0]->isa( 'DB::Object::Operator' ) )
2099             {
2100 0           my $op_obj = shift( @_ );
2101             return( $self->error( "Database Object operator provided is invalid. It should be either an AND or OR." ) ) if( $op_obj->operator ne 'AND' and $op_obj->operator ne 'OR' and $op_obj->operator ne 'NOT' );
2102             $op = $op_obj->operator;
2103 0           @params = grep( !$self->_is_a( 'DB::Object::Fields::Unknown' ), $op_obj->value );
2104 0 0         }
2105 0           else
2106 0 0         {
2107 0           @params = @_;
2108             }
2109            
2110             my @clause = ();
2111 0 0         @clause = ( $self->value ) if( $self->value->length > 0 );
2112             my @generic = ();
2113 0           @generic = ( $self->generic ) if( $self->generic->length > 0 );
2114 0           foreach my $this ( @params )
2115             {
2116             # Safeguard against garbage
2117 0 0         # Special treatment for DB::Object::Fields::Field::Overloaded who are already formatted
2118             if( $self->_is_a( $this => [qw( DB::Object::Fields::Field::Overloaded DB::Object::Expression )] ) )
2119 0 0         {
2120             push( @clause, $this );
2121 0           next;
2122             }
2123 0 0 0      
      0        
2124             next if( !$self->_is_a( $this => 'DB::Object::Query::Clause' ) );
2125 0           # First check we even have a clause, otherwise skip
2126             if( !$this->value->length )
2127             {
2128             CORE::next;
2129             }
2130             if( $self->type->length && $this->type->length && $this->type ne $self->type )
2131             {
2132             return( $self->error( "This clause provided for merge is not of the same type \"", $this->type, "\" as ours \"", $self->type, "\"." ) );
2133             }
2134 0 0         # Possibly our type is empty and if so, we initiate it by using the type of the first object we find
2135 0           # This makes it convenient to merge without having to set the type beforehand like so:
2136 0 0         # $clause->type( 'where' );
2137 0 0         # $clause->merge( $w1, $w2, $e3 );
  0            
2138 0 0         # We can do instead
  0            
2139 0 0         # $clause->merge( $w1, $w2, $e3 );
  0            
2140 0           # And it will take the type from $w1
2141 0           $self->type( $this->type ) if( !$self->type->length );
2142 0           CORE::push( @clause, $this->value );
2143             CORE::push( @generic, $this->generic ) if( $this->generic->length );
2144 0 0         $self->fields->push( @{$this->fields} ) if( $this->fields->length );
2145             $self->bind->types->push( @{$this->bind->types} ) if( $this->bind->types->length );
2146 0           $self->bind->values->push( @{$this->bind->values} ) if( $this->bind->values->length );
2147             my $ref = $this->metadata;
2148 0           my $hash = $self->metadata;
2149 0           foreach my $k ( keys( %$ref ) )
2150             {
2151 0           $hash->{ $k } = $ref->{ $k } if( !CORE::exists( $hash->{ $k } ) );
2152             }
2153             $self->metadata( $hash );
2154 0     0     }
2155             $self->value( CORE::join( " $op ", @clause ) );
2156             $self->generic( CORE::join( " $op ", @generic ) );
2157 0     0     }
2158             return( $self );
2159             }
2160 0     0      
2161             sub query_object { return( shift->_set_get_object( 'query_object', 'DB::Object::Query', @_ ) ); }
2162              
2163             # The clause type e.g. where, order, group, having, limit, etc
2164             sub type { return( shift->_set_get_scalar_as_object( 'type', @_ ) ); }
2165              
2166             # The string value of the clause
2167             sub value { return( shift->_set_get_scalar_as_object( 'value', @_ ) ); }
2168              
2169             1;
2170              
2171             # NOTE: POD
2172             __END__
2173              
2174             =encoding utf-8
2175              
2176             =head1 NAME
2177              
2178             DB::Object::Query - Query Object
2179              
2180             =head1 SYNOPSIS
2181              
2182             my $q = DB::Object::Query->new;
2183              
2184             =head1 VERSION
2185              
2186             v0.5.2
2187              
2188             =head1 DESCRIPTION
2189              
2190             This is the base class for this L<DB::Object> query formatter.
2191              
2192             =head1 METHODS
2193              
2194             =head2 alias
2195              
2196             Sets or gets an hash of column name to alias.
2197              
2198             =head2 as_string
2199              
2200             Returns the formatted query as a string.
2201              
2202             =head2 avoid
2203              
2204             Takes a list or array reference of column to avoid in the next query. This returns a L<Module::Generic::Array> object.
2205              
2206             =head2 binded
2207              
2208             Takes a list or array reference of values to bind in the next query in L<DB::Object::Statement/execute>. This returns a L<Module::Generic::Array> object.
2209              
2210             =head2 binded_group
2211              
2212             This returns the values to bind for the C<group> clause of the query. This returns a L<Module::Generic::Array> object.
2213              
2214             =head2 binded_limit
2215              
2216             This returns the values to bind for the C<limit> clause of the query. This returns a L<Module::Generic::Array> object.
2217              
2218             =head2 binded_order
2219              
2220             This returns the values to bind for the C<order> clause of the query. This returns a L<Module::Generic::Array> object.
2221              
2222             =head2 binded_types
2223              
2224             Takes a list or array reference of value types to bind in the next query in L<DB::Object::Statement/execute>. This returns a L<Module::Generic::Array> object.
2225              
2226             =head2 binded_types_as_param
2227              
2228             This does nothing and must be implemented by the driver package. So, see L<DB::Object::Mysql::Query/binded_types_as_param>, L<DB::Object::Postgres::Query/binded_types_as_param>, and L<DB::Object::SQLite::Query/binded_types_as_param>
2229              
2230             =head2 binded_values
2231              
2232             Takes a list or array reference of values to bind in the next query in L<DB::Object::Statement/execute>. This returns a L<Module::Generic::Array> object.
2233              
2234             =head2 binded_where
2235              
2236             This returns the values to bind for the C<where> clause of the query. This returns a L<Module::Generic::Array> object.
2237              
2238             =head2 constant
2239              
2240             If any argument is provided, this expects an hash reference of constants to value pairs.
2241              
2242             It returns the currently set constants as a hash reference.
2243              
2244             =head2 database_object
2245              
2246             Returns the current database object, which should be driver specific like L<DB::Object::Postgres>
2247              
2248             =head2 delete
2249              
2250             Takes some optional arguments used to define the C<where> clause, and this will prepare a C<DELETE> query.
2251              
2252             It will refuse to prepare the query if no C<where> clause has been defined, as this would be a very unsafe query. You would need to execute such query yourself using L<DB::Object/do>.
2253              
2254             If this method is called in void, this will execute the query.
2255              
2256             It returns the newly created statement handler as a L<DB::Object::Statement>
2257              
2258             =head2 enhance
2259              
2260             Enable or disable enhancement mode.
2261              
2262             =head2 final
2263              
2264             Enables to know the query reached the end, so that when constant is used, all the processing can be skipped.
2265              
2266             =head2 from_table
2267              
2268             The table used, if any, in a C<FROM> clause.
2269              
2270             =head2 format_statement
2271              
2272             Provided with an hash or hash reference of parameters and this will format the sql statement for queries of types C<select>, C<delete> and C<insert>
2273              
2274             In list context, it returns 2 strings: one comma-separated list of fields and one comma-separated list of values. In scalar context, it only returns a comma-separated string of fields.
2275              
2276             Accepted parameters are:
2277              
2278             =over 4
2279              
2280             =item I<data>
2281              
2282             =item I<order>
2283              
2284             If not provided, this will use the default column order for this table.
2285              
2286             =item I<table>
2287              
2288             The table name to use, or, if not specified, this will be set to a value set with L<DB::Object::Tables/qualified_name>
2289              
2290             =back
2291              
2292             If any values were set by L</from_unixtime> or L</unix_timestamp>, the associated columns will be formatted accordingly in the sql statement.
2293              
2294             It will go through each of the parameter passed to the original C<insert>, C<delete>, or C<select> query and if a column is one set earlier by L</from_unixtime> or L</unix_timestamp>, it will format it.
2295              
2296             If a parameter provided is a L<DB::Object::Statement> it will stringify the query and add it surrounded by parenthesis.
2297              
2298             If a parameter is actually a scalar reference, this means to us to use the underlying string as is.
2299              
2300             If a parameter is C<?>, this will be treated as a placeholder.
2301              
2302             If a parameter is a blob, it will be transformed into a parameter as a placeholder with its value saved to be bound in L<DB::Object::Statement/execute>
2303              
2304             If L<DB::Object/bind> is not enabled, then the value provided with this parameter will be added after being possibly surrounded by quotes using L<DB::Object::Tables/quote>.
2305              
2306             If the column type for this parameter is C<ENUM> and the query is of type C<INSERT> or C<UPDATE>, then the parameter value is surrounded with single quote.
2307              
2308             If L<DB::Object/bind> is enabled, then a placeholder C<?> will be added and the parameter value will be saed to be passed during L<DB::Object::Statement/execute>
2309              
2310             If nothing else matches it will add the value, possible quoted, using L<DB::Object::Tables/quote>, whose implementation can be driver specific.
2311              
2312             If column prefix is required, then the necessary prefix will be prepended to columns.
2313              
2314             In list context, this returns the formatted columns and their values, and in scalar context it will returns only the formatted columns.
2315              
2316             =head2 format_update
2317              
2318             Provided with a list of parameters either as a key-value pairs, as an hash reference or even as an array reference and this will format update query based on the following arguments provided:
2319              
2320             =over 4
2321              
2322             =item I<data>
2323              
2324             An array of key-value pairs to be used in the update query. This array can be provided as the prime argument as a reference to an array, an array, or as the I<data> element of a hash or a reference to a hash provided.
2325              
2326             Why an array if eventually we build a list of key-value pair? Because the order of the fields may be important, and if the key-value pair list is provided, B<format_update> honors the order in which the fields are provided.
2327              
2328             =back
2329              
2330             If no data is provided, this will return an error.
2331              
2332             L</format_update> will then iterate through each field-value pair, and perform some work:
2333              
2334             If the field being reviewed was provided to L</from_unixtime>, then L</format_update> will enclose it in the function suitable for the driver to convert it into a database datetime. For example, for Mysql, this would be:
2335              
2336             FROM_UNIXTIME(field_name)
2337            
2338             If the the given value is a reference to a scalar, it will be used as-is, ie. it will not be enclosed in quotes or anything. This is useful if you want to control which function to use around that field.
2339              
2340             If the value is C<?> it will be used as a placeholder and the value will be saved to be bound later in L<DB::Object::Statement/execute>. Its associated type will be added as blank, so it can be guessed later. However, if the column data type is C<bytea>, the the PostgreSQL data type C<DBD::Pg::PG_BYTEA> will be used when binding the value.
2341              
2342             If the column type is C<jsonb>, and the value is an hash reference, it will be json encoded and used instead.
2343              
2344             If the given value is another field or looks like a function having parenthesis, or if the value is a question mark, the value will be used as-is.
2345              
2346             If L<DB::Object/bind> is off, the value will be escaped and the pair field='value' created.
2347              
2348             If the field is a SET data type and the value is a number, the value will be used as-is without surrounding single quote.
2349              
2350             If L<DB::Object/bind> is enabled, a question mark will be used as the value and the original value will be saved as value to bind upon executing the query.
2351              
2352             Finally, otherwise the value is escaped and surrounded by single quotes.
2353              
2354             L</format_update> returns a regular string representing the comma-separated list of columns with their value assigment that will be used.
2355              
2356             =head2 from_unixtime
2357              
2358             Takes a list or array reference of columns that needs to be treated as unix timestamp and will be converted into a database timestamp.
2359              
2360             It returns that list as a L<Module::Generic::Array>
2361              
2362             =head2 format_from_epoch
2363              
2364             This is the driver specific implementation to convert unix timestamp to the database timestamp.
2365              
2366             This is superseded in driver specific implementation, so see L<DB::Object::Mysql::Query/format_from_epoch>, L<DB::Object::Postgres::Query/format_from_epoch> and L<DB::Object::SQLite:::Query/format_from_epoch>
2367              
2368             =head2 format_to_epoch
2369              
2370             This is the driver specific implementation to convert the database timestamp to unix timestamp.
2371              
2372             This is superseded in driver specific implementation, so see L<DB::Object::Mysql::Query/format_from_epoch>, L<DB::Object::Postgres::Query/format_from_epoch> and L<DB::Object::SQLite:::Query/format_from_epoch>
2373              
2374             =head2 getdefault
2375              
2376             Provided with an hash or hash reference of parameters and this will do some preparation work.
2377              
2378             Possible parameters are:
2379              
2380             =over 4
2381              
2382             =item I<arg>
2383              
2384             An array reference of data which should be a key-value pairs.
2385              
2386             =item I<as>
2387              
2388             An hash reference of column to alias pairs. Alternatively, if this is not provided, the value set with L</alias> will be used.
2389              
2390             =item I<avoid>
2391              
2392             An array reference of column to avoid using. Alternatively, if this is not provided, the value set with L</avoid> will be used.
2393              
2394             =item I<from_unixtime>
2395              
2396             An array reference of columns to be converted from unix timestamp to the database timestamp.
2397              
2398             =item I<query_type>
2399              
2400             The type of query, such as C<delete>, C<insert>, C<replace>, C<select>, C<update>
2401              
2402             =item I<table>
2403              
2404             The table name.
2405              
2406             =item I<time>
2407              
2408             A unix timestamp. Alternatively, I<unixtime> can be used.
2409              
2410             =item I<unix_timestamp>
2411              
2412             An array reference of columns to be converted into unix timestamp.
2413              
2414             =back
2415              
2416             Does some preparation work such as :
2417              
2418             =over 4
2419              
2420             =item 1
2421              
2422             the date/time field to use the FROM_UNIXTIME and UNIX_TIMESTAMP functions
2423              
2424             =item 2
2425              
2426             removing from the query the fields to avoid, ie the ones set with the B<avoid> method.
2427              
2428             =item 3
2429              
2430             set the fields alias based on the information provided with the B<alias> method.
2431              
2432             =item 4
2433              
2434             if a field last_name and first_name exist, it will also create an alias I<name> based on the concatenation of the 2.
2435              
2436             =item 5
2437              
2438             it will set the default values provided. This is used for UPDATE queries.
2439              
2440             =back
2441              
2442             It sets the following properties of the current object:
2443              
2444             =over 4
2445              
2446             =item I<bind>
2447              
2448             A boolean value whether the use of placeholder is enabled.
2449              
2450             =item I<query_type>
2451              
2452             The type of query, such as C<select>, C<insert>, etc...
2453              
2454             =item I<_args>
2455              
2456             The arguments provided as an array reference.
2457              
2458             =item I<_default>
2459              
2460             The default value as an hash reference.
2461              
2462             =item I<_extra>
2463              
2464             Extra parameters as an array reference.
2465              
2466             =item I<_fields>
2467              
2468             The columns as an hash reference.
2469              
2470             =item I<_from_unix>
2471              
2472             An hash reference
2473              
2474             =item I<_structure>
2475              
2476             The table structure which is an hash reference of column name to definition pairs.
2477              
2478             =item I<_to_unix>
2479              
2480             An hash reference
2481              
2482             =back
2483              
2484             It returns a new L<DB::Object::Tables> object with all the data prepared within.
2485              
2486             =head2 group
2487              
2488             Format the C<group by> portion of the query by calling L</_group_order>
2489              
2490             It returns a new L<DB::Object::Query::Clause> object.
2491              
2492             =head2 having
2493              
2494             This must be superseded by driver specific implementation of this class. Check out L<DB::Object::Mysql::Query/having>, L<DB::Object::Postgres::Query/having>, L<DB::Object::SQLite::Query/having>
2495              
2496             =head2 insert
2497              
2498             $tbl->insert( col1 => $val1, col2 => $val 2 );
2499             # or
2500             $other_tbl->where( user => 'joe' );
2501             my $sth = $other_tbl->select;
2502             $tbl->insert( $sth );
2503             # will become INSERT INTO some_table SELECT col1, col2 FROM other_table WHERE user = 'joe'
2504              
2505             Provided with an array reference or an hash reference or a statement object (L<DB::Object::Statement>) or a list of parameters and this will prepares an C<insert> query using the field-value pairs provided.
2506              
2507             If a L<DB::Object::Statement> object is provided as first argument, it will be considered as a SELECT query to be used in the INSERT query, as in: INSERT INTO my table SELECT FROM another_table
2508              
2509             Otherwise, L</insert> will build the query based on the fields provided.
2510              
2511             In void context, it will execute the query by calling of L<DB::Object::Statement/execute>.
2512              
2513             It returns the statement object.
2514              
2515             =head2 is_upsert
2516              
2517             Sets or gets the boolean value if the query is an C<upsert>, which means a C<insert> or C<update> query that uses an C<ON CONFLICT> clause. See L<DB::Object::Postgres::Query/on_conflict>
2518              
2519             =head2 join_fields
2520              
2521             Sets or gets the join fields. This is a regular string.
2522              
2523             =head2 join_tables
2524              
2525             Sets or gets the table joined. This returns a L<Module::Generic::Array>
2526              
2527             =head2 left_join
2528              
2529             Sets or gets an hash reference of column joint column pairs
2530              
2531             =head2 limit
2532              
2533             Set or get the limit for the future statement, by calling L</_process_limit>
2534              
2535             It returns a L<DB::Object::Query::Clause> representing the C<limit> clause.
2536              
2537             =head2 local
2538              
2539             Provided with a variable name and value pairs and this will set them.
2540              
2541             It returns the formated declaration as a string.
2542              
2543             =head2 new_clause
2544              
2545             This returns a new L<DB::Object::Query::Clause> object.
2546              
2547             =head2 order
2548              
2549             Provided with a list of parameter and this will format the C<order> clause by calling L</_group_order>
2550              
2551             It returns a new L<DB::Object::Query::Clause> object.
2552              
2553             =head2 prepare_options
2554              
2555             Sets or gets the options that will be used in L<DB::Object/_cache_this>, which is taked with preparing statement when they are not already cached.
2556              
2557             This method basically handles an hash reference of properties set by L<DB::Object::Query> and their inheriting packages. Currently only PostgreSQL makes use of this with L<DB::Object::Postgres::Query/dollar_placeholder> and L<DB::Object::Postgres::Query/server_prepare>
2558              
2559             =head2 query
2560              
2561             Sets or gets the query string. It returns whatever is set as a regular string.
2562              
2563             =head2 query_reset
2564              
2565             Reset the query object to its nominal value so it can be re-used.
2566              
2567             =head2 query_reset_core_keys
2568              
2569             Returns an L<Module::Generic::Array> object of core object properties shared with inheriting package.
2570              
2571             Those are used to know what properties to reset.
2572              
2573             =head2 query_reset_keys
2574              
2575             Returns an L<Module::Generic::Array> object of object properties shared with inheriting package.
2576              
2577             This contains driver specific properties and together with the ones provided with L</query_reset_core_keys>, they form a whole.
2578              
2579             =head2 query_type
2580              
2581             Sets or gets the query type, such as C<delete>, C<insert>, C<select>, C<update>, etc.
2582              
2583             =head2 query_values
2584              
2585             Sets or gets the query values.
2586              
2587             =head2 replace
2588              
2589             This is unsupported by default and its implementation is driver specific.
2590              
2591             =head2 reset
2592              
2593             Reset the query object.
2594              
2595             What it does is remove the following object properties: alias local binded binded_group binded_limit binded_order binded_types binded_values binded_where where limit group_by order_by reverse from_unixtime unix_timestamp sorted
2596              
2597             =head2 reset_bind
2598              
2599             Reset the bind values by setting the following object property to an empty anonymous array: binded binded_group binded_limit binded_order binded_types binded_where
2600              
2601             =head2 returning
2602              
2603             This is unsupported by default and its implementation is driver specific.
2604              
2605             =head2 reverse
2606              
2607             Mark the query to use reverse order. This is used by L</order>.
2608              
2609             =head2 select
2610              
2611             Provided with a list or an array reference of columns, and this will format the C<select> statement.
2612              
2613             If the parameters provided is actually a scalar reference, it will be used as is.
2614              
2615             If the parameters provided is an array or array reference, it will be joined using comma to get the list of columns to get, or, if the array is empty, the special C<*> will be used to get all the columns.
2616              
2617             Otherwise, it will use the data parameter provided as is.
2618              
2619             If any alias have been set using L</alias>, they will be added to the list of columns to get.
2620              
2621             if a table alias was set using L</table_alias> it will be set here.
2622              
2623             If the method was called in void context, it will execute immediately the statement object prepared.
2624              
2625             It returns the statement object (DB::Object::Statement).
2626              
2627             =head2 selected_fields
2628              
2629             Sets or gets the string representing the list of columns used in previous C<select> statement.
2630              
2631             =head2 sort
2632              
2633             Set the query to use normal sorting order.
2634              
2635             =head2 sorted
2636              
2637             Sets or gets the list of sorted columns used in statements. This returns a L<Module::Generic::Array> object.
2638              
2639             =head2 table_alias
2640              
2641             Sets an optional alias for this table to be used in statement.
2642              
2643             =head2 table_object
2644              
2645             Sets or gets the table object. This will return a L<DB::Object::Tables> object
2646              
2647             =head2 tie
2648              
2649             If provided a hash or a hash ref, it sets the list of fields and their corresponding perl variable to bind their values to.
2650              
2651             In list context, it returns the list of those field-variable pair, or a reference to it in scalar context.
2652              
2653             =head2 unix_timestamp
2654              
2655             Provided a list or an array reference of columns, and this sets the columns to be treated for seamless conversion from and to unix time.
2656              
2657             It returns a L<Module::Generic::Array> object.
2658              
2659             =head2 update
2660              
2661             Provided with a list, an array reference, or an hash or hash reference of key-value pairs and this will format the update statement.
2662              
2663             If no parameter is provided, this will return an error.
2664              
2665             This will call L</format_update> to format the parameter provided and use the resulting string in the C<update> statement.
2666              
2667             If any clauses have been defined such as C<where>, C<limit>, etc, they will be properly formatted and added to the statement.
2668              
2669             The resulting formatted query will be saved as the object property L</query>.
2670              
2671             The formatted update columns and values will be saved in the current object property L</query_values>
2672              
2673             If L</update> is called in void context, this will execute the query immediately.
2674              
2675             It returns the statement object (L<DB::Object::Statement>).
2676              
2677             =head2 where
2678              
2679             Build the where clause based on the field-value hash provided by calling L</_where_having>.
2680              
2681             It returns a clause object (L<DB::Object::Query::Clause>).
2682              
2683             =head2 _group_order
2684              
2685             This support method is called by L</group> and L</order> to format those clauses.
2686              
2687             Provided with an object, or a list or an array reference of parameters and this will format the relevant clause.
2688              
2689             it will go through each parameter and if the parameter provided is an L<DB::Object::Fields::Field> object, it will collect its various attribute.
2690              
2691             If the parameter is a scalar reference, it will be used as is.
2692              
2693             If the parameter looks like it contains some field, it will be prepended by an appropriate prefix of table and possible database and schema name, if necessary.
2694              
2695             Otherwise, it will use whatever value was provided as a column and use it.
2696              
2697             It returns a L<DB::Object::Query::Clause> object.
2698              
2699             =head2 _having
2700              
2701             This is called by L</where> and L</having>
2702              
2703             Provided with some data as a list or an array reference and this will format the C<where> or C<having> clause.
2704              
2705             Walking through each parameter provided, if a parameter is a scalar reference, it will be used as is.
2706              
2707             If the parameter looks like it contains some field, it will be prepended by an appropriate prefix of table and possible database and schema name, if necessary.
2708              
2709             If L<DB::Object/bind> is enabled, it will save the value used and use a placeholder.
2710              
2711             It returns a L<DB::Object::Query::Clause> object.
2712              
2713             =head2 _initiate_clause_object
2714              
2715             This instantiate a new L<DB::Object::Query::Clause> object passing it whatever parameters were provided.
2716              
2717             =head2 _limit
2718              
2719             Sets or gets the limit clause object and returns a L<DB::Object::Query::Clause> object.
2720              
2721             =head2 _process_limit
2722              
2723             Provided with some parameters and this will format the C<limit> clause of the query.
2724              
2725             If one parameter was provided, then this will only define the ending limit. The start will be set as L<perlfunc/undef>
2726              
2727             If two parameters are provided, then this will set the start offset and the limit.
2728              
2729             It check each of the start offset and end limit thus set, and if it is a scalar reference, it will be used as is. However, if the parameter is a C<?> it will be used as a placeholder.
2730              
2731             Otherwise, if L<DB::Object/bind> is enabled, this will save the parameter value as a binded value to be passed to L<DN::Object::Statement/execute>
2732              
2733             It returns the C<limit> clause object (DB::Object::Query::Clause)
2734              
2735             =head2 _query_components
2736              
2737             This returns an array reference of formatted clause, in their proper order to be added to query.
2738              
2739             This method is called by L</delete>, L</insert>, L</replace>, L</select> and L</update>
2740              
2741             This method is overriden by driver packages, so check L<DB::Object::Mysql::Query/_query_components>, L<DB::Object::Postgres::Query/_query_components> and L<DB::Object::SQLite::Query/_query_components>
2742              
2743             =head2 _query_type
2744              
2745             Based on the latest formatted query and the object property L</query>, this will return the type of query this is. This can be possibly one of the following: C<alter>, C<create>, C<drop>, C<grant>, C<listen>, C<notify>, C<insert>, C<update>, C<delete>, C<select>, C<truncate>
2746              
2747             =head2 _save_bind
2748              
2749             Provided with a query type and this will collect binded values from various clauses.
2750              
2751             It returns the current object.
2752              
2753             =head2 _value2bind
2754              
2755             If L<DB::Object/use_bind> is enabled, and this will modify the query passed to replace value with placeholders.
2756              
2757             Actually this method is not used anymore and really qui dangerous because parsing sql is quite challenging.
2758              
2759             =head2 _where_having
2760              
2761             This is used to format C<WHERE> and C<HAVING> clause.
2762              
2763             Provided with a query type and clause property name such as C<having> or C<where> and other parameters and this will format the C<where> or C<having> clause and return a new L<DB::Object::Query::Clause> object.
2764              
2765             It checks each parameter passed.
2766              
2767             if the first parameter is a L<DB::Object::Operator> object, it will take it embedded values by calling L<DB::Object::Query::Clause/value>. However, if there are any unknown fields, they will be ignored.
2768              
2769             If the parameter is a scalar reference, it will use it as is.
2770              
2771             If the parameter is a L<DB::Object::Operator> object like L<DB::Object::AND>, L<DB::Object::OR> or L<DB::Object::NOT>, it will recursively process its embedded elements.
2772              
2773             If the parameter is a L<DB::Object::Query::Clause> object, it will be added to the stack of elements.
2774              
2775             If the parameter is a L<DB::Object::Expression> object, it will be added to the stack of elements.
2776              
2777             If the parameter is a L<DB::Object::Fields::Field::Overloaded> object, it will be added as a new L<DB::Object::Query::Clause> to the stack.
2778              
2779             If the parameter is a litteral represented as a string or a scalar reference, then it will be added to the list as-is. For example:
2780              
2781             $tbl->where(
2782             $tbl->fo->status eq 'active',
2783             "LENGTH(?) > 12"
2784             );
2785              
2786             or
2787              
2788             $tbl->where(
2789             $tbl->fo->status eq 'active',
2790             \"LENGTH(?) > 12"
2791             );
2792              
2793             However, make sure to put this expression at the end.
2794              
2795             It then checks parameters two by two, the first one being the column and the second being its value.
2796              
2797             If the value is the operator object L<DB::Object::NOT>, it adds to the stack a new clause object of type C<column IS NOT something>, such as C<column IS NOT NULL>
2798              
2799             if the value is undefined or that the value is equal to C<NULL>, then it adds to the stack a new clause object L<DB::Object::Query::Clause> of type C<column IS NULL>
2800              
2801             If the value is a scalar reference, it will be added as is in a new clause object that is added to the stack.
2802              
2803             If the value is a L<DB::Object::Statement>, L<DB::Object::Statement/fetchrow> will be called and the value fetched will be added as a new clause object to the stack.
2804              
2805             If the value is a perl Regexp object, then it will be formatted in a way suitable to the driver and added to a new clause object and onto the stack.
2806              
2807             If the value looks like some table field embedded inside some SQL function, then it will be added to a new clause object and onto the stack.
2808              
2809             See L<Postgres documentation for more information|https://www.postgresql.org/docs/9.5/functions-matching.html>
2810              
2811             See L<MySQL documentation for more information|https://dev.mysql.com/doc/refman/5.7/en/regexp.html>
2812              
2813             See L<SQLite documentation for more information|https://sqlite.org/lang_expr.html>
2814              
2815             If the column is of type C<bytea>, then a new clause object will be added to the stack with the column value being quoted properly using L<DB::Object/quote>
2816              
2817             All the clause objects in the stack will be merged into one new clause object using L<DB::Object::Query::Clause/merge>
2818              
2819             The resulting final clause object (L<DB::Object::Query::Clause>) is returned.
2820              
2821             =head1 AUTOLOAD
2822              
2823             When the C<AUTOLOAD> is called, it will check if the value of the method used corresponds to an existing database table, and if it does, it returns the value returned by calling L</table> with the table name.
2824              
2825             =head1 SEE ALSO
2826              
2827             L<DBI>
2828              
2829             =head1 AUTHOR
2830              
2831             Jacques Deguest E<lt>F<jack@deguest.jp>E<gt>
2832              
2833             =head1 COPYRIGHT & LICENSE
2834              
2835             Copyright (c) 2018-2021 DEGUEST Pte. Ltd.
2836              
2837             You can use, copy, modify and redistribute this package and associated
2838             files under the same terms as Perl itself.
2839              
2840             =cut