File Coverage

blib/lib/SQL/SimpleOps.pm
Criterion Covered Total %
statement 591 947 62.4
branch 316 660 47.8
condition 66 185 35.6
subroutine 53 65 81.5
pod 17 28 60.7
total 1043 1885 55.3


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 3     3   237848 use 5.006001;
  3         30  
23 3     3   28 use strict;
  3         6  
  3         63  
24 3     3   15 use warnings;
  3         5  
  3         104  
25 3     3   17 use Exporter;
  3         6  
  3         127  
26              
27 3     3   5431 use DBI;
  3         55228  
  3         197  
28 3     3   24 use File::Spec;
  3         6  
  3         419  
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
55             getDBH getMessage getRC getRows
56             getLastCursor getLastSQL getLastSave getWhere
57             getAliasTable getAliasCols
58              
59             SQL_SIMPLE_CURSOR_BACK
60             SQL_SIMPLE_CURSOR_NEXT
61             SQL_SIMPLE_CURSOR_TOP
62             SQL_SIMPLE_CURSOR_LAST
63             SQL_SIMPLE_CURSOR_RELOAD
64              
65             SQL_SIMPLE_ORDER_OFF
66             SQL_SIMPLE_ORDER_ASC
67             SQL_SIMPLE_ORDER_DESC
68              
69             SQL_SIMPLE_CMD_OFF
70             SQL_SIMPLE_CMD_ON
71             SQL_SIMPLE_CMD_ALL
72              
73             SQL_SIMPLE_LOG_OFF
74             SQL_SIMPLE_LOG_STD
75             SQL_SIMPLE_LOG_SYS
76             SQL_SIMPLE_LOG_ALL
77              
78             SQL_SIMPLE_RC_SYNTAX
79             SQL_SIMPLE_RC_OK
80             SQL_SIMPLE_RC_ERROR
81             SQL_SIMPLE_RC_EMPTY
82              
83             $VERSION
84             $errstr
85             $err
86             );
87              
88             our $VERSION = "2023.199.1";
89              
90             our @EXPORT_OK = @EXPORT;
91              
92             our %EXPORT_TAGS = ( all => [@EXPORT_OK] );
93              
94             ################################################################################
95             ## literals initialization
96              
97 3     3   21 use constant SQL_SIMPLE_DB_PG => 1; # engine postgres
  3         7  
  3         302  
98 3     3   27 use constant SQL_SIMPLE_DB_MARIADB => 2; # engine mariadb/mysql
  3         50  
  3         165  
99 3     3   19 use constant SQL_SIMPLE_DB_SQLLITE3 => 3; # engine sqlite3
  3         9  
  3         160  
100              
101 3     3   38 use constant SQL_SIMPLE_CURSOR_TOP => 1; # page first
  3         6  
  3         134  
102 3     3   17 use constant SQL_SIMPLE_CURSOR_BACK => 2; # page backward
  3         6  
  3         162  
103 3     3   17 use constant SQL_SIMPLE_CURSOR_NEXT => 3; # page next
  3         6  
  3         148  
104 3     3   17 use constant SQL_SIMPLE_CURSOR_LAST => 4; # page last
  3         6  
  3         119  
105 3     3   16 use constant SQL_SIMPLE_CURSOR_RELOAD => 5; # page current
  3         6  
  3         158  
106              
107 3     3   28 use constant SQL_SIMPLE_ORDER_OFF => undef; # order disabled
  3         7  
  3         148  
108 3     3   18 use constant SQL_SIMPLE_ORDER_ASC => 1; # order asceding
  3         5  
  3         180  
109 3     3   18 use constant SQL_SIMPLE_ORDER_DESC => 2; # order descending
  3         6  
  3         157  
110              
111 3     3   18 use constant SQL_SIMPLE_CMD_OFF => 0; # sql_save disabled
  3         6  
  3         136  
112 3     3   17 use constant SQL_SIMPLE_CMD_ON => 1; # sql_save update
  3         4  
  3         153  
113 3     3   19 use constant SQL_SIMPLE_CMD_ALL => 2; # sql_save read/update
  3         5  
  3         153  
114              
115 3     3   20 use constant SQL_SIMPLE_LOG_OFF => 0; # log disabled
  3         10  
  3         130  
116 3     3   17 use constant SQL_SIMPLE_LOG_SYS => 1; # log syslog
  3         14  
  3         207  
117 3     3   23 use constant SQL_SIMPLE_LOG_STD => 2; # log stderr
  3         6  
  3         244  
118 3     3   29 use constant SQL_SIMPLE_LOG_ALL => 3; # log stderr/syslog
  3         24  
  3         188  
119              
120 3     3   20 use constant SQL_SIMPLE_RC_SYNTAX => -1; # syntax error
  3         6  
  3         145  
121 3     3   19 use constant SQL_SIMPLE_RC_OK => 0; # sql successul
  3         6  
  3         172  
122 3     3   19 use constant SQL_SIMPLE_RC_ERROR => 1; # sql error
  3         4  
  3         190  
123 3     3   19 use constant SQL_SIMPLE_RC_EMPTY => 2; # sql successul, empty
  3         5  
  3         36321  
124              
125             ################################################################################
126             ## local environments
127            
128             our $SQL_SIMPLE_CLASS = "SQL::SimpleOps";
129              
130             our %SQL_SIMPLE_TABLE_OF_MSGS =
131             (
132             "001" => { T=>"E", M=>"[%s] Database is missing" },
133             "002" => { T=>"E", M=>"[%s] Server is missing" },
134             "003" => { T=>"E", M=>"[%s] Interface invalid" },
135             "004" => { T=>"S", M=>"[%s] The Database driver is omitted or empty" },
136             "005" => { T=>"E", M=>"[%s] Table is missing" },
137             "006" => { T=>"E", M=>"[%s] Table invalid, must be single-value or array" },
138             "007" => { T=>"E", M=>"[%s] Fields invalid, must be array" },
139             "008" => { T=>"E", M=>"[%s] Group_by invalid, must be single-value or array" },
140             "009" => { T=>"E", M=>"[%s] Order_by invalid, must be single-value or array-pairs" },
141             "010" => { T=>"E", M=>"[%s] Table/Field Index invalid" },
142             "011" => { T=>"E", M=>"[%s} Stat File error, %s" },
143             "012" => { T=>"I", M=>"[%s] Key not found" },
144             "013" => { T=>"E", M=>"[%s] Cursor is missing or invalid" },
145             "014" => { T=>"E", M=>"[%s] Cursor-key is missing or invalid" },
146             "015" => { T=>"E", M=>"[%s] Cursor Command invalid" },
147             "016" => { T=>"W", M=>"[%s] Key is missing, option 'force' is required" },
148             "017" => { T=>"E", M=>"[%s] Fields is missing" },
149             "018" => { T=>"E", M=>"[%s] Fields Format error, must be hash-pairs or arrayref" },
150             "019" => { T=>"E", M=>"[%s] Interface '%s::%s' missing" },
151             "020" => { T=>"E", M=>"[%s] Where Clause invalid" },
152             "021" => { T=>"E", M=>"[%s] Field invalid, must be single-value or array" },
153             "022" => { T=>"E", M=>"[%s] Database is not open" },
154             "023" => { T=>"E", M=>"[%s] SQL Command is missing" },
155             "024" => { T=>"E", M=>"[%s] Buffer Type invalid, must be hashref, arrayref, scalaref or callback_ref" },
156             "025" => { T=>"S", M=>"[%s] Make Folder error, %s" },
157             "026" => { T=>"S", M=>"[%s] Open File error, %s" },
158             "027" => { T=>"S", M=>"[%s] Values is missing" },
159             "028" => { T=>"E", M=>"[%s] Table/Field Value invalid, must be single-value or array" },
160             "029" => { T=>"E", M=>"[%s] TCP Port invalid, must be numeric and between 1-65536" },
161             "030" => { T=>"E", M=>"[%s] Aliass Table is not a hashref" },
162             "031" => { T=>"E", M=>"[%s] Aliases '%s' invalid, table_cols must be hashref" },
163             "032" => { T=>"E", M=>"[%s] Aliases '%s' invalid, table_cols invalid format" },
164             "033" => { T=>"E", M=>"[%s] Table '%s' already, there can be only one" },
165             "034" => { T=>"E", M=>"[%s] Aliases '%s' invalid, table_name is missing" },
166             "035" => { T=>"S", M=>"[%s] Interface '%s::%s' error, %s" },
167             "036" => { T=>"S", M=>"[%s] Interface '%s::%s' load error" },
168             "037" => { T=>"S", M=>"[%s] Interface '%s::%s' aborted, %s" },
169             "038" => { T=>"E", M=>"[%s] Syslog Facility invalid, must be 'local0' to 'local7'" },
170             "038" => { T=>"E", M=>"[%s] Syslog Service invalid, must contains 'alphanumeric' characters" },
171             "040" => { T=>"E", M=>"[%s] Log File invalid, must contains 'alphanumeric' characters" },
172             "041" => { T=>"E", M=>"[%s] Values Format error, must be arrayref" },
173             "042" => { T=>"E", M=>"[%s] Conflict/Duplicate Format error, must be hashref" },
174             "043" => { T=>"E", M=>"[%s] Limit is missing" },
175             "099" => { T=>"S", M=>"[%s] %s" },
176             );
177              
178             our $errstr = ""; # last message
179             our $err = 0; # last return code
180              
181             1;
182              
183             ################################################################################
184             ## action: create object
185             ## return:
186             ## null falure to loaded, system error
187             ## bless is successful loaded
188              
189             sub new()
190             {
191 2   33 2 0 220 my $class = shift; $class = ref($class) || $class || $SQL_SIMPLE_CLASS;
  2         18  
192 2         6 my $self = {};
193              
194 2         15 $self->{argv} = {@_};
195              
196             ## checking for configfile
197 2 50       10 if (defined($self->{argv}{configfile}))
198             {
199 0 0       0 if (!stat($self->{argv}{configfile}))
200             {
201 0         0 &setMessage($self,"new",SQL_SIMPLE_RC_SYNTAX,"011",$self->{argv}{configfile});
202 0         0 return undef;
203             }
204 0         0 my $fh = new IO::File($self->{argv}{configfile});
205 0 0       0 if (!defined($fh))
206             {
207 0         0 &setMessage($self,"new",SQL_SIMPLE_RC_SYNTAX,"026",$!);
208 0         0 return undef;
209             }
210 0         0 require JSON;
211 0         0 my $st; while (!$fh->eof) { $st .= <$fh>; }; undef($fh);
  0         0  
  0         0  
  0         0  
212 0         0 my $pt = new JSON(); $self->{argv} = $pt->decode($st); undef($pt);
  0         0  
  0         0  
213             }
214              
215             ## defaults
216 2 50       10 $self->{argv}{interface} = "dbi" if (!defined($self->{argv}{interface}));
217 2 50       11 $self->{argv}{quote} = "'" if (!defined($self->{argv}{quote}));
218 2 50       8 $self->{argv}{connect} = 1 if (!defined($self->{argv}{connect}));
219 2 50       11 $self->{argv}{message_log} = SQL_SIMPLE_LOG_STD if (!defined($self->{argv}{message_log}));
220 2 50       10 $self->{argv}{port} = "" if (!defined($self->{argv}{port}));
221              
222             ## mandatory itens
223 2 50       37 if (!grep(/^$self->{argv}{interface}$/i,"dbi"))
224             {
225 0         0 &setMessage($self,"new",SQL_SIMPLE_RC_SYNTAX,"003");
226 0         0 return undef;
227             }
228             ## check interface/driver(plugin)
229 2 50       74 if (!defined($self->{argv}{driver}))
    50          
    50          
    50          
230             {
231 0         0 &setMessage($self,"new",SQL_SIMPLE_RC_SYNTAX,"004");
232 0         0 return undef;
233             }
234             elsif (grep(/^$self->{argv}{driver}$/i,"pg","postgres","postsql","pgsql"))
235             {
236 0 0       0 return undef if (!&_newTestServer($self));
237              
238 0         0 $self->{init}{driver_id} = SQL_SIMPLE_DB_PG;
239 0         0 $self->{init}{plugin_id} = "PG";
240 0         0 $self->{init}{schema} = 1;
241             }
242             elsif (grep(/^$self->{argv}{driver}$/i,"mysql","mariadb"))
243             {
244 0 0       0 return undef if (!&_newTestServer($self));
245              
246 0         0 $self->{init}{driver_id} = SQL_SIMPLE_DB_MARIADB;
247 0         0 $self->{init}{plugin_id} = "MySQL";
248 0         0 $self->{init}{schema} = 0;
249             }
250             elsif (grep(/^$self->{argv}{driver}$/i,"sqlite","sqlite3"))
251             {
252 2 50 33     10 if ($self->{argv}{db} eq "" && $self->{argv}{dbfile} eq "")
253             {
254 0         0 &setMessage($self,"new",SQL_SIMPLE_RC_SYNTAX,"001");
255 0         0 return undef;
256             }
257 2         9 $self->{init}{driver_id} = SQL_SIMPLE_DB_SQLLITE3;
258 2         6 $self->{init}{plugin_id} = "SQLite";
259 2         5 $self->{init}{schema} = 0;
260             }
261             else
262             {
263 0         0 &setMessage($self,"new",SQL_SIMPLE_RC_SYNTAX,"004");
264 0         0 return undef;
265             }
266             ## check aliases table
267 2 50       7 if (defined($self->{argv}{tables}))
268             {
269 0 0       0 if (ref($self->{argv}{tables}) ne "HASH")
270             {
271 0         0 &setMessage($self,"new",SQL_SIMPLE_RC_SYNTAX,"030");
272 0         0 return undef;
273             }
274 0         0 foreach my $table(keys(%{$self->{argv}{tables}}))
  0         0  
275             {
276 0 0 0     0 if (!defined($self->{argv}{tables}{$table}{name}) || $self->{argv}{tables}{$table}{name} eq "")
277             {
278 0         0 &setMessage($self,"new",SQL_SIMPLE_RC_SYNTAX,"034",$table);
279 0         0 return undef;
280             }
281 0 0       0 if (defined($self->{argv}{tables}{$table}{cols}))
282             {
283 0 0       0 if (ref($self->{argv}{tables}{$table}{cols}) ne "HASH")
284             {
285 0         0 &setMessage($self,"new",SQL_SIMPLE_RC_SYNTAX,"031",$table);
286 0         0 return undef;
287             }
288 0         0 foreach my $field(keys(%{$self->{argv}{tables}{$table}{cols}}))
  0         0  
289             {
290 0 0       0 if ($self->{argv}{tables}{$table}{cols}{$field} eq "")
291             {
292 0         0 &setMessage($self,"new",SQL_SIMPLE_RC_SYNTAX,"032",$field);
293 0         0 return undef;
294             }
295             }
296             }
297             }
298             }
299             ## check syslog options
300 2 50 33     11 if (defined($self->{argv}{message_syslog_facility}) && !($self->{argv}{message_syslog_facility} =~ /^local[0-7]$/i))
301             {
302 0         0 &setMessage($self,"new",SQL_SIMPLE_RC_SYNTAX,"038",$self->{argv}{message_syslog_facility});
303 0         0 return undef;
304             }
305 2 50 33     19 if (defined($self->{argv}{message_syslog_service}) && ($self->{argv}{message_syslog_service} =~ s/[a-zA-Z0-9\-\_]//g))
306             {
307 0         0 &setMessage($self,"new",SQL_SIMPLE_RC_SYNTAX,"039",$self->{argv}{message_syslog_service});
308 0         0 return undef;
309             }
310 2 50 33     10 if (defined($self->{argv}{sql_save_name}) && ($self->{argv}{sql_save_name} =~ s/[a-zA-Z0-9\-\_]//g))
311             {
312 0         0 &setMessage($self,"new",SQL_SIMPLE_RC_SYNTAX,"040",$self->{argv}{sql_save_name});
313 0         0 return undef;
314             }
315             ## load interface type
316 2 50       11 if ($self->{argv}{interface} =~ /^dbi$/i)
317             {
318 2         7 $self->{argv}{interface} = "DBI";
319 2 50       11 $self->{argv}{interface_options}{RaiseError} = 0 if (!defined($self->{argv}{interface_options}{RaiseError}));
320 2 50       11 $self->{argv}{interface_options}{PrintError} = 0 if (!defined($self->{argv}{interface_options}{PrintError}));
321             }
322 0         0 else { return undef; }
323              
324             ## load pluging
325             ## making: dsname option and more
326 2 50 33     21 if (defined($self->{init}{plugin_id}) && $self->{init}{plugin_id} ne "")
327             {
328 2         5 my $fn;
329              
330 2         12 my $plugin = $SQL_SIMPLE_CLASS."::".$self->{argv}{interface}."::".$self->{init}{plugin_id};
331 2         7 foreach my $dir(@INC)
332             {
333 4         56 $fn = File::Spec->catdir($dir,split(/::/,$plugin)).".pm";
334 4 100       87 last if (stat($fn));
335 2         19 $fn = "";
336             }
337 2 50       13 if ($fn eq "")
338             {
339 0         0 &setMessage($self,"new",SQL_SIMPLE_RC_SYNTAX,"019",$self->{argv}{interface},$self->{init}{plugin_id});
340 0         0 return undef;
341             }
342 2         6 eval { require $fn; };
  2         1019  
343 2 50       10 if ($@)
344             {
345 0         0 &setMessage($self,"new",SQL_SIMPLE_RC_SYNTAX,"035",$self->{argv}{interface},$self->{init}{plugin_id},$@);
346 0         0 return undef;
347             }
348 2         15 $self->{init}{plugin_fh} = $plugin->new(sql_simple => $self);
349 2 50       9 if (!defined($self->{init}{plugin_fh}))
350             {
351 0         0 &setMessage($self,"new",SQL_SIMPLE_RC_SYNTAX,"035",$self->{argv}{interface},$self->{init}{plugin_id},$@);
352 0         0 return undef;
353             }
354             }
355             ## new object
356 2         9 my $bless = bless($self,$class);
357 2 50       6 return undef if (!defined($bless));
358              
359             ## my first connect
360 2 50 33     22 return undef if ($self->{argv}{connect} && $self->Open());
361              
362             ## successful
363 2         7 $bless;
364             }
365              
366             ################################################################################
367             ## action: test server/tcpport for remote databases
368             ## rc=0 syntax error
369             ## rc=1 successful
370             #
371             sub _newTestServer()
372             {
373 0     0   0 my $self = shift;
374 0 0       0 if ($self->{argv}{server} eq "")
375             {
376 0         0 &setMessage($self,"new",SQL_SIMPLE_RC_SYNTAX,"002");
377 0         0 return undef;
378             }
379 0 0 0     0 if ($self->{argv}{port} ne "" && (($self->{argv}{port} =~ /^\D+$/) || ($self->{argv}{port} < 1 || $self->{argv}{port} > 65535)))
      0        
380             {
381 0         0 &setMessage($self,"new",SQL_SIMPLE_RC_SYNTAX,"029");
382 0         0 return undef;
383             }
384 0         0 return 1;
385             }
386              
387             ################################################################################
388             ## action: open database
389             ## return:
390             ## rc<0 syntax error
391             ## rc=0 successful
392             ## rc>0 sql return code
393              
394             sub Open()
395             {
396 1     1 1 3 my $self = shift;
397              
398 1 50 33     24 if ($self->{init}{plugin_fh}->can('Open') && $self->{init}{plugin_fh}->Open())
399             {
400 0         0 $self->setMessage("open",SQL_SIMPLE_RC_SYNTAX,"037",$self->{argv}{interface},$self->{argv}{driver},$self->getMessage());
401 0         0 return SQL_SIMPLE_RC_SYNTAX;
402             }
403 1 50       7 if ($self->{argv}{interface} =~ /^dbi$/i)
404             {
405             $self->{init}{dbh} = DBI->connect(
406 1         5 $self->{argv}{dsname}, $self->{argv}{login}, $self->{argv}{password}, \%{$self->{argv}{interface_options}});
  1         9  
407 1         13676 $self->setMessage("open");
408 1         10 return $self->getRC();
409             }
410 0         0 return SQL_SIMPLE_RC_SYNTAX;
411             }
412              
413             ################################################################################
414             ## action: select as fetch command, buffers of lines based cursor
415             ## return:
416             ## rc<0 syntax error
417             ## rc=0 successful
418             ## rc=1 sql error
419             ## rc=2 successful, no lines selected (no match or empty)
420              
421             sub SelectCursor()
422             {
423 8     8 1 15961 my $self = shift;
424 8         36 my $argv = {@_};
425              
426 8         24 $self->setLastSQL("");
427 8 50       23 $self->Open() if (!defined($self->{init}{dbh}));
428              
429             ## define the command in load
430 8         20 $self->{init}{command} = "select";
431              
432 8 50 33     36 if ($self->{init}{plugin_fh}->can('SelectCursor') && $self->{init}{plugin_fh}->SelectCursor($argv))
433             {
434 0         0 $self->setMessage("select",SQL_SIMPLE_RC_SYNTAX,"037",$self->{argv}{interface},$self->{argv}{driver},$self->getMessage());
435 0         0 return SQL_SIMPLE_RC_SYNTAX;
436             }
437              
438 8 50       32 my $saved_message_log = $self->setLogMessage($argv->{message_log}) if (defined($argv->{message_log}));
439 8 50       18 my $saved_quote = $self->setQuote($argv->{quote}) if (defined($argv->{quote}));
440 8 50       16 my $saved_sql_save = $self->setSqlSave($argv->{sql_save}) if (defined($argv->{sql_save}));
441              
442 8         12 my $rc = $self->_SelectCursor(%{$argv});
  8         34  
443              
444 8 50       25 $self->setMessgeLog($saved_message_log) if (defined($argv->{message_log}));
445 8 50       18 $self->setQuote($saved_quote) if (defined($argv->{quote}));
446 8 50       15 $self->setSqlSave($saved_sql_save) if (defined($argv->{sql_save}));
447              
448 8         24 return $rc;
449             }
450              
451             sub _SelectCursor()
452             {
453 8     8   13 my $self = shift;
454 8         23 my $argv = {@_};
455              
456             ## check mandatory options
457 8 100 100     35 if ($argv->{cursor_command} != SQL_SIMPLE_CURSOR_TOP && $argv->{cursor_command} != SQL_SIMPLE_CURSOR_LAST)
458             {
459 5 50 33     15 if (!defined($argv->{cursor}) || $argv->{cursor} eq "")
460             {
461 5 50       12 if (!defined($argv->{cursor_info}))
462             {
463 0         0 $self->setMessage("select",SQL_SIMPLE_RC_SYNTAX,"013");
464 0         0 return SQL_SIMPLE_RC_SYNTAX;
465             }
466 5         10 my ($first,$last);
467 5 50       13 if (ref($argv->{cursor_info}) eq "HASH") { ($first,$last) = ($argv->{cursor_info}{first},$argv->{cursor_info}{last}); }
  5 0       16  
    0          
468 0         0 elsif (ref($argv->{cursor_info}) eq "ARRAY") { ($first,$last) = ($argv->{cursor_info}[2],$argv->{cursor_info}[3]); }
469 0         0 elsif (ref($argv->{cursor_info}) eq "SCALAR") { my @a=split(" ",$argv->{cursor_info}); ($first,$last) = ($a[2],$a[3]); }
  0         0  
470             else
471             {
472 0         0 $self->setMessage("select",SQL_SIMPLE_RC_SYNTAX,"013");
473 0         0 return SQL_SIMPLE_RC_SYNTAX;
474             }
475 5 100       16 if ($argv->{cursor_command} == SQL_SIMPLE_CURSOR_NEXT) { $argv->{cursor} = $last; $argv->{cursor_command} = SQL_SIMPLE_CURSOR_TOP if (!defined($last));}
  2 100       6  
  2 100       17  
    50          
476 2 100       8 elsif ($argv->{cursor_command} == SQL_SIMPLE_CURSOR_BACK) { $argv->{cursor} = $first; $argv->{cursor_command} = SQL_SIMPLE_CURSOR_LAST if (!defined($first));}
  2         8  
477 1         4 elsif ($argv->{cursor_command} == SQL_SIMPLE_CURSOR_RELOAD) { $argv->{cursor} = $first; }
478             }
479             }
480 8 50 33     46 if (!defined($argv->{cursor_key}) || ref($argv->{cursor_key}) ne "")
481             {
482 0         0 $self->setMessage("select",SQL_SIMPLE_RC_SYNTAX,"014");
483 0         0 return SQL_SIMPLE_RC_SYNTAX;
484             }
485 8 50 33     21 if (defined($argv->{where}) && ref($argv->{where}) ne "ARRAY")
486             {
487 0         0 $self->setMessage("select",SQL_SIMPLE_RC_SYNTAX,"021");
488 0         0 return SQL_SIMPLE_RC_SYNTAX;
489             }
490              
491             ## have order by?
492 8         12 my @order;
493 8 50       28 if (!defined($argv->{order_by})) {}
    0          
    0          
494 0         0 elsif (ref($argv->{order_by}) eq "") { @order = ($argv->{order_by}); }
495 0         0 elsif (ref($argv->{order_by}) eq "ARRAY") { @order = @{$argv->{order_by}}; }
  0         0  
496             else
497             {
498 0         0 $self->setMessage("select",SQL_SIMPLE_RC_SYNTAX,"009");
499 0         0 return SQL_SIMPLE_RC_SYNTAX;
500             }
501             ## test the type of cursor
502 8 100 100     41 if ($argv->{cursor_command} == SQL_SIMPLE_CURSOR_TOP)
    100          
    100          
    50          
503             {
504 3         8 unshift(@order,$argv->{cursor_key} => SQL_SIMPLE_ORDER_ASC);
505             }
506             elsif ($argv->{cursor_command} == SQL_SIMPLE_CURSOR_BACK)
507             {
508 1         4 unshift(@order,$argv->{cursor_key} => SQL_SIMPLE_ORDER_DESC);
509              
510 1         2 unshift(@{$argv->{where}}, $argv->{cursor_key} => [ "<", $argv->{cursor} ]);
  1         6  
511             }
512             elsif ($argv->{cursor_command} == SQL_SIMPLE_CURSOR_NEXT || $argv->{cursor_command} == SQL_SIMPLE_CURSOR_RELOAD)
513             {
514 2         6 unshift(@order,$argv->{cursor_key} => SQL_SIMPLE_ORDER_ASC);
515              
516 2         3 unshift(@{$argv->{where}}, $argv->{cursor_key} => [ ">", $argv->{cursor} ]);
  2         9  
517             }
518             elsif ($argv->{cursor_command} == SQL_SIMPLE_CURSOR_LAST)
519             {
520 2         7 unshift(@order,$argv->{cursor_key} => SQL_SIMPLE_ORDER_DESC);
521             }
522             else
523             {
524 0         0 $self->setMessage("select",SQL_SIMPLE_RC_SYNTAX,"015");
525 0         0 return SQL_SIMPLE_RC_SYNTAX;
526             }
527 8 50 33     34 if (!defined($argv->{limit}) || $argv->{limit} eq "")
528             {
529 0         0 $self->setMessage("select",SQL_SIMPLE_RC_SYNTAX,"043");
530 0         0 return SQL_SIMPLE_RC_SYNTAX;
531             }
532             ## format o order options
533 8 50       17 unshift(@{$argv->{order_by}},@order) if (@order);
  8         32  
534              
535             ## define notfound if not exists
536 8 50       25 $argv->{notfound} = 1 if (!defined($argv->{notfound}));
537              
538             ## execute and save cursor info
539 8 50       10 return $self->{init}{cursor}{rc} if ($self->{init}{cursor}{rc} = $self->_Select(%{$argv}));
  8         31  
540              
541 0         0 $self->{init}{cursor}{lines} = $self->getRows();
542              
543             ($self->{init}{cursor}{first},$self->{init}{cursor}{last}) =
544             ($self->{init}{cursor}{lines}) ?
545 0 0       0 ( $argv->{buffer}[0]{$argv->{cursor_key}}, $argv->{buffer}[$self->{init}{cursor}{lines}-1]{$argv->{cursor_key}} ):
546             ( 0, 0 );
547              
548             ## return cursor info
549 0 0       0 if (!defined($argv->{cursor_info})) {}
    0          
    0          
    0          
550             elsif (ref($argv->{cursor_info}) eq "HASH")
551             {
552 0         0 $argv->{cursor_info}->{rc} = $self->{init}{cursor}{rc};
553 0         0 $argv->{cursor_info}->{lines} = $self->{init}{cursor}{lines};
554             ($argv->{cursor_info}->{first},$argv->{cursor_info}->{last}) = ($argv->{cursor_command} == SQL_SIMPLE_CURSOR_BACK) ?
555             ($self->{init}{cursor}{last},$self->{init}{cursor}{first}) :
556 0 0       0 ($self->{init}{cursor}{first},$self->{init}{cursor}{last});
557             }
558             elsif (ref($argv->{cursor_info}) eq "ARRAY")
559             {
560 0         0 $argv->{cursor_info}->[0] = $self->{init}{cursor}{rc};
561 0         0 $argv->{cursor_info}->[1] = $self->{init}{cursor}{lines};
562             ($argv->{cursor_info}->[2],$argv->{cursor_info}->[3]) = ($argv->{cursor_command} == SQL_SIMPLE_CURSOR_BACK) ?
563             ($self->{init}{cursor}{last},$self->{init}{cursor}{first}) :
564 0 0       0 ($self->{init}{cursor}{first},$self->{init}{cursor}{last});
565             }
566             elsif (ref($argv->{cursor_info}) eq "SCALAR")
567             {
568 0         0 my @a = split(" ",${$argv->{cursor_info}});
  0         0  
569 0         0 $argv->{cursor_info} = $self->{init}{cursor}{rc}." ".$self->{init}{cursor}{lines}." ".$a[2]." ".$a[3];
570             }
571 0         0 return SQL_SIMPLE_RC_OK;
572             }
573              
574             ################################################################################
575             ## action: select command
576             ## return:
577             ## rc<0 syntax error
578             ## rc=0 successful
579             ## rc=1 sql error
580             ## rc=2 no selected found (no match where found)
581              
582             sub Select()
583             {
584 18     18 1 32172 my $self = shift;
585 18         65 my $argv = {@_};
586              
587 18         55 $self->setLastSQL("");
588 18 50       51 $self->Open() if (!defined($self->{init}{dbh}));
589              
590             ## define the command in load
591 18         34 $self->{init}{command} = "select";
592              
593 18 50 33     84 if ($self->{init}{plugin_fh}->can('Select') && $self->{init}{plugin_fh}->Select($argv))
594             {
595 0         0 $self->setMessage("select",SQL_SIMPLE_RC_SYNTAX,"037",$self->{argv}{interface},$self->{argv}{driver},$self->getMessage());
596 0         0 return SQL_SIMPLE_RC_SYNTAX;
597             }
598              
599 18 50       39 my $saved_message_log = $self->setLogMessage($argv->{message_log}) if (defined($argv->{message_log}));
600 18 50       37 my $saved_quote = $self->setQuote($argv->{quote}) if (defined($argv->{quote}));
601 18 100       40 my $saved_sql_save = $self->setSqlSave($argv->{sql_save}) if (defined($argv->{sql_save}));
602              
603 18         30 my $rc = $self->_Select(%{$argv});
  18         63  
604              
605 18 50       72 $self->setMessgeLog($saved_message_log) if (defined($argv->{message_log}));
606 18 50       39 $self->setQuote($saved_quote) if (defined($argv->{quote}));
607 18 100       40 $self->setSqlSave($saved_sql_save) if (defined($argv->{sql_save}));
608              
609 18         53 return $rc;
610             }
611              
612             sub _Select()
613             {
614 26     26   50 my $self = shift;
615 26         80 my $argv = {@_};
616              
617             ## check mandatory options
618 26 50       67 if (!defined($argv->{table}))
619             {
620 0         0 $self->setMessage("select",SQL_SIMPLE_RC_SYNTAX,"005");
621 0         0 return SQL_SIMPLE_RC_SYNTAX;
622             }
623 26         34 my @tables_work;
624 26 100       70 if (ref($argv->{table}) eq "") { @tables_work = ($argv->{table}); }
  23 50       48  
625             elsif (ref($argv->{table}) eq "ARRAY")
626             {
627 3         6 my %tables_tmp;
628 3         8 foreach my $table(@{$argv->{table}})
  3         10  
629             {
630 6 50       15 if ($tables_tmp{$table})
631             {
632 0         0 $self->setMessage("select",SQL_SIMPLE_RC_SYNTAX,"033",$table);
633 0         0 return SQL_SIMPLE_RC_SYNTAX;
634             }
635 6         12 $tables_tmp{$table}=1;
636             }
637 3         7 @tables_work = @{$argv->{table}};
  3         11  
638             }
639             else
640             {
641 0         0 $self->setMessage("select",SQL_SIMPLE_RC_SYNTAX,"006");
642 0         0 return SQL_SIMPLE_RC_SYNTAX;
643             }
644 26         59 my @fields_work;
645             my %fields_distinct;
646 26         0 my %fields_aliases;
647 26 50       47 if (defined($argv->{fields}))
648             {
649 26 50       62 if (ref($argv->{fields}) ne "ARRAY")
650             {
651 0         0 $self->setMessage("select",SQL_SIMPLE_RC_SYNTAX,"007");
652 0         0 return SQL_SIMPLE_RC_SYNTAX;
653             }
654 26         50 for (my $ix=0; $ix < @{$argv->{fields}}; $ix++)
  81         167  
655             {
656 55         121 my $field = $argv->{fields}[$ix];
657 55         85 my $distinct;
658             my $alias;
659 55 100       95 if (ref($field) eq "HASH")
660             {
661 7         8 $alias = $field;
662 7         10 ($fields_aliases{$alias}{f},$fields_aliases{$alias}{a}) = each(%{$field});
  7         33  
663 7         20 $field = $fields_aliases{$alias}{f};
664             }
665 55 100       142 if ($field =~ /^distinct$/i)
    50          
666             {
667 3         10 $field = $argv->{fields}[++$ix];
668 3         5 $distinct = 1;
669             }
670             elsif ($field =~ /^distinct\s+(.*)/i)
671             {
672 0         0 $field = $1;
673 0         0 $distinct = 1;
674             }
675 55 100       117 if (!($field =~ /^\\/))
676             {
677 52 100       154 my $value = ($field =~ /^(.*?)\((.*?)\,(.*)\)/) ? $2 : ($field =~ /^(.*?)\((.*)\)/) ? $2 : $field;
    100          
678 52 100       146 if ($value =~ /^(.*)\.(.*)$/)
679             {
680 9         23 my $table = $1;
681 9 50       143 if (!grep(/^$table$/i,@tables_work))
682             {
683 0         0 $self->setMessage("select",SQL_SIMPLE_RC_SYNTAX,"010");
684 0         0 return SQL_SIMPLE_RC_SYNTAX;
685             }
686             }
687             }
688 55   66     153 push(@fields_work,$alias || $field);
689 55 100       118 $fields_distinct{$field} = 1 if ($distinct);
690             }
691             }
692             else
693             {
694 0 0       0 if (@tables_work > 1)
695             {
696 0         0 foreach my $table(@tables_work)
697             {
698 0 0 0     0 if (!defined($self->{argv}{tables}{$table}) || !defined($self->{argv}{tables}{$table}{cols}))
699             {
700 0         0 $self->setMessage("select",SQL_SIMPLE_RC_SYNTAX,"010");
701 0         0 return SQL_SIMPLE_RC_SYNTAX;
702             }
703 0         0 foreach my $field(sort(keys(%{$self->{argv}{tables}{$table}{cols}})))
  0         0  
704             {
705 0         0 push(@fields_work,$table.".".$field);
706             }
707             }
708             }
709             else
710             {
711 0 0 0     0 if (defined($self->{argv}{tables}{$tables_work[0]}) && defined($self->{argv}{tables}{$tables_work[0]}{cols}))
712             {
713 0         0 push(@fields_work,sort(keys(%{$self->{argv}{tables}{$tables_work[0]}{cols}})));
  0         0  
714             }
715             }
716             }
717 26         36 my @group_work;
718 26 50       65 if (defined($argv->{group_by}))
719             {
720 0 0       0 if (ref($argv->{group_by}) eq "") { @group_work = ($argv->{group_by}); }
  0 0       0  
721 0         0 elsif (ref($argv->{group_by}) eq "ARRAY") { push(@group_work,@{$argv->{group_by}}); }
  0         0  
722             else
723             {
724 0         0 $self->setMessage("select",SQL_SIMPLE_RC_SYNTAX,"008");
725 0         0 return SQL_SIMPLE_RC_SYNTAX;
726             }
727             }
728 26         32 my @order_work;
729 26 100       53 if (defined($argv->{order_by}))
730             {
731 8 50       32 if (ref($argv->{order_by}) eq "") { @order_work = ($argv->{order_by}); }
  0 50       0  
732             elsif (ref($argv->{order_by}) eq "ARRAY")
733             {
734 8 50       11 if (@{$argv->{order_by}} == 1) { @order_work = @{$argv->{order_by}}; }
  8         22  
  0         0  
  0         0  
735 8 50       11 if (@{$argv->{order_by}} % 2 != 0)
  8         20  
736             {
737 0         0 $self->setMessage("select",SQL_SIMPLE_RC_SYNTAX,"009");
738 0         0 return SQL_SIMPLE_RC_SYNTAX;
739             }
740 8         12 push(@order_work,@{$argv->{order_by}});
  8         17  
741             }
742             else
743             {
744 0         0 $self->setMessage("select",SQL_SIMPLE_RC_SYNTAX,"009");
745 0         0 return SQL_SIMPLE_RC_SYNTAX;
746             }
747             }
748             ## making fields
749 26 50       61 my $middle = ($self->{init}{driver_id} == SQL_SIMPLE_DB_PG) ? " AS " : " ";
750 26         36 my @fields;
751 26         40 my $table = $tables_work[0];
752 26 50       47 if (@fields_work)
753             {
754 26         45 foreach my $field(@fields_work)
755             {
756 55         79 my $alias;
757 55 100       100 my $distinct = ($fields_distinct{$field}) ? "DISTINCT " : "";
758             ## field is hash?
759 55 100       150 if (defined($fields_aliases{$field}))
760             {
761 7         12 $alias = $fields_aliases{$field}{a};
762 7         14 $field = $fields_aliases{$field}{f};
763             }
764             ## is escape?
765 55 100       159 if ($field =~ /^\\(.*)/)
766             {
767 3 100       14 ($alias) ?
768             push(@fields,$distinct.$1." ".$alias) :
769             push(@fields,$distinct.$1);
770 3         7 next;
771             }
772             ## have function?
773 52         74 my $field_a;
774             my $field_b;
775 52 100       150 if ($field =~ /^(.*?)\((.*?)\,(.*)\)/)
    100          
776             {
777 1         4 $field_a = $1."(";
778 1         3 $field = $2;
779 1         4 $field_b = ",".$3.")";
780             }
781             elsif ($field =~ /^(.*?)\((.*)\)/)
782             {
783 5         12 $field_a = $1."(";
784 5         11 $field = $2;
785 5         9 $field_b = ")";
786             }
787             else
788             {
789 46         77 $field_a = "";
790 46         59 $field_b = "";
791             }
792             ## translate field
793 52 100       109 if ($field =~ /^(.*)\.(.*)$/)
794             {
795 9         17 my $table = $1;
796 9         15 my $field = $2;
797 9         22 my $realn = $self->getAliasCols($table,$field);
798 9 50       55 ($alias) ?
    100          
799             push(@fields,$distinct.$field_a.$table.".".$realn.$field_b." ".$alias) :
800             ($field ne $realn) ?
801             push(@fields,$distinct.$field_a.$table.".".$realn.$field_b." ".$table."_".$field) :
802             push(@fields,$distinct.$field_a.$table.".".$realn.$field_b);
803             }
804             else
805             {
806 43 50       73 if (@tables_work == 1)
807             {
808 43         80 my $realn = $self->getAliasCols($table,$field);
809 43 50       162 ($alias) ?
    100          
810             push(@fields,$distinct.$field_a.$realn.$field_b." ".$alias) :
811             ($field ne $realn) ?
812             push(@fields,$distinct.$field_a.$realn.$field_b." ".$field) :
813             push(@fields,$distinct.$field_a.$field.$field_b);
814             }
815             else
816             {
817 0 0       0 ($alias) ?
818             push(@fields,$distinct.$field." ".$alias):
819             push(@fields,$distinct.$field);
820             }
821             }
822             }
823             }
824             else
825             {
826 0         0 push(@fields,"*");
827             }
828             ## make where
829 26         37 my $where;
830 26 50       82 return SQL_SIMPLE_RC_SYNTAX if ($self->_getWhere("select",\@tables_work,$argv->{where},\$where));
831              
832             ## make order
833 26         50 my @order;
834 26         53 while (@order_work)
835             {
836 8         15 my $field = shift(@order_work);
837 8 50       21 if ($field =~ /^(.*?)\.(.*?)$/)
838             {
839 0         0 my $table = $1;
840 0         0 my $field = $2;
841 0         0 $field = $table.".".$self->getAliasCols($table,$field);
842             }
843             else
844             {
845 8         19 $field = $self->getAliasCols($table,$field);
846             }
847 8 50       19 if (@order_work)
848             {
849 8         16 my $ordem = shift(@order_work);
850 8 50       38 $field .= " ".(($ordem == SQL_SIMPLE_ORDER_DESC) ? 'DESC' : ($ordem == SQL_SIMPLE_ORDER_ASC) ? 'ASC' : $ordem);
    100          
851             }
852 8         22 push(@order,$field);
853             }
854             ## make tables
855 26         33 my @tables;
856 26         48 foreach my $table(@tables_work)
857             {
858 29         57 push(@tables,$self->getAliasTable($table,1));
859             }
860              
861             ## build sql command
862 26         87 my $sql = "SELECT ".join(", ",@fields)." FROM ".join(", ",@tables);
863 26 100       58 $sql .= " WHERE ".$where if ($where);
864 26 50       54 $sql .= " GROUP BY ".join(", ",@group_work) if (@group_work);
865 26 100       57 $sql .= " ORDER BY ".join(", ",@order) if (@order);
866 26 100 100     77 $sql .= " LIMIT ".$argv->{limit} if (defined($argv->{limit}) && $argv->{limit} > 0);
867              
868             ## execute
869             return SQL_SIMPLE_RC_ERROR if ($self->_Call(
870             command => $sql,
871             command_type => 0, # (ZERO is read)
872             buffer => $argv->{buffer},
873             buffer_options => $argv->{buffer_options},
874             make_only => $argv->{make_only},
875             flush => $argv->{flush},
876             sql_save => $argv->{sql_save},
877 26 50       155 ));
878 0 0       0 return SQL_SIMPLE_RC_OK if ($self->getRows());
879 0 0       0 return SQL_SIMPLE_RC_OK if ($argv->{notfound});
880              
881 0         0 $self->setMessage("select",SQL_SIMPLE_RC_SYNTAX,"012");
882 0         0 return SQL_SIMPLE_RC_EMPTY;
883             }
884              
885             ################################################################################
886             ## action: delete
887             ## return:
888             ## rc<0 syntax error
889             ## rc=0 successful
890             ## rc=1 sql error
891             ## rc=2 no selected found (no match where found)
892              
893             sub Delete()
894             {
895 2     2 1 3127 my $self = shift;
896 2         10 my $argv = {@_};
897              
898 2         8 $self->setLastSQL("");
899 2 100       11 $self->Open() if (!defined($self->{init}{dbh}));
900              
901             ## define the command in load
902 2         5 $self->{init}{command} = "delete";
903              
904 2 50 33     15 if ($self->{init}{plugin_fh}->can('Delete') && $self->{init}{plugin_fh}->Delete($argv))
905             {
906 0         0 $self->setMessage("delete",SQL_SIMPLE_RC_SYNTAX,"037",$self->{argv}{interface},$self->{argv}{driver},$self->getMessage());
907 0         0 return SQL_SIMPLE_RC_SYNTAX;
908             }
909              
910 2 50       8 my $saved_commit = $self->setCommit($argv->{commit}) if (defined($argv->{commit}));
911 2 50       6 my $saved_message_log = $self->setLogMessage($argv->{message_log}) if (defined($argv->{message_log}));
912 2 50       6 my $saved_quote = $self->setQuote($argv->{quote}) if (defined($argv->{quote}));
913 2 50       18 my $saved_sql_save = $self->setSqlSave($argv->{sql_save}) if (defined($argv->{sql_save}));
914              
915 2         4 my $rc = $self->_Delete(%{$argv});
  2         12  
916              
917 2 50       13 $self->setCommit($saved_commit) if (defined($argv->{commit}));
918 2 50       5 $self->setMessgeLog($saved_message_log) if (defined($argv->{message_log}));
919 2 50       5 $self->setQuote($saved_quote) if (defined($argv->{quote}));
920 2 50       6 $self->setSqlSave($saved_sql_save) if (defined($argv->{sql_save}));
921              
922 2         7 return $rc;
923             }
924              
925             sub _Delete()
926             {
927 2     2   4 my $self = shift;
928 2         6 my $argv = {@_};
929              
930             ## check mandatory options
931 2 50 33     8 if (!defined($argv->{table}) && ref($argv->{table}) ne "")
932             {
933 0         0 $self->setMessage("delete",SQL_SIMPLE_RC_SYNTAX,"005");
934 0         0 return SQL_SIMPLE_RC_SYNTAX;
935             }
936             ## make where
937 2         4 my $where;
938 2 50       11 return SQL_SIMPLE_RC_SYNTAX if ($self->_getWhere("delete",[$argv->{table}],$argv->{where},\$where));
939 2 50 66     18 if ((!defined($where) || $where eq "") && !$argv->{force})
      66        
940             {
941 0         0 $self->setMessage("delete",SQL_SIMPLE_RC_SYNTAX,"016");
942 0         0 return SQL_SIMPLE_RC_SYNTAX;
943             }
944             ## build sql command
945 2         10 my $sql = "DELETE FROM ".$self->getAliasTable($argv->{table},0);
946 2 100       7 $sql .= " WHERE ".$where if ($where);
947              
948             return SQL_SIMPLE_RC_ERROR if ($self->_Call(
949             command => $sql,
950             command_type => 1, # (NOT_ZERO is update)
951             buffer => $argv->{buffer},
952             buffer_options => $argv->{buffer_options},
953             make_only => $argv->{make_only},
954             flush => $argv->{flush},
955             sql_save => $argv->{sql_save},
956 2 50       15 ));
957 0 0       0 return SQL_SIMPLE_RC_OK if ($argv->{notfound});
958 0 0       0 if ($self->getRows() == 0)
959             {
960 0         0 $self->setMessage("delete",SQL_SIMPLE_RC_SYNTAX,"012");
961 0         0 return SQL_SIMPLE_RC_EMPTY;
962             }
963 0         0 return SQL_SIMPLE_RC_OK;
964             }
965              
966             ################################################################################
967             ## action: insert
968             ## return:
969             ## rc<0 syntax error
970             ## rc=0 successful
971             ## rc=1 sql error
972             ## rc=2 no selected found (no match where found)
973              
974             sub Insert()
975             {
976 2     2 1 3572 my $self = shift;
977 2         12 my $argv = {@_};
978              
979 2         7 $self->setLastSQL("");
980 2 50       9 $self->Open() if (!defined($self->{init}{dbh}));
981              
982             ## define the command in load
983 2         4 $self->{init}{command} = "insert";
984              
985 2 50 33     15 if ($self->{init}{plugin_fh}->can('Insert') && $self->{init}{plugin_fh}->Insert($argv))
986             {
987 0         0 $self->setMessage("insert",SQL_SIMPLE_RC_SYNTAX,"037",$self->{argv}{interface},$self->{argv}{driver},$self->getMessage());
988 0         0 return SQL_SIMPLE_RC_SYNTAX;
989             }
990              
991 2 50       6 my $saved_commit = $self->setCommit($argv->{commit}) if (defined($argv->{commit}));
992 2 50       8 my $saved_message_log = $self->setLogMessage($argv->{message_log}) if (defined($argv->{message_log}));
993 2 50       5 my $saved_quote = $self->setQuote($argv->{quote}) if (defined($argv->{quote}));
994 2 50       5 my $saved_sql_save = $self->setSqlSave($argv->{sql_save}) if (defined($argv->{sql_save}));
995              
996 2         3 my $rc = $self->_Insert(%{$argv});
  2         9  
997              
998 2 50       16 $self->setCommit($saved_commit) if (defined($argv->{commit}));
999 2 50       7 $self->setMessgeLog($saved_message_log) if (defined($argv->{message_log}));
1000 2 50       5 $self->setQuote($saved_quote) if (defined($argv->{quote}));
1001 2 50       16 $self->setSqlSave($saved_sql_save) if (defined($argv->{sql_save}));
1002              
1003 2         9 return $rc;
1004             }
1005              
1006             sub _Insert()
1007             {
1008 2     2   5 my $self = shift;
1009 2         5 my $argv = {@_};
1010              
1011             ## check mandatory options
1012 2 50 33     8 if (!defined($argv->{table}) && ref($argv->{table}) ne "")
1013             {
1014 0         0 $self->setMessage("insert",SQL_SIMPLE_RC_SYNTAX,"005");
1015 0         0 return SQL_SIMPLE_RC_SYNTAX;
1016             }
1017 2 50       7 if (!defined($argv->{fields}))
1018             {
1019 0         0 $self->setMessage("insert",SQL_SIMPLE_RC_SYNTAX,"017");
1020 0         0 return SQL_SIMPLE_RC_SYNTAX;
1021             }
1022 2 100       23 if (ref($argv->{fields}) eq "HASH") {}
    50          
1023             elsif (ref($argv->{fields}) eq "ARRAY")
1024             {
1025 1 50       5 if (!defined($argv->{values}))
1026             {
1027 0         0 $self->setMessage("insert",SQL_SIMPLE_RC_SYNTAX,"027");
1028 0         0 return SQL_SIMPLE_RC_SYNTAX;
1029             }
1030 1 50       3 if (ref($argv->{values}) ne "ARRAY")
1031             {
1032 0         0 $self->setMessage("insert",SQL_SIMPLE_RC_SYNTAX,"041");
1033 0         0 return SQL_SIMPLE_RC_SYNTAX;
1034             }
1035             }
1036             else
1037             {
1038 0         0 $self->setMessage("insert",SQL_SIMPLE_RC_SYNTAX,"018");
1039 0         0 return SQL_SIMPLE_RC_SYNTAX;
1040             }
1041 2 50 33     9 if (defined($argv->{conflict}) && ref($argv->{conflict}) ne "HASH")
1042             {
1043 0         0 $self->setMessage("insert",SQL_SIMPLE_RC_SYNTAX,"042");
1044 0         0 return SQL_SIMPLE_RC_SYNTAX;
1045             }
1046             ## making fields
1047 2         4 my @fields;
1048             my @values;
1049 2 100       7 if (ref($argv->{fields}) eq "HASH")
1050             {
1051 1         3 my @line;
1052 1         2 foreach my $field(sort(keys(%{$argv->{fields}})))
  1         10  
1053             {
1054 3         8 push(@fields,$self->getAliasCols($argv->{table},$field));
1055 3         8 push(@line,$argv->{fields}{$field});
1056             }
1057 1         14 push(@values,"(".$self->{argv}{quote}.join($self->{argv}{quote}.",".$self->{argv}{quote},@line).$self->{argv}{quote}.")");
1058             }
1059             else
1060             {
1061 1         3 my $no_fld = @{$argv->{fields}};
  1         2  
1062 1         2 foreach my $field(@{$argv->{fields}})
  1         3  
1063             {
1064 3         10 push(@fields,$self->getAliasCols($argv->{table},$field));
1065             }
1066 1         3 foreach my $values(@{$argv->{values}})
  1         4  
1067             {
1068 1 50       3 if ($no_fld == 1)
1069             {
1070 0 0       0 if (ref($values) eq "ARRAY")
1071             {
1072 0         0 push(@values,"(".$self->{argv}{quote}.join($self->{argv}{quote}."),(".$self->{argv}{quote},@{$values}).$self->{argv}{quote}.")");
  0         0  
1073             }
1074             else
1075             {
1076 0         0 push(@values,"(".$self->{argv}{quote}.$values.$self->{argv}{quote}.")");
1077             }
1078             }
1079             else
1080             {
1081 1 50       3 if (ref($values) eq "ARRAY")
1082             {
1083 0         0 push(@values,"(".$self->{argv}{quote}.join($self->{argv}{quote}.",".$self->{argv}{quote},@{$values}).$self->{argv}{quote}.")");
  0         0  
1084             }
1085             else
1086             {
1087 1         5 push(@values,"(".$self->{argv}{quote}.join($self->{argv}{quote}.",".$self->{argv}{quote},@{$argv->{values}}).$self->{argv}{quote}.")");
  1         6  
1088 1         16 goto EXIT_VALUES;
1089             }
1090             }
1091             }
1092             EXIT_VALUES:
1093 1         2 }
1094             ## build sql
1095 2         6 my $sql = "INSERT INTO ".$self->getAliasTable($argv->{table},0)." (".join(",",@fields).") VALUES ".join(",",@values);
1096 2 50       7 if (defined($argv->{conflict}))
1097             {
1098 0         0 my @conflict;
1099 0         0 foreach my $field(sort(keys(%{$argv->{conflict}})))
  0         0  
1100             {
1101             ($argv->{conflict}{$field} =~ /^\\(.*)/) ?
1102             push(@conflict,$self->getAliasCols($argv->{table},$field)." = ".$1):
1103 0 0       0 push(@conflict,$self->getAliasCols($argv->{table},$field)." = ".$self->{argv}{quote}.$argv->{conflict}{$field}.$self->{argv}{quote});
1104             }
1105             $sql .= ($self->{init}{plugin_id} =~ /^mysql/i || $self->{init}{plugin_id} =~ /^mariadb/i) ?
1106             " ON DUPLICATE KEY UPDATE ".join(", ",@conflict) :
1107 0 0 0     0 " ON CONFLICT ".(($argv->{conflict_key})?"(".$self->getAliasCols($argv->{table},$argv->{conflict_key}).") ":"")."DO UPDATE SET ".join(", ",@conflict);
    0          
1108             }
1109             ## execute
1110             return SQL_SIMPLE_RC_ERROR if ($self->_Call(
1111             command => $sql,
1112             command_type => 1, # (NOT_ZERO is update)
1113             buffer => $argv->{buffer},
1114             buffer_options => $argv->{buffer_options},
1115             make_only => $argv->{make_only},
1116             flush => $argv->{flush},
1117             sql_save => $argv->{sql_save},
1118 2 50       13 ));
1119 0         0 return SQL_SIMPLE_RC_OK;
1120             }
1121              
1122             ################################################################################
1123             ## action: update
1124             ## return:
1125             ## rc<0 syntax error
1126             ## rc=0 successful
1127             ## rc=1 sql error
1128             ## rc=2 no selected found (no match where found)
1129              
1130             sub Update()
1131             {
1132 2     2 1 3475 my $self = shift;
1133 2         9 my $argv = {@_};
1134              
1135 2         7 $self->setLastSQL("");
1136 2 50       18 $self->Open() if (!defined($self->{init}{dbh}));
1137              
1138             ## define the command in load
1139 2         6 $self->{init}{command} = "update";
1140              
1141 2 50 33     15 if ($self->{init}{plugin_fh}->can('Update') && $self->{init}{plugin_fh}->Update($argv))
1142             {
1143 0         0 $self->setMessage("update",SQL_SIMPLE_RC_SYNTAX,"037",$self->{argv}{interface},$self->{argv}{driver},$self->getMessage());
1144 0         0 return SQL_SIMPLE_RC_SYNTAX;
1145             }
1146              
1147 2 50       7 my $saved_commit = $self->setCommit($argv->{commit}) if (defined($argv->{commit}));
1148 2 50       6 my $saved_message_log = $self->setLogMessage($argv->{message_log}) if (defined($argv->{message_log}));
1149 2 50       6 my $saved_quote = $self->setQuote($argv->{quote}) if (defined($argv->{quote}));
1150 2 50       5 my $saved_sql_save = $self->setSqlSave($argv->{sql_save}) if (defined($argv->{sql_save}));
1151              
1152 2         4 my $rc = $self->_Update(%{$argv});
  2         10  
1153              
1154 2 50       9 $self->setCommit($saved_commit) if (defined($argv->{commit}));
1155 2 50       12 $self->setMessgeLog($saved_message_log) if (defined($argv->{message_log}));
1156 2 50       7 $self->setQuote($saved_quote) if (defined($argv->{quote}));
1157 2 50       6 $self->setSqlSave($saved_sql_save) if (defined($argv->{sql_save}));
1158              
1159 2         7 return $rc;
1160             }
1161              
1162             sub _Update()
1163             {
1164 2     2   4 my $self = shift;
1165 2         5 my $argv = {@_};
1166              
1167             ## check mandatory options
1168 2 50 33     8 if (!defined($argv->{table}) && ref($argv->{table}) ne "")
1169             {
1170 0         0 $self->setMessage("update",SQL_SIMPLE_RC_SYNTAX,"005");
1171 0         0 return SQL_SIMPLE_RC_SYNTAX;
1172             }
1173 2 50       4 if (!defined($argv->{fields}))
1174             {
1175 0         0 $self->setMessage("update",SQL_SIMPLE_RC_SYNTAX,"017");
1176 0         0 return SQL_SIMPLE_RC_SYNTAX;
1177             }
1178 2 50       7 if (ref($argv->{fields}) ne "HASH")
1179             {
1180 0         0 $self->setMessage("update",SQL_SIMPLE_RC_SYNTAX,"018");
1181 0         0 return SQL_SIMPLE_RC_SYNTAX;
1182             }
1183             ## make fields
1184 2         3 my @fields;
1185 2         4 foreach my $field(keys(%{$argv->{fields}}))
  2         6  
1186             {
1187             ($argv->{fields}{$field} =~ /^\\(.*)/) ?
1188             push(@fields,$self->getAliasCols($argv->{table},$field)." = ".$1):
1189 3 100       21 push(@fields,$self->getAliasCols($argv->{table},$field)." = ".$self->{argv}{quote}.$argv->{fields}{$field}.$self->{argv}{quote});
1190             }
1191             ## make where
1192 2         4 my $where;
1193 2 50       24 return SQL_SIMPLE_RC_SYNTAX if ($self->_getWhere("update",[$argv->{table}],$argv->{where},\$where));
1194              
1195 2 50 66     15 if ((!defined($where) || $where eq "") && !$argv->{force})
      66        
1196             {
1197 0         0 $self->setMessage("update",SQL_SIMPLE_RC_SYNTAX,"016");
1198 0         0 return SQL_SIMPLE_RC_SYNTAX;
1199             }
1200             ## formata o sql
1201 2         6 my $sql = "UPDATE ".$self->getAliasTable($argv->{table},0)." SET ".join(", ",@fields);
1202 2 100       6 $sql .= " WHERE ".$where if ($where);
1203              
1204             ## execute
1205             return SQL_SIMPLE_RC_ERROR if ($self->_Call(
1206             command => $sql,
1207             command_type => 1, # (NOT_ZERO is update)
1208             buffer => $argv->{buffer},
1209             buffer_options => $argv->{buffer_options},
1210             make_only => $argv->{make_only},
1211             flush => $argv->{flush},
1212             sql_save => $argv->{sql_save},
1213 2 50       12 ));
1214 0 0       0 return SQL_SIMPLE_RC_OK if ($argv->{notfound});
1215 0 0       0 if ($self->getRows() == 0)
1216             {
1217 0         0 $self->setMessage("update",SQL_SIMPLE_RC_SYNTAX,"012");
1218 0         0 return SQL_SIMPLE_RC_EMPTY;
1219             }
1220 0         0 return SQL_SIMPLE_RC_OK;
1221             }
1222              
1223             ################################################################################
1224             ## action: wait db connect
1225             ## return:
1226             ## rc<0 syntax error
1227             ## rc=0 successful
1228             ## rc>0 sql command error
1229              
1230             sub Wait()
1231             {
1232 0     0 0 0 my $self = shift;
1233 0         0 my $argv= {@_};
1234              
1235 0 0       0 my $count = 1 if (!defined($argv->{count}));
1236 0 0       0 my $sleep = 5 if (!defined($argv->{interval}));
1237              
1238 0 0       0 return SQL_SIMPLE_RC_SYNTAX if ($count =~ /^\D+$/);
1239 0 0       0 return SQL_SIMPLE_RC_SYNTAX if ($sleep =~ /^\D+$/);
1240              
1241 0         0 while ($count-- > 0)
1242             {
1243 0 0       0 last if (!$self->Open());
1244              
1245 0 0 0     0 sleep($sleep) if ($count && $sleep);
1246             }
1247 0         0 return $self->getRC();
1248             }
1249              
1250             ################################################################################
1251             ## action: execute sql command
1252             ## return:
1253             ## rc<0 syntax error
1254             ## rc=0 successful
1255             ## rc>0 sql command error
1256             #
1257             ## callback example:
1258             ## sub myfunc()
1259             ## {
1260             ## my $ref = shift; # input field hash info
1261             ## my $options = shift; # options args
1262             ## return 0; # if ok to continue than return ZERO
1263             ## return 1; # if aboort needed than return NOT_ZERO
1264             ## }
1265              
1266             sub Call()
1267             {
1268 0     0 1 0 my $self = shift;
1269 0         0 my $argv = {@_};
1270              
1271 0         0 $self->setLastSQL("");
1272 0 0       0 $self->Open() if (!defined($self->{init}{dbh}));
1273              
1274             ## define the command in load
1275 0         0 $self->{init}{command} = "call";
1276              
1277 0 0 0     0 if ($self->{init}{plugin_fh}->can('Call') && $self->{init}{plugin_fh}->Call($argv))
1278             {
1279 0         0 $self->setMessage("call",SQL_SIMPLE_RC_SYNTAX,"037",$self->{argv}{interface},$self->{argv}{driver},$self->getMessage());
1280 0         0 return SQL_SIMPLE_RC_SYNTAX;
1281             }
1282 0 0       0 if ($argv->{command} eq "")
1283             {
1284 0         0 $self->setMessage("call",SQL_SIMPLE_RC_SYNTAX,"023");
1285 0         0 return SQL_SIMPLE_RC_SYNTAX;
1286             }
1287              
1288 0 0       0 my $saved_commit = $self->setCommit($argv->{commit}) if (defined($argv->{commit}));
1289 0 0       0 my $saved_message_log = $self->setLogMessage($argv->{message_log}) if (defined($argv->{message_log}));
1290 0 0       0 my $saved_quote = $self->setQuote($argv->{quote}) if (defined($argv->{quote}));
1291 0 0       0 my $saved_sql_save = $self->setSqlSave($argv->{sql_save}) if (defined($argv->{sql_save}));
1292              
1293 0         0 my $rc = $self->_Call(%{$argv});
  0         0  
1294              
1295 0 0       0 $self->setCommit($saved_commit) if (defined($argv->{commit}));
1296 0 0       0 $self->setMessgeLog($saved_message_log) if (defined($argv->{message_log}));
1297 0 0       0 $self->setQuote($saved_quote) if (defined($argv->{quote}));
1298 0 0       0 $self->setSqlSave($saved_sql_save) if (defined($argv->{sql_save}));
1299              
1300 0         0 return $rc;
1301             }
1302              
1303             sub _Call()
1304             {
1305 32     32   68 my $self = shift;
1306 32         245 my $argv = {@_};
1307              
1308 32         103 $self->setLastSQL($argv->{command});
1309              
1310             ## save command (call-sql_save is prior that new-sql_save
1311 32 50 66     139 if ((defined($argv->{sql_save}) && $argv->{sql_save}) || (defined($self->{argv}{sql_save}) && $self->{argv}{sql_save} && $argv->{command_type}))
      33        
      0        
      66        
1312             {
1313 1 50       13 return SQL_SIMPLE_RC_ERROR if ($self->Save($argv->{command}));
1314             }
1315             ## return if makeonly
1316 32 50       267 return SQL_SIMPLE_RC_ERROR if ($argv->{make_only});
1317              
1318             ## mandatory
1319 0 0       0 if (!defined($self->{init}{dbh}))
1320             {
1321 0         0 $self->setMessage("call",SQL_SIMPLE_RC_SYNTAX,"022");
1322 0         0 return SQL_SIMPLE_RC_SYNTAX;
1323             }
1324 0 0 0     0 my $flush_buffer = (!defined($argv->{flush}) || $argv->{flush}) ? 1 : 0;
1325 0         0 my $type;
1326 0 0       0 if (!defined($argv->{buffer})) {}
    0          
    0          
    0          
    0          
1327 0 0       0 elsif (ref($argv->{buffer}) eq "HASH") { $type=1; undef(%{$argv->{buffer}}) if ($flush_buffer); }
  0         0  
  0         0  
1328 0 0       0 elsif (ref($argv->{buffer}) eq "ARRAY") { $type=2; undef(@{$argv->{buffer}}) if ($flush_buffer); }
  0         0  
  0         0  
1329 0         0 elsif (ref($argv->{buffer}) eq "CODE") { $type=3; }
1330 0         0 elsif (ref($argv->{buffer}) eq "SCALAR") { $type=4; }
1331             else
1332             {
1333 0         0 $self->setMessage("call",SQL_SIMPLE_RC_SYNTAX,"024");
1334 0         0 return SQL_SIMPLE_RC_SYNTAX;
1335             }
1336             ## prepare command
1337 0         0 $argv->{command} =~ s/^\s+|\s+$//;
1338 0 0       0 my $sth = $self->{init}{dbh}->prepare($argv->{command}.( ($argv->{command} =~ /\;$/) ? "":";") );
1339              
1340             ## execute command
1341 0 0       0 if (defined($sth))
1342             {
1343 0         0 $sth->execute(); # send command to run
1344 0         0 $self->setMessage("call"); # save the current status
1345              
1346             ## scan the fields
1347 0 0       0 if (defined($argv->{buffer}))
1348             {
1349 0 0       0 if ($sth->{NUM_OF_FIELDS})
1350             {
1351 0         0 while (my $ref = $sth->fetchrow_hashref())
1352             {
1353 0 0       0 if ($type == 1) { %{$argv->{buffer}} = %{$ref}; }
  0 0       0  
  0 0       0  
  0 0       0  
1354 0         0 elsif ($type == 2) { push(@{$argv->{buffer}},$ref); }
  0         0  
1355 0 0       0 elsif ($type == 3) { last if (&{$argv->{buffer}}($ref,$argv->{buffer_options})); }
  0         0  
1356 0         0 elsif ($type == 4) { foreach my $id(keys(%{$ref})) { ${$argv->{buffer}} = $ref->{$id}; }}
  0         0  
  0         0  
  0         0  
1357             }
1358             }
1359             }
1360 0         0 $self->{init}{rows} = $sth->rows(); # get number of extracted lines
1361              
1362             ## close and commit (if need)
1363 0         0 $sth->finish();
1364             }
1365             else
1366             {
1367 0         0 $self->setMessage("call");
1368             }
1369 0         0 undef($sth);
1370              
1371             ## force commit if required
1372 0 0 0     0 $self->Commit(%{$argv}) if ($self->{argv}->{commit} && $argv->{command_type});
  0         0  
1373 0         0 return $self->getRC();
1374             }
1375              
1376             ################################################################################
1377             ## action: commit command
1378             ## return:
1379             ## rc=0 successful
1380             ## rc>0 sql command error
1381              
1382             sub Commit()
1383             {
1384 0     0 0 0 my $self = shift;
1385 0         0 my $argv = {@_};
1386              
1387 0         0 $self->setLastSQL("");
1388              
1389 0 0       0 return SQL_SIMPLE_RC_OK if (!defined($self->{init}{dbh}));
1390             return $self->_Call(
1391             command => "commit",
1392             command_type => 0, # (ZERO to eliminate the LOOP)
1393             make_only => $argv->{make_only},
1394             flush => $argv->{flush},
1395             sql_save => $argv->{sql_save},
1396 0         0 );
1397             }
1398              
1399             ################################################################################
1400             ## action: disconnect database
1401             ## return:
1402             ## rc=0 successful
1403             ## rc>0 sql command error
1404              
1405             sub Close()
1406             {
1407 0     0 0 0 my $self = shift;
1408              
1409 0 0       0 return SQL_SIMPLE_RC_OK if (!defined($self->{init}{dbh}));
1410              
1411 0         0 my $rc = $self->{init}{dbh}->disconnect();
1412              
1413 0         0 $self->setMessage("close");
1414              
1415 0         0 undef($self->{init}{dbh});
1416              
1417 0         0 return $self->getRC();
1418             }
1419              
1420             ##############################################################################
1421             ## action: save the current sql command
1422             ## return:
1423             ## rc=0, successful
1424             ## rc=1, system error (mkdir/openfile)
1425              
1426             sub Save()
1427             {
1428 1     1 0 18 my $self = shift;
1429 1         5 my @sqls = @_;
1430              
1431 1 50       7 $self->{init}{sql_save_ix} = 0 if (!defined($self->{init}{sql_save_ix}));
1432 1 50       16 $self->{init}{sql_save_name} = "sql" if (!defined($self->{init}{sql_save_name}));
1433             $self->{init}{sql_save_dir} =
1434             (defined($self->{argv}{sql_save_dir})) ? $self->{argv}{sql_save_dir} :
1435             ($^O ne 'MSWin32') ? File::Spec->catdir("","var","spool","sql") :
1436 1 0       10 File::Spec->catdir("","windows","temp") if (!defined($self->{init}{sql_save_dir}));
    50          
    50          
1437              
1438 1         751 require Date::Calc;
1439 1         6337 require File::Path;
1440 1         467 require IO::File;
1441              
1442 1         8759 my $today = sprintf("%04s%02s%02s",Date::Calc::Today());
1443             my $path = ($self->{argv}{sql_save_bydate}) ?
1444             File::Spec->catdir($self->{init}{sql_save_dir},substr($today,0,4),substr($today,0,6),$today) :
1445 1 50       26 $self->{init}{sql_save_dir};
1446              
1447 1 50       74 if (!stat($path))
1448             {
1449 1         5 eval { &File::Path::mkpath($path); };
  1         425  
1450 1 50       8 if ($@)
1451             {
1452 0         0 $self->setMessage("save",SQL_SIMPLE_RC_ERROR,"025",$@);
1453 0 0       0 return ($self->{argv}{sql_save_ignore}) ? SQL_SIMPLE_RC_OK : SQL_SIMPLE_RC_ERROR;
1454             }
1455             }
1456              
1457 1   50     33 $self->{init}{sql_save_logfile} = File::Spec->catpath("", $path,$self->{init}{sql_save_name}.".".($self->{argv}{db}||"public").".".$today.".".$$.".".(++$self->{init}{sql_save_ix}));
1458 1         8 my $fh = IO::File->new(">".$self->{init}{sql_save_logfile});
1459 1 50       126 if (!defined($fh))
1460             {
1461 0         0 $self->setMessage("save",SQL_SIMPLE_RC_ERROR,"026",$!);
1462 0 0       0 return ($self->{argv}{sql_save_ignore}) ? SQL_SIMPLE_RC_OK : SQL_SIMPLE_RC_ERROR;
1463             }
1464              
1465 1         20 print $fh join("\n",@sqls),"\n";
1466 1         52 close($fh);
1467 1         10 undef($fh);
1468 1         7 return SQL_SIMPLE_RC_OK;
1469             }
1470              
1471             ################################################################################
1472             ## action: where clause formater, used by: select, insert, delete, update
1473             ## return:
1474             ## rc<0 syntax error
1475             ## rc=0 successful
1476              
1477             sub getWhere()
1478             {
1479              
1480 33     33 1 31003 my $self = shift;
1481 33         98 my $argv = {@_};
1482              
1483             ## criar as regras de validacao da table, where, buffer.
1484             ## criar as regras de validacao da table, where, buffer.
1485             ## criar as regras de validacao da table, where, buffer.
1486              
1487 33         51 my @tables;
1488 33 100       104 if (ref($argv->{table}) eq "ARRAY"){ push(@tables,@{$argv->{table}}); }
  8 50       15  
  8         19  
1489 25         65 elsif (ref($argv->{table}) eq "") { push(@tables,$argv->{table}); }
1490             else
1491             {
1492 0         0 $self->setMessage("getWhere",SQL_SIMPLE_RC_SYNTAX,"006");
1493 0         0 return SQL_SIMPLE_RC_SYNTAX;
1494             }
1495              
1496 33         87 return $self->_getWhere("where",\@tables,$argv->{where},$argv->{buffer});
1497             }
1498              
1499             sub _getWhere()
1500             {
1501 63     63   99 my $self = shift;
1502 63         130 my $command = shift;
1503 63         112 my $tables = shift;
1504 63         92 my $where = shift;
1505 63         85 my $buffer = shift;
1506              
1507             ## return dummy where
1508 63 100       156 return SQL_SIMPLE_RC_OK if (!$where);
1509              
1510             ## format where
1511 47         63 my @where_local;
1512 47 50       118 return SQL_SIMPLE_RC_SYNTAX if ($self->_getWhereRecursive($command,0,$tables,$where,\@where_local));
1513              
1514             ## return the where clause
1515 47         88 ${$buffer} = join(" ",@where_local);
  47         76  
1516 47         150 return SQL_SIMPLE_RC_OK;
1517             }
1518              
1519             sub _getWhereRecursive()
1520             {
1521 53     53   74 my $self = shift;
1522 53         78 my $command = shift;
1523 53         72 my $level = shift;
1524 53         73 my $tables = shift;
1525 53         68 my $where = shift;
1526 53         77 my $buffer = shift;
1527              
1528             ## return error if argvs is empty, format error
1529 53 50       134 if ($where eq "")
1530             {
1531 0         0 $self->setMessage($command,SQL_SIMPLE_RC_SYNTAX,"020");
1532 0         0 return SQL_SIMPLE_RC_SYNTAX;
1533             }
1534 53 50       113 if (ref($where) eq "")
1535             {
1536 0         0 push(@{$buffer},$where);
  0         0  
1537 0         0 return 0;
1538             }
1539             ## return error if value1 is not array or value type
1540 53 50       104 if (ref($where) ne "ARRAY")
1541             {
1542 0         0 $self->setMessage($command,SQL_SIMPLE_RC_SYNTAX,"021");
1543 0         0 return SQL_SIMPLE_RC_SYNTAX;
1544             }
1545             ## format where
1546 53         80 my @where_tmp;
1547 53         79 my $oper_pend = 0;
1548 53         88 for (my $ix=0; $ix < @{$where};)
  137         313  
1549             {
1550 84         147 my $value1 = $where->[$ix++];
1551              
1552 84 100       157 if (ref($value1) ne "")
1553             {
1554 6         12 my @where_aux;
1555 6 50       65 return SQL_SIMPLE_RC_SYNTAX if ($self->_getWhereRecursive($command,$level+1,$tables,$value1,\@where_aux));
1556              
1557             ## valida se requer AND/OR
1558 6 100 66     20 push(@where_tmp,"AND") if ($oper_pend && @where_tmp);
1559             ## salva o where recursivo
1560 6         17 push(@where_tmp,join(" ",@where_aux));
1561 6         9 $oper_pend = 1;
1562 6         9 next;
1563             }
1564             ## check and/or logical connector
1565 78 100       271 if ($value1 =~ /^(and|\&\&|or|\|\|)$/i)
1566             {
1567 6         15 push(@where_tmp,uc($value1));
1568 6         8 $oper_pend = 0;
1569 6         9 next;
1570             }
1571             ## valida se requer AND/OR
1572 72 100 66     206 if ($oper_pend && @where_tmp)
1573             {
1574 17         34 push(@where_tmp,"AND");
1575 17         20 $oper_pend = 0;
1576             }
1577             ## convert value1 to realname if possible
1578 72 50 33     141 if ($value1 =~ /^\\/) {}
    100          
    50          
1579 72         213 elsif (@{$tables} == 1)
1580             {
1581 54         121 $value1 = $self->getAliasCols($tables->[0],$value1,0);
1582             }
1583 18         196 elsif ($value1 =~ /^(.*?)\.(.*?)$/ && grep(/^$1$/,@{$tables}))
1584             {
1585 18         54 $value1 = $self->getAliasCols($1,$2,1);
1586             }
1587             else
1588             {
1589 0         0 $value1 = $self->getAliasCols($tables->[0],$value1,0);
1590             }
1591 72 50       115 if ($ix >= @{$where})
  72         148  
1592             {
1593 0         0 push(@where_tmp,$value1);
1594 0         0 last;
1595             }
1596 72         144 my $value2 = $where->[$ix++];
1597 72         111 my $quote = $self->{argv}{quote};;
1598              
1599 72         100 $oper_pend = 1;
1600              
1601             ## value2 is array, multiple values
1602 72 100       147 if (ref($value2) eq "ARRAY")
1603             {
1604 34         47 my @_value2 = @{$value2};
  34         75  
1605 34         98 my $value2_b = "";
1606 34         46 my $value2_a = "";
1607 34         51 my $operator = $value2->[0];
1608 34         52 my $where_opr = "AND";
1609              
1610             ## value0 is escaped (not operator)
1611 34 50       238 if (!defined($operator)) { $operator = "="; }
  0 50       0  
    100          
    100          
    50          
    50          
    50          
    100          
    50          
    100          
    100          
    100          
    100          
    100          
    50          
    100          
    100          
    50          
1612 0         0 elsif ($operator =~ /^\\/) { $operator = "="; }
1613 4         9 elsif ($operator eq "=") { shift(@_value2); }
1614 12         20 elsif ($operator eq "!") { shift(@_value2); $operator = "!="; }
  12         20  
1615 0         0 elsif ($operator eq "!=") { shift(@_value2); $operator = "!="; }
  0         0  
1616 0         0 elsif ($operator eq "<>") { shift(@_value2); $operator = "!="; }
  0         0  
1617 0         0 elsif ($operator eq "<=") { shift(@_value2); }
1618 2         9 elsif ($operator eq "<") { shift(@_value2); }
1619 0         0 elsif ($operator eq ">=") { shift(@_value2); }
1620 3         7 elsif ($operator eq ">") { shift(@_value2); }
1621 1 50       3 elsif ($operator eq "%%") { shift(@_value2); $operator = "LIKE"; $value2_b = "%"; $value2_a = "%"; $where_opr = "OR" if (@_value2 > 1); }
  1         3  
  1         2  
  1         1  
  1         3  
1622 2 100       4 elsif ($operator eq "^%") { shift(@_value2); $operator = "LIKE"; $value2_b = "%"; $where_opr = "OR" if (@_value2 > 1); }
  2         5  
  2         3  
  2         6  
1623 2 100       4 elsif ($operator eq "%^") { shift(@_value2); $operator = "LIKE"; $value2_a = "%"; $where_opr = "OR" if (@_value2 > 1); }
  2         3  
  2         4  
  2         7  
1624 1 50       3 elsif ($operator eq "^^") { shift(@_value2); $operator = "LIKE"; $where_opr = "OR" if (@_value2 > 1); }
  1         2  
  1         3  
1625 0         0 elsif ($operator eq "!%%") { shift(@_value2); $operator = "NOT LIKE"; $value2_b = "%"; $value2_a = "%"; }
  0         0  
  0         0  
  0         0  
1626 2         6 elsif ($operator eq "!^%") { shift(@_value2); $operator = "NOT LIKE"; $value2_b = "%"; }
  2         3  
  2         3  
1627 2         4 elsif ($operator eq "!%^") { shift(@_value2); $operator = "NOT LIKE"; $value2_a = "%"; }
  2         3  
  2         4  
1628 0         0 elsif ($operator eq "!^^") { shift(@_value2); $operator = "NOT LIKE"; }
  0         0  
1629 3         4 else { $operator = "="; }
1630              
1631             ## construct condition
1632 34 100 100     124 if ($operator eq "=" || $operator eq "!=")
1633             {
1634 19 100       57 if (@_value2 > 1)
1635             {
1636 5 100       11 my $not = ($operator eq "!=") ? " NOT" : "";
1637 5 100 66     33 (@_value2 == 3 && $_value2[1] eq "..") ?
1638             push(@where_tmp,$value1.$not." BETWEEN (".$quote.$_value2[0].$quote.",".$quote.$_value2[2].$quote.")") :
1639             push(@where_tmp,$value1.$not." IN (".$quote.join("$quote,$quote",@_value2).$quote.")");
1640 5         15 next;
1641             }
1642             }
1643             ## multiple conditions
1644 29         50 my @where_aux;
1645 29         52 foreach my $value(@_value2)
1646             {
1647 35 100 66     125 if (defined($value) && $value ne "")
    50          
1648             {
1649 33 100 66     65 if ($value =~ /^\\(.*)/)
    100          
    100          
1650             {
1651 1         12 push(@where_tmp,$value1." ".$operator." ".$1);
1652             }
1653 32         85 elsif (@{$tables} == 1)
1654             {
1655 24         74 push(@where_aux,$value1." ".$operator." ".$quote.$value2_a.$value.$value2_b.$quote);
1656             }
1657 6         119 elsif ($value =~ /^(.*?)\.(.*?)$/ && grep(/^$1$/,@{$tables}))
1658             {
1659 6         21 my $_value = $self->getAliasCols($1,$2,1);
1660 6         22 push(@where_aux,$value1." ".$operator." ".$_value);
1661             }
1662             else
1663             {
1664 2         8 push(@where_aux,$value1." ".$operator." ".$quote.$value2_a.$value.$value2_b.$quote);
1665             }
1666             }
1667             elsif ($operator eq "=")
1668             {
1669 0         0 push(@where_aux,$value1." IS NULL");
1670             }
1671             else
1672             {
1673 2         11 push(@where_aux,$value1." NOT NULL");
1674             }
1675             }
1676 29 100       63 if (@where_aux > 1)
1677             {
1678 6         12 $where_aux[0] = "(".$where_aux[0];
1679 6         12 $where_aux[@where_aux-1] .= ")";
1680             }
1681 29 100       97 push(@where_tmp,join(" ".$where_opr." ",@where_aux)) if (@where_aux);
1682 29         74 next;
1683             }
1684             ## value2 is single value
1685 38 100       71 if (!defined($value2))
1686             {
1687 2         5 push(@where_tmp,$value1." IS NULL");
1688 2         3 next;
1689             }
1690 36 50       69 if (ref($value2) eq "")
1691             {
1692 36 50       67 if ($value2 ne "")
1693             {
1694 36 100 33     79 if ($value2 =~ /^\\(.*)/)
    100          
    50          
1695             {
1696 2         10 push(@where_tmp,$value1." = ".$1);
1697             }
1698 34         121 elsif (@{$tables} == 1)
1699             {
1700 25         64 push(@where_tmp,$value1." = ".$quote.$value2.$quote);
1701             }
1702 9         115 elsif ($value2 =~ /^(.*?)\.(.*?)$/ && grep(/^$1$/,@{$tables}))
1703             {
1704 9         35 my $_value2 = $self->getAliasCols($1,$2,1);
1705 9         31 push(@where_tmp,$value1." = ".$_value2);
1706             }
1707 0         0 else { push(@where_tmp,$value1." = ".$quote.$value2.$quote); }
1708             }
1709 0         0 else { push(@where_tmp,$value1." IS NULL"); }
1710 36         76 next;
1711             }
1712              
1713             ## return error if value2 is not array or value type
1714 0         0 $self->setMessage($command,SQL_SIMPLE_RC_SYNTAX,"028");
1715 0         0 return SQL_SIMPLE_RC_SYNTAX;
1716             }
1717 53 50       105 if (@where_tmp)
1718             {
1719 53         70 push(@{$buffer},join(" ",@where_tmp));
  53         131  
1720 53 100       100 $buffer->[0] = "(".$buffer->[0] if ($level);
1721 53         71 my $n = @{$buffer};
  53         79  
1722 53 100       109 $buffer->[$n-1] .= ")" if ($level);
1723             }
1724 53         144 return 0;
1725             }
1726              
1727             ##############################################################################
1728             ## action: get dbh entry point module
1729             ## return: current dbi drive pointer module
1730              
1731             sub getDBH()
1732             {
1733 0     0 1 0 return $_[0]->{init}{dbh};
1734             }
1735              
1736             ##############################################################################
1737             ## action: get last condition state
1738             ## return: last return code state
1739              
1740             sub getRC()
1741             {
1742 33     33 1 123 return $err;
1743             }
1744              
1745             ##############################################################################
1746             ## action: get last message state
1747             ## return: last system message
1748              
1749             sub getMessage()
1750             {
1751 0     0 1 0 return $errstr;
1752             }
1753              
1754             ##############################################################################
1755             ## action: get number of extracted lines
1756             ## return: number of extracted lines
1757              
1758             sub getRows()
1759             {
1760 0     0 1 0 return $_[0]->{init}{rows};
1761             }
1762              
1763             ##############################################################################
1764             ## action: get the last sql command
1765             ## return: last sql command
1766              
1767             sub getLastSQL()
1768             {
1769 32     32 1 181 return $_[0]->{init}{sql_command};
1770             }
1771              
1772             ##############################################################################
1773             ## action: get the last cursor pointer
1774             ## return: cursor pointer
1775              
1776             sub getLastCursor()
1777             {
1778 0     0 1 0 my $self = shift;
1779 0         0 return %{$self->{init}{cursor}};
  0         0  
1780             }
1781              
1782             ##############################################################################
1783             ## action: get the last saved fileset
1784             ## return: last sql logfile
1785              
1786             sub getLastSave()
1787             {
1788 1     1 1 1032 return $_[0]->{init}{sql_save_logfile};
1789             }
1790              
1791             ##############################################################################
1792             ## action: get the table's realname
1793             ## return: name of the table
1794              
1795             sub getAliasTable()
1796             {
1797 35     35 1 48 my $self = shift;
1798 35         51 my $table = shift;
1799 35         50 my $ident = shift;
1800              
1801 35 50 33     123 my $schema = ($self->{init}{schema} && defined($self->{argv}{schema}) && $self->{argv}{schema} ne "") ? $self->{argv}{schema}."." : "";
1802              
1803             return (!defined($self->{argv}{tables}) ||
1804             !defined($self->{argv}{tables}{$table}) ||
1805             !defined($self->{argv}{tables}{$table}{name}) ||
1806             $self->{argv}{tables}{$table}{name} eq $table) ?
1807             $schema.$table :
1808             ($ident) ?
1809             $schema.$self->{argv}{tables}{$table}{name}." ".$table :
1810 35 0 33     177 $schema.$self->{argv}{tables}{$table}{name};
    50          
1811             }
1812              
1813             ##############################################################################
1814             ## action: get the table's realname
1815             ## return: name of the table
1816              
1817             sub getAliasCols()
1818             {
1819 156     156 1 224 my $self = shift;
1820 156         259 my $table = shift;
1821 156         215 my $field = shift;
1822 156         196 my $notab = shift;
1823              
1824             return (!defined($self->{argv}{tables}) ||
1825             !defined($self->{argv}{tables}{$table}) ||
1826             !defined($self->{argv}{tables}{$table}{cols}) ||
1827             !defined($self->{argv}{tables}{$table}{cols}{$field})) ?
1828             (($notab) ? $table.".".$field : $field) :
1829 156 100 0     613 (($notab) ? $table.".".$self->{argv}{tables}{$table}{cols}{$field} : $self->{argv}{tables}{$table}{cols}{$field});
    0          
    50          
1830             }
1831              
1832             ################################################################################
1833             ## action: set last command sql
1834             ## return: none
1835              
1836             sub setLastSQL()
1837             {
1838 64     64 0 139 $_[0]->{init}{sql_command} = $_[1];
1839             }
1840              
1841             ################################################################################
1842             ## action: set commit
1843             ## return: old commit
1844              
1845             sub setCommit()
1846             {
1847 0     0 0 0 my $self = shift;
1848 0         0 my $save = $self->{argv}{commit};
1849 0   0     0 $self->{argv}{commit} = shift || 0;
1850 0         0 return $save;
1851             }
1852              
1853             ################################################################################
1854             ## action: set message_log
1855             ## return: old message_log
1856              
1857             sub setLogMessage()
1858             {
1859 0     0 0 0 my $self = shift;
1860 0         0 my $save = $self->{argv}{message_log};
1861 0   0     0 $self->{argv}{message_log} = shift || 0 ;
1862 0         0 return $save;
1863             }
1864              
1865             ################################################################################
1866             ## action: set sql_save
1867             ## return: old sql_save
1868              
1869             sub setSqlSave()
1870             {
1871 2     2 0 6 my $self = shift;
1872 2         5 my $save = $self->{argv}{sql_save};
1873 2   100     12 $self->{argv}{sql_save} = shift || 0;
1874 2         4 return $save;
1875             }
1876              
1877             ################################################################################
1878             ## action: set quote character
1879             ## return: old quote chacracter
1880              
1881             sub setQuote()
1882             {
1883 0     0 0 0 my $self = shift;
1884 0         0 my $quote = shift;
1885 0         0 my $save = $self->{argv}{quote};
1886 0 0 0     0 $self->{argv}{quote} = $quote || "'" if ($quote eq "" || $quote eq '"' || $quote eq "'");
      0        
      0        
1887 0         0 return $save;
1888             }
1889              
1890             ################################################################################
1891             ## action: set message state
1892             ## return: return code
1893              
1894             sub setMessage()
1895             {
1896 1     1 0 2 my $self = shift;
1897 1         12 my $command = shift;
1898 1         3 my $rc = shift;
1899 1         1 my $code = shift;
1900 1         3 my @argv = @_;
1901              
1902 1 50       5 if (!defined($rc))
1903             {
1904 1 50 33     17 return $self->setMessage($command,$self->{init}{dbh}->err+0,"099",$self->{init}{dbh}->errstr()) if (defined($self->{init}{dbh}) && $self->{init}{dbh}->err);
1905 1 50       8 return $self->setMessage($command,$DBI::err+0,"099",$DBI::errstr) if ($DBI::err);
1906              
1907 1         11 $err = 0;
1908 1         2 $errstr = "";
1909 1         3 return $err;
1910             }
1911              
1912 0           $err = $rc;
1913             $errstr = (defined($SQL_SIMPLE_TABLE_OF_MSGS{$code})) ?
1914 0 0         $code.$SQL_SIMPLE_TABLE_OF_MSGS{$code}{T}." ".sprintf($SQL_SIMPLE_TABLE_OF_MSGS{$code}{M},$command,@argv) :
1915             "999S [message] invalid message code '$code'";
1916              
1917 0 0         if ($self->{argv}{message_log})
1918             {
1919 0 0         print STDERR $errstr."\n" if ($self->{argv}{message_log} & SQL_SIMPLE_LOG_STD);
1920              
1921 0 0         if ($self->{argv}{message_log} & SQL_SIMPLE_LOG_SYS)
1922             {
1923 0           require Sys::Syslog;
1924 0   0       openlog($self->{argv}{message_syslog_service} || "SQL-SimpleOps", "ndelay,pid", $self->{argv}{message_syslog_facility} || "local0");
      0        
1925             syslog(
1926             ($SQL_SIMPLE_TABLE_OF_MSGS{$code}{T} eq "E") ? "error" :
1927             ($SQL_SIMPLE_TABLE_OF_MSGS{$code}{T} eq "S") ? "error" :
1928 0 0         ($SQL_SIMPLE_TABLE_OF_MSGS{$code}{T} eq "W") ? "warning" :
    0          
    0          
1929             "info",
1930             $errstr
1931             );
1932 0           closelog();
1933             }
1934             }
1935 0           return $err;
1936             }
1937              
1938             __END__