File Coverage

blib/lib/SQL/SimpleOps.pm
Criterion Covered Total %
statement 883 1348 65.5
branch 500 944 52.9
condition 114 257 44.3
subroutine 69 82 84.1
pod 19 24 79.1
total 1585 2655 59.7


line stmt bran cond sub pod time code
1             ## ABSTRACT SQL Simple Operations Commands
2             #
3             ## LICENSE AND COPYRIGHT
4             #
5             ## Copyright (C) Carlos Celso
6             #
7             ## This program is free software: you can redistribute it and/or modify
8             ## it under the terms of the GNU General Public License as published by
9             ## the Free Software Foundation, either version 3 of the License, or
10             ## (at your option) any later version.
11             #
12             ## This program is distributed in the hope that it will be useful,
13             ## but WITHOUT ANY WARRANTY; without even the implied warranty of
14             ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15             ## GNU General Public License for more details.
16             #
17             ## You should have received a copy of the GNU General Public License
18             ## along with this program. If not, see L.
19             #
20             package SQL::SimpleOps;
21              
22 4     4   398173 use 5.006001;
  4         15  
23 4     4   24 use strict;
  4         13  
  4         125  
24 4     4   26 use warnings;
  4         17  
  4         282  
25 4     4   24 use Exporter;
  4         8  
  4         197  
26              
27 4     4   10055 use DBI;
  4         96029  
  4         433  
28 4     4   41 use File::Spec;
  4         9  
  4         723  
29              
30             ## dynamic modules
31              
32             ## option configfile=
33             ## JSON
34              
35             ## option driver=[drivername]
36             ## SQL::SimpleOps::[interface]::[driver]
37              
38             ## option message_log=1 (used as "required")
39             ## Sys::Syslog
40              
41             ## option sql_save=1 (used as "required")
42             ## Calc::Date
43             ## File::Path
44             ## IO::File
45              
46             ################################################################################
47             ## global initialization
48              
49             our @ISA = qw ( Exporter );
50              
51             our @EXPORT = qw(
52             new
53             Open Select SelectCursor Delete Insert
54             Update Commit Close Call Wait SelectSubQuery
55             getDBH getMessage getRC getRows
56             getLastCursor getLastSQL getLastSave getWhere
57             getAliasTable getAliasCols
58             setDumper
59              
60             SQL_SIMPLE_ALIAS_INSERT
61             SQL_SIMPLE_ALIAS_UPDATE
62             SQL_SIMPLE_ALIAS_DELETE
63             SQL_SIMPLE_ALIAS_SELECT
64             SQL_SIMPLE_ALIAS_WHERE
65             SQL_SIMPLE_ALIAS_GROUPBY
66             SQL_SIMPLE_ALIAS_ORDERBY
67              
68             SQL_SIMPLE_CURSOR_BACK
69             SQL_SIMPLE_CURSOR_NEXT
70             SQL_SIMPLE_CURSOR_TOP
71             SQL_SIMPLE_CURSOR_LAST
72             SQL_SIMPLE_CURSOR_RELOAD
73              
74             SQL_SIMPLE_ORDER_OFF
75             SQL_SIMPLE_ORDER_ASC
76             SQL_SIMPLE_ORDER_DESC
77              
78             SQL_SIMPLE_CMD_OFF
79             SQL_SIMPLE_CMD_ON
80             SQL_SIMPLE_CMD_ALL
81              
82             SQL_SIMPLE_LOG_OFF
83             SQL_SIMPLE_LOG_STD
84             SQL_SIMPLE_LOG_SYS
85             SQL_SIMPLE_LOG_ALL
86              
87             SQL_SIMPLE_RC_SYNTAX
88             SQL_SIMPLE_RC_OK
89             SQL_SIMPLE_RC_ERROR
90             SQL_SIMPLE_RC_EMPTY
91              
92             $VERSION
93             $errstr
94             $err
95             );
96              
97             our $VERSION = "2024.213.1";
98              
99             our @EXPORT_OK = @EXPORT;
100              
101             our %EXPORT_TAGS = ( all => [@EXPORT_OK] );
102              
103             ################################################################################
104             ## literals initialization
105              
106 4     4   28 use constant SQL_SIMPLE_ALIAS_INSERT => 1;
  4         7  
  4         492  
107 4     4   39 use constant SQL_SIMPLE_ALIAS_UPDATE => 2;
  4         10  
  4         226  
108 4     4   41 use constant SQL_SIMPLE_ALIAS_DELETE => 4;
  4         10  
  4         191  
109 4     4   22 use constant SQL_SIMPLE_ALIAS_SELECT => 8;
  4         7  
  4         211  
110 4     4   22 use constant SQL_SIMPLE_ALIAS_WHERE => 16;
  4         7  
  4         197  
111 4     4   22 use constant SQL_SIMPLE_ALIAS_GROUPBY => 32;
  4         7  
  4         223  
112 4     4   23 use constant SQL_SIMPLE_ALIAS_ORDERBY => 64;
  4         6  
  4         204  
113 4     4   23 use constant SQL_SIMPLE_ALIAS_FQDN => 32768;
  4         6  
  4         248  
114              
115 4     4   45 use constant SQL_SIMPLE_CURSOR_TOP => 1; # page first
  4         7  
  4         241  
116 4     4   23 use constant SQL_SIMPLE_CURSOR_BACK => 2; # page backward
  4         20  
  4         180  
117 4     4   21 use constant SQL_SIMPLE_CURSOR_NEXT => 3; # page next
  4         7  
  4         204  
118 4     4   18 use constant SQL_SIMPLE_CURSOR_LAST => 4; # page last
  4         6  
  4         250  
119 4     4   24 use constant SQL_SIMPLE_CURSOR_RELOAD => 5; # page current
  4         13  
  4         246  
120              
121 4     4   25 use constant SQL_SIMPLE_ORDER_OFF => undef; # order disabled
  4         8  
  4         250  
122 4     4   18 use constant SQL_SIMPLE_ORDER_ASC => "ASC"; # order asceding
  4         6  
  4         192  
123 4     4   18 use constant SQL_SIMPLE_ORDER_DESC => "DESC"; # order descending
  4         7  
  4         186  
124              
125 4     4   17 use constant SQL_SIMPLE_CMD_OFF => 0; # sql_save disabled
  4         7  
  4         162  
126 4     4   16 use constant SQL_SIMPLE_CMD_ON => 1; # sql_save update
  4         6  
  4         174  
127 4     4   19 use constant SQL_SIMPLE_CMD_ALL => 2; # sql_save read/update
  4         5  
  4         208  
128              
129 4     4   27 use constant SQL_SIMPLE_LOG_OFF => 0; # log disabled
  4         7  
  4         174  
130 4     4   23 use constant SQL_SIMPLE_LOG_SYS => 1; # log syslog
  4         6  
  4         176  
131 4     4   18 use constant SQL_SIMPLE_LOG_STD => 2; # log stderr
  4         7  
  4         157  
132 4     4   26 use constant SQL_SIMPLE_LOG_ALL => 3; # log stderr/syslog
  4         50  
  4         210  
133              
134 4     4   67 use constant SQL_SIMPLE_RC_SYNTAX => -1; # syntax error
  4         7  
  4         243  
135 4     4   23 use constant SQL_SIMPLE_RC_OK => 0; # sql successul
  4         8  
  4         184  
136 4     4   19 use constant SQL_SIMPLE_RC_ERROR => 1; # sql error
  4         6  
  4         196  
137 4     4   22 use constant SQL_SIMPLE_RC_EMPTY => 2; # sql successul, empty
  4         7  
  4         80355  
138              
139             our $SQL_SIMPLE_CURSOR_ORDER =
140             {
141             1 => SQL_SIMPLE_ORDER_ASC, # top
142             2 => SQL_SIMPLE_ORDER_DESC, # last
143             3 => SQL_SIMPLE_ORDER_ASC, # next
144             4 => SQL_SIMPLE_ORDER_DESC, # last
145             5 => SQL_SIMPLE_ORDER_ASC, # reload
146             };
147              
148             ################################################################################
149             ## local environments
150            
151             our $SQL_SIMPLE_CLASS = "SQL::SimpleOps";
152              
153             our %SQL_SIMPLE_TABLE_OF_MSGS =
154             (
155             "001" => { T=>"E", M=>"[%s] Database is missing" },
156             "002" => { T=>"E", M=>"[%s] Server is missing" },
157             "003" => { T=>"E", M=>"[%s] Interface invalid" },
158             "004" => { T=>"S", M=>"[%s] The Database driver is omitted or empty" },
159             "005" => { T=>"E", M=>"[%s] Table is missing or invalid" },
160             "006" => { T=>"E", M=>"[%s] Table invalid, must be single-value or array" },
161             "007" => { T=>"E", M=>"[%s] Fields invalid, must be array" },
162             "008" => { T=>"E", M=>"[%s] Group_by invalid, must be single-value or array" },
163             "009" => { T=>"E", M=>"[%s] Order_by invalid, must be single-value or array-pairs" },
164             "010" => { T=>"E", M=>"[%s] Field '%s' not mapped in table list" },
165             "011" => { T=>"E", M=>"[%s} Stat File error, %s" },
166             "012" => { T=>"I", M=>"[%s] Key not found" },
167             "013" => { T=>"E", M=>"[%s] Cursor is missing or invalid" },
168             "014" => { T=>"E", M=>"[%s] Cursor Key is missing or invalid" },
169             "015" => { T=>"E", M=>"[%s] Cursor Command invalid" },
170             "016" => { T=>"W", M=>"[%s] Key is missing, option 'force' is required" },
171             "017" => { T=>"E", M=>"[%s] Fields is missing" },
172             "018" => { T=>"E", M=>"[%s] Fields Format error, must be hash-pairs or arrayref" },
173             "019" => { T=>"E", M=>"[%s] Interface '%s::%s' missing" },
174             "020" => { T=>"E", M=>"[%s] Where Clause invalid" },
175             "021" => { T=>"E", M=>"[%s] Where invalid, must be single-value or array" },
176             "022" => { T=>"E", M=>"[%s] Database is not open" },
177             "023" => { T=>"E", M=>"[%s] SQL Command is missing" },
178             "024" => { T=>"E", M=>"[%s] Buffer Type invalid, must be hashref, arrayref, scalaref or callback_ref" },
179             "025" => { T=>"S", M=>"[%s] Make Folder error, %s" },
180             "026" => { T=>"S", M=>"[%s] Open File error, %s" },
181             "027" => { T=>"S", M=>"[%s] Values is missing" },
182             "028" => { T=>"E", M=>"[%s] Table/Field Value invalid, must be single-value or array" },
183             "029" => { T=>"E", M=>"[%s] TCP Port invalid, must be numeric and between 1-65536" },
184             "030" => { T=>"E", M=>"[%s] Aliass Table is not a hashref" },
185             "031" => { T=>"E", M=>"[%s] Aliases '%s' invalid, table_cols must be hashref" },
186             "032" => { T=>"E", M=>"[%s] Aliases '%s' invalid, table_cols invalid format" },
187             "033" => { T=>"E", M=>"[%s] Table '%s' already, there can be only one" },
188             "034" => { T=>"E", M=>"[%s] Aliases '%s' invalid, table_name is missing" },
189             "035" => { T=>"S", M=>"[%s] Interface '%s::%s' error, %s" },
190             "036" => { T=>"S", M=>"[%s] Interface '%s::%s' load error" },
191             "037" => { T=>"S", M=>"[%s] Interface '%s::%s' aborted, %s" },
192             "038" => { T=>"E", M=>"[%s] Syslog Facility invalid, must be 'local0' to 'local7'" },
193             "039" => { T=>"E", M=>"[%s] Syslog Service invalid, must contains 'alphanumeric' characters" },
194             "040" => { T=>"E", M=>"[%s] Log File invalid, must contains 'alphanumeric' characters" },
195             "041" => { T=>"E", M=>"[%s] Values Format error, must be arrayref" },
196             "042" => { T=>"E", M=>"[%s] Conflict/Duplicate Format error, must be hashref" },
197             "043" => { T=>"E", M=>"[%s] Limit is missing" },
198             "044" => { T=>"E", M=>"[%s] Buffer hashkey invalid, buffer is not hashref" },
199             "045" => { T=>"E", M=>"[%s] Buffer hashkey not mapped" },
200             "046" => { T=>"E", M=>"[%s] Buffer hashkey must be scalaref or arrayref" },
201             "047" => { T=>"E", M=>"[%s] Buffer arrayref Off not allowed for multiple field list" },
202             "048" => { T=>"E", M=>"[%s] Buffer hashindex must be arrayref" },
203             "049" => { T=>"E", M=>"[%s] Cursor_order invalid" },
204             "099" => { T=>"S", M=>"[%s] %s" },
205             );
206              
207             our $errstr = ""; # last message
208             our $err = 0; # last return code
209              
210             1;
211              
212             ################################################################################
213             ## action: create object
214             ## return:
215             ## null falure to loaded, system error
216             ## bless is successful loaded
217              
218             sub new()
219             {
220 3   33 3 0 469185 my $class = shift; $class = ref($class) || $class || $SQL_SIMPLE_CLASS;
  3         28  
221 3         8 my $self = {};
222              
223 3         36 $self->{argv} = {@_};
224              
225             ## checking for configfile
226 3 50       15 if (defined($self->{argv}{configfile}))
227             {
228 0 0       0 if (!stat($self->{argv}{configfile}))
229             {
230 0         0 &_setMessage($self,"new",SQL_SIMPLE_RC_SYNTAX,"011",$self->{argv}{configfile});
231 0         0 return undef;
232             }
233 0         0 my $fh = new IO::File($self->{argv}{configfile});
234 0 0       0 if (!defined($fh))
235             {
236 0         0 &_setMessage($self,"new",SQL_SIMPLE_RC_SYNTAX,"026",$!);
237 0         0 return undef;
238             }
239 0         0 require JSON;
240 0         0 my $st; while (!$fh->eof) { $st .= <$fh>; }; undef($fh);
  0         0  
  0         0  
  0         0  
241 0         0 my $pt = new JSON(); $self->{argv} = $pt->decode($st); undef($pt);
  0         0  
  0         0  
242             }
243              
244             ## defaults
245 3 50       17 $self->{argv}{interface} = "dbi" if (!defined($self->{argv}{interface}));
246 3 50       18 $self->{argv}{quote} = "'" if (!defined($self->{argv}{quote}));
247 3 50       12 $self->{argv}{connect} = 1 if (!defined($self->{argv}{connect}));
248 3 100       13 $self->{argv}{message_log} = SQL_SIMPLE_LOG_STD if (!defined($self->{argv}{message_log}));
249 3 50       16 $self->{argv}{port} = "" if (!defined($self->{argv}{port}));
250              
251             ## check interfaces
252 3 50       86 if (!grep(/^$self->{argv}{interface}$/i,"dbi"))
253             {
254 0         0 &_setMessage($self,"new",SQL_SIMPLE_RC_SYNTAX,"003");
255 0         0 return undef;
256             }
257              
258             ## check driver
259 3 50 33     47 if (!defined($self->{argv}{driver}) || $self->{argv}{driver} eq "")
260             {
261 0         0 &_setMessage($self,"new",SQL_SIMPLE_RC_SYNTAX,"004");
262 0         0 return undef;
263             }
264              
265             ## check database
266 3 50 33     22 if (!defined($self->{argv}{db}) || $self->{argv}{db} eq "")
267             {
268 0         0 &_setMessage($self,"new",SQL_SIMPLE_RC_SYNTAX,"001");
269 0         0 return undef;
270             }
271              
272             ## check aliases table
273 3 100       12 if (defined($self->{argv}{tables}))
274             {
275 1 50       5 if (ref($self->{argv}{tables}) ne "HASH")
276             {
277 0         0 &_setMessage($self,"new",SQL_SIMPLE_RC_SYNTAX,"030");
278 0         0 return undef;
279             }
280 1         2 foreach my $table(keys(%{$self->{argv}{tables}}))
  1         7  
281             {
282 3 50 33     20 if (!defined($self->{argv}{tables}{$table}{name}) || $self->{argv}{tables}{$table}{name} eq "")
283             {
284 0         0 &_setMessage($self,"new",SQL_SIMPLE_RC_SYNTAX,"034",$table);
285 0         0 return undef;
286             }
287 3 50       13 if (defined($self->{init}{table_realname}{$self->{argv}{tables}{$table}{name}}))
288             {
289 0         0 &_setMessage($self,"new",SQL_SIMPLE_RC_SYNTAX,"034",$table);
290 0         0 return undef;
291             }
292 3 50       9 if (defined($self->{argv}{tables}{$self->{argv}{tables}{$table}{name}}))
293             {
294 0         0 &_setMessage($self,"new",SQL_SIMPLE_RC_SYNTAX,"034",$table);
295 0         0 return undef;
296             }
297 3         29 $self->{init}{table_realname}{$self->{argv}{tables}{$table}{name}} = $table;
298 3 100       10 if (defined($self->{argv}{tables}{$table}{cols}))
299             {
300 2 50       8 if (ref($self->{argv}{tables}{$table}{cols}) ne "HASH")
301             {
302 0         0 &_setMessage($self,"new",SQL_SIMPLE_RC_SYNTAX,"031",$table);
303 0         0 return undef;
304             }
305 2         37 my $myTable = $self->{argv}{tables}{$table}{name};
306 2         4 foreach my $field(keys(%{$self->{argv}{tables}{$table}{cols}}))
  2         11  
307             {
308 6 50       21 if ($self->{argv}{tables}{$table}{cols}{$field} eq "")
309             {
310 0         0 &_setMessage($self,"new",SQL_SIMPLE_RC_SYNTAX,"032",$field);
311 0         0 return undef;
312             }
313 6         8 push(@{$self->{init}{fields_xref}{$field}},[$table,$self->{argv}{tables}{$table}{cols}{$field}]);
  6         40  
314             }
315             }
316             }
317             }
318              
319             ## check syslog options
320 3 50 33     14 if (defined($self->{argv}{message_syslog_facility}) && !($self->{argv}{message_syslog_facility} =~ /^local[0-7]$/i))
321             {
322 0         0 &_setMessage($self,"new",SQL_SIMPLE_RC_SYNTAX,"038",$self->{argv}{message_syslog_facility});
323 0         0 return undef;
324             }
325 3 50 33     13 if (defined($self->{argv}{message_syslog_service}) && ($self->{argv}{message_syslog_service} =~ s/[a-zA-Z0-9\-\_]//g))
326             {
327 0         0 &_setMessage($self,"new",SQL_SIMPLE_RC_SYNTAX,"039",$self->{argv}{message_syslog_service});
328 0         0 return undef;
329             }
330 3 50 33     14 if (defined($self->{argv}{sql_save_name}) && ($self->{argv}{sql_save_name} =~ s/[a-zA-Z0-9\-\_]//g))
331             {
332 0         0 &_setMessage($self,"new",SQL_SIMPLE_RC_SYNTAX,"040",$self->{argv}{sql_save_name});
333 0         0 return undef;
334             }
335              
336             ## interface defaults values
337 3         14 $self->{argv}{interface} = uc($self->{argv}{interface});
338 3 50       18 $self->{argv}{interface_options}{RaiseError} = 0 if (!defined($self->{argv}{interface_options}{RaiseError}));
339 3 50       16 $self->{argv}{interface_options}{PrintError} = 0 if (!defined($self->{argv}{interface_options}{PrintError}));
340              
341             ## standards plugins
342 3 50       119 if (grep(/^$self->{argv}{driver}$/i,"mysql","mariadb")) {$self->{init}{plugin_id} = "MySQL";}
  0 50       0  
    50          
343 0         0 elsif (grep(/^$self->{argv}{driver}$/i,"pg","postgres","postsql","pgsql")) {$self->{init}{plugin_id} = "PG";}
344 3         13 elsif (grep(/^$self->{argv}{driver}$/i,"sqlite","sqlite3")) {$self->{init}{plugin_id} = "SQLite";}
345 0         0 else {$self->{init}{plugin_id} = $self->{argv}{driver};}
346              
347             ## load pluging
348 3         7 my $fn;
349 3         118 my $plugin = $SQL_SIMPLE_CLASS."::".$self->{argv}{interface}."::".$self->{init}{plugin_id};
350 3         12 foreach my $dir(@INC)
351             {
352 6         103 $fn = File::Spec->catdir($dir,split(/::/,$plugin)).".pm";
353 6 100       178 last if (stat($fn));
354 3         10 $fn = "";
355             }
356 3 50       30 if ($fn eq "")
357             {
358 0         0 &_setMessage($self,"new",SQL_SIMPLE_RC_SYNTAX,"019",$self->{argv}{interface},$self->{init}{plugin_id});
359 0         0 return undef;
360             }
361 3         7 eval { require $fn; };
  3         1716  
362 3 50       14 if ($@)
363             {
364 0         0 &_setMessage($self,"new",SQL_SIMPLE_RC_SYNTAX,"035",$self->{argv}{interface},$self->{init}{plugin_id},$@);
365 0         0 return undef;
366             }
367 3         31 $self->{init}{plugin_fh} = $plugin->new(sql_simple => $self);
368 3 50       30 if (!defined($self->{init}{plugin_fh}))
369             {
370 0         0 &_setMessage($self,"new",SQL_SIMPLE_RC_SYNTAX,"035",$self->{argv}{interface},$self->{init}{plugin_id},$@);
371 0         0 return undef;
372             }
373              
374             ## test server, the 'test_server' env must be defined on plugin
375 3 50       12 if ($self->{init}{test_server})
376             {
377 0 0       0 if ($self->{argv}{server} eq "")
378             {
379 0         0 &_setMessage($self,"new",SQL_SIMPLE_RC_SYNTAX,"002");
380 0         0 return undef;
381             }
382 0 0 0     0 if ($self->{argv}{port} ne "" && (($self->{argv}{port} =~ /^\D+$/) || ($self->{argv}{port} < 1 || $self->{argv}{port} > 65535)))
      0        
383             {
384 0         0 &_setMessage($self,"new",SQL_SIMPLE_RC_SYNTAX,"029");
385 0         0 return undef;
386             }
387             }
388              
389             ## new object
390 3         11 my $bless = bless($self,$class);
391 3 50       11 return undef if (!defined($bless));
392              
393             ## my first connect
394 3 50 33     24 return undef if ($self->{argv}{connect} && $self->Open());
395              
396             ## successful
397 3         12 return $bless;
398             }
399              
400             ################################################################################
401             ## action: open database
402             ## return:
403             ## rc<0 syntax error
404             ## rc=0 successful
405             ## rc>0 sql return code
406              
407             sub Open()
408             {
409 2     2 1 5 my $self = shift;
410              
411 2         8 $self->_resetSession();
412 2 50 33     34 if ($self->{init}{plugin_fh}->can('Open') && $self->{init}{plugin_fh}->Open())
413             {
414 0         0 $self->_setMessage("open",SQL_SIMPLE_RC_SYNTAX,"037",$self->{argv}{interface},$self->{argv}{driver},$self->getMessage());
415 0         0 return SQL_SIMPLE_RC_SYNTAX;
416             }
417 2 50       42 if ($self->{argv}{interface} =~ /^dbi$/i)
418             {
419 2         16 $self->{init}{dbh} = DBI->connect($self->{argv}{dsname}, $self->{argv}{login}, $self->{argv}{password}, \%{$self->{argv}{interface_options}});
  2         22  
420 2         36549 $self->_setMessage("open");
421 2         10 return $self->getRC();
422             }
423 0         0 return SQL_SIMPLE_RC_SYNTAX;
424             }
425              
426             ################################################################################
427             ## action: create select command to inject as subquery
428             ## return:
429             ## rc<0 syntax error
430             ## rc=0 returns SQL STRING COMMAND
431             ## rc=1 sql error
432             ## rc=2 successful, no lines selected (no match or empty)
433              
434             sub SelectSubQuery()
435             {
436 2     2 1 5 my $self = shift;
437 2         8 my $argv = {@_};
438              
439 2         24 $argv->{subquery} = 1;
440              
441 2         5 return $self->Select(%{$argv});
  2         10  
442             }
443              
444             ################################################################################
445             ## action: select as fetch command, buffers of lines based cursor
446             ## return:
447             ## rc<0 syntax error
448             ## rc=0 successful
449             ## rc=1 sql error
450             ## rc=2 successful, no lines selected (no match or empty)
451              
452             sub SelectCursor()
453             {
454 17     17 1 47 my $self = shift;
455 17         119 my $argv = {@_};
456              
457 17         63 $self->_resetSession();
458 17         55 $self->_Dumper("selectcursor",$argv);
459 17 50       80 $self->Open() if (!defined($self->{init}{dbh}));
460              
461             ## define the command in load
462 17         40 $self->{work}{command} = SQL_SIMPLE_ALIAS_SELECT;
463              
464 17 50 33     118 if ($self->{init}{plugin_fh}->can('SelectCursor') && $self->{init}{plugin_fh}->SelectCursor($argv))
465             {
466 0         0 $self->_setMessage("select",SQL_SIMPLE_RC_SYNTAX,"037",$self->{argv}{interface},$self->{argv}{driver},$self->getMessage());
467 0         0 return SQL_SIMPLE_RC_SYNTAX;
468             }
469              
470 17 50       54 my $saved_message_log = $self->_setLogMessage($argv->{message_log}) if (defined($argv->{message_log}));
471 17 50       60 my $saved_quote = $self->_setQuote($argv->{quote}) if (defined($argv->{quote}));
472 17 50       42 my $saved_sql_save = $self->_setSqlSave($argv->{sql_save}) if (defined($argv->{sql_save}));
473              
474 17         34 my $rc = $self->_SelectCursor(%{$argv});
  17         82  
475              
476 17 50       78 $self->setMessgeLog($saved_message_log) if (defined($argv->{message_log}));
477 17 50       46 $self->_setQuote($saved_quote) if (defined($argv->{quote}));
478 17 50       45 $self->_setSqlSave($saved_sql_save) if (defined($argv->{sql_save}));
479              
480 17         110 return $rc;
481             }
482              
483             sub _SelectCursor()
484             {
485 17     17   31 my $self = shift;
486 17         79 my $argv = {@_};
487              
488             ## validate cursor-key
489 17 50       98 if (!defined($argv->{cursor_key})) { @{$self->{work}{cursor_key}} = []; }
  0 100       0  
  0 50       0  
490 9         19 elsif (ref($argv->{cursor_key}) eq "") { @{$self->{work}{cursor_key}} = ($argv->{cursor_key}); }
  9         35  
491 8         15 elsif (ref($argv->{cursor_key}) eq "ARRAY") { @{$self->{work}{cursor_key}} = @{$argv->{cursor_key}}; }
  8         32  
  8         19  
492             else
493             {
494 0         0 $self->_setMessage("select",SQL_SIMPLE_RC_SYNTAX,"014");
495 0         0 return SQL_SIMPLE_RC_SYNTAX;
496             }
497              
498             ## validate cursor, must be similar type of cursor-key
499 17 50 0     48 if (!defined($argv->{cursor})) {}
    0 0        
    0          
500 0         0 elsif (ref($argv->{cursor}) eq "" && @{$self->{work}{cursor_key}} == 1) {}
501 0         0 elsif (ref($argv->{cursor}) eq "ARRAY" && $self->{work}{cursor_key} == @{$argv->{cursor}}+0) {}
502             else
503             {
504 0         0 $self->_setMessage("select",SQL_SIMPLE_RC_SYNTAX,"013");
505 0         0 return SQL_SIMPLE_RC_SYNTAX;
506             }
507              
508             ## enforce cursor as top if missed
509 17 100 66     149 $argv->{cursor_command} = SQL_SIMPLE_CURSOR_TOP if (!defined($argv->{cursor_command}) || $argv->{cursor_command} eq "");
510              
511 17 100 100     77 if ($argv->{cursor_command} != SQL_SIMPLE_CURSOR_TOP && $argv->{cursor_command} != SQL_SIMPLE_CURSOR_LAST)
512             {
513             ## if im not using cursor the cursor_info is required
514 9 50 33     31 if (!defined($argv->{cursor}) || $argv->{cursor} eq "")
515             {
516 9 50       30 if (!defined($argv->{cursor_info}))
517             {
518 0         0 $self->_setMessage("select",SQL_SIMPLE_RC_SYNTAX,"013");
519 0         0 return SQL_SIMPLE_RC_SYNTAX;
520             }
521              
522             ## getting the last and first cursors
523 9         25 my ($first,$last);
524 9 50       31 if (ref($argv->{cursor_info}) eq "HASH")
    0          
    0          
525             {
526 9         35 ($first,$last) = ($argv->{cursor_info}{first},$argv->{cursor_info}{last});
527             }
528             elsif (ref($argv->{cursor_info}) eq "ARRAY")
529             {
530 0         0 ($first,$last) = ($argv->{cursor_info}[2],$argv->{cursor_info}[3]);
531             }
532             elsif (ref($argv->{cursor_info}) eq "SCALAR")
533             {
534             ## scalar cursor_info mismatch with multiple keys
535 0 0       0 if (@{$self->{work}{cursor_key}} > 1)
  0         0  
536             {
537 0         0 $self->_setMessage("select",SQL_SIMPLE_RC_SYNTAX,"013");
538 0         0 return SQL_SIMPLE_RC_SYNTAX;
539             }
540 0         0 my @a=split(" ",$argv->{cursor_info}); ($first,$last) = ($a[2],$a[3]);
  0         0  
541             }
542             else
543             {
544 0         0 $self->_setMessage("select",SQL_SIMPLE_RC_SYNTAX,"013");
545 0         0 return SQL_SIMPLE_RC_SYNTAX;
546             }
547              
548             ## adjusting cursor if cursor_key is array
549 9 100       31 if (ref($argv->{cursor_key}) eq "ARRAY")
550             {
551 4 50       14 $first = [] if (ref($first) ne "ARRAY");
552 4 50       16 $last = [] if (ref($last) ne "ARRAY");
553             }
554              
555             ## adjusting cursor
556 9 100       39 if ($argv->{cursor_command} == SQL_SIMPLE_CURSOR_NEXT)
    100          
    50          
557             {
558 3         7 $argv->{cursor} = $last;
559 3 100       53 $argv->{cursor_command} = SQL_SIMPLE_CURSOR_TOP if (!defined($last));
560             }
561             elsif ($argv->{cursor_command} == SQL_SIMPLE_CURSOR_BACK)
562             {
563 3         10 $argv->{cursor} = $first;
564 3 100       12 $argv->{cursor_command} = SQL_SIMPLE_CURSOR_LAST if (!defined($first));
565             }
566             elsif ($argv->{cursor_command} == SQL_SIMPLE_CURSOR_RELOAD)
567             {
568 3         9 $argv->{cursor} = $first;
569             }
570             }
571            
572             ## enforce rerun last command if exists and request is reload
573 9 100       30 if ($argv->{cursor_command} == SQL_SIMPLE_CURSOR_RELOAD)
574             {
575 3         10 $self->{work}{cursor_command_reload} = 1;
576 3 50       13 if (ref($argv->{cursor_info}) eq "HASH")
    0          
577             {
578 3 50       14 $argv->{cursor_command} = $argv->{cursor_info}{previouscmd} if (defined($argv->{cursor_info}{previouscmd}));
579             }
580             elsif (ref($argv->{cursor_info}) eq "ARRAY")
581             {
582 0 0       0 $argv->{cursor_command} = $argv->{cursor_info}[ @{$argv->{cursor_info}}-1 ] if (@{$argv->{cursor_info}} >= 5);
  0         0  
  0         0  
583             }
584             else
585             {
586 0         0 my @a = split(" ",$argv->{cursor_info});
587 0 0       0 my $b = (@{$self->{work}{cursor_key}} < 2) ? 2 : @{$self->{work}{cursor_key}} * 2;
  0         0  
  0         0  
588 0 0       0 $argv->{cursor_command} = $a[@a-1] if (@a > (2 + $b));
589             }
590             }
591             }
592              
593             ## validade where
594 17 50 66     73 if (defined($argv->{where}) && ref($argv->{where}) ne "ARRAY")
595             {
596 0         0 $self->_setMessage("select",SQL_SIMPLE_RC_SYNTAX,"021");
597 0         0 return SQL_SIMPLE_RC_SYNTAX;
598             }
599              
600             ## have order by?
601 17         59 my @order;
602 17 50       45 if (!defined($argv->{order_by})) {}
    0          
    0          
    0          
603 0         0 elsif (ref($argv->{order_by}) eq "ARRAY") { @order = @{$argv->{order_by}}; }
  0         0  
604 0         0 elsif (ref($argv->{order_by}) eq "HASH") { @order = ($argv->{order_by}); }
605 0         0 elsif (ref($argv->{order_by}) eq "") { @order = ($argv->{order_by}); }
606             else
607             {
608 0         0 $self->_setMessage("select",SQL_SIMPLE_RC_SYNTAX,"009");
609 0         0 return SQL_SIMPLE_RC_SYNTAX;
610             }
611              
612             ## test the type of cursor and adjust where clause
613 17 100 100     85 if ($argv->{cursor_command} == SQL_SIMPLE_CURSOR_TOP)
    100          
    100          
    50          
614             {
615 7         15 my @o;
616 7 100       28 foreach my $key( (ref($argv->{cursor_key}) eq "ARRAY") ? @{$argv->{cursor_key}} : $argv->{cursor_key} )
  3         11  
617             {
618 10         41 push(@o,{$key => SQL_SIMPLE_ORDER_ASC});
619             }
620 7         21 unshift(@order,@o);
621             }
622             elsif ($argv->{cursor_command} == SQL_SIMPLE_CURSOR_BACK)
623             {
624 2 50       33 my $oper = ($self->{work}{cursor_command_reload}) ? "<=" : "<";
625 2 100       11 if (ref($argv->{cursor_key}) ne "ARRAY")
626             {
627 1         5 unshift(@order,{$argv->{cursor_key} => SQL_SIMPLE_ORDER_DESC});
628 1         3 unshift(@{$argv->{where}}, $argv->{cursor_key} => [ $oper, $argv->{cursor} ]);
  1         5  
629             }
630             else
631             {
632 1         3 my @w;
633             my @o;
634 1         4 for (my $i=0; $i < @{$argv->{cursor_key}}; $i++)
  3         11  
635             {
636 2         7 push(@o,{$argv->{cursor_key}[$i] => SQL_SIMPLE_ORDER_DESC});
637 2         5 my @s;
638 2         7 for (my $j=0; $j < $i; $j++)
639             {
640 1         5 push(@s,$argv->{cursor_key}[$j] => $argv->{cursor}[$j]);
641             }
642 2         24 push(@s,$argv->{cursor_key}[$i] => [ $oper, $argv->{cursor}[$i]]);
643 2 100       7 push(@w,"or") if (@w);
644 2         5 push(@w,\@s);
645             }
646 1 50       3 push(@{$argv->{where}},(@{$argv->{where}}) ? [\@w] : \@w);
  1         3  
  1         6  
647 1         4 unshift(@order,@o);
648             }
649             }
650             elsif ($argv->{cursor_command} == SQL_SIMPLE_CURSOR_NEXT || $argv->{cursor_command} == SQL_SIMPLE_CURSOR_RELOAD)
651             {
652 5 100 66     41 my $oper = ($argv->{cursor_command} == SQL_SIMPLE_CURSOR_RELOAD || $self->{work}{cursor_command_reload}) ? ">=" : ">";
653 5 100       18 if (ref($argv->{cursor_key}) ne "ARRAY")
654             {
655 2         12 unshift(@order,{$argv->{cursor_key} => SQL_SIMPLE_ORDER_ASC});
656 2         4 unshift(@{$argv->{where}}, $argv->{cursor_key} => [ $oper, $argv->{cursor} ]);
  2         11  
657             }
658             else
659             {
660 3         6 my @w;
661             my @o;
662 3         9 for (my $i=0; $i < @{$argv->{cursor_key}}; $i++)
  9         23  
663             {
664 6         25 push(@o,{$argv->{cursor_key}[$i] => SQL_SIMPLE_ORDER_ASC});
665 6         12 my @s;
666 6         18 for (my $j=0; $j < $i; $j++)
667             {
668 3         13 push(@s,$argv->{cursor_key}[$j] => $argv->{cursor}[$j]);
669             }
670 6         18 push(@s,$argv->{cursor_key}[$i] => [ $oper, $argv->{cursor}[$i]]);
671 6 100       20 push(@w,"or") if (@w);
672 6         16 push(@w,\@s);
673             }
674 3 100       7 push(@{$argv->{where}},(@{$argv->{where}}) ? [\@w] : \@w);
  3         10  
  3         12  
675 3         33 unshift(@order,@o);
676             }
677             }
678             elsif ($argv->{cursor_command} == SQL_SIMPLE_CURSOR_LAST)
679             {
680 3         7 my @o;
681 3 100       31 foreach my $key( (ref($argv->{cursor_key}) eq "ARRAY") ? @{$argv->{cursor_key}} : $argv->{cursor_key} )
  1         5  
682             {
683 4         20 push(@o,{$key => SQL_SIMPLE_ORDER_DESC});
684             }
685 3         10 unshift(@order,@o);
686             }
687             else
688             {
689 0         0 $self->_setMessage("select",SQL_SIMPLE_RC_SYNTAX,"015");
690 0         0 return SQL_SIMPLE_RC_SYNTAX;
691             }
692 17         49 $argv->{order_by} = \@order;
693              
694             ## validate cursor_order option
695 17 50 0     46 if (!defined($argv->{cursor_order})) { }
    0          
696             elsif ($argv->{cursor_order} eq SQL_SIMPLE_ORDER_ASC || $argv->{cursor_order} eq SQL_SIMPLE_ORDER_DESC)
697             {
698 0         0 $self->{work}{cursor_order} = ($argv->{cursor_order} eq $SQL_SIMPLE_CURSOR_ORDER->{$argv->{cursor_command}})+0;
699             }
700             else
701             {
702 0         0 $self->_setMessage("select",SQL_SIMPLE_RC_SYNTAX,"049");
703 0         0 return SQL_SIMPLE_RC_SYNTAX;
704             }
705              
706             ## validate limits
707 17 50 33     96 if (!defined($argv->{limit}) || $argv->{limit} eq "")
708             {
709 0         0 $self->_setMessage("select",SQL_SIMPLE_RC_SYNTAX,"043");
710 0         0 return SQL_SIMPLE_RC_SYNTAX;
711             }
712              
713             ## define notfound if not exists
714 17 50       70 $argv->{notfound} = 1 if (!defined($argv->{notfound}));
715              
716             ## execute and save cursor info
717 17 50       27 return $self->{init}{cursor}{rc} if ($self->{init}{cursor}{rc} = $self->_Select(%{$argv}));
  17         96  
718              
719 0         0 $self->{init}{cursor}{lines} = $self->getRows();
720 0 0       0 if (!$self->{init}{cursor}{lines})
721             {
722 0         0 $self->{init}{cursor}{first} = [];
723 0         0 $self->{init}{cursor}{last} = [];
724             }
725              
726             ## return cursor info
727 0 0       0 if (!defined($argv->{cursor_info})) {}
    0          
    0          
    0          
728             elsif (ref($argv->{cursor_info}) eq "HASH")
729             {
730 0         0 $argv->{cursor_info}->{rc} = $self->{init}{cursor}{rc};
731 0         0 $argv->{cursor_info}->{lines} = $self->{init}{cursor}{lines};
732              
733 0 0 0     0 if ($argv->{cursor_command} == SQL_SIMPLE_CURSOR_BACK || $argv->{cursor_command} == SQL_SIMPLE_CURSOR_LAST)
734             {
735 0 0       0 $argv->{cursor_info}{first} = (ref($argv->{cursor_key}) eq "ARRAY") ? $self->{init}{cursor}{last} : $self->{init}{cursor}{last}[0];
736 0 0       0 $argv->{cursor_info}{last} = (ref($argv->{cursor_key}) eq "ARRAY") ? $self->{init}{cursor}{first} : $self->{init}{cursor}{first}[0];
737             }
738             else
739             {
740 0 0       0 $argv->{cursor_info}{first} = (ref($argv->{cursor_key}) eq "ARRAY") ? $self->{init}{cursor}{first} :$self->{init}{cursor}{first}[0];
741 0 0       0 $argv->{cursor_info}{last} = (ref($argv->{cursor_key}) eq "ARRAY") ? $self->{init}{cursor}{last} : $self->{init}{cursor}{last}[0];
742             }
743 0         0 $argv->{cursor_info}{previouscmd} = $argv->{cursor_command};
744             }
745             elsif (ref($argv->{cursor_info}) eq "ARRAY")
746             {
747 0         0 $argv->{cursor_info} = [];
748 0         0 push(@{$argv->{cursor_info}},$self->{init}{cursor}{rc},$self->{init}{cursor}{lines});
  0         0  
749 0 0 0     0 if ($argv->{cursor_command} == SQL_SIMPLE_CURSOR_BACK || $argv->{cursor_command} == SQL_SIMPLE_CURSOR_LAST)
750             {
751 0 0       0 push(@{$argv->{cursor_info}},(ref($argv->{cursor_key}) eq "ARRAY") ? $self->{init}{cursor}{last} : $self->{init}{cursor}{last}[0]);
  0         0  
752 0 0       0 push(@{$argv->{cursor_info}},(ref($argv->{cursor_key}) eq "ARRAY") ? $self->{init}{cursor}{first} : $self->{init}{cursor}{first}[0]);
  0         0  
753             }
754             else
755             {
756 0 0       0 push(@{$argv->{cursor_info}},(ref($argv->{cursor_key}) eq "ARRAY") ? $self->{init}{cursor}{first} :$self->{init}{cursor}{first}[0]);
  0         0  
757 0 0       0 push(@{$argv->{cursor_info}},(ref($argv->{cursor_key}) eq "ARRAY") ? $self->{init}{cursor}{last} : $self->{init}{cursor}{last}[0]);
  0         0  
758             }
759 0         0 push(@{$argv->{cursor_info}},$argv->{cursor_command});
  0         0  
760             }
761             elsif (ref($argv->{cursor_info}) eq "SCALAR")
762             {
763 0         0 my @a;
764 0 0 0     0 if ($argv->{cursor_command} == SQL_SIMPLE_CURSOR_BACK || $argv->{cursor_command} == SQL_SIMPLE_CURSOR_LAST)
765             {
766             push(@a,
767 0         0 (ref($argv->{cursor_key}) eq "ARRAY") ? join(" ",@{$self->{init}{cursor}{last}}) : $self->{init}{cursor}{last}[0],
768 0 0       0 (ref($argv->{cursor_key}) eq "ARRAY") ? join(" ",@{$self->{init}{cursor}{first}}) : $self->{init}{cursor}{first}[0],
  0 0       0  
769             );
770             }
771             else
772             {
773             push(@a,
774 0         0 (ref($argv->{cursor_key}) eq "ARRAY") ? join(" ",@{$self->{init}{cursor}{first}}) : $self->{init}{cursor}{first}[0],
775 0 0       0 (ref($argv->{cursor_key}) eq "ARRAY") ? join(" ",@{$self->{init}{cursor}{last}}) : $self->{init}{cursor}{last}[0],
  0 0       0  
776             );
777             }
778 0         0 ${$argv->{cursor_info}} = join(" ",$self->{init}{cursor}{rc},$self->{init}{cursor}{lines},@a,$argv->{cursor_command});
  0         0  
779             }
780 0         0 return SQL_SIMPLE_RC_OK;
781             }
782              
783             ################################################################################
784             ## action: select command
785             ## return:
786             ## rc<0 syntax error
787             ## rc=0 successful
788             ## rc=1 sql error
789             ## rc=2 no selected found (no match where found)
790              
791             sub Select()
792             {
793 187     187 1 43234 my $self = shift;
794 187         766 my $argv = {@_};
795              
796 187 100       669 $argv->{make_only} = 1 if ($argv->{subquery});
797              
798 187         723 $self->_resetSession();
799 187         636 $self->_Dumper("select",$argv);
800 187 50       598 $self->Open() if (!defined($self->{init}{dbh}));
801              
802             ## define the command in load
803 187         506 $self->{work}{command} = SQL_SIMPLE_ALIAS_SELECT;
804              
805 187 50 33     1204 if ($self->{init}{plugin_fh}->can('Select') && $self->{init}{plugin_fh}->Select($argv))
806             {
807 0         0 $self->_setMessage("select",SQL_SIMPLE_RC_SYNTAX,"037",$self->{argv}{interface},$self->{argv}{driver},$self->getMessage());
808 0         0 return SQL_SIMPLE_RC_SYNTAX;
809             }
810              
811 187 50       657 my $saved_message_log = $self->_setLogMessage($argv->{message_log}) if (defined($argv->{message_log}));
812 187 50       463 my $saved_quote = $self->_setQuote($argv->{quote}) if (defined($argv->{quote}));
813 187 100       447 my $saved_sql_save = $self->_setSqlSave($argv->{sql_save}) if (defined($argv->{sql_save}));
814              
815 187         278 my $rc = $self->_Select(%{$argv});
  187         852  
816              
817 187 50       1202 $self->setMessgeLog($saved_message_log) if (defined($argv->{message_log}));
818 187 50       462 $self->_setQuote($saved_quote) if (defined($argv->{quote}));
819 187 100       437 $self->_setSqlSave($saved_sql_save) if (defined($argv->{sql_save}));
820              
821 187 50       434 return "\\(". ( ($self->getRC()==0) ? $self->getLastSQL() : "**".$self->getMessage()."**" ) .")" if ($argv->{subquery});
    100          
822 181         749 return $rc;
823             }
824              
825             sub _Select()
826             {
827 204     204   351 my $self = shift;
828 204         627 my $argv = {@_};
829              
830 204 50       1012 return SQL_SIMPLE_RC_SYNTAX if ($self->_checkTablesEntries("select",$argv) != SQL_SIMPLE_RC_OK);
831              
832             ## testing buffer-hashindex
833 204 50       637 if (!defined($argv->{buffer})){}
    0          
    0          
    0          
    0          
834             elsif (ref($argv->{buffer}) ne "HASH"){}
835             elsif (!defined($argv->{buffer_hashkey})){}
836             elsif (!defined($argv->{buffer_hashindex})){}
837             elsif (ref($argv->{buffer_hashindex}) ne "ARRAY")
838             {
839 0         0 $self->_setMessage("select",SQL_SIMPLE_RC_SYNTAX,"048");
840 0         0 return SQL_SIMPLE_RC_SYNTAX;
841             }
842              
843             ## testing fields
844 204         543 my @fields_work;
845             my %fields_distinct;
846 204         0 my %fields_aliases;
847              
848 204 100       466 if (defined($argv->{fields}))
    100          
849             {
850 192         356 my $fields_argv;
851 192 100       531 if (ref($argv->{fields}) eq "ARRAY") { $fields_argv = $argv->{fields}; }
  181 50       339  
852 11         36 elsif (ref($argv->{fields}) eq "") { $fields_argv = [ $argv->{fields} ]; }
853             else
854             {
855 0         0 $self->_setMessage("select",SQL_SIMPLE_RC_SYNTAX,"007");
856 0         0 return SQL_SIMPLE_RC_SYNTAX;
857             }
858 192 100 100     261 if (@{$fields_argv} != 1 || $fields_argv->[0] ne "*")
  192         968  
859             {
860 189         341 for (my $ix=0; $ix < @{$fields_argv}; $ix++)
  444         1127  
861             {
862 272         506 my $field = $fields_argv->[$ix];
863 272         458 my $distinct;
864             my $alias;
865 272 100       653 if (ref($field) eq "HASH")
866             {
867 80         121 $alias = $field;
868 80         111 ($fields_aliases{$alias}{f},$fields_aliases{$alias}{a}) = %{$field};
  80         471  
869 80         188 $field = $fields_aliases{$alias}{f};
870 80         362 $self->{work}{field_alias}{$fields_aliases{$alias}{a}} = $fields_aliases{$alias}{f};
871 80         308 $self->{work}{field_realname}{$fields_aliases{$alias}{f}} = $fields_aliases{$alias}{a};
872 80 100       720 $self->{work}{field_cols}{$1}{$fields_aliases{$alias}{a}} = $2 if ($fields_aliases{$alias}{f} =~ /^(.*?)\.(.*?)$/);
873             }
874 272 100       1319 if ($field =~ /^distinct$/i)
    50          
875             {
876 3         7 $field = $fields_argv->[++$ix];
877 3         5 $distinct = 1;
878             }
879             elsif ($field =~ /^distinct\s+(.*)/i)
880             {
881 0         0 $field = $1;
882 0         0 $distinct = 1;
883             }
884 272 100       727 if (!($field =~ /^\\/))
885             {
886 269 100       867 my $value = ($field =~ /^(.*?)\((.*?)\,(.*)\)/) ? $2 : ($field =~ /^(.*?)\((.*)\)/) ? $2 : $field;
    100          
887 269 100       1367 if ($value =~ /^(.*)\.(.*)$/)
888             {
889 129 100       207 if (!grep(/^$1$/,@{$self->{work}{tables_valids}}))
  129         2958  
890             {
891 17         75 $self->_setMessage("select",SQL_SIMPLE_RC_SYNTAX,"010",$field);
892 17         119 return SQL_SIMPLE_RC_SYNTAX;
893             }
894             }
895             }
896 255   66     895 push(@fields_work,$alias || $field);
897 255 100       707 $fields_distinct{$field} = 1 if ($distinct);
898             }
899             }
900             }
901             elsif (defined($self->{argv}{tables}))
902             {
903 5 100       5 if (@{$self->{work}{tables_inuse}} > 1)
  5         15  
904             {
905 1         2 my $any=0;
906 1         2 foreach my $table(@{$self->{work}{tables_inuse}})
  1         2  
907             {
908 2         4 my $temp;
909 2 50 33     6 if (!defined($self->{argv}{tables}{$table}) || !defined($self->{argv}{tables}{$table}{cols}))
910             {
911 2 50       4 if (!defined($self->{init}{table_realname}{$table}))
912             {
913 2         3 $any=1;
914 2         3 next;
915             }
916 0         0 $temp = $self->{init}{table_realname}{$table};
917             }
918             else
919             {
920 0         0 $temp = $table;
921             }
922 0         0 foreach my $field(sort(keys(%{$self->{argv}{tables}{$temp}{cols}})))
  0         0  
923             {
924 0         0 push(@fields_work,$table.".".$field);
925             }
926             }
927 1 50 33     19 if ($any && @fields_work)
928             {
929 0         0 $self->_setMessage("select",SQL_SIMPLE_RC_SYNTAX,"010","*");
930 0         0 return SQL_SIMPLE_RC_SYNTAX;
931             }
932             }
933             else
934             {
935 4 100       16 my $temp = (!defined($self->{init}{table_realname}{$self->{work}{tables_inuse}[0]})) ? $self->{work}{tables_inuse}[0] : $self->{init}{table_realname}{$self->{work}{tables_inuse}[0]};
936 4 100 66     17 if (defined($self->{argv}{tables}{$temp}) && defined($self->{argv}{tables}{$temp}{cols}))
937             {
938 2         4 push(@fields_work,sort(keys(%{$self->{argv}{tables}{$temp}{cols}})));
  2         11  
939             }
940             }
941             }
942             ## testing groupby
943 187         343 my @group_work;
944 187 100       429 if (defined($argv->{group_by}))
945             {
946 15 50       39 if (ref($argv->{group_by}) eq "") { @group_work = ($argv->{group_by}); }
  0 50       0  
947 15         18 elsif (ref($argv->{group_by}) eq "ARRAY") { push(@group_work,@{$argv->{group_by}}); }
  15         26  
948             else
949             {
950 0         0 $self->_setMessage("select",SQL_SIMPLE_RC_SYNTAX,"008");
951 0         0 return SQL_SIMPLE_RC_SYNTAX;
952             }
953             }
954            
955             ## testing orderby
956 187         267 my @order_work;
957 187 100       381 if (defined($argv->{order_by}))
958             {
959 42 100       204 if (ref($argv->{order_by}) eq "") { @order_work = ($argv->{order_by}); }
  2 100       7  
    50          
960 2         7 elsif (ref($argv->{order_by}) eq "HASH") { @order_work = ($argv->{order_by}); }
961             elsif (ref($argv->{order_by}) eq "ARRAY")
962             {
963 38         66 push(@order_work,@{$argv->{order_by}});
  38         81  
964             }
965             else
966             {
967 0         0 $self->_setMessage("select",SQL_SIMPLE_RC_SYNTAX,"009");
968 0         0 return SQL_SIMPLE_RC_SYNTAX;
969             }
970             }
971            
972             ## making fields
973 187 50       498 my $middle = ($self->{init}{alias_with_as}) ? " AS " : " ";
974 187         376 my @fields;
975 187         382 my $table = $self->{work}{tables_inuse}[0];
976 187 100       413 if (@fields_work)
977             {
978 174         334 foreach my $field(@fields_work)
979             {
980 261         424 my $alias;
981 261 100       583 my $distinct = ($fields_distinct{$field}) ? "DISTINCT " : "";
982             ## field is hash?
983 261 100       667 if (defined($fields_aliases{$field}))
984             {
985 72         135 $alias = $fields_aliases{$field}{a};
986 72         165 $field = $fields_aliases{$field}{f};
987             }
988             ## is escape?
989 261 100       616 if ($field =~ /^\\(.*)/)
990             {
991 3 100       16 ($alias) ?
992             push(@fields,$distinct.$1.$middle.$alias) :
993             push(@fields,$distinct.$1);
994 3         6 next;
995             }
996             ## have function?
997 258         449 my $field_a;
998             my $field_b;
999 258 100       760 if ($field =~ /^(.*?)\((.*?)\,(.*)\)/)
    100          
1000             {
1001 1         3 $field_a = $1."(";
1002 1         2 $field = $2;
1003 1         5 $field_b = ",".$3.")";
1004             }
1005             elsif ($field =~ /^(.*?)\((.*)\)/)
1006             {
1007 18         41 $field_a = $1."(";
1008 18         33 $field = $2;
1009 18         23 $field_b = ")";
1010             }
1011             else
1012             {
1013 239         603 $field_a = "";
1014 239         401 $field_b = "";
1015             }
1016             ## translate field
1017 258 100       803 if ($field =~ /^(.*)\.(.*)$/)
1018             {
1019 112         349 my $realn = $self->_getAliasCols(1,$field,SQL_SIMPLE_ALIAS_SELECT);
1020 112 100       544 my $table = (!defined($self->{init}{table_realname}{$1})) ? $1 : $self->{init}{table_realname}{$1};
1021 112         239 my $field = $2;
1022 112 100       490 if ($realn =~ /^.*\..*$/)
1023             {
1024 88 100       516 ($alias) ?
    100          
1025             push(@fields,$distinct.$field_a.$realn.$field_b.$middle.$alias) :
1026             ($table.".".$field ne $realn) ?
1027             push(@fields,$distinct.$field_a.$realn.$field_b.$middle.$field) :
1028             push(@fields,$distinct.$field_a.$realn.$field_b);
1029             }
1030             else
1031             {
1032 24 100       155 ($alias) ?
    100          
1033             push(@fields,$distinct.$field_a.$table.".".$realn.$field_b.$middle.$alias) :
1034             ($field ne $realn) ?
1035             push(@fields,$distinct.$field_a.$table.".".$realn.$field_b.$middle.$field) :
1036             push(@fields,$distinct.$field_a.$table.".".$realn.$field_b);
1037             }
1038             }
1039             else
1040             {
1041 146 100       218 if (@{$self->{work}{tables_inuse}} == 1)
  146         396  
1042             {
1043 120         354 my $realn = $self->_getAliasCols(2,$field,SQL_SIMPLE_ALIAS_SELECT);
1044 120 100       675 ($alias) ?
    100          
1045             push(@fields,$distinct.$field_a.$realn.$field_b.$middle.$alias) :
1046             ($field ne $realn) ?
1047             push(@fields,$distinct.$field_a.$realn.$field_b.$middle.$field) :
1048             push(@fields,$distinct.$field_a.$field.$field_b);
1049             }
1050             else
1051             {
1052 26 100       57 if ($alias)
1053             {
1054 10         35 push(@fields,$distinct.$field_a.$field.$field_b.$middle.$alias);
1055             }
1056             else
1057             {
1058 16         24 foreach my $table(@{$self->{work}{tables_inuse}})
  16         43  
1059             {
1060 32         84 my $realn = $self->_getAliasCols(3,$field,SQL_SIMPLE_ALIAS_SELECT);
1061 32 50       114 if ($realn ne $field)
1062             {
1063 0         0 $alias = $field;
1064 0         0 $field = $realn;
1065 0         0 last;
1066             }
1067             }
1068 16 50       72 ($alias) ?
1069             push(@fields,$distinct.$field_a.$field.$field_b.$middle.$alias):
1070             push(@fields,$distinct.$field_a.$field.$field_b);
1071             }
1072             }
1073             }
1074             }
1075             }
1076             else
1077             {
1078 13         86 push(@fields,"*");
1079             }
1080              
1081             ## make where
1082 187         295 my $where;
1083 187 50       836 return SQL_SIMPLE_RC_SYNTAX if ($self->_getWhere("select",$argv->{where},\$where));
1084              
1085             ## make group_by
1086 187         618 for (my $i=0; $i < @group_work; $i++)
1087             {
1088 22 100       101 $group_work[$i] = ($group_work[$i] =~ /^(.*)\.(.*)$/) ?
1089             $self->_getAliasCols(4,$group_work[$i],SQL_SIMPLE_ALIAS_GROUPBY+SQL_SIMPLE_ALIAS_FQDN) :
1090             $self->_getAliasCols(5,$group_work[$i],SQL_SIMPLE_ALIAS_GROUPBY);
1091             }
1092              
1093             ## make order
1094 187         282 my @order;
1095 187         390 while (@order_work)
1096             {
1097 56         105 my $field = shift(@order_work);
1098 56 100       174 if (ref($field) eq "HASH")
1099             {
1100 48         85 foreach my $_id(sort(keys(%{$field})))
  48         188  
1101             {
1102 48         153 $self->_SelectOrderBy(\@order,$table,$_id,$field->{$_id});
1103             }
1104             }
1105 8         43 else { $self->_SelectOrderBy(\@order,$table,$field); }
1106             }
1107              
1108             ## make tables
1109 187         402 my @tables;
1110 187         256 foreach my $table(@{$self->{work}{tables_inuse}})
  187         519  
1111             {
1112 253         700 push(@tables,$self->_getAliasTable($table,$argv));
1113             }
1114              
1115             ## build sql command
1116 187         628 my $sql = "SELECT ".join(", ",@fields)." FROM ".join(", ",@tables);
1117 187 100       480 $sql .= " WHERE ".$where if ($where);
1118 187 100       389 $sql .= " GROUP BY ".join(", ",@group_work) if (@group_work);
1119 187 100       436 $sql .= " ORDER BY ".join(", ",@order) if (@order);
1120 187 100 100     676 $sql .= " LIMIT ".$argv->{limit} if (defined($argv->{limit}) && $argv->{limit} > 0);
1121              
1122             ## cross check cursor_key v buffer_hashkey
1123 187         624 $self->{work}{cursor_key_vs_hashkey} = 0;
1124 187 50       456 if (defined($argv->{buffer_hashkey}))
1125             {
1126 0         0 $self->{work}{buffer_hashkey} = [];
1127 0 0       0 foreach my $key( (ref($argv->{buffer_hashkey}) eq "ARRAY") ? @{$argv->{buffer_hashkey}} : ($argv->{buffer_hashkey}) )
  0         0  
1128             {
1129 0         0 push(@{$self->{work}{buffer_hashkey}},$key);
  0         0  
1130 0 0 0     0 $self->{work}{cursor_key_vs_hashkey}++ if (defined($self->{work}{cursor_key}) && grep(/^$key$/,@{$self->{work}{cursor_key}}));
  0         0  
1131             }
1132             }
1133              
1134             ## execute
1135             return SQL_SIMPLE_RC_ERROR if ($self->_Call(
1136             command => $sql,
1137             command_type => 0, # (ZERO is read)
1138             buffer => $argv->{buffer},
1139             buffer_options => $argv->{buffer_options},
1140             buffer_hashkey => $argv->{buffer_hashkey},
1141             buffer_arrayref => $argv->{buffer_arrayref},
1142             buffer_hashindex => $argv->{buffer_hashindex},
1143             buffer_hashindex => $argv->{buffer_hashindex},
1144             buffer_fields => @fields+0,
1145             cursor => $argv->{cursor},
1146             cursor_command => $argv->{cursor_command},
1147             cursor_key => $argv->{cursor_key},
1148             cursor_order => $argv->{cursor_order},
1149             make_only => $argv->{make_only},
1150             flush => $argv->{flush},
1151             sql_save => $argv->{sql_save},
1152 187 50       2682 ));
1153 0 0       0 return SQL_SIMPLE_RC_OK if ($self->getRows());
1154 0 0       0 return SQL_SIMPLE_RC_OK if ($argv->{notfound});
1155              
1156 0         0 $self->_setMessage("select",SQL_SIMPLE_RC_SYNTAX,"012");
1157 0         0 return SQL_SIMPLE_RC_EMPTY;
1158             }
1159              
1160             sub _SelectOrderBy()
1161             {
1162 56     56   93 my $self = shift;
1163 56         111 my $array = shift;
1164 56         85 my $table = shift;
1165 56         90 my $field = shift;
1166 56         126 my $order = shift;
1167              
1168 56 100       289 if ($field =~ /^(.*?)\.(.*?)$/)
1169             {
1170 41         109 $field = $self->_getAliasCols(6,$field,SQL_SIMPLE_ALIAS_ORDERBY+SQL_SIMPLE_ALIAS_FQDN);
1171             }
1172             else
1173             {
1174 15         40 $field = $self->_getAliasCols(7,$field,SQL_SIMPLE_ALIAS_ORDERBY);
1175             }
1176 56 100       153 if ($order)
1177             {
1178 48         97 $order = uc($order);
1179 48 50       178 $field .= " ".(($order eq SQL_SIMPLE_ORDER_ASC) ? 'ASC' : ($order eq SQL_SIMPLE_ORDER_DESC) ? 'DESC' : 'USING '.$order);
    100          
1180             }
1181 56         80 push(@{$array},$field);
  56         265  
1182             }
1183              
1184             ################################################################################
1185             ## action: delete
1186             ## return:
1187             ## rc<0 syntax error
1188             ## rc=0 successful
1189             ## rc=1 sql error
1190             ## rc=2 no selected found (no match where found)
1191              
1192             sub Delete()
1193             {
1194 15     15 1 12699 my $self = shift;
1195 15         69 my $argv = {@_};
1196              
1197 15         61 $self->_resetSession();
1198 15         51 $self->_Dumper("delete",$argv);
1199 15 100       62 $self->Open() if (!defined($self->{init}{dbh}));
1200              
1201             ## define the command in load
1202 15         43 $self->{work}{command} = SQL_SIMPLE_ALIAS_DELETE;
1203              
1204 15 50 33     94 if ($self->{init}{plugin_fh}->can('Delete') && $self->{init}{plugin_fh}->Delete($argv))
1205             {
1206 0         0 $self->_setMessage("delete",SQL_SIMPLE_RC_SYNTAX,"037",$self->{argv}{interface},$self->{argv}{driver},$self->getMessage());
1207 0         0 return SQL_SIMPLE_RC_SYNTAX;
1208             }
1209              
1210 15 50       49 my $saved_commit = $self->_setCommit($argv->{commit}) if (defined($argv->{commit}));
1211 15 50       41 my $saved_message_log = $self->_setLogMessage($argv->{message_log}) if (defined($argv->{message_log}));
1212 15 50       40 my $saved_quote = $self->_setQuote($argv->{quote}) if (defined($argv->{quote}));
1213 15 50       38 my $saved_sql_save = $self->_setSqlSave($argv->{sql_save}) if (defined($argv->{sql_save}));
1214              
1215 15         27 my $rc = $self->_Delete(%{$argv});
  15         96  
1216              
1217 15 50       118 $self->_setCommit($saved_commit) if (defined($argv->{commit}));
1218 15 50       42 $self->setMessgeLog($saved_message_log) if (defined($argv->{message_log}));
1219 15 50       39 $self->_setQuote($saved_quote) if (defined($argv->{quote}));
1220 15 50       39 $self->_setSqlSave($saved_sql_save) if (defined($argv->{sql_save}));
1221              
1222 15         70 return $rc;
1223             }
1224              
1225             sub _Delete()
1226             {
1227 15     15   39 my $self = shift;
1228 15         52 my $argv = {@_};
1229              
1230 15 50       48 return SQL_SIMPLE_RC_SYNTAX if ($self->_checkTablesEntries("delete",$argv) != SQL_SIMPLE_RC_OK);
1231              
1232             ## make where
1233 15         29 my $where;
1234 15 50       65 return SQL_SIMPLE_RC_SYNTAX if ($self->_getWhere("delete",$argv->{where},\$where));
1235 15 50 66     84 if ((!defined($where) || $where eq "") && !$argv->{force})
      66        
1236             {
1237 0         0 $self->_setMessage("delete",SQL_SIMPLE_RC_SYNTAX,"016");
1238 0         0 return SQL_SIMPLE_RC_SYNTAX;
1239             }
1240              
1241             ## build sql command
1242 15         31 my $sql = "DELETE FROM ".join(", ",@{$self->{work}{tables_inuse}});
  15         47  
1243 15 100       53 $sql .= " WHERE ".$where if ($where);
1244              
1245             return SQL_SIMPLE_RC_ERROR if ($self->_Call(
1246             command => $sql,
1247             command_type => 1, # (NOT_ZERO is update)
1248             buffer => $argv->{buffer},
1249             buffer_options => $argv->{buffer_options},
1250             buffer_hashkey => $argv->{buffer_hashkey},
1251             buffer_arrayref => $argv->{buffer_arrayref},
1252             make_only => $argv->{make_only},
1253             flush => $argv->{flush},
1254             sql_save => $argv->{sql_save},
1255 15 50       141 ));
1256 0 0       0 return SQL_SIMPLE_RC_OK if ($argv->{notfound});
1257 0 0       0 if ($self->getRows() == 0)
1258             {
1259 0         0 $self->_setMessage("delete",SQL_SIMPLE_RC_SYNTAX,"012");
1260 0         0 return SQL_SIMPLE_RC_EMPTY;
1261             }
1262 0         0 return SQL_SIMPLE_RC_OK;
1263             }
1264              
1265             ################################################################################
1266             ## action: insert
1267             ## return:
1268             ## rc<0 syntax error
1269             ## rc=0 successful
1270             ## rc=1 sql error
1271             ## rc=2 no selected found (no match where found)
1272              
1273             sub Insert()
1274             {
1275 22     22 1 34852 my $self = shift;
1276 22         105 my $argv = {@_};
1277              
1278 22         84 $self->_resetSession();
1279 22         77 $self->_Dumper("insert",$argv);
1280 22 50       73 $self->Open() if (!defined($self->{init}{dbh}));
1281              
1282             ## define the command in load
1283 22         115 $self->{work}{command} = SQL_SIMPLE_ALIAS_INSERT;
1284              
1285 22 50 33     139 if ($self->{init}{plugin_fh}->can('Insert') && $self->{init}{plugin_fh}->Insert($argv))
1286             {
1287 0         0 $self->_setMessage("insert",SQL_SIMPLE_RC_SYNTAX,"037",$self->{argv}{interface},$self->{argv}{driver},$self->getMessage());
1288 0         0 return SQL_SIMPLE_RC_SYNTAX;
1289             }
1290              
1291 22 50       72 my $saved_commit = $self->_setCommit($argv->{commit}) if (defined($argv->{commit}));
1292 22 50       63 my $saved_message_log = $self->_setLogMessage($argv->{message_log}) if (defined($argv->{message_log}));
1293 22 50       62 my $saved_quote = $self->_setQuote($argv->{quote}) if (defined($argv->{quote}));
1294 22 50       54 my $saved_sql_save = $self->_setSqlSave($argv->{sql_save}) if (defined($argv->{sql_save}));
1295              
1296 22         66 my $rc = $self->_Insert(%{$argv});
  22         99  
1297              
1298 22 50       135 $self->_setCommit($saved_commit) if (defined($argv->{commit}));
1299 22 50       52 $self->setMessgeLog($saved_message_log) if (defined($argv->{message_log}));
1300 22 50       56 $self->_setQuote($saved_quote) if (defined($argv->{quote}));
1301 22 50       50 $self->_setSqlSave($saved_sql_save) if (defined($argv->{sql_save}));
1302              
1303 22         119 return $rc;
1304             }
1305              
1306             sub _Insert()
1307             {
1308 22     22   41 my $self = shift;
1309 22         68 my $argv = {@_};
1310              
1311 22 50       69 return SQL_SIMPLE_RC_SYNTAX if ($self->_checkTablesEntries("insert",$argv) != SQL_SIMPLE_RC_OK);
1312              
1313             ## check mandatory options
1314 22 50       70 if (!defined($argv->{fields}))
1315             {
1316 0         0 $self->_setMessage("insert",SQL_SIMPLE_RC_SYNTAX,"017");
1317 0         0 return SQL_SIMPLE_RC_SYNTAX;
1318             }
1319              
1320             ## hash: fields=> { fld => value }
1321             ## array: fields=> [ fld1,fld2 }, values=> [ val1,val2 ]
1322 22 100       90 if (ref($argv->{fields}) eq "HASH") {}
    50          
1323             elsif (ref($argv->{fields}) eq "ARRAY")
1324             {
1325 11 50       33 if (!defined($argv->{values}))
1326             {
1327 0         0 $self->_setMessage("insert",SQL_SIMPLE_RC_SYNTAX,"027");
1328 0         0 return SQL_SIMPLE_RC_SYNTAX;
1329             }
1330 11 50       34 if (ref($argv->{values}) ne "ARRAY")
1331             {
1332 0         0 $self->_setMessage("insert",SQL_SIMPLE_RC_SYNTAX,"041");
1333 0         0 return SQL_SIMPLE_RC_SYNTAX;
1334             }
1335             }
1336             else
1337             {
1338 0         0 $self->_setMessage("insert",SQL_SIMPLE_RC_SYNTAX,"018");
1339 0         0 return SQL_SIMPLE_RC_SYNTAX;
1340             }
1341              
1342             ## validat conflict option
1343 22 50 33     65 if (defined($argv->{conflict}) && ref($argv->{conflict}) ne "HASH")
1344             {
1345 0         0 $self->_setMessage("insert",SQL_SIMPLE_RC_SYNTAX,"042");
1346 0         0 return SQL_SIMPLE_RC_SYNTAX;
1347             }
1348              
1349             ## making fields
1350 22         51 my @fields;
1351             my @values;
1352              
1353             ## format: fields => { ... }
1354 22 100       79 if (ref($argv->{fields}) eq "HASH")
1355             {
1356             ## mapping field and value
1357 11         17 my @value_;
1358 11         29 foreach my $field(sort(keys(%{$argv->{fields}})))
  11         90  
1359             {
1360 16         72 push(@fields,$self->_getAliasCols(8,$field,SQL_SIMPLE_ALIAS_INSERT));
1361 16 100       97 push(@value_,(!defined($argv->{fields}{$field})) ? "NULL" : $self->{argv}{quote}.$self->_escapeQuote($argv->{fields}{$field}).$self->{argv}{quote});
1362             }
1363 11         60 @values = ("(".join(",",@value_).")");
1364             }
1365             ## format: fields => [ ... ]
1366             else
1367             {
1368             ## mapping field
1369 11         19 foreach my $field(@{$argv->{fields}})
  11         33  
1370             {
1371 16         52 push(@fields,$self->_getAliasCols(9,$field,SQL_SIMPLE_ALIAS_INSERT));
1372             }
1373 11         25 my @value_;
1374 11         19 foreach my $value(@{$argv->{values}})
  11         27  
1375             {
1376             ## format: fields => [ col => val ]
1377 22 50       61 if (ref($value) ne "ARRAY")
1378             {
1379 22 100       107 push(@value_,(!defined($value)) ? "NULL" : $self->{argv}{quote}.$self->_escapeQuote($value).$self->{argv}{quote});
1380             }
1381             ## format: fields => [ col => [ val1, ... ] ], field must be 1
1382             else
1383             {
1384 0         0 my @value2;
1385 0         0 foreach my $value2(@{$value})
  0         0  
1386             {
1387 0 0       0 push(@value2,(!defined($value2)) ? "NULL" : $self->{argv}{quote}.$self->_escapeQuote($value2).$self->{argv}{quote});
1388             }
1389 0         0 push(@values,"(".join(",",@value2).")");
1390             }
1391             }
1392 11 100       78 push(@values, (@fields == 1) ? "(".join("),(",@value_).")" : "(".join(",",@value_).")" ) if (@value_);
    50          
1393             }
1394              
1395             ## build sql
1396 22         44 my $sql = "INSERT INTO ".join(", ",@{$self->{work}{tables_inuse}})." (".join(",",@fields).") VALUES ".join(",",@values);
  22         84  
1397 22 50       66 if (defined($argv->{conflict}))
1398             {
1399 0         0 my @conflict;
1400 0         0 foreach my $field(sort(keys(%{$argv->{conflict}})))
  0         0  
1401             {
1402             ($argv->{conflict}{$field} =~ /^\\(.*)/) ?
1403             push(@conflict,$self->_getAliasCols(10,$field,SQL_SIMPLE_ALIAS_INSERT)." = ".$1):
1404 0 0       0 push(@conflict,$self->_getAliasCols(11,$field,SQL_SIMPLE_ALIAS_INSERT)." = ".$self->{argv}{quote}.$self->_escapeQuote($argv->{conflict}{$field}).$self->{argv}{quote});
1405             }
1406             $sql .= ($self->{init}{plugin_id} =~ /^mysql/i || $self->{init}{plugin_id} =~ /^mariadb/i) ?
1407             " ON DUPLICATE KEY UPDATE ".join(", ",@conflict) :
1408 0 0 0     0 " ON CONFLICT ".(($argv->{conflict_key})?"(".$self->_getAliasCols(12,$argv->{conflict_key},SQL_SIMPLE_ALIAS_INSERT).") ":"")."DO UPDATE SET ".join(", ",@conflict);
    0          
1409             }
1410              
1411             ## execute
1412             return SQL_SIMPLE_RC_ERROR if ($self->_Call(
1413             command => $sql,
1414             command_type => 1, # (NOT_ZERO is update)
1415             buffer => $argv->{buffer},
1416             buffer_options => $argv->{buffer_options},
1417             buffer_hashkey => $argv->{buffer_hashkey},
1418             buffer_arrayref => $argv->{buffer_arrayref},
1419             make_only => $argv->{make_only},
1420             flush => $argv->{flush},
1421             sql_save => $argv->{sql_save},
1422 22 50       210 ));
1423 0         0 return SQL_SIMPLE_RC_OK;
1424             }
1425              
1426             ################################################################################
1427             ## action: update
1428             ## return:
1429             ## rc<0 syntax error
1430             ## rc=0 successful
1431             ## rc=1 sql error
1432             ## rc=2 no selected found (no match where found)
1433              
1434             sub Update()
1435             {
1436 40     40 1 68901 my $self = shift;
1437 40         205 my $argv = {@_};
1438              
1439 40         155 $self->_resetSession();
1440 40         135 $self->_Dumper("update",$argv);
1441 40 50       130 $self->Open() if (!defined($self->{init}{dbh}));
1442              
1443             ## define the command in load
1444 40         96 $self->{work}{command} = SQL_SIMPLE_ALIAS_UPDATE;
1445              
1446 40 50 33     267 if ($self->{init}{plugin_fh}->can('Update') && $self->{init}{plugin_fh}->Update($argv))
1447             {
1448 0         0 $self->_setMessage("update",SQL_SIMPLE_RC_SYNTAX,"037",$self->{argv}{interface},$self->{argv}{driver},$self->getMessage());
1449 0         0 return SQL_SIMPLE_RC_SYNTAX;
1450             }
1451              
1452 40 50       118 my $saved_commit = $self->_setCommit($argv->{commit}) if (defined($argv->{commit}));
1453 40 50       105 my $saved_message_log = $self->_setLogMessage($argv->{message_log}) if (defined($argv->{message_log}));
1454 40 50       110 my $saved_quote = $self->_setQuote($argv->{quote}) if (defined($argv->{quote}));
1455 40 50       95 my $saved_sql_save = $self->_setSqlSave($argv->{sql_save}) if (defined($argv->{sql_save}));
1456              
1457 40         70 my $rc = $self->_Update(%{$argv});
  40         171  
1458              
1459 40 50       251 $self->_setCommit($saved_commit) if (defined($argv->{commit}));
1460 40 50       122 $self->setMessgeLog($saved_message_log) if (defined($argv->{message_log}));
1461 40 50       130 $self->_setQuote($saved_quote) if (defined($argv->{quote}));
1462 40 50       93 $self->_setSqlSave($saved_sql_save) if (defined($argv->{sql_save}));
1463              
1464 40         204 return $rc;
1465             }
1466              
1467             sub _Update()
1468             {
1469 40     40   81 my $self = shift;
1470 40         176 my $argv = {@_};
1471              
1472 40 50       118 return SQL_SIMPLE_RC_SYNTAX if ($self->_checkTablesEntries("update",$argv) != SQL_SIMPLE_RC_OK);
1473              
1474             ## check mandatory options
1475 40 50       122 if (!defined($argv->{fields}))
1476             {
1477 0         0 $self->_setMessage("update",SQL_SIMPLE_RC_SYNTAX,"017");
1478 0         0 return SQL_SIMPLE_RC_SYNTAX;
1479             }
1480 40 50       154 if (ref($argv->{fields}) ne "HASH")
1481             {
1482 0         0 $self->_setMessage("update",SQL_SIMPLE_RC_SYNTAX,"018");
1483 0         0 return SQL_SIMPLE_RC_SYNTAX;
1484             }
1485              
1486             ## make fields
1487 40         67 my $ident = 0;
1488 40         112 my @fields;
1489 40         65 foreach my $field(sort(keys(%{$argv->{fields}})))
  40         219  
1490             {
1491 54         187 my $realn = $self->_getAliasCols(13,$field,SQL_SIMPLE_ALIAS_UPDATE);
1492 54 100       228 $ident = 1 if ($realn =~ /^.*\..*$/);
1493              
1494 54 100       233 if (!defined($argv->{fields}{$field}))
    100          
1495             {
1496 2         8 push(@fields,$realn." = NULL");
1497             }
1498             elsif ($argv->{fields}{$field} =~ /^\\(.*)/)
1499             {
1500 1         7 my $value = $1;
1501 1         5 push(@fields,$realn." = ".$value);
1502             }
1503             else
1504             {
1505             ## validate functions as arguments
1506 51         209 $self->_checkFunctions(\$argv->{fields}{$field},SQL_SIMPLE_ALIAS_UPDATE);
1507 51         192 push(@fields,$realn." = ".$self->{argv}{quote}.$self->_escapeQuote($argv->{fields}{$field}).$self->{argv}{quote});
1508             }
1509             }
1510              
1511             ## make tables
1512 40         81 my @tables;
1513 40         60 foreach my $table(@{$self->{work}{tables_inuse}})
  40         107  
1514             {
1515 51         156 my $_table = $self->_getAliasTable($table,$argv);
1516              
1517             ## remove alias if not required
1518 51 100 100     419 $_table = $1 if (!$ident && $_table =~ /^(.*?)\s+.*?$/);
1519              
1520 51         126 push(@tables,$_table);
1521             }
1522              
1523             ## make where
1524 40         92 my $where;
1525 40 50       443 return SQL_SIMPLE_RC_SYNTAX if ($self->_getWhere("update",$argv->{where},\$where));
1526 40 50 66     234 if ((!defined($where) || $where eq "") && !$argv->{force})
      66        
1527             {
1528 0         0 $self->_setMessage("update",SQL_SIMPLE_RC_SYNTAX,"016");
1529 0         0 return SQL_SIMPLE_RC_SYNTAX;
1530             }
1531              
1532             ## formata o sql
1533 40         142 my $sql = "UPDATE ".join(", ",@tables)." SET ".join(", ",@fields);
1534 40 100       120 $sql .= " WHERE ".$where if ($where);
1535              
1536             ## execute
1537             return SQL_SIMPLE_RC_ERROR if ($self->_Call(
1538             command => $sql,
1539             command_type => 1, # (NOT_ZERO is update)
1540             buffer => $argv->{buffer},
1541             buffer_options => $argv->{buffer_options},
1542             buffer_hashkey => $argv->{buffer_hashkey},
1543             buffer_arrayref => $argv->{buffer_arrayref},
1544             make_only => $argv->{make_only},
1545             flush => $argv->{flush},
1546             sql_save => $argv->{sql_save},
1547 40 50       428 ));
1548 0 0       0 return SQL_SIMPLE_RC_OK if ($argv->{notfound});
1549 0 0       0 if ($self->getRows() == 0)
1550             {
1551 0         0 $self->_setMessage("update",SQL_SIMPLE_RC_SYNTAX,"012");
1552 0         0 return SQL_SIMPLE_RC_EMPTY;
1553             }
1554 0         0 return SQL_SIMPLE_RC_OK;
1555             }
1556              
1557             ################################################################################
1558             ## action: wait db connect
1559             ## return:
1560             ## rc<0 syntax error
1561             ## rc=0 successful
1562             ## rc>0 sql command error
1563              
1564             sub Wait()
1565             {
1566 0     0 0 0 my $self = shift;
1567 0         0 my $argv= {@_};
1568              
1569 0         0 $self->_Dumper("wait",$argv);
1570              
1571 0 0       0 my $count = 1 if (!defined($argv->{count}));
1572 0 0       0 my $sleep = 5 if (!defined($argv->{interval}));
1573              
1574 0 0       0 return SQL_SIMPLE_RC_SYNTAX if ($count =~ /^\D+$/);
1575 0 0       0 return SQL_SIMPLE_RC_SYNTAX if ($sleep =~ /^\D+$/);
1576              
1577 0         0 while ($count-- > 0)
1578             {
1579 0 0       0 last if (!$self->Open());
1580              
1581 0 0 0     0 sleep($sleep) if ($count && $sleep);
1582             }
1583 0         0 return $self->getRC();
1584             }
1585              
1586             ################################################################################
1587             ## action: execute sql command
1588             ## return:
1589             ## rc<0 syntax error
1590             ## rc=0 successful
1591             ## rc>0 sql command error
1592             #
1593             ## callback example:
1594             ## sub myfunc()
1595             ## {
1596             ## my $ref = shift; # input field hash info
1597             ## my $options = shift; # options args
1598             ## return 0; # if ok to continue than return ZERO
1599             ## return 1; # if aboort needed than return NOT_ZERO
1600             ## }
1601              
1602             sub Call()
1603             {
1604 0     0 1 0 my $self = shift;
1605 0         0 my $argv = {@_};
1606              
1607 0         0 $self->_resetSession();
1608 0         0 $self->_Dumper("call",$argv);
1609 0 0       0 $self->Open() if (!defined($self->{init}{dbh}));
1610              
1611             ## define the command in load
1612              
1613 0 0 0     0 if ($self->{init}{plugin_fh}->can('Call') && $self->{init}{plugin_fh}->Call($argv))
1614             {
1615 0         0 $self->_setMessage("call",SQL_SIMPLE_RC_SYNTAX,"037",$self->{argv}{interface},$self->{argv}{driver},$self->getMessage());
1616 0         0 return SQL_SIMPLE_RC_SYNTAX;
1617             }
1618 0 0       0 if ($argv->{command} eq "")
1619             {
1620 0         0 $self->_setMessage("call",SQL_SIMPLE_RC_SYNTAX,"023");
1621 0         0 return SQL_SIMPLE_RC_SYNTAX;
1622             }
1623              
1624 0 0       0 my $saved_commit = $self->_setCommit($argv->{commit}) if (defined($argv->{commit}));
1625 0 0       0 my $saved_message_log = $self->_setLogMessage($argv->{message_log}) if (defined($argv->{message_log}));
1626 0 0       0 my $saved_quote = $self->_setQuote($argv->{quote}) if (defined($argv->{quote}));
1627 0 0       0 my $saved_sql_save = $self->_setSqlSave($argv->{sql_save}) if (defined($argv->{sql_save}));
1628              
1629 0         0 my $rc = $self->_Call(%{$argv});
  0         0  
1630              
1631 0 0       0 $self->_setCommit($saved_commit) if (defined($argv->{commit}));
1632 0 0       0 $self->setMessgeLog($saved_message_log) if (defined($argv->{message_log}));
1633 0 0       0 $self->_setQuote($saved_quote) if (defined($argv->{quote}));
1634 0 0       0 $self->_setSqlSave($saved_sql_save) if (defined($argv->{sql_save}));
1635              
1636 0         0 return $rc;
1637             }
1638              
1639             sub _Call()
1640             {
1641 264     264   550 my $self = shift;
1642 264         3197 my $argv = {@_};
1643              
1644 264         964 $self->_setLastSQL($argv->{command});
1645              
1646             ## save command (call-sql_save is prior that new-sql_save
1647 264 50 66     1415 if ((defined($argv->{sql_save}) && $argv->{sql_save}) || (defined($self->{argv}{sql_save}) && $self->{argv}{sql_save} && $argv->{command_type}))
      66        
      33        
      66        
1648             {
1649 1 50       6 return SQL_SIMPLE_RC_ERROR if ($self->Save($argv->{command}));
1650             }
1651              
1652             ## return if makeonly
1653 264 50       2658 return SQL_SIMPLE_RC_ERROR if ($argv->{make_only});
1654              
1655             ## mandatory
1656 0 0       0 if (!defined($self->{init}{dbh}))
1657             {
1658 0         0 $self->_setMessage("call",SQL_SIMPLE_RC_SYNTAX,"022");
1659 0         0 return SQL_SIMPLE_RC_SYNTAX;
1660             }
1661 0 0 0     0 my $flush_buffer = (!defined($argv->{flush}) || $argv->{flush}) ? 1 : 0;
1662 0         0 my $type;
1663              
1664             ## define type of return data
1665 0 0       0 if (!defined($argv->{buffer})) {}
    0          
1666             elsif (ref($argv->{buffer}) eq "HASH")
1667             {
1668 0 0       0 if (!defined($argv->{buffer_hashkey})) { $type=1; }
  0 0       0  
    0          
    0          
1669 0 0       0 elsif (ref($argv->{buffer_hashkey}) eq "ARRAY") { $type = (@{$argv->{buffer_hashkey}} > 1) ? 6 : 5; }
  0         0  
1670 0         0 elsif (ref($argv->{buffer_hashkey}) eq "SCALAR") { $type=5; }
1671 0         0 elsif (ref($argv->{buffer_hashkey}) eq "") { $type=5; }
1672             else
1673             {
1674 0         0 $self->_setMessage("call",SQL_SIMPLE_RC_SYNTAX,"046");
1675 0         0 return SQL_SIMPLE_RC_SYNTAX;
1676             }
1677 0 0       0 if ($flush_buffer)
1678             {
1679 0         0 undef(%{$argv->{buffer}});;
  0         0  
1680 0 0       0 undef(@{$argv->{buffer_hashindex}}) if (defined($argv->{buffer_hashindex}));
  0         0  
1681             }
1682             }
1683             else
1684             {
1685 0 0       0 if (ref($argv->{buffer}) eq "ARRAY")
    0          
    0          
1686             {
1687 0 0 0     0 if (defined($argv->{buffer_arrayref}) && !$argv->{buffer_arrayref})
1688             {
1689 0 0       0 if ($argv->{buffer_fields} != 1)
1690             {
1691 0         0 $self->_setMessage("call",SQL_SIMPLE_RC_SYNTAX,"047");
1692 0         0 return SQL_SIMPLE_RC_SYNTAX;
1693             }
1694 0         0 $type=7;
1695             }
1696 0         0 else { $type=2; }
1697 0 0       0 undef(@{$argv->{buffer}}) if ($flush_buffer);
  0         0  
1698             }
1699 0         0 elsif (ref($argv->{buffer}) eq "CODE") { $type=3; }
1700 0         0 elsif (ref($argv->{buffer}) eq "SCALAR") { $type=4; }
1701             else
1702             {
1703 0         0 $self->_setMessage("call",SQL_SIMPLE_RC_SYNTAX,"024");
1704 0         0 return SQL_SIMPLE_RC_SYNTAX;
1705             }
1706              
1707             ## test buffer_hashkey
1708 0 0       0 if (defined($argv->{buffer_hashkey}))
1709             {
1710 0         0 $self->_setMessage("call",SQL_SIMPLE_RC_SYNTAX,"044");
1711 0         0 return SQL_SIMPLE_RC_SYNTAX;
1712             }
1713             }
1714              
1715             ## run-PreFetch if exists
1716 0 0 0     0 if ($self->{init}{plugin_fh}->can('PreFetch') && $self->{init}{plugin_fh}->PreFetch($argv))
1717             {
1718 0         0 $self->_setMessage("prefetch",SQL_SIMPLE_RC_SYNTAX,"037",$self->{argv}{interface},$self->{argv}{driver},$self->getMessage());
1719 0         0 return SQL_SIMPLE_RC_SYNTAX;
1720             }
1721              
1722             ## prepare command
1723 0         0 $argv->{command} =~ s/^\s+|\s+$//;
1724 0 0       0 my $sth = $self->{init}{dbh}->prepare($argv->{command}.( ($argv->{command} =~ /\;$/) ? "":";") );
1725              
1726             ## enforce cursor_order if not defined
1727 0 0       0 $self->{work}{cursor_order} = 1 if (!defined($self->{work}{cursor_order}));
1728              
1729             ## execute command
1730 0 0       0 if (defined($sth))
1731             {
1732 0         0 $sth->execute(); # send command to run
1733 0         0 $self->_setMessage("call"); # save the current status
1734              
1735             ## scan the fields
1736 0 0       0 if (defined($argv->{buffer}))
1737             {
1738 0 0       0 if ($sth->{NUM_OF_FIELDS})
1739             {
1740 0         0 $self->{init}{cursor}{first} = [];
1741 0         0 my $ref_saved;
1742 0         0 while (my $ref = $sth->fetchrow_hashref())
1743             {
1744             ## get first keys elements
1745 0 0 0     0 if (defined($self->{work}{cursor_key}) && @{$self->{work}{cursor_key}})
  0         0  
1746             {
1747 0 0       0 if (!@{$self->{init}{cursor}{first}})
  0         0  
1748             {
1749 0         0 foreach my $key(@{$self->{work}{cursor_key}})
  0         0  
1750             {
1751 0         0 push(@{$self->{init}{cursor}{first}},$ref->{$key});
  0         0  
1752             }
1753             }
1754             }
1755              
1756             ## move data
1757 0 0       0 if ($type == 1) { %{$argv->{buffer}} = %{$ref}; }
  0 0       0  
  0 0       0  
  0 0       0  
    0          
    0          
    0          
1758 0 0       0 elsif ($type == 2) { ($self->{work}{cursor_order}) ? push(@{$argv->{buffer}},$ref): unshift(@{$argv->{buffer}},$ref); }
  0         0  
  0         0  
1759 0 0       0 elsif ($type == 3) { last if (&{$argv->{buffer}}($ref,$argv->{buffer_options})); }
  0         0  
1760 0         0 elsif ($type == 4) { foreach my $id(keys(%{$ref})) { ${$argv->{buffer}} = $ref->{$id}; }}
  0         0  
  0         0  
  0         0  
1761             elsif ($type == 5)
1762             {
1763             ## save value before remove
1764 0         0 my $val = $ref->{ $self->{work}{buffer_hashkey}[0] };
1765 0 0       0 $self->{work}{cursor_last_saved}{ $self->{work}{buffer_hashkey}[0] } = $val if ($self->{work}{cursor_key_vs_hashkey});
1766            
1767             ## create hashindex if required
1768 0 0       0 (($self->{work}{cursor_order}) ? push(@{$argv->{buffer_hashindex}},$val) : unshift(@{$argv->{buffer_hashindex}},$val)) if (defined($argv->{buffer_hashindex}));
  0 0       0  
  0         0  
1769              
1770             ## remove hashkey from the data buffer
1771 0         0 delete($ref->{ $self->{work}{buffer_hashkey}[0] });
1772              
1773             ## move data to buffer (hashkey + 1 field data)
1774 0 0       0 if ($argv->{buffer_fields} == 2)
1775             {
1776 0         0 my @k = each(%{$ref});
  0         0  
1777 0         0 $argv->{buffer}->{ $val } = $ref->{$k[0]};
1778             }
1779             else
1780             {
1781 0         0 $argv->{buffer}->{ $val } = $ref;
1782             }
1783             }
1784             elsif ($type == 6)
1785             {
1786 0         0 my $addr = $argv->{buffer};
1787 0         0 my @keys;
1788 0         0 foreach my $key(@{$argv->{buffer_hashkey}})
  0         0  
1789             {
1790 0 0       0 if (!defined($ref->{$key}))
1791             {
1792 0         0 $self->_setMessage("call",SQL_SIMPLE_RC_SYNTAX,"045");
1793 0         0 return SQL_SIMPLE_RC_SYNTAX;
1794             }
1795            
1796             ## save value before remove if match with cursor_key
1797 0 0       0 $self->{work}{cursor_last_saved}{$key} = $ref->{$key} if ($self->{work}{cursor_key_vs_hashkey});
1798            
1799             ## create temporary hashindex if required
1800 0 0       0 push(@keys,$ref->{$key}) if (defined($argv->{buffer_hashindex}));
1801              
1802             ## switch index over index
1803 0 0       0 $addr->{$ref->{$key}} = {} if (!defined($addr->{$ref->{$key}}));
1804 0         0 $addr = $addr->{$ref->{$key}};
1805              
1806             ## remove hashkey from the data
1807 0         0 delete($ref->{$key});
1808             }
1809             ## create hashindex if required
1810 0 0       0 (($self->{work}{cursor_order}) ? push(@{$argv->{buffer_hashindex}},\@keys) : unshift(@{$argv->{buffer_hashindex}},\@keys)) if (defined($argv->{buffer_hashindex}));
  0 0       0  
  0         0  
1811              
1812             ## move data to buffer
1813 0 0       0 %{$addr} = (keys(%{$ref}) != 1) ? %{$ref} : $ref->{ each(%{$ref}) };
  0         0  
  0         0  
  0         0  
  0         0  
1814             }
1815             elsif ($type == 7)
1816             {
1817 0         0 my @key = keys(%{$ref});
  0         0  
1818 0 0       0 ($self->{work}{cursor_order}) ? push(@{$argv->{buffer}},$ref->{ $key[0] }) : unshift(@{$argv->{buffer}},$ref->{ $key[0] });
  0         0  
  0         0  
1819             }
1820 0         0 $ref_saved = $ref;
1821             }
1822              
1823             ## get last keys elements
1824 0 0 0     0 if ($ref_saved && defined($self->{work}{cursor_key}) && @{$self->{work}{cursor_key}})
  0   0     0  
1825             {
1826 0         0 $self->{init}{cursor}{last} = [];
1827 0         0 foreach my $key(@{$self->{work}{cursor_key}})
  0         0  
1828             {
1829 0 0       0 push(@{$self->{init}{cursor}{last}},(defined($ref_saved->{$key})) ? $ref_saved->{$key} : $self->{work}{cursor_last_saved}{$key});
  0         0  
1830             }
1831             }
1832             }
1833             }
1834 0         0 $self->{init}{rows} = $sth->rows(); # get number of extracted lines
1835              
1836             ## close and commit (if need)
1837 0         0 $sth->finish();
1838             }
1839             else
1840             {
1841 0         0 $self->_setMessage("call");
1842             }
1843 0         0 undef($sth);
1844              
1845             ## force commit if required
1846 0 0 0     0 $self->_Commit(%{$argv}) if ($self->{argv}->{commit} && $argv->{command_type});
  0         0  
1847 0         0 return $self->getRC();
1848             }
1849              
1850             ################################################################################
1851             ## action: commit command
1852             ## return:
1853             ## rc=0 successful
1854             ## rc>0 sql command error
1855              
1856             sub Commit()
1857             {
1858 0     0 0 0 my $self = shift;
1859 0         0 my $argv = {@_};
1860              
1861 0         0 $self->_resetSession();
1862 0         0 $self->_Dumper("commit",$argv);
1863              
1864 0 0       0 return SQL_SIMPLE_RC_OK if (!defined($self->{init}{dbh}));
1865 0         0 return $self->_Commit(%{$argv});
  0         0  
1866             }
1867              
1868             sub _Commit()
1869             {
1870 0     0   0 my $self = shift;
1871 0         0 my $argv = {@_};
1872              
1873             return $self->_Call(
1874             command => "commit",
1875             command_type => 0, # (ZERO to eliminate the LOOP)
1876             make_only => $argv->{make_only},
1877             flush => $argv->{flush},
1878             sql_save => $argv->{sql_save},
1879 0         0 );
1880             }
1881              
1882             ################################################################################
1883             ## action: disconnect database
1884             ## return:
1885             ## rc=0 successful
1886             ## rc>0 sql command error
1887              
1888             sub Close()
1889             {
1890 2     2 0 5 my $self = shift;
1891              
1892 2 50       13 return SQL_SIMPLE_RC_OK if (!defined($self->{init}{dbh}));
1893              
1894 2         138 my $rc = $self->{init}{dbh}->disconnect();
1895              
1896 2         15 $self->_setMessage("close");
1897              
1898 2         146 undef($self->{init}{dbh});
1899              
1900 2         10 return $self->getRC();
1901             }
1902              
1903             ##############################################################################
1904             ## action: save the current sql command
1905             ## return:
1906             ## rc=0, successful
1907             ## rc=1, system error (mkdir/openfile)
1908              
1909             sub Save()
1910             {
1911 1     1 0 2 my $self = shift;
1912 1         3 my @sqls = @_;
1913              
1914 1         4 $self->_Dumper("save",\@sqls);
1915 1 50       5 $self->{init}{sql_save_ix} = 0 if (!defined($self->{init}{sql_save_ix}));
1916 1 50       5 $self->{init}{sql_save_name} = "sql" if (!defined($self->{init}{sql_save_name}));
1917             $self->{init}{sql_save_dir} =
1918             (defined($self->{argv}{sql_save_dir})) ? $self->{argv}{sql_save_dir} :
1919             ($^O ne 'MSWin32') ? File::Spec->catdir("","var","spool","sql") :
1920 1 0       7 File::Spec->catdir("","windows","temp") if (!defined($self->{init}{sql_save_dir}));
    50          
    50          
1921              
1922 1         1088 require Date::Calc;
1923 1         10438 require File::Path;
1924 1         643 require IO::File;
1925              
1926 1         7860 my $today = sprintf("%04s%02s%02s",Date::Calc::Today());
1927             my $path = ($self->{argv}{sql_save_bydate}) ?
1928             File::Spec->catdir($self->{init}{sql_save_dir},substr($today,0,4),substr($today,0,6),$today) :
1929 1 50       26 $self->{init}{sql_save_dir};
1930              
1931 1 50       85 if (!stat($path))
1932             {
1933 1         3 eval { &File::Path::mkpath($path); };
  1         726  
1934 1 50       7 if ($@)
1935             {
1936 0         0 $self->_setMessage("save",SQL_SIMPLE_RC_ERROR,"025",$@);
1937 0 0       0 return ($self->{argv}{sql_save_ignore}) ? SQL_SIMPLE_RC_OK : SQL_SIMPLE_RC_ERROR;
1938             }
1939             }
1940              
1941 1   50     44 $self->{init}{sql_save_logfile} = File::Spec->catpath("", $path,$self->{init}{sql_save_name}.".".($self->{argv}{db}||"public").".".$today.".".$$.".".(++$self->{init}{sql_save_ix}));
1942 1         9 my $fh = IO::File->new(">".$self->{init}{sql_save_logfile});
1943 1 50       158 if (!defined($fh))
1944             {
1945 0         0 $self->_setMessage("save",SQL_SIMPLE_RC_ERROR,"026",$!);
1946 0 0       0 return ($self->{argv}{sql_save_ignore}) ? SQL_SIMPLE_RC_OK : SQL_SIMPLE_RC_ERROR;
1947             }
1948              
1949 1         7 print $fh join("\n",@sqls),"\n";
1950 1         42 close($fh);
1951 1         9 undef($fh);
1952 1         6 return SQL_SIMPLE_RC_OK;
1953             }
1954              
1955             ################################################################################
1956             ## action: where clause formater, used by: select, insert, delete, update
1957             ## return:
1958             ## rc<0 syntax error
1959             ## rc=0 successful
1960              
1961             sub getWhere()
1962             {
1963              
1964 40     40 1 99420 my $self = shift;
1965 40         186 my $argv = {@_};
1966              
1967 40         138 $self->{work}{tables_inuse} = [];
1968 40 100       152 if (ref($argv->{table}) eq "ARRAY"){ push(@{$self->{work}{tables_inuse}},@{$argv->{table}}); }
  9 50       16  
  9         25  
  9         32  
1969 31         49 elsif (ref($argv->{table}) eq "") { push(@{$self->{work}{tables_inuse}},$argv->{table}); }
  31         100  
1970             else
1971             {
1972 0         0 $self->_setMessage("getWhere",SQL_SIMPLE_RC_SYNTAX,"006");
1973 0         0 return SQL_SIMPLE_RC_SYNTAX;
1974             }
1975 40         123 return $self->_getWhere("where",$argv->{where},$argv->{buffer});
1976             }
1977              
1978             sub _getWhere()
1979             {
1980 282     282   477 my $self = shift;
1981 282         420 my $command = shift;
1982 282         604 my $where = shift;
1983 282         436 my $buffer = shift;
1984              
1985             ## return dummy where
1986 282 100       845 return SQL_SIMPLE_RC_OK if (!$where);
1987              
1988             ## format where
1989 131         215 my @where_local;
1990 131 50       517 return SQL_SIMPLE_RC_SYNTAX if ($self->_getWhereRecursive($command,0,$where,\@where_local));
1991              
1992             ## return the where clause
1993 131         295 ${$buffer} = join(" ",@where_local);
  131         327  
1994 131         565 return SQL_SIMPLE_RC_OK;
1995             }
1996              
1997             sub _getWhereRecursive()
1998             {
1999 155     155   241 my $self = shift;
2000 155         287 my $command = shift;
2001 155         252 my $level = shift;
2002 155         229 my $where = shift;
2003 155         269 my $buffer = shift;
2004              
2005             ## return error if argvs is empty, format error
2006 155 50       554 if ($where eq "")
2007             {
2008 0         0 $self->_setMessage($command,SQL_SIMPLE_RC_SYNTAX,"020");
2009 0         0 return SQL_SIMPLE_RC_SYNTAX;
2010             }
2011 155 50       479 if (ref($where) eq "")
2012             {
2013 0         0 push(@{$buffer},$where);
  0         0  
2014 0         0 return 0;
2015             }
2016             ## return error if value1 is not array or value type
2017 155 50       402 if (ref($where) ne "ARRAY")
2018             {
2019 0         0 $self->_setMessage($command,SQL_SIMPLE_RC_SYNTAX,"021");
2020 0         0 return SQL_SIMPLE_RC_SYNTAX;
2021             }
2022             ## format where
2023 155         238 my @where_tmp;
2024 155         237 my $oper_pend = 0;
2025 155         337 for (my $ix=0; $ix < @{$where};)
  374         1035  
2026             {
2027 220 100 100     790 undef(@where_tmp) if (@where_tmp && join('',@where_tmp) eq '');
2028              
2029             ###############################################################
2030             ## value1
2031              
2032 220         499 my $value1 = $where->[$ix++];
2033              
2034 220 100       576 if (ref($value1) ne "")
2035             {
2036 24         46 my @where_aux;
2037 24 50       227 return SQL_SIMPLE_RC_SYNTAX if ($self->_getWhereRecursive($command,$level+1,$value1,\@where_aux));
2038              
2039             ## valida se requer AND/OR
2040 24 100 66     80 push(@where_tmp,"AND") if ($oper_pend && @where_tmp);
2041             ## salva o where recursivo
2042 24         111 push(@where_tmp,join(" ",@where_aux));
2043 24         46 $oper_pend = 1;
2044 24         56 next;
2045             }
2046              
2047             ## check and/or logical connector
2048 196 100       952 if ($value1 =~ /^(and|\&\&|or|\|\|)$/i)
2049             {
2050 12 100 66     70 push(@where_tmp,uc($value1)) if ($oper_pend && @where_tmp);
2051 12         22 $oper_pend = 0;
2052 12         25 next;
2053             }
2054              
2055             ## valida se requer AND/OR
2056 184 100 66     539 if ($oper_pend && @where_tmp)
2057             {
2058 36         71 push(@where_tmp,"AND");
2059 36         58 $oper_pend = 0;
2060             }
2061              
2062             ## process value if not escape
2063 184 50       539 if (!($value1 =~ /^\\(.*)/))
2064             {
2065             ## validate functions as arguments
2066 184 100 66     663 if ($self->_checkFunctions(\$value1,SQL_SIMPLE_ALIAS_WHERE))
    100 66        
    100          
    100          
2067             {}
2068             ## adjusts for single tables
2069 176         1016 elsif (@{$self->{work}{tables_inuse}} == 1)
2070             {
2071 115         349 $value1 = $self->_getAliasCols(19,$value1,SQL_SIMPLE_ALIAS_WHERE);
2072             }
2073             ## adjusts for multiple tables
2074             elsif ($value1 =~ /^(.*?)\.(.*?)$/ && (grep(/^$1$/,@{$self->{work}{tables_inuse}}) || defined($self->{init}{table_realname}{$1})))
2075             {
2076 46         168 $value1 = $self->_getAliasCols(20,$value1,SQL_SIMPLE_ALIAS_WHERE+SQL_SIMPLE_ALIAS_FQDN);
2077             }
2078             elsif (defined($self->{work}{field_alias}{$value1}))
2079             {
2080 2         10 $value1 = $self->_getAliasCols(28,$self->{work}{field_alias}{$value1},SQL_SIMPLE_ALIAS_WHERE+SQL_SIMPLE_ALIAS_FQDN);
2081             }
2082             ## others adjusts
2083             else
2084             {
2085 13         47 $value1 = $self->_getAliasCols(21,$value1,SQL_SIMPLE_ALIAS_WHERE);
2086             }
2087             }
2088             else
2089             {
2090 0         0 $value1 = $1;
2091             }
2092              
2093             ## finis where if no more values
2094 184 100       364 if ($ix >= @{$where})
  184         517  
2095             {
2096 1         2 push(@where_tmp,$value1);
2097 1         3 last;
2098             }
2099              
2100             ###############################################################
2101             ## value2
2102              
2103             ## test value2, if required
2104 183         447 my $value2 = $where->[$ix++];
2105 183         454 my $quote = $self->{argv}{quote};
2106              
2107 183         332 $oper_pend = 1;
2108              
2109             ## value2 is array, multiple values
2110 183 100       470 if (ref($value2) eq "ARRAY")
2111             {
2112 51         76 my @_value2 = @{$value2};
  51         151  
2113 51         117 my $value2_b = "";
2114 51         108 my $value2_a = "";
2115 51         94 my $operator = $value2->[0];
2116 51         106 my $where_opr = "AND";
2117              
2118             ## value0 is escaped (not operator)
2119 51 100       423 if (!defined($operator)) { $operator = "="; }
  2 100       6  
    100          
    100          
    50          
    50          
    50          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    50          
    100          
    100          
    50          
2120 1         3 elsif ($operator =~ /^\\/) { $operator = "="; }
2121 4         8 elsif ($operator eq "=") { shift(@_value2); }
2122 16         29 elsif ($operator eq "!") { shift(@_value2); $operator = "!="; }
  16         38  
2123 0         0 elsif ($operator eq "!=") { shift(@_value2); $operator = "!="; }
  0         0  
2124 0         0 elsif ($operator eq "<>") { shift(@_value2); $operator = "!="; }
  0         0  
2125 0         0 elsif ($operator eq "<=") { shift(@_value2); }
2126 4         9 elsif ($operator eq "<") { shift(@_value2); }
2127 5         15 elsif ($operator eq ">=") { shift(@_value2); }
2128 4         9 elsif ($operator eq ">") { shift(@_value2); }
2129 1 50       4 elsif ($operator eq "%%") { shift(@_value2); $operator = "LIKE"; $value2_b = "%"; $value2_a = "%"; $where_opr = "OR" if (@_value2 > 1); }
  1         3  
  1         2  
  1         3  
  1         5  
2130 2 100       4 elsif ($operator eq "^%") { shift(@_value2); $operator = "LIKE"; $value2_b = "%"; $where_opr = "OR" if (@_value2 > 1); }
  2         4  
  2         4  
  2         6  
2131 2 100       4 elsif ($operator eq "%^") { shift(@_value2); $operator = "LIKE"; $value2_a = "%"; $where_opr = "OR" if (@_value2 > 1); }
  2         3  
  2         4  
  2         7  
2132 1 50       2 elsif ($operator eq "^^") { shift(@_value2); $operator = "LIKE"; $where_opr = "OR" if (@_value2 > 1); }
  1         2  
  1         3  
2133 0         0 elsif ($operator eq "!%%") { shift(@_value2); $operator = "NOT LIKE"; $value2_b = "%"; $value2_a = "%"; }
  0         0  
  0         0  
  0         0  
2134 2         5 elsif ($operator eq "!^%") { shift(@_value2); $operator = "NOT LIKE"; $value2_b = "%"; }
  2         5  
  2         5  
2135 2         5 elsif ($operator eq "!%^") { shift(@_value2); $operator = "NOT LIKE"; $value2_a = "%"; }
  2         5  
  2         4  
2136 0         0 elsif ($operator eq "!^^") { shift(@_value2); $operator = "NOT LIKE"; }
  0         0  
2137 5         11 else { $operator = "="; }
2138              
2139             ## construct condition
2140 51 100 100     214 if ($operator eq "=" || $operator eq "!=")
2141             {
2142 28 100       84 if (@_value2 > 1)
2143             {
2144 8         23 for (my $i=0; $i < @_value2; $i++)
2145             {
2146 21 50       63 if (!defined($_value2[$i]))
    100          
2147             {
2148 0         0 $_value2[$i] = 'NULL';
2149             }
2150             elsif ($_value2[$i] =~ /^\\(.*)/)
2151             {
2152 2         6 my $v = $1;
2153 2 50 0     10 if ($v =~ /^(\(SELECT\s+.*\))$/)
    0          
    0          
2154             {
2155 2         8 $_value2[$i] = $v;
2156             }
2157 0         0 elsif ($v =~ /^(.*?)\..*?$/ && grep(/^$1$/,@{$self->{work}{tables_valids}}))
2158             {
2159 0         0 $_value2[$i] = $self->_getAliasCols(22,$v,SQL_SIMPLE_ALIAS_WHERE+SQL_SIMPLE_ALIAS_FQDN);
2160             }
2161             elsif (defined($self->{work}{field_alias}{$v}))
2162             {
2163 0         0 $_value2[$i] = $self->_getAliasCols(27,$self->{work}{field_alias}{$v},SQL_SIMPLE_ALIAS_WHERE+SQL_SIMPLE_ALIAS_FQDN);
2164             }
2165             else
2166             {
2167 0         0 $_value2[$i] = $v;
2168             }
2169             }
2170             else
2171             {
2172 19         54 $_value2[$i] = $quote.$self->_escapeQuote($_value2[$i]).$quote;
2173             }
2174             }
2175 8         15 $quote = "";
2176 8 100       60 my $not = ($operator eq "!=") ? " NOT" : "";
2177            
2178             ## no _escapeQuote required, already done in value2 build
2179 8 100 66     58 (@_value2 == 3 && $_value2[1] eq "'..'") ?
2180             push(@where_tmp,$value1.$not." BETWEEN (".$quote.$_value2[0].$quote.",".$quote.$_value2[2].$quote.")"):
2181             push(@where_tmp,$value1.$not." IN (".$quote.join("$quote,$quote",@_value2).$quote.")");
2182 8         30 next;
2183             }
2184             }
2185              
2186             ## multiple conditions
2187 43         80 my @where_aux;
2188 43         94 foreach my $value(@_value2)
2189             {
2190 47 100       108 if (defined($value))
    50          
2191             {
2192 44 100       149 if ($value =~ /^\\(.*)/)
2193             {
2194 9         32 my $v = $1;
2195 9 100 66     59 if ($v =~ /^(\(SELECT\s+.*\))$/)
    50          
    50          
2196             {
2197 2 50       12 if ($operator eq "=") { push(@where_tmp,$value1." IN ".$1); }
  0 50       0  
2198 2         14 elsif ($operator eq "!=") { push(@where_tmp,$value1." NOT IN ".$1); }
2199 0         0 else { push(@where_tmp,$value1." ".$operator." ".$1); }
2200             }
2201 6         30 elsif ($v =~ /^(.*?)\..*?$/ && grep(/^$1$/,@{$self->{work}{tables_valids}}))
2202             {
2203 0         0 push(@where_aux,$value1." ".$operator." ".$self->_getAliasCols(23,$v,SQL_SIMPLE_ALIAS_WHERE+SQL_SIMPLE_ALIAS_FQDN));
2204             }
2205             elsif (defined($self->{work}{field_alias}{$v}))
2206             {
2207 0         0 push(@where_aux,$value1." = ".$self->_getAliasCols(26,$self->{work}{field_alias}{$v},SQL_SIMPLE_ALIAS_WHERE+SQL_SIMPLE_ALIAS_FQDN));
2208             }
2209             else
2210             {
2211 7         64 push(@where_aux,$value1." ".$operator." ".$v);
2212             }
2213             }
2214             else
2215             {
2216 35         138 push(@where_aux,$value1." ".$operator." ".$quote.$self->_escapeQuote($value2_a.$value.$value2_b).$quote);
2217             }
2218             }
2219             elsif ($operator eq "=")
2220             {
2221 0         0 push(@where_aux,$value1." IS NULL");
2222             }
2223             else
2224             {
2225 3         12 push(@where_aux,$value1." NOT NULL");
2226             }
2227             }
2228 43 100       115 if (@where_aux > 1)
2229             {
2230 6         12 $where_aux[0] = "(".$where_aux[0];
2231 6         14 $where_aux[@where_aux-1] .= ")";
2232             }
2233 43 100       171 push(@where_tmp,join(" ".$where_opr." ",@where_aux)) if (@where_aux);
2234 43         146 next;
2235             }
2236              
2237             ## value2 is single value
2238 132 100       330 if (!defined($value2))
2239             {
2240 3         13 push(@where_tmp,$value1." IS NULL");
2241 3         7 next;
2242             }
2243 129 50       335 if (ref($value2) eq "")
2244             {
2245 129 100       418 if ($value2 =~ /^\\(.*)/)
2246             {
2247 29         99 my $v = $1;
2248 29 100 100     258 if ($v =~ /^(\(SELECT\s+(.*)\))$/)
    100          
    100          
2249             {
2250 2         14 push(@where_tmp,$value1." IN ".$1);
2251             }
2252 23         383 elsif ($v =~ /^(.*?)\..*?$/ && grep(/^$1$/,@{$self->{work}{tables_valids}}))
2253             {
2254 15         122 push(@where_tmp,$value1." = ".$self->_getAliasCols(24,$v,SQL_SIMPLE_ALIAS_WHERE+SQL_SIMPLE_ALIAS_FQDN));
2255             }
2256             elsif (defined($self->{work}{field_alias}{$v}))
2257             {
2258 1         6 push(@where_tmp,$value1." = ".$self->_getAliasCols(25,$self->{work}{field_alias}{$v},SQL_SIMPLE_ALIAS_WHERE+SQL_SIMPLE_ALIAS_FQDN));
2259             }
2260             else
2261             {
2262 11         41 push(@where_tmp,$value1." = ".$v);
2263             }
2264             }
2265             else
2266             {
2267 100         334 push(@where_tmp,$value1." = ".$quote.$self->_escapeQuote($value2).$quote);
2268             }
2269 129         386 next;
2270             }
2271              
2272             ## return error if value2 is not array or value type
2273 0         0 $self->_setMessage($command,SQL_SIMPLE_RC_SYNTAX,"028");
2274 0         0 return SQL_SIMPLE_RC_SYNTAX;
2275             }
2276 155 100       342 if (@where_tmp)
2277             {
2278 154         233 push(@{$buffer},join(" ",@where_tmp));
  154         506  
2279 154 100 100     485 if ($level && @where_tmp > 1)
2280             {
2281 14         39 $buffer->[0] = "(".$buffer->[0];
2282 14         30 $buffer->[@{$buffer}-1] .= ")";
  14         67  
2283             }
2284             }
2285 155         580 return 0;
2286             }
2287              
2288             ##############################################################################
2289             ## action: get dbh entry point module
2290             ## return: current dbi drive pointer module
2291              
2292             sub getDBH()
2293             {
2294 0     0 1 0 return $_[0]->{init}{dbh};
2295             }
2296              
2297             ##############################################################################
2298             ## action: get last condition state
2299             ## return: last return code state
2300              
2301             sub getRC()
2302             {
2303 562     562 1 2050 return $err;
2304             }
2305              
2306             ##############################################################################
2307             ## action: get last message state
2308             ## return: last system message
2309              
2310             sub getMessage()
2311             {
2312 17     17 1 106 return $errstr;
2313             }
2314              
2315             ##############################################################################
2316             ## action: get number of extracted lines
2317             ## return: number of extracted lines
2318              
2319             sub getRows()
2320             {
2321 0     0 1 0 return $_[0]->{init}{rows};
2322             }
2323              
2324             ##############################################################################
2325             ## action: get the last sql command
2326             ## return: last sql command
2327              
2328             sub getLastSQL()
2329             {
2330 281     281 1 1130 return $_[0]->{init}{sql_command};
2331             }
2332              
2333             ##############################################################################
2334             ## action: get the last cursor pointer
2335             ## return: cursor pointer
2336              
2337             sub getLastCursor()
2338             {
2339 0     0 1 0 my $self = shift;
2340 0         0 return %{$self->{init}{cursor}};
  0         0  
2341             }
2342              
2343             ##############################################################################
2344             ## action: get the last saved fileset
2345             ## return: last sql logfile
2346              
2347             sub getLastSave()
2348             {
2349 1     1 1 8 return $_[0]->{init}{sql_save_logfile};
2350             }
2351              
2352             ##############################################################################
2353             ## action: get the table's realname
2354             ## return: name of the table
2355              
2356             sub getAliasTable()
2357             {
2358 0     0 1 0 my $self = shift;
2359 0         0 return $self->_getAliasTable(@_,{schema=>defined($self->{init}{schema})});
2360             }
2361              
2362             sub _getAliasTable()
2363             {
2364 304     304   508 my $self = shift;
2365 304         518 my $table = shift;
2366 304         450 my $argv = shift;
2367              
2368 304 100       1024 return $self->_getSchemaName($argv).$table." ".$self->{work}{tables_alias}{$table} if (defined($self->{work}{tables_alias}{$table}));
2369 106         213 return $self->_getSchemaName($argv).$table;
2370             }
2371              
2372             ##############################################################################
2373             ## action: get the schema name if required
2374             ## return: name of the schema
2375              
2376             sub _getSchemaName()
2377             {
2378 304     304   482 my $self = shift;
2379 304         486 my $argv = shift;
2380              
2381 304 50       1557 return "" if (!$argv->{schema});
2382 0 0       0 return "" if (!defined($self->{argv}{schema}));
2383 0         0 return $self->{argv}{schema}.".";
2384             }
2385              
2386             ##############################################################################
2387             ## action: get the table's realname
2388             ## return: name of the table
2389              
2390             sub getAliasCols()
2391             {
2392 0     0 1 0 my $self = shift;
2393 0         0 return $self->_getAliasCols(0,@_);
2394             }
2395              
2396             ##############################################################################
2397             # 0x01 - return col_real wo/table
2398              
2399             sub _getAliasCols()
2400             {
2401 628     628   1144 my $self = shift;
2402 628         905 my $mycall = shift;
2403 628         952 my $field = shift;
2404 628         911 my $result = shift;
2405              
2406 628         1062 my $_table;
2407             my $_field;
2408              
2409             ## enforce prefered aliases if defined
2410 628 100       1837 $field = $self->{work}{field_alias}{$field} if (defined($self->{work}{field_alias}{$field}));
2411              
2412             ## field have ident?
2413 628 100       2470 if ($field =~ /^(.*?)\.(.*?)$/)
2414             {
2415 306         831 $_table = $1;
2416 306         655 $_field = $2;
2417 306 100       830 if (defined($self->{work}{field_cols}))
2418             {
2419 78 100       173 if (defined($self->{work}{field_cols}{$_table}))
2420             {
2421 66 100       171 if (defined($self->{work}{field_cols}{$_table}{$_field}))
2422             {
2423 4         13 $_field = $self->{work}{field_cols}{$_table}{$_field};
2424             }
2425             }
2426             else
2427             {
2428 12 100       43 if (defined($self->{work}{tables_alias}{$_table}))
2429             {
2430 6         12 my $a = $self->{work}{tables_alias}{$_table};
2431 6 50       19 if (defined($self->{work}{field_cols}{$a}))
2432             {
2433 6 100       19 if (defined($self->{work}{field_cols}{$a}{$_field}))
2434             {
2435 2         8 $_field = $self->{work}{field_cols}{$a}{$_field};
2436             }
2437             }
2438             }
2439             }
2440              
2441             }
2442 306 100       481 if (!grep(/^$_table$/,@{$self->{work}{tables_inuse}}))
  306         5753  
2443             {
2444 104 100 66     684 return $field if (!defined($self->{argv}{tables}) || !defined($self->{argv}{tables}{$_table}));
2445 94         266 $_table = $self->{argv}{tables}{$_table}{name};
2446             }
2447 296 100 100     2060 $_field = $self->{argv}{tables}{ $self->{work}{tables_alias}{$_table} }{cols}{$_field} if (defined($self->{argv}{tables}) && defined($self->{work}{tables_alias}{$_table}) && defined($self->{argv}{tables}{ $self->{work}{tables_alias}{$_table} }{cols}{$_field}));
      100        
2448 296 100       504 $result |= SQL_SIMPLE_ALIAS_FQDN if (@{$self->{work}{tables_inuse}} != 1);
  296         980  
2449             }
2450             else
2451             {
2452 322         542 $_field = $field;
2453              
2454             ## single table in use?
2455 322 100       465 if (@{$self->{work}{tables_inuse}} == 1)
  322         735  
2456             {
2457 286         759 $_table = $self->{work}{tables_inuse}[0];
2458 286 100 100     1637 $_field = $self->{argv}{tables}{ $self->{work}{tables_alias}{$_table} }{cols}{$_field} if (defined($self->{work}{tables_alias}{$_table}) && defined($self->{argv}{tables}{ $self->{work}{tables_alias}{$_table} }{cols}{$_field}));
2459             }
2460            
2461             ## scan contents
2462             else
2463             {
2464 36         57 foreach my $t(@{$self->{work}{tables_inuse}})
  36         83  
2465             {
2466             ## ignore table if field not found
2467 72 100 100     319 next if ( defined($self->{work}{tables_alias}{$t}) && !defined($self->{argv}{tables}{ $self->{work}{tables_alias}{$t} }{cols}{$_field}) );
2468              
2469             ## returns field as is if duplicated
2470 56 100       218 return $field if ($_table);
2471              
2472             ## define the table by alias
2473 28         57 $_table = $t;
2474             }
2475             }
2476             }
2477 590 100 100     2450 if ($_table && $result & SQL_SIMPLE_ALIAS_FQDN)
2478             {
2479 232 100       697 $_table = $self->{work}{tables_alias}{$_table} if (defined($self->{work}{tables_alias}{$_table}));
2480 232         980 return $_table.".".$_field;
2481             }
2482 358         1008 return $_field;
2483             }
2484              
2485             ################################################################################
2486             ## action: validate functions and convert the fields named
2487              
2488             sub _checkFunctions()
2489             {
2490 235     235   422 my $self = shift;
2491 235         355 my $value1 = shift;
2492 235         348 my $result = shift;
2493              
2494             ## test if value is function
2495 235         410 my $fnc;
2496 235         368 my $op1 = ${$value1};
  235         477  
2497 235         433 my $op2 = '';
2498 235         326 my $lvl;
2499 235   100     1262 while (($op1 =~ /^(.*?)\((.*)\)(.*)\)$/) || ($op1 =~ /^(.*?)\((.*)\)$/))
2500             {
2501 10         19 $lvl++;
2502 10         31 $fnc .= $1."(";
2503 10 100       34 $op1 = $2.((defined($3)) ? ")" : "");
2504 10 100       53 $op2 .= (defined($3)) ? ")".$3 : ")";
2505             }
2506              
2507             ## process functions if mapped
2508 235 100       586 if ($lvl)
2509             {
2510 8 100       35 if ($op1 =~ /^(.*?)\,(.*)$/)
2511             {
2512 2         4 my $o1 = $1;
2513 2         3 my $o2 = $2;
2514 2 50       5 if ($o1 =~ /^.*?\..*?$/)
2515             {
2516 0         0 $op1 = $self->_getAliasCols(15,$o1,$result+SQL_SIMPLE_ALIAS_FQDN);
2517             }
2518             else
2519             {
2520 2         5 $op1 = $self->_getAliasCols(16,$o1,$result);
2521             }
2522 2         3 $op1 .= ",".$o2;
2523             }
2524             else
2525             {
2526 6 100       32 if ($op1 =~ /^.*?\..*?$/)
2527             {
2528 2         7 $op1 = $self->_getAliasCols(17,$op1,$result+SQL_SIMPLE_ALIAS_FQDN);
2529             }
2530             else
2531             {
2532 4         13 $op1 = $self->_getAliasCols(18,$op1,$result);
2533             }
2534             }
2535 8         13 ${$value1} = $fnc.$op1.$op2;
  8         17  
2536             }
2537 235         668 return $lvl;
2538             }
2539              
2540             ################################################################################
2541             ## action: test the argv->{table} and create the tables_inuse list
2542              
2543             sub _checkTablesEntries()
2544             {
2545 281     281   449 my $self = shift;
2546 281         465 my $cmnd = shift;
2547 281         498 my $argv = shift;
2548              
2549             ## tables is missing?
2550 281 50       726 if (!defined($argv->{table}))
2551             {
2552 0         0 $self->_setMessage($cmnd,SQL_SIMPLE_RC_SYNTAX,"005");
2553 0         0 return SQL_SIMPLE_RC_SYNTAX;
2554             }
2555              
2556             ## validate tables
2557 281         440 my $tables_work;
2558 281 100 66     1283 if (ref($argv->{table}) eq "")
    50 33        
2559             {
2560 195         491 $tables_work = [$argv->{table}];
2561             }
2562             elsif (ref($argv->{table}) eq "ARRAY" && ($self->{work}{command} == SQL_SIMPLE_ALIAS_SELECT || $self->{work}{command} == SQL_SIMPLE_ALIAS_UPDATE))
2563             {
2564 86         202 $tables_work = $argv->{table};
2565             }
2566             else
2567             {
2568 0         0 $self->_setMessage($cmnd,SQL_SIMPLE_RC_SYNTAX,"006");
2569 0         0 return SQL_SIMPLE_RC_SYNTAX;
2570             }
2571              
2572             ## assign table as in use
2573 281         658 $self->{work}{tables_valids} = [];
2574 281         443 foreach my $table(@{$tables_work})
  281         654  
2575             {
2576 367 50       549 if (grep(/^$table$/,@{$self->{work}{tables_inuse}}))
  367         2343  
2577             {
2578 0         0 $self->_setMessage($cmnd,SQL_SIMPLE_RC_SYNTAX,"033",$table);
2579 0         0 return SQL_SIMPLE_RC_SYNTAX;
2580             }
2581 367 100       1132 if (defined($self->{argv}{tables}))
2582             {
2583             ## defined as alias in content tables?
2584 305 100 66     1696 if (defined($self->{argv}{tables}{$table}) && defined($self->{argv}{tables}{$table}{name}))
    100          
2585             {
2586 158         359 my $realname = $self->{argv}{tables}{$table}{name};
2587 158 50       514 if (defined($self->{work}{tables_alias}{$realname}))
2588             {
2589 0         0 $self->_setMessage($cmnd,SQL_SIMPLE_RC_SYNTAX,"033",$table);
2590 0         0 return SQL_SIMPLE_RC_SYNTAX;
2591             }
2592 158         275 push(@{$self->{work}{tables_inuse}},$realname);
  158         449  
2593 158         389 $self->{work}{tables_alias}{$realname} = $table;
2594 158         311 push(@{$self->{work}{tables_valids}},$table);
  158         395  
2595 158         424 next;
2596             }
2597             elsif (defined($self->{init}{table_realname}{$table}))
2598             {
2599 68         214 $self->{work}{tables_alias}{$table} = $self->{init}{table_realname}{$table};
2600 68         122 push(@{$self->{work}{tables_valids}},$self->{init}{table_realname}{$table});
  68         317  
2601             }
2602             }
2603 209         295 push(@{$self->{work}{tables_inuse}},$table);
  209         633  
2604             }
2605 281         535 push(@{$self->{work}{tables_valids}},@{$self->{work}{tables_inuse}});
  281         498  
  281         718  
2606 281         1039 return SQL_SIMPLE_RC_OK;
2607             }
2608              
2609             ################################################################################
2610             ## action: set last command sql
2611             ## return: none
2612              
2613             sub _setLastSQL()
2614             {
2615 547     547   1726 $_[0]->{init}{sql_command} = $_[1];
2616             }
2617              
2618             ################################################################################
2619             ## action: set commit
2620             ## return: old commit
2621              
2622             sub _setCommit()
2623             {
2624 0     0   0 my $self = shift;
2625 0         0 my $save = $self->{argv}{commit};
2626 0   0     0 $self->{argv}{commit} = shift || 0;
2627 0         0 return $save;
2628             }
2629              
2630             ################################################################################
2631             ## action: set message_log
2632             ## return: old message_log
2633              
2634             sub _setLogMessage()
2635             {
2636 0     0   0 my $self = shift;
2637 0         0 my $save = $self->{argv}{message_log};
2638 0   0     0 $self->{argv}{message_log} = shift || 0 ;
2639 0         0 return $save;
2640             }
2641              
2642             ################################################################################
2643             ## action: set sql_save
2644             ## return: old sql_save
2645              
2646             sub _setSqlSave()
2647             {
2648 2     2   5 my $self = shift;
2649 2         7 my $save = $self->{argv}{sql_save};
2650 2   100     10 $self->{argv}{sql_save} = shift || 0;
2651 2         4 return $save;
2652             }
2653              
2654             ################################################################################
2655             ## action: set quote character
2656             ## return: old quote chacracter
2657              
2658             sub _setQuote()
2659             {
2660 0     0   0 my $self = shift;
2661 0         0 my $quote = shift;
2662 0         0 my $save = $self->{argv}{quote};
2663 0 0 0     0 $self->{argv}{quote} = $quote || "'" if ($quote eq "" || $quote eq '"' || $quote eq "'");
      0        
      0        
2664 0         0 return $save;
2665             }
2666              
2667             ################################################################################
2668             ## action: escape quote in string
2669             ## return: string with escape (if exists)
2670              
2671             sub _escapeQuote()
2672             {
2673 234     234   390 my $self = shift;
2674 234         412 my $value = shift;
2675            
2676             ## return if not quote
2677 234 50       717 return $value if ($self->{argv}{quote} eq "");
2678            
2679             ## escape and return
2680 234         1350 $value =~ s/$self->{argv}{quote}/\\$self->{argv}{quote}/g;
2681 234         1013 return $value;
2682             }
2683              
2684             ################################################################################
2685             ## action: cleanup the last session call
2686             ## return: return code
2687              
2688             sub _resetSession()
2689             {
2690 283     283   1983 my $self = shift;
2691 283         531 $err = 0;
2692 283         676 $errstr = "";
2693 283         914 $self->_setLastSQL("");
2694 283         1466 delete ($self->{work});
2695 283         867 $self->{work} = {};
2696             }
2697              
2698             ################################################################################
2699             ## action: set message state
2700             ## return: return code
2701              
2702             sub _setMessage()
2703             {
2704 21     21   50 my $self = shift;
2705 21         40 my $command = shift;
2706 21         38 my $rc = shift;
2707 21         37 my $code = shift;
2708 21         55 my @argv = @_;
2709              
2710 21 100       61 if (!defined($rc))
2711             {
2712 4 50 33     58 return $self->_setMessage($command,$self->{init}{dbh}->err+0,"099",$self->{init}{dbh}->errstr()) if (defined($self->{init}{dbh}) && $self->{init}{dbh}->err);
2713 4 50       39 return $self->_setMessage($command,$DBI::err+0,"099",$DBI::errstr) if ($DBI::err);
2714              
2715 4         12 $err = 0;
2716 4         9 $errstr = "";
2717 4         13 return $err;
2718             }
2719              
2720 17         51 $err = $rc;
2721             $errstr = (defined($SQL_SIMPLE_TABLE_OF_MSGS{$code})) ?
2722 17 50       131 $code.$SQL_SIMPLE_TABLE_OF_MSGS{$code}{T}." ".sprintf($SQL_SIMPLE_TABLE_OF_MSGS{$code}{M},$command,@argv) :
2723             "999S [message] invalid message code '$code'";
2724              
2725 17 50       54 if ($self->{argv}{message_log})
2726             {
2727 0 0       0 print STDERR $errstr."\n" if ($self->{argv}{message_log} & SQL_SIMPLE_LOG_STD);
2728              
2729 0 0       0 if ($self->{argv}{message_log} & SQL_SIMPLE_LOG_SYS)
2730             {
2731 0         0 require Sys::Syslog;
2732 0   0     0 openlog($self->{argv}{message_syslog_service} || "SQL-SimpleOps", "ndelay,pid", $self->{argv}{message_syslog_facility} || "local0");
      0        
2733             syslog(
2734             ($SQL_SIMPLE_TABLE_OF_MSGS{$code}{T} eq "E") ? "error" :
2735             ($SQL_SIMPLE_TABLE_OF_MSGS{$code}{T} eq "S") ? "error" :
2736 0 0       0 ($SQL_SIMPLE_TABLE_OF_MSGS{$code}{T} eq "W") ? "warning" :
    0          
    0          
2737             "info",
2738             $errstr
2739             );
2740 0         0 closelog();
2741             }
2742             }
2743 17         43 return $err;
2744             }
2745              
2746             ################################################################################
2747             ## action: enable/disable show dumper data at each call
2748             ## note: used for debug mode only.
2749              
2750             sub setDumper()
2751             {
2752 275     275 1 717 my $self = shift;
2753 275         727 return $self->{init}{dumper} = shift;
2754             }
2755              
2756             sub _Dumper()
2757             {
2758 282     282   532 my $self = shift;
2759 282         559 my $call = shift;
2760 282         488 my $argv = shift;
2761              
2762 282 50       1024 return if (!$self->{init}{dumper});
2763              
2764 0           require Data::Dumper;
2765 0     0     $Data::Dumper::Sortkeys = \sub { my ($hash) = @_; return [ (sort keys %$hash) ]; };
  0            
  0            
2766              
2767 0           my $dumper = new Data::Dumper([$argv]);
2768              
2769 0           $dumper->Terse(1);
2770              
2771 0           print STDERR $call." = ".$dumper->Dump;
2772             }
2773              
2774             __END__