blib/lib/JLdap.pm | |||
---|---|---|---|
Criterion | Covered | Total | % |
statement | 9 | 687 | 1.3 |
branch | 0 | 232 | 0.0 |
condition | 0 | 51 | 0.0 |
subroutine | 3 | 27 | 11.1 |
pod | 0 | 24 | 0.0 |
total | 12 | 1021 | 1.1 |
line | stmt | bran | cond | sub | pod | time | code |
---|---|---|---|---|---|---|---|
1 | #!/usr/bin/perl | ||||||
2 | |||||||
3 | package JLdap; | ||||||
4 | |||||||
5 | require 5.002; | ||||||
6 | |||||||
7 | 1 | 1 | 438 | use Net::LDAP::Entry; | |||
1 | 2783 | ||||||
1 | 31 | ||||||
8 | 1 | 1 | 7 | no warnings qw (uninitialized); | |||
1 | 6 | ||||||
1 | 44 | ||||||
9 | |||||||
10 | #use Fcntl; | ||||||
11 | |||||||
12 | ##++ | ||||||
13 | ## Global Variables. Declare lock constants manually, instead of | ||||||
14 | ## importing them from Fcntl. | ||||||
15 | ## | ||||||
16 | 1 | 1 | 6 | use vars qw ($VERSION); | |||
1 | 1 | ||||||
1 | 9137 | ||||||
17 | ##-- | ||||||
18 | |||||||
19 | $JLdap::VERSION = '0.24'; | ||||||
20 | |||||||
21 | #my $NUMERICTYPES = '^(NUMBER|FLOAT|DOUBLE|INT|INTEGER|NUM)$'; #20000224 | ||||||
22 | #my $STRINGTYPES = '^(VARCHAR|CHAR|VARCHAR|DATE|LONG|BLOB|MEMO)$'; | ||||||
23 | |||||||
24 | ##++ | ||||||
25 | ## Public Methods and Constructor | ||||||
26 | ##-- | ||||||
27 | |||||||
28 | sub new | ||||||
29 | { | ||||||
30 | 0 | 0 | 0 | my $class = shift; | |||
31 | 0 | my $self; | |||||
32 | |||||||
33 | 0 | $self = { | |||||
34 | commands => 'select|update|delete|alter|insert|create|drop|primary_key_info', | ||||||
35 | column => '[A-Za-z0-9\~\x80-\xFF][\w\x80-\xFF]+', | ||||||
36 | _select => '[\w\x80-\xFF\*,\s\~]+', | ||||||
37 | path => '[\w\x80-\xFF\-\/\.\:\~\\\\]+', | ||||||
38 | table => '', | ||||||
39 | timestamp => 0, | ||||||
40 | fields => {}, | ||||||
41 | use_fields => '', | ||||||
42 | key_fields => '', | ||||||
43 | order => [], | ||||||
44 | types => {}, | ||||||
45 | lengths => {}, | ||||||
46 | scales => {}, | ||||||
47 | defaults => {}, | ||||||
48 | records => [], | ||||||
49 | errors => {}, | ||||||
50 | lasterror => 0, #JWT: ADDED FOR ERROR-CONTROL | ||||||
51 | lastmsg => '', | ||||||
52 | CaseTableNames => 0, #JWT: 19990991 TABLE-NAME CASE-SENSITIVITY? | ||||||
53 | LongTruncOk => 0, #JWT: 19991104: ERROR OR NOT IF TRUNCATION. | ||||||
54 | RaiseError => 0, #JWT: 20000114: ADDED DBI RAISEERROR HANDLING. | ||||||
55 | silent => 0, | ||||||
56 | ldap_dbh => 0, | ||||||
57 | ldap_sizelimit => 0, #JWT: LIMIT #RECORDS FETCHED, IF SET. | ||||||
58 | ldap_timelimit => 0, #JWT: LIMIT #RECORDS FETCHED, IF SET. | ||||||
59 | ldap_deref => 0, #JWT: LIMIT #RECORDS FETCHED, IF SET. | ||||||
60 | ldap_typesonly => 0, | ||||||
61 | ldap_callback => 0, | ||||||
62 | ldap_scope => 0, | ||||||
63 | ldap_inseparator => '|', | ||||||
64 | ldap_outseparator => '|', | ||||||
65 | ldap_firstonly => 0, | ||||||
66 | ldap_nullsearchvalue => ' ', #ADDED 20040330 TO FOR BACKWARD COMPATABILITY. | ||||||
67 | ldap_appendbase2ins => 0, #ADDED 20060719 FOR BACKWARD COMPAT. - 0.08+ NO LONGER APPENDS BASE TO ALWAYSINSERT PER REQUEST. | ||||||
68 | dirty => 0, #JWT: 20000229: PREVENT NEEDLESS RECOMMITS. | ||||||
69 | tindx => 0 #REPLACES GLOBAL VARIABLE. | ||||||
70 | }; | ||||||
71 | |||||||
72 | 0 | bless $self, $class; | |||||
73 | |||||||
74 | 0 | for (my $i=0;$i | |||||
75 | { | ||||||
76 | 0 | $self->{$_[$i]} = $_[$i+1]; | |||||
77 | } | ||||||
78 | |||||||
79 | 0 | $self->initialize; | |||||
80 | 0 | return $self; | |||||
81 | } | ||||||
82 | sub initialize | ||||||
83 | { | ||||||
84 | 0 | 0 | 0 | my $self = shift; | |||
85 | |||||||
86 | 0 | $self->define_errors; | |||||
87 | } | ||||||
88 | |||||||
89 | sub sql | ||||||
90 | { | ||||||
91 | 0 | 0 | 0 | my ($self, $csr, $query) = @_; | |||
92 | |||||||
93 | 0 | my ($command, $status, $base, $fields); | |||||
94 | #print STDERR "-sql1($command,$status,$base,$fields)"; | ||||||
95 | 0 | 0 | return wantarray ? () : -514 unless ($query); | ||||
0 | |||||||
96 | 0 | $self->{lasterror} = 0; | |||||
97 | 0 | $self->{lastmsg} = ''; | |||||
98 | 0 | $query =~ s/\n/ /gso; | |||||
99 | 0 | $query =~ s/^\s*(.*?)\s*$/$1/; | |||||
100 | 0 | 0 | $query = 'select tables' if ($query =~ /^show\s+tables$/i); | ||||
101 | 0 | 0 | $query = 'select tables' if ($query =~ /^select\s+TABLE_NAME\s+from\s+USER_TABLES$/i); #ORACLE-COMPATABILITY. | ||||
102 | 0 | $command = ''; | |||||
103 | |||||||
104 | 0 | 0 | if ($query =~ /^($self->{commands})/io) | ||||
105 | { | ||||||
106 | 0 | $command = $1; | |||||
107 | 0 | $command =~ tr/A-Z/a-z/; #ADDED 19991202! | |||||
108 | 0 | $status = $self->$command ($csr, $query); | |||||
109 | 0 | 0 | if (!defined($status)) #NEXT 5 ADDED PER PATCH REQUEST 20091101: | ||||
0 | |||||||
110 | { | ||||||
111 | 0 | $self->display_error(-599); | |||||
112 | 0 | 0 | return wantarray ? () : -599; | ||||
113 | } | ||||||
114 | elsif (ref ($status) eq 'ARRAY') #SELECT RETURNED OK (LIST OF RECORDS). | ||||||
115 | { | ||||||
116 | 0 | 0 | return wantarray ? @$status : $status; | ||||
117 | } | ||||||
118 | else | ||||||
119 | { | ||||||
120 | 0 | 0 | if ($status < 0) | ||||
121 | { #SQL RETURNED AN ERROR! | ||||||
122 | #print STDERR "-sql6 status=$status=\n"; | ||||||
123 | 0 | $self->display_error ($status); | |||||
124 | #return ($status); | ||||||
125 | 0 | 0 | return wantarray ? () : $status; | ||||
126 | } | ||||||
127 | else | ||||||
128 | { #SQL RETURNED OK. | ||||||
129 | #print STDERR "-sql7 status=$status= at=$@= cash=$_= bang=$!= query=$?=\n"; | ||||||
130 | 0 | 0 | return wantarray ? ($status) : $status; | ||||
131 | } | ||||||
132 | } | ||||||
133 | } | ||||||
134 | else | ||||||
135 | { | ||||||
136 | 0 | 0 | return wantarray ? () : -514; | ||||
137 | } | ||||||
138 | } | ||||||
139 | |||||||
140 | sub select | ||||||
141 | { | ||||||
142 | 0 | 0 | 0 | my ($self, $csr, $query) = @_; | |||
143 | |||||||
144 | 0 | my (@ordercols) = (); | |||||
145 | 0 | $regex = $self->{_select}; | |||||
146 | 0 | $path = $self->{path}; | |||||
147 | 0 | my (@rtnvals) = (); | |||||
148 | |||||||
149 | 0 | my $distinct; | |||||
150 | 0 | 0 | $distinct = 1 if ($query =~ s/select\s+distinct(\s+\w|\s*\(|\s+\*)/select $1/i); | ||||
151 | 0 | my ($dbh) = $csr->FETCH('ldap_dbh'); | |||||
152 | 0 | my ($tablehash); | |||||
153 | |||||||
154 | 0 | 0 | if ($query =~ /^select tables$/io) | ||||
0 | |||||||
155 | { | ||||||
156 | 0 | $tablehash = $dbh->FETCH('ldap_tablenames'); | |||||
157 | 0 | $self->{use_fields} = 'TABLE_NAME'; #ADDED 20000224 FOR DBI! | |||||
158 | 0 | $values_or_error = []; | |||||
159 | 0 | for ($i=0;$i<=$#{$tablehash};$i++) | |||||
0 | |||||||
160 | { | ||||||
161 | 0 | push (@$values_or_error,[$tablehash->[$i]]); | |||||
162 | } | ||||||
163 | 0 | unshift (@$values_or_error, ($#{$tablehash}+1)); | |||||
0 | |||||||
164 | 0 | return $values_or_error; | |||||
165 | } | ||||||
166 | elsif ($query =~ /^select\s+ # Keyword | ||||||
167 | ($regex)\s+ # Columns | ||||||
168 | from\s+ # 'from' | ||||||
169 | ($path)(.*)$/iox) | ||||||
170 | { | ||||||
171 | 0 | ($attbs, $table, $extra) = ($1, $2, $3); | |||||
172 | |||||||
173 | 0 | 0 | $table =~ tr/A-Z/a-z/ unless ($self->{CaseTableNames}); #JWT:TABLE-NAMES ARE NOW CASE-INSENSITIVE! | ||||
174 | 0 | $self->{file} = $table; | |||||
175 | 0 | 0 | if ($extra =~ s/([\s|\)]+)order\s+by\s*(.*)/$1/i) | ||||
176 | { | ||||||
177 | 0 | $orderclause = $2; | |||||
178 | 0 | @ordercols = split(/,/,$orderclause); | |||||
179 | 0 | $descorder = ($ordercols[$#ordercols] =~ s/(\w+\W+)desc(?:end|ending)?$/$1/i); #MODIFIED 20000721 TO ALLOW "desc|descend|descending"! | |||||
180 | 0 | for $i (0..$#ordercols) | |||||
181 | { | ||||||
182 | 0 | $ordercols[$i] =~ s/\s//igo; #CASE-INSENSITIVITY ADDED NEXT 2: 20050416 PER PATCH BY jmorano | |||||
183 | 0 | $ordercols[$i] =~ s/[\(\)]+//igo; | |||||
184 | } | ||||||
185 | } | ||||||
186 | 0 | $tablehash = $dbh->FETCH('ldap_tables'); | |||||
187 | 0 | 0 | return (-524) unless ($tablehash->{$table}); | ||||
188 | |||||||
189 | 0 | my ($base, $objfilter, $dnattbs, $allattbs, $alwaysinsert) = split(/\:/o ,$tablehash->{$table}); | |||||
190 | 0 | 0 | 0 | $attbs = $allattbs if ($allattbs && $attbs =~ s/\*//o); | |||
191 | 0 | $attbs =~ s/\s//go; | |||||
192 | 0 | $attbs =~ tr/A-Z/a-z/; | |||||
193 | 0 | 0 | @{$self->{order}} = split(/,/o, $attbs) unless ($attbs eq '*'); | ||||
0 | |||||||
194 | 0 | my $fieldnamehash = (); | |||||
195 | 0 | my $attbcnt = 0; | |||||
196 | 0 | foreach my $i (@{$self->{order}}) | |||||
0 | |||||||
197 | { | ||||||
198 | 0 | $fieldnamehash{$i} = $attbcnt++; | |||||
199 | } | ||||||
200 | 0 | my ($ldap) = $csr->FETCH('ldap_ldap'); | |||||
201 | 0 | 0 | $objfilter ||= 'objectclass=*'; | ||||
202 | 0 | 0 | $objfilter = "($objfilter)" unless ($objfilter =~ /^\(/o); | ||||
203 | #print " -where=$extra=\n"; |
||||||
204 | 0 | 0 | if ($extra =~ /^\s+where\s*(.+)$/io) | ||||
205 | { | ||||||
206 | 0 | $filter = $self->parse_expression($1); | |||||
207 | 0 | 0 | $filter = '('.$filter.')' unless ($filter =~ /^\(/o); | ||||
208 | 0 | $filter = "(&$objfilter$filter)"; | |||||
209 | } | ||||||
210 | else | ||||||
211 | { | ||||||
212 | 0 | $filter = $objfilter; | |||||
213 | } | ||||||
214 | #print " -filter =$filter=\n"; |
||||||
215 | 0 | my $data; | |||||
216 | 0 | my (@searchops) = ( | |||||
217 | 'base' => $base, | ||||||
218 | 'filter' => $filter, | ||||||
219 | 'attrs' => [split(/\,/o, $attbs)] | ||||||
220 | ); | ||||||
221 | 0 | foreach my $i (qw(ldap_sizelimit ldap_timelimit deref typesonly | |||||
222 | callback)) | ||||||
223 | { | ||||||
224 | 0 | $j = $i; | |||||
225 | 0 | $j =~ s/^ldap_//o; | |||||
226 | 0 | 0 | push (@searchops, ($j, $self->{$i})) if ($self->{$i}); | ||||
227 | } | ||||||
228 | 0 | 0 | push (@searchops, ('scope', ($self->{ldap_scope} || 'one'))); | ||||
229 | #print "--- ATTBS =$attbs=\n"; | ||||||
230 | #print "--- SEARCH OPS =".join('|',@searchops)."=\n"; | ||||||
231 | 0 | 0 | $data = $ldap->search(@searchops) | ||||
232 | or return($self->ldap_error($@,"Search failed to return object: filter=$filter (".$data->error().")")); | ||||||
233 | #print "--- data=$data=\n"; | ||||||
234 | 0 | my ($j) = 0; | |||||
235 | 0 | my (@varlist) = (); | |||||
236 | 0 | while (my $entry = $data->shift_entry()) | |||||
237 | { | ||||||
238 | 0 | $dn = $entry->dn(); | |||||
239 | 0 | 0 | next unless ($dn =~ /$base$/i); #CASE-INSENSITIVITY ADDED NEXT 2: 20050416 PER PATCH BY jmorano | ||||
240 | 0 | @attributes = $entry->attributes; | |||||
241 | 0 | 0 | unless ($attbcnt) | ||||
242 | { | ||||||
243 | 0 | $attbs = join(',',@attributes); | |||||
244 | 0 | $attbcnt = 0; | |||||
245 | 0 | @{$self->{order}} = @attributes; | |||||
0 | |||||||
246 | 0 | foreach my $i (@{$self->{order}}) | |||||
0 | |||||||
247 | { | ||||||
248 | 0 | $fieldnamehash{$i} = $attbcnt++; | |||||
249 | } | ||||||
250 | } | ||||||
251 | 0 | $varlist[$j] = []; | |||||
252 | 0 | for (my $i=0;$i<$attbcnt;$i++) | |||||
253 | { | ||||||
254 | 0 | $varlist[$j][$i] = ''; | |||||
255 | } | ||||||
256 | 0 | $i = 0; | |||||
257 | 0 | foreach my $attr (@{$self->{order}}) | |||||
0 | |||||||
258 | { | ||||||
259 | # $valuesref = $entry->get($attr); #CHGD. TO NEXT PER PATCH REQUEST 20091101: | ||||||
260 | 0 | $valuesref = $entry->get_value($attr, asref => 1); | |||||
261 | 0 | 0 | 0 | if ($self->{ldap_firstonly} && $self->{ldap_firstonly} <= scalar (@{$valuesref})) | |||
0 | |||||||
262 | { | ||||||
263 | #$varlist[$j][$fieldnamehash{$attr}] = join($self->{ldap_outseparator}, $valuesref->[0]); #CHGD. 20010829 TO NEXT. | ||||||
264 | 0 | $varlist[$j][$fieldnamehash{$attr}] = join($self->{ldap_outseparator}, @{$valuesref}[0..($self->{ldap_firstonly}-1)]); | |||||
0 | |||||||
265 | } | ||||||
266 | else | ||||||
267 | { | ||||||
268 | 0 | 0 | $varlist[$j][$fieldnamehash{$attr}] = join($self->{ldap_outseparator}, @$valuesref) || ''; | ||||
269 | } | ||||||
270 | 0 | 0 | unless ($valuesref[0]) | ||||
271 | { | ||||||
272 | 0 | 0 | $varlist[$j][$fieldnamehash{dn}] = $dn if ($attr eq 'dn'); | ||||
273 | } | ||||||
274 | 0 | $i++; | |||||
275 | } | ||||||
276 | 0 | ++$j; | |||||
277 | } | ||||||
278 | 0 | $self->{use_fields} = $attbs; | |||||
279 | 0 | 0 | if ($distinct) #THIS MAKES "DISTINCT" WORK. | ||||
280 | { | ||||||
281 | 0 | my (%disthash); | |||||
282 | 0 | for (my $i=0;$i<=$#varlist;$i++) | |||||
283 | { | ||||||
284 | 0 | ++$disthash{join("\x02",@{$varlist[$i]})}; | |||||
0 | |||||||
285 | } | ||||||
286 | 0 | @varlist = (); | |||||
287 | 0 | foreach my $i (keys(%disthash)) | |||||
288 | { | ||||||
289 | 0 | push (@varlist, [split(/\x02/o, $i, -1)]); | |||||
290 | } | ||||||
291 | } | ||||||
292 | 0 | 0 | if ($#ordercols >= 0) #SORT 'EM! | ||||
293 | { | ||||||
294 | 0 | my @SV; | |||||
295 | 0 | for (my $i=0;$i<=$#varlist;$i++) | |||||
296 | { | ||||||
297 | 0 | $SV[$i] = ''; | |||||
298 | 0 | foreach my $j (@ordercols) | |||||
299 | { | ||||||
300 | 0 | $SV[$i] .= $varlist[$i][$fieldnamehash{$j}] . "\x01"; | |||||
301 | } | ||||||
302 | } | ||||||
303 | 0 | @sortvector = &sort_elements(\@SV); | |||||
304 | 0 | 0 | @sortvector = reverse(@sortvector) if ($descorder); | ||||
305 | 0 | @SV = (); | |||||
306 | 0 | while (@sortvector) | |||||
307 | { | ||||||
308 | 0 | push (@SV, $varlist[shift(@sortvector)]); | |||||
309 | } | ||||||
310 | 0 | @varlist = @SV; | |||||
311 | 0 | @SV = (); | |||||
312 | } | ||||||
313 | 0 | return [($#attributes+1), @varlist]; | |||||
314 | } | ||||||
315 | else #INVALID SELECT STATEMENT! | ||||||
316 | { | ||||||
317 | 0 | return (-503); | |||||
318 | } | ||||||
319 | } | ||||||
320 | |||||||
321 | sub sort_elements | ||||||
322 | { | ||||||
323 | 0 | 0 | 0 | my (@elements, $line, @sortlist, @sortedlist, $j, $t, $argcnt, $linedata, | |||
324 | $vectorid, @sortvector); | ||||||
325 | |||||||
326 | 0 | my ($lo) = 0; | |||||
327 | 0 | my ($hi) = 0; | |||||
328 | 0 | 0 | $lo = shift unless (ref($_[0])); | ||||
329 | 0 | 0 | $hi = shift unless (ref($_[0])); | ||||
330 | |||||||
331 | 0 | 0 | 0 | if ($lo || $hi) | |||
332 | { | ||||||
333 | 0 | for ($j=0;$j<=$#{$_[0]};$j++) | |||||
0 | |||||||
334 | { | ||||||
335 | 0 | $sortvector[$j] = $j; | |||||
336 | } | ||||||
337 | } | ||||||
338 | 0 | 0 | $hi ||= $#{$_[0]}; | ||||
0 | |||||||
339 | 0 | $argcnt = scalar(@_); | |||||
340 | 0 | for (my $i=$lo;$i<=$hi;$i++) | |||||
341 | { | ||||||
342 | 0 | $line = $_[0][$i]; | |||||
343 | 0 | for ($j=1;$j<$argcnt;$j++) | |||||
344 | { | ||||||
345 | 0 | $line .= "\x02" . $_[$j][$i]; | |||||
346 | } | ||||||
347 | 0 | $line .= "\x04".$i; | |||||
348 | 0 | push (@sortlist, $line); | |||||
349 | } | ||||||
350 | |||||||
351 | 0 | @sortedlist = sort @sortlist; | |||||
352 | 0 | $i = $lo; | |||||
353 | 0 | foreach $line (@sortedlist) | |||||
354 | { | ||||||
355 | 0 | ($linedata,$vectorid) = split(/\x04/o, $line); | |||||
356 | 0 | (@elements) = split(/\x02/o, $linedata); | |||||
357 | 0 | 0 | $t = $#elements unless $t; | ||||
358 | 0 | for ($j=$t;$j>=1;$j--) | |||||
359 | { | ||||||
360 | #push (@{$_[$j]}, $elements[$j]); | ||||||
361 | 0 | ${$_[$j]}[$i] = $elements[$j]; | |||||
0 | |||||||
362 | } | ||||||
363 | 0 | $sortvector[$i] = $vectorid; | |||||
364 | 0 | $elements[0] =~ s/\s+//go; | |||||
365 | 0 | ${$_[0]}[$i] = $elements[$j]; | |||||
0 | |||||||
366 | 0 | ++$i; | |||||
367 | } | ||||||
368 | 0 | return @sortvector; | |||||
369 | } | ||||||
370 | |||||||
371 | sub ldap_error | ||||||
372 | { | ||||||
373 | 0 | 0 | 0 | my ($self,$errcode,$errmsg,$warn) = @_; | |||
374 | |||||||
375 | 0 | 0 | $err = $errcode || -1; | ||||
376 | 0 | $errdetails = $errmsg; | |||||
377 | 0 | 0 | $err = -1 * $err if ($err > 0); | ||||
378 | 0 | 0 | 0 | return ($err) unless (defined($warn) && $warn); | |||
379 | |||||||
380 | # print "Content-type: text/html\nWindow-target: _parent", "\n\n" | ||||||
381 | # if (defined($warn) && $warn == 1); | ||||||
382 | |||||||
383 | 0 | return ($self->display_error($errcode)); | |||||
384 | } | ||||||
385 | |||||||
386 | sub display_error | ||||||
387 | { | ||||||
388 | 0 | 0 | 0 | my ($self, $error) = @_; | |||
389 | |||||||
390 | 0 | 0 | $other = $@ || $! || 'None'; | ||||
391 | |||||||
392 | 0 | 0 | print STDERR < |
||||
393 | |||||||
394 | Oops! The following error occurred when processing your request: | ||||||
395 | |||||||
396 | $self->{errors}->{$error} ($errdetails) | ||||||
397 | |||||||
398 | Here's some more information to help you: | ||||||
399 | |||||||
400 | file: $self->{file} | ||||||
401 | $other | ||||||
402 | |||||||
403 | Error_Message | ||||||
404 | |||||||
405 | #JWT: ADDED FOR ERROR-CONTROL. | ||||||
406 | |||||||
407 | 0 | $self->{lasterror} = $error; | |||||
408 | 0 | $self->{lastmsg} = "$error:" . $self->{errors}->{$error}; | |||||
409 | 0 | 0 | $self->{lastmsg} .= '('.$errdetails.')' if ($errdetails); #20000114 | ||||
410 | |||||||
411 | 0 | $errdetails = ''; #20000114 | |||||
412 | 0 | 0 | die $self->{lastmsg} if ($self->{RaiseError}); #20000114. | ||||
413 | |||||||
414 | #return (1); | ||||||
415 | 0 | return ($error); | |||||
416 | } | ||||||
417 | |||||||
418 | sub commit | ||||||
419 | { | ||||||
420 | 0 | 0 | 0 | my ($self) = @_; | |||
421 | 0 | my ($status) = 1; | |||||
422 | 0 | my ($dbh) = $self->FETCH('ldap_dbh'); | |||||
423 | 0 | my ($autocommit) = $dbh->FETCH('AutoCommit'); | |||||
424 | |||||||
425 | 0 | 0 | $status = $dbh->commit() unless ($autocommit); | ||||
426 | |||||||
427 | 0 | 0 | $self->{dirty} = 0 if ($status > 0); | ||||
428 | 0 | 0 | return undef if ($status <= 0); #ADDED 20000103 | ||||
429 | 0 | return $status; | |||||
430 | } | ||||||
431 | |||||||
432 | ##++ | ||||||
433 | ## Private Methods | ||||||
434 | ##-- | ||||||
435 | |||||||
436 | sub define_errors | ||||||
437 | { | ||||||
438 | 0 | 0 | 0 | my $self = shift; | |||
439 | 0 | my $errors; | |||||
440 | |||||||
441 | 0 | $errors = {}; | |||||
442 | |||||||
443 | 0 | $errors->{'-501'} = 'Could not open specified database.'; | |||||
444 | 0 | $errors->{'-502'} = 'Specified column(s) not found.'; | |||||
445 | 0 | $errors->{'-503'} = 'Incorrect format in [select] statement.'; | |||||
446 | 0 | $errors->{'-504'} = 'Incorrect format in [update] statement.'; | |||||
447 | 0 | $errors->{'-505'} = 'Incorrect format in [delete] statement.'; | |||||
448 | 0 | $errors->{'-506'} = 'Incorrect format in [add/drop column] statement.'; | |||||
449 | 0 | $errors->{'-507'} = 'Incorrect format in [alter table] statement.'; | |||||
450 | 0 | $errors->{'-508'} = 'Incorrect format in [insert] command.'; | |||||
451 | 0 | $errors->{'-509'} = 'The no. of columns does not match no. of values.'; | |||||
452 | 0 | $errors->{'-510'} = 'A severe error! Check your query carefully.'; | |||||
453 | 0 | $errors->{'-511'} = 'Cannot write the database to output file.'; | |||||
454 | 0 | $errors->{'-512'} = 'Unmatched quote in expression.'; | |||||
455 | 0 | $errors->{'-513'} = 'Need to open the database first!'; | |||||
456 | 0 | $errors->{'-514'} = 'Please specify a valid query.'; | |||||
457 | # $errors->{'-515'} = 'Cannot get lock on database file.'; | ||||||
458 | # $errors->{'-516'} = 'Cannot delete temp. lock file.'; | ||||||
459 | 0 | $errors->{'-517'} = "Built-in function failed ($@)."; | |||||
460 | 0 | $errors->{'-518'} = "Unique Key Constraint violated."; #JWT. | |||||
461 | 0 | $errors->{'-519'} = "Field would have to be truncated."; #JWT. | |||||
462 | 0 | $errors->{'-520'} = "Can not create existing table (drop first!)."; #20000225 JWT. | |||||
463 | 0 | $errors->{'-521'} = "Can not change datatype on non-empty table."; #20000323 JWT. | |||||
464 | 0 | $errors->{'-522'} = "Can not decrease field-size on non-empty table."; #20000323 JWT. | |||||
465 | 0 | $errors->{'-523'} = "Update Failed to commit changes."; #20000323 JWT. | |||||
466 | 0 | $errors->{'-524'} = "No such table."; #20000323 JWT. | |||||
467 | 0 | $errors->{'-599'} = 'General error.'; | |||||
468 | |||||||
469 | 0 | $self->{errors} = $errors; | |||||
470 | |||||||
471 | 0 | return (1); | |||||
472 | } | ||||||
473 | |||||||
474 | sub parse_expression | ||||||
475 | { | ||||||
476 | 0 | 0 | 0 | my ($self, $s) = @_; | |||
477 | |||||||
478 | 0 | $s =~ s/\s+$//o; #STRIP OFF LEADING AND TRAILING WHITESPACE. | |||||
479 | 0 | $s =~ s/^\s+//o; | |||||
480 | 0 | 0 | return unless ($s); | ||||
481 | |||||||
482 | |||||||
483 | 0 | my $relop = '(?:<|=|>|<=|>=|!=|like|not\s+like|is\s+not|is)'; | |||||
484 | 0 | my %boolopsym = ('and' => '&', 'or' => '|'); | |||||
485 | |||||||
486 | 0 | my $indx = 0; | |||||
487 | |||||||
488 | 0 | my @P = (); | |||||
489 | 0 | my @T3 = (); #PROTECTS MULTI-WAY RELOP EXPRESSIONS, IE. (A AND B AND C) | |||||
490 | 0 | my $t3indx = 0; | |||||
491 | 0 | @T = (); | |||||
492 | 0 | my @QS = (); | |||||
493 | |||||||
494 | 0 | $s=~s|\\\'|\x04|go; #PROTECT "\'" IN QUOTES. | |||||
495 | 0 | $s=~s|\\\"|\x02|go; #PROTECT "\"" IN QUOTES. | |||||
496 | |||||||
497 | #THIS NEXT LOOP STRIPS OUT AND SAVES ALL QUOTED STRING LITERALS | ||||||
498 | #TO PREVENT THEM FROM INTERFEARING WITH OTHER REGICES, IE. DON'T | ||||||
499 | #WANT OPERATORS IN STRINGS TO BE TREATED AS OPERATORS! | ||||||
500 | |||||||
501 | 0 | $indx++ while ($s =~ s/([\'\"])([^\1]*?)\1/ | |||||
502 | 0 | $QS[$indx] = $2; "\$QS\[$indx]"/e); | |||||
0 | |||||||
503 | |||||||
504 | 0 | for (my $i=0;$i<=$#QS;$i++) #ESCAPE LDAP SPECIAL-CHARACTERS. | |||||
505 | { | ||||||
506 | 0 | $QS[$i] =~ s/\\x([\da-fA-F][\da-fA-F])/\x05$1/g; #PROTECT PERL HEX TO LDAP HEX (\X## => \##). | |||||
507 | #$QS[$i] =~ s/([\*\(\)\+\\\<\>])/\\$1/g; #CHGD. TO NEXT. 20020409! | ||||||
508 | 0 | $QS[$i] =~ s/([\*\(\)\\])/"\\".unpack('H2',$1)/eg; | |||||
0 | |||||||
509 | #$QS[$i] =~ s/\\x(\d\d)/\\$1/g; #CONVERT PERL HEX TO LDAP HEX (\X## => \##). | ||||||
510 | 0 | $QS[$i] =~ s/\x05([\da-fA-F][\da-fA-F])/\\$1/go; #CONVERT PERL HEX TO LDAP HEX (\X## => \##). | |||||
511 | } | ||||||
512 | #print STDERR "-parse_expression: QS list=".join('|',@QS)."= SSSS=$s=\n"; | ||||||
513 | 0 | $indx = 0; | |||||
514 | |||||||
515 | #I TRIED TO ALLOWING ATTRIBUTES TO BE COMPARED W/OTHER ATTRIBUTES, BUT | ||||||
516 | #(20020409), BUT APPARENTLY LDAP ONLY ALLOWS STRING CONSTANTS ON RHS OF OPERATORS! | ||||||
517 | |||||||
518 | # $indx++ while ($s =~ s/(\w+)\s*($relop)\s*(\$QS\[\d*\]|\w+)/ #THIS WAS TRIED TO COMPARE ATTRIBUTES WITH ATTRIBUTES, BUT APPARENTLY DOESN'T WORK IN LDAP! | ||||||
519 | 0 | $indx++ while ($s =~ s/(\w+)\s*($relop)\s*(\$QS\[\d*\])/ | |||||
520 | 0 | my ($one, $two, $three) = ($1, $2, $3); | |||||
521 | 0 | my ($regex) = 0; | |||||
522 | 0 | my ($opr) = $two; | |||||
523 | #CONVERT "NOT LIKE" AND "IS NOT" TO "!( = ). | ||||||
524 | |||||||
525 | 0 | 0 | if ($two =~ m!(?:not\s+like|is\s+not)!io) | ||||
0 | |||||||
526 | { | ||||||
527 | 0 | $two = '='; | |||||
528 | 0 | $regex = 2; | |||||
529 | } | ||||||
530 | elsif ($two =~ m!(?:like|is)!io) #CONVERT "LIKE" AND "IS" TO "=". | ||||||
531 | { | ||||||
532 | 0 | $two = '='; | |||||
533 | 0 | $regex = 1; | |||||
534 | } | ||||||
535 | 0 | $P[$indx] = $one.$two.$three; #SAVE EXPRESSION. | |||||
536 | |||||||
537 | #CONVERT SQL WILDCARDS INTO LDAP WILDCARDS IN OPERAND. | ||||||
538 | |||||||
539 | 0 | my ($qsindx); | |||||
540 | 0 | 0 | if ($three =~ m!\$QS\[(\d+)\]!) | ||||
541 | { | ||||||
542 | 0 | $qsindx = $1; | |||||
543 | 0 | 0 | if ($regex > 0) | ||||
544 | { | ||||||
545 | 0 | 0 | if ($opr !~ m!is!io) | ||||
546 | { | ||||||
547 | 0 | $QS[$qsindx] =~ s!\%!\*!go; #FIX WILDCARD. NOTE - NO FIX FOR "_"! | |||||
548 | } | ||||||
549 | } | ||||||
550 | 0 | 0 | $QS[$qsindx] = $self->{ldap_nullsearchvalue} unless (length($QS[$qsindx])); | ||||
551 | } | ||||||
552 | 0 | 0 | 0 | $P[$indx] = "!($P[$indx])" if ($regex == 2 || $opr eq '!=' || ($opr eq '=' && !length($QS[$qsindx]))); #INVERT EXPRESSION IF "NOT"! | |||
0 | |||||||
0 | |||||||
553 | 0 | $P[$indx] =~ s!\!\=!\=!o; #AFTER INVERSION, FIX "!=" (NOT VALID IN LDAP!) | |||||
554 | 0 | "\$P\[$indx]"; | |||||
555 | /ei); #CASE-INSENSITIVITY ADDED NEXT 2: 20050416 PER PATCH BY jmorano | ||||||
556 | 0 | $self->{tindx} = 0; | |||||
557 | 0 | $s = &parseParins($self, $s); | |||||
558 | |||||||
559 | 0 | for (my $i=0;$i<=$#T;$i++) | |||||
560 | { | ||||||
561 | # 1 while ($T[$i] =~ s/(.+?)\s*\band\b\s*(.+)/\&\($1\)\($2\)/i); | ||||||
562 | 0 | 1 while ($T[$i] =~ s/([^\(\)]+)\s*\band\b\s*([^\(\)]+)(?:and|or)?/\&\($1\)\($2\)/i); | |||||
563 | 0 | 1 while ($T[$i] =~ s/([^\(\)]+)\s*\bor\b\s*([^\(\)]+)(?:and|or)?/\|\($1\)\($2\)/i); | |||||
564 | } | ||||||
565 | 0 | $s =~ s/AND/and/igo; | |||||
566 | 0 | $s =~ s/OR/or/igo; | |||||
567 | # 1 while ($s =~ s/(.+?)\s*\band\b\s*(.+)/\(\&\($1\)\($2\)\)/i); #CASE-INSENSITIVITY ADDED NEXT 2: 20050416 PER PATCH BY jmorano | ||||||
568 | 0 | 1 while ($s =~ s/([^\(\)]+)\s*\band\b\s*([^\(\)]+)(?:and|or)?/\&\($1\)\($2\)/i); #CASE-INSENSITIVITY ADDED NEXT 2: 20050416 PER PATCH BY jmorano | |||||
569 | 0 | 1 while ($s =~ s/([^\(\)]+)\s*\bor\b\s*([^\(\)]+)(?:and|or)?/\|\($1\)\($2\)/i); #CASE-INSENSITIVITY ADDED NEXT 2: 20050416 PER PATCH BY jmorano | |||||
570 | 0 | 1 while ($s =~ s/\bnot\b\s*([^\s\)]+)?/\!\($1\)/); | |||||
571 | 0 | 1 while ($s =~ s/\$T\[(\d+)\]/$T[$1]/g); | |||||
572 | 0 | $s =~ s/(\w+)\s+is\s+not\s+null?/$1\=\*/gi; | |||||
573 | 0 | $s =~ s/(\w+)\s+is\s+null?/\!\($1\=\*\)/gi; | |||||
574 | |||||||
575 | #CONVERT SQL WILDCARDS TO PERL REGICES. | ||||||
576 | |||||||
577 | 0 | 1 while ($s =~ s/\$P\[(\d+)\]/$P[$1]/g); | |||||
578 | 0 | $s =~ s/ +//go; | |||||
579 | 0 | 1 while ($s =~ s/\$QS\[(\d+)\]/$QS[$1]/g); | |||||
580 | 0 | $s =~ s/\x04/\'/go; #UNPROTECT AND UNESCAPE QUOTES WITHIN QUOTES. | |||||
581 | 0 | 0 | $s = '(' . $s . ')' unless ($s =~ /^\(/o); | ||||
582 | 0 | return $s; | |||||
583 | } | ||||||
584 | |||||||
585 | sub parseParins | ||||||
586 | { | ||||||
587 | 0 | 0 | 0 | my $self = shift; | |||
588 | 0 | my $s = shift; | |||||
589 | |||||||
590 | 0 | $self->{tindx}++ while ($s =~ s/\(([^\(\)]+)\)/ | |||||
591 | 0 | $T[$self->{tindx}] = &parseParins($self, $1); "\$T\[$self->{tindx}]" | |||||
0 | |||||||
592 | /e); | ||||||
593 | 0 | return $s; | |||||
594 | } | ||||||
595 | |||||||
596 | sub rollback | ||||||
597 | { | ||||||
598 | 0 | 0 | 0 | my ($self) = @_; | |||
599 | |||||||
600 | 0 | my ($status) = 1; | |||||
601 | 0 | my ($dbh) = $self->FETCH('ldap_dbh'); | |||||
602 | 0 | my ($autocommit) = $dbh->FETCH('AutoCommit'); | |||||
603 | |||||||
604 | 0 | 0 | $status = $dbh->rollback() unless ($autocommit); | ||||
605 | |||||||
606 | 0 | 0 | $self->{dirty} = 0 if ($status > 0); | ||||
607 | 0 | return $status; | |||||
608 | } | ||||||
609 | |||||||
610 | sub update | ||||||
611 | { | ||||||
612 | 0 | 0 | 0 | my ($self, $csr, $query) = @_; | |||
613 | 0 | my ($i, $path, $regex, $table, $extra, @attblist, $filter, $all_columns); | |||||
614 | 0 | my $status = 0; | |||||
615 | 0 | my ($psuedocols) = "CURVAL|NEXTVAL|ROWNUM"; | |||||
616 | #print STDERR "-update10 sql=$query=\n"; | ||||||
617 | ##++ | ||||||
618 | ## Hack to allow parenthesis to be escaped! | ||||||
619 | ##-- | ||||||
620 | |||||||
621 | 0 | $query =~ s/\\([()])/sprintf ("%%\0%d: ", ord ($1))/ge; | |||||
0 | |||||||
622 | 0 | $path = $self->{path}; | |||||
623 | 0 | $regex = $self->{column}; | |||||
624 | |||||||
625 | 0 | 0 | if ($query =~ /^update\s+($path)\s+set\s+(.+)$/i) | ||||
626 | { | ||||||
627 | 0 | ($table, $extra) = ($1, $2); | |||||
628 | #print STDERR "-update20: table=$table= extra=$extra=\n"; | ||||||
629 | #ADDED IF-STMT 20010418 TO CATCH | ||||||
630 | #PARENTHESIZED SET-CLAUSES (ILLEGAL IN ORACLE & CAUSE WIERD PARSING ERRORS!) | ||||||
631 | |||||||
632 | 0 | 0 | if ($extra =~ /^\(.+\)\s*where/io) | ||||
633 | { | ||||||
634 | 0 | $errdetails = 'parenthesis around SET clause?'; | |||||
635 | 0 | return (-504); | |||||
636 | } | ||||||
637 | 0 | 0 | $table =~ tr/A-Z/a-z/ unless ($self->{CaseTableNames}); #JWT:TABLE-NAMES ARE NOW CASE-INSENSITIVE! | ||||
638 | 0 | $self->{file} = $table; | |||||
639 | |||||||
640 | 0 | my ($dbh) = $csr->FETCH('ldap_dbh'); | |||||
641 | 0 | my ($ldap) = $csr->FETCH('ldap_ldap'); | |||||
642 | 0 | my ($tablehash) = $dbh->FETCH('ldap_tables'); | |||||
643 | 0 | 0 | return (-524) unless ($tablehash->{$table}); | ||||
644 | 0 | my ($base, $objfilter, $dnattbs, $allattbs, $alwaysinsert) = split(/\:/,$tablehash->{$table}); | |||||
645 | |||||||
646 | 0 | $all_columns = {}; | |||||
647 | |||||||
648 | 0 | $extra =~ s/\\\\/\x02/go; #PROTECT "\\" | |||||
649 | #1$extra =~ s/\'\'/\x03\x03/go; #PROTECT '', AND \'. | ||||||
650 | 0 | $extra =~ s/\\\'/\x03/go; #PROTECT '', AND \'. | |||||
651 | |||||||
652 | 0 | $extra =~ s/^\s+//o; #STRIP OFF SURROUNDING SPACES. | |||||
653 | 0 | $extra =~ s/\s+$//o; | |||||
654 | |||||||
655 | #NOW TEMPORARILY PROTECT COMMAS WITHIN (), IE. FN(ARG1,ARG2). | ||||||
656 | |||||||
657 | 0 | $column = $self->{column}; | |||||
658 | 0 | $extra =~ s/($column\s*\=\s*)\'(.*?)\'(,|$)/ | |||||
659 | 0 | my ($one,$two,$three) = ($1,$2,$3); | |||||
660 | 0 | $two =~ s|\,|\x05|go; | |||||
661 | 0 | $two =~ s|\(|\x06|go; | |||||
662 | 0 | $two =~ s|\)|\x07|go; | |||||
663 | 0 | $one."'".$two."'".$three; | |||||
664 | /eg; | ||||||
665 | |||||||
666 | 0 | 1 while ($extra =~ s/\(([^\(\)]*)\)/ | |||||
667 | 0 | my ($args) = $1; | |||||
668 | 0 | $args =~ s|\,|\x05|go; | |||||
669 | 0 | "\x06$args\x07"; | |||||
670 | /eg); | ||||||
671 | 0 | @expns = split(',',$extra); | |||||
672 | #print STDERR "-update50: extra=$extra= expns=".join('|',@expns)."=\n"; | ||||||
673 | 0 | for ($i=0;$i<=$#expns;$i++) #PROTECT "WHERE" IN QUOTED VALUES. | |||||
674 | { | ||||||
675 | 0 | $expns[$i] =~ s/\x05/\,/go; | |||||
676 | 0 | $expns[$i] =~ s/\x06/\(/go; | |||||
677 | 0 | $expns[$i] =~ s/\x07/\)/go; | |||||
678 | 0 | $expns[$i] =~ s/\=\s*'([^']*?)where([^']*?)'/\='$1\x05$2'/gi; | |||||
679 | 0 | $expns[$i] =~ s/\'(.*?)\'/my ($j)=$1; | |||||
0 | |||||||
680 | 0 | $j=~s|where|\x05|gio; | |||||
681 | 0 | "'$j'" | |||||
682 | /eg; | ||||||
683 | } | ||||||
684 | 0 | $extra = $expns[$#expns]; #EXTRACT WHERE-CLAUSE, IF ANY. | |||||
685 | 0 | 0 | $filter = ($extra =~ s/(.*)where(.+)$/where$1/i) ? $2 : ''; | ||||
686 | 0 | $filter =~ s/\s+//o; | |||||
687 | 0 | $expns[$#expns] =~ s/\s*where(.+)$//io; #20000108 REP. PREV. LINE 2FIX BUG IF LAST COLUMN CONTAINS SINGLE QUOTES. | |||||
688 | 0 | $column = $self->{column}; | |||||
689 | 0 | 0 | $objfilter ||= 'objectclass=*'; | ||||
690 | 0 | 0 | $objfilter = "($objfilter)" unless ($objfilter =~ /^\(/o); | ||||
691 | 0 | 0 | if ($filter) | ||||
692 | { | ||||||
693 | #print STDERR "--update: BEF parse_expn: filter=$filter=\n"; | ||||||
694 | 0 | $filter = $self->parse_expression ($filter); | |||||
695 | #print STDERR "--update: AFT parse_expn: filter=$filter= objfilter=$objfilter=\n"; | ||||||
696 | 0 | 0 | $filter = '('.$filter.')' unless ($filter =~ /^\(/o); | ||||
697 | 0 | $filter = "(&$objfilter$filter)"; | |||||
698 | } | ||||||
699 | else | ||||||
700 | { | ||||||
701 | 0 | $filter = "$objfilter"; | |||||
702 | } | ||||||
703 | 0 | $filter =~ s/\x03/\\\'/go; #UNPROTECT '', AND \'. #NEXT 2 ADDED 20091101: | |||||
704 | 0 | $filter =~ s/\x02/\\\\/go; #UNPROTECT "\\". | |||||
705 | # $alwaysinsert .= ',' . $base; #CHGD TO NEXT 200780719 PER REQUEST. | ||||||
706 | 0 | 0 | $alwaysinsert .= ',' . $base if ($self->{ldap_appendbase2ins}); | ||||
707 | 0 | $alwaysinsert =~ s/\\\\/\x02/go; #PROTECT "\\" | |||||
708 | 0 | $alwaysinsert =~ s/\\\,/\x03/go; #PROTECT "\," | |||||
709 | 0 | $alwaysinsert =~ s/\\\=/\x04/go; #PROTECT "\=" | |||||
710 | 0 | my ($i1, $col, $vals, $j, @l); | |||||
711 | 0 | for ($i=0;$i<=$#expns;$i++) #EXTRACT FIELD NAMES AND | |||||
712 | #VALUES FROM EACH EXPRESSION. | ||||||
713 | { | ||||||
714 | 0 | $expns[$i] =~ s/\x03/\\\'/go; #UNPROTECT '', AND \'. | |||||
715 | 0 | $expns[$i] =~ s/\x02/\\\\/go; #UNPROTECT "\\". | |||||
716 | 0 | $expns[$i] =~ s!\s*($column)\s*=\s*(.+)$! | |||||
717 | 0 | my ($var) = $1; | |||||
718 | 0 | my ($val) = $2; | |||||
719 | |||||||
720 | 0 | 0 | $val = &pscolfn($self,$val) if ($val =~ "$column\.$psuedocols"); | ||||
721 | 0 | $var =~ tr/A-Z/a-z/; | |||||
722 | 0 | $val =~ s|%\0(\d+): |pack("C",$1)|ge; | |||||
0 | |||||||
723 | 0 | $val =~ s/^\'//o; #NEXT 2 ADDED 20010530 TO STRIP EXCESS QUOTES. | |||||
724 | 0 | $val =~ s/([^\\\'])\'$/$1/; | |||||
725 | 0 | $val =~ s/\'$//o; | |||||
726 | 0 | $all_columns->{$var} = $val; | |||||
727 | 0 | @_ = split(/\,\s*/o, $alwaysinsert); | |||||
728 | 0 | while (@_) | |||||
729 | { | ||||||
730 | 0 | ($col, $vals) = split(/\=/o, shift); | |||||
731 | 0 | 0 | next unless ($col eq $var); | ||||
732 | 0 | $vals =~ s/\x04/\\\=/go; #UNPROTECT "\=" | |||||
733 | 0 | $vals =~ s/\x03/\\\,/go; #UNPROTECT "\," | |||||
734 | 0 | $vals =~ s/\x02/\\\\/go; #UNPROTECT "\\" | |||||
735 | 0 | @l = split(/\Q$self->{ldap_inseparator}\E/, $vals); | |||||
736 | 0 | VALUE: for (my $j=0;$j<=$#l;$j++) | |||||
737 | { | ||||||
738 | 0 | 0 | next if ($all_columns->{$var} =~ /\b$l[$j]\b/); | ||||
739 | $all_columns->{$var} .= $self->{ldap_inseparator} | ||||||
740 | 0 | 0 | if ($all_columns->{$var}); | ||||
741 | 0 | $all_columns->{$var} .= $l[$j]; | |||||
742 | } | ||||||
743 | } | ||||||
744 | 0 | $all_columns->{$var} =~ s/\x02/\\\\/go; | |||||
745 | # $all_columns->{$var} =~ s/\x03/\'/go; #20091030: REPL. W.NEXT LINE TO KEEP ESCAPE SLASH "\" - RETAIN ORIG. COMMENT: | ||||||
746 | 0 | $all_columns->{$var} =~ s/\x03/\\\'/go; #20000108 REPL. PREV. LINE - NO NEED TO DOUBLE QUOTES (WE ESCAPE THEM) - THIS AIN'T ORACLE. | |||||
747 | !e; | ||||||
748 | } | ||||||
749 | |||||||
750 | 0 | delete $all_columns->{dn}; #DO NOT ALLOW DN TO BE CHANGED DIRECTLY! | |||||
751 | #foreach my $xxx (sort keys %{$all_columns}) { print STDERR "---data($xxx)=".$all_columns->{$xxx}."=\n"; }; | ||||||
752 | 0 | my ($data); | |||||
753 | 0 | my (@searchops) = ( | |||||
754 | 'base' => $base, | ||||||
755 | 'filter' => $filter, | ||||||
756 | ); | ||||||
757 | 0 | foreach my $i (qw(ldap_sizelimit ldap_timelimit deref typesonly | |||||
758 | callback)) | ||||||
759 | { | ||||||
760 | 0 | $j = $i; | |||||
761 | 0 | $j =~ s/^ldap_//o; | |||||
762 | 0 | 0 | push (@searchops, ($j, $self->{$i})) if ($self->{$i}); | ||||
763 | } | ||||||
764 | 0 | 0 | push (@searchops, ('scope', ($self->{ldap_scope} || 'one'))); | ||||
765 | #print STDERR "-update: filter=$filter= searchops=".join('|',@searchops)."=\n"; | ||||||
766 | 0 | 0 | $data = $ldap->search(@searchops) | ||||
767 | or return($self->ldap_error($@,"Search failed to return object: filter=$filter (".$data->error().")")); | ||||||
768 | #print STDERR "-update: got thru search; data=$data=\n"; | ||||||
769 | 0 | my (@varlist) = (); | |||||
770 | 0 | $dbh = $csr->FETCH('ldap_dbh'); | |||||
771 | 0 | my ($autocommit) = $dbh->FETCH('AutoCommit'); | |||||
772 | 0 | 0 | my ($commitqueue) = $dbh->FETCH('ldap_commitqueue') unless ($autocommit); | ||||
773 | 0 | my (@dnattbs) = split(/\,/o, $dnattbs); | |||||
774 | 0 | my ($changedn); | |||||
775 | #print STDERR "-update: going into loop!\n"; | ||||||
776 | 0 | while (my $entry = $data->shift_entry()) | |||||
777 | { | ||||||
778 | #print STDERR "----update: in loop entry=$entry=\n"; | ||||||
779 | 0 | $dn = $entry->dn(); | |||||
780 | 0 | $dn =~ s/\\/\x02/go; #PROTECT "\"; | |||||
781 | 0 | $dn =~ s/\\\,/\x03/go; #PROTECT "\,"; | |||||
782 | 0 | $changedn = 0; | |||||
783 | 0 | I: foreach my $i (@dnattbs) | |||||
784 | { | ||||||
785 | 0 | foreach my $j (keys %$all_columns) | |||||
786 | { | ||||||
787 | 0 | 0 | if ($i eq $j) | ||||
788 | { | ||||||
789 | 0 | $dn =~ s/(\b$i\=)([^\,]+)/$1$all_columns->{$j}/; | |||||
790 | 0 | $changedn = 1; | |||||
791 | 0 | next I; | |||||
792 | } | ||||||
793 | } | ||||||
794 | } | ||||||
795 | 0 | $dn =~ s/(?:\,\s*)$base$//; | |||||
796 | 0 | $dn =~ s/\x03/\\\,/go; #UNPROTECT "\,"; | |||||
797 | 0 | $dn =~ s/\x02/\\/go; #UNPROTECT "\"; | |||||
798 | 0 | foreach my $i (keys %$all_columns) | |||||
799 | { | ||||||
800 | 0 | $all_columns->{$i} =~ s/(?:\\|\')\'/\'/go; #1UNESCAPE QUOTES IN VALUES. | |||||
801 | 0 | @_ = split(/\Q$self->{ldap_inseparator}\E/, $all_columns->{$i}); | |||||
802 | 0 | 0 | if (!@_) | ||||
0 | |||||||
803 | { | ||||||
804 | 0 | push (@attblist, ($i, '')); | |||||
805 | } | ||||||
806 | elsif (@_ == 1) | ||||||
807 | { | ||||||
808 | 0 | push (@attblist, ($i, shift)); | |||||
809 | } | ||||||
810 | else | ||||||
811 | { | ||||||
812 | 0 | push (@attblist, ($i, [@_])); | |||||
813 | } | ||||||
814 | } | ||||||
815 | 0 | $r1 = $entry->replace(@attblist); | |||||
816 | #print STDERR "-update: r1=$r1= attblist=".join('|',@attblist)."=\n"; | ||||||
817 | 0 | 0 | if ($r1 > 0) | ||||
818 | { | ||||||
819 | 0 | 0 | if ($autocommit) | ||||
820 | { | ||||||
821 | 0 | $r2 = $entry->update($ldap); #COMMIT!!! | |||||
822 | 0 | 0 | if ($r2->is_error) | ||||
823 | { | ||||||
824 | 0 | $errdetails = $r2->code . ': ' . $r2->error; | |||||
825 | 0 | return (-523); | |||||
826 | } | ||||||
827 | 0 | 0 | if ($changedn) | ||||
828 | { | ||||||
829 | 0 | $r2 = $ldap->moddn($entry, newrdn => $dn); | |||||
830 | 0 | 0 | if ($r2->is_error) | ||||
831 | { | ||||||
832 | 0 | $errdetails = "Could not change dn - " | |||||
833 | . $r2->code . ': ' . $r2->error . '!'; | ||||||
834 | 0 | return (-523); | |||||
835 | } | ||||||
836 | } | ||||||
837 | } | ||||||
838 | else | ||||||
839 | { | ||||||
840 | 0 | push (@{$commitqueue}, (\$entry, \$ldap)); | |||||
0 | |||||||
841 | 0 | 0 | push (@{$commitqueue}, "dn=$dn") if ($changedn); | ||||
0 | |||||||
842 | } | ||||||
843 | 0 | ++$status; | |||||
844 | } | ||||||
845 | else | ||||||
846 | { | ||||||
847 | #return($self->ldap_error($@,"Search failed to return object: filter=$filter (".$data->error().")")); | ||||||
848 | 0 | $errdetails = $data->code . ': ' . $data->error; | |||||
849 | 0 | return (-523); | |||||
850 | } | ||||||
851 | } | ||||||
852 | 0 | return ($status); | |||||
853 | } | ||||||
854 | else | ||||||
855 | { | ||||||
856 | 0 | return (-504); | |||||
857 | } | ||||||
858 | } | ||||||
859 | |||||||
860 | sub delete | ||||||
861 | { | ||||||
862 | 0 | 0 | 0 | my ($self, $csr, $query) = @_; | |||
863 | 0 | my ($path, $table, $filter, $wherepart); | |||||
864 | 0 | my $status = 0; | |||||
865 | |||||||
866 | 0 | $path = $self->{path}; | |||||
867 | 0 | 0 | if ($query =~ /^delete\s+from\s+($path)(?:\s+where\s+(.+))?$/io) | ||||
868 | { | ||||||
869 | 0 | $table = $1; | |||||
870 | 0 | $wherepart = $2; | |||||
871 | 0 | 0 | $table =~ tr/A-Z/a-z/ unless ($self->{CaseTableNames}); #JWT:TABLE-NAMES ARE NOW CASE-INSENSITIVE! | ||||
872 | 0 | $self->{file} = $table; | |||||
873 | |||||||
874 | 0 | my ($dbh) = $csr->FETCH('ldap_dbh'); | |||||
875 | 0 | my ($ldap) = $csr->FETCH('ldap_ldap'); | |||||
876 | 0 | my ($tablehash) = $dbh->FETCH('ldap_tables'); | |||||
877 | 0 | 0 | return (-524) unless ($tablehash->{$table}); | ||||
878 | 0 | my ($base, $objfilter, $dnattbs, $allattbs, $alwaysinsert) = split(/\:/,$tablehash->{$table}); | |||||
879 | 0 | 0 | $objfilter ||= 'objectclass=*'; | ||||
880 | 0 | 0 | $objfilter = "($objfilter)" unless ($objfilter =~ /^\(/o); | ||||
881 | 0 | 0 | if ($wherepart =~ /\S/o) | ||||
882 | { | ||||||
883 | 0 | $filter = $self->parse_expression ($wherepart); | |||||
884 | 0 | 0 | $filter = '('.$filter.')' unless ($filter =~ /^\(/o); | ||||
885 | 0 | $filter = "(&$objfilter$filter)"; | |||||
886 | } | ||||||
887 | else | ||||||
888 | { | ||||||
889 | 0 | $filter = "$objfilter"; | |||||
890 | } | ||||||
891 | 0 | 0 | $filter = '('.$filter.')' unless ($filter =~ /^\(/o); | ||||
892 | |||||||
893 | 0 | 0 | $data = $ldap->search( | ||||
894 | base => $base, | ||||||
895 | filter => $filter, | ||||||
896 | ) or return ($self->ldap_error($@,"Search failed to return object: filter=$filter (".$data->error().")")); | ||||||
897 | 0 | my ($j) = 0; | |||||
898 | 0 | my (@varlist) = (); | |||||
899 | 0 | $dbh = $csr->FETCH('ldap_dbh'); | |||||
900 | 0 | my ($autocommit) = $dbh->FETCH('AutoCommit'); | |||||
901 | 0 | 0 | my ($commitqueue) = $dbh->FETCH('ldap_commitqueue') unless ($autocommit); | ||||
902 | 0 | while (my $entry = $data->shift_entry()) | |||||
903 | { | ||||||
904 | 0 | $dn = $entry->dn(); | |||||
905 | 0 | 0 | next unless ($dn =~ /$base$/i); #CASE-INSENSITIVITY ADDED NEXT 2: 20050416 PER PATCH BY jmorano | ||||
906 | 0 | $r1 = $entry->delete(); | |||||
907 | 0 | 0 | if ($autocommit) | ||||
908 | { | ||||||
909 | 0 | $r2 = $entry->update($ldap); #COMMIT!!! | |||||
910 | 0 | 0 | if ($r2->is_error) | ||||
911 | { | ||||||
912 | 0 | $errdetails = $r2->code . ': ' . $r2->error; | |||||
913 | 0 | return (-523); | |||||
914 | } | ||||||
915 | } | ||||||
916 | else | ||||||
917 | { | ||||||
918 | 0 | push (@{$commitqueue}, (\$entry, \$ldap)); | |||||
0 | |||||||
919 | } | ||||||
920 | 0 | ++$status; | |||||
921 | } | ||||||
922 | |||||||
923 | 0 | return $status; | |||||
924 | } | ||||||
925 | else | ||||||
926 | { | ||||||
927 | 0 | return (-505); | |||||
928 | } | ||||||
929 | } | ||||||
930 | |||||||
931 | sub primary_key_info | ||||||
932 | { | ||||||
933 | 0 | 0 | 0 | my ($self, $csr, $query) = @_; | |||
934 | 0 | my $table = $query; | |||||
935 | 0 | $table =~ s/^.*\s+(\w+)$/$1/; | |||||
936 | 0 | 0 | $table =~ tr/A-Z/a-z/ unless ($self->{CaseTableNames}); #JWT:TABLE-NAMES ARE NOW CASE-INSENSITIVE! | ||||
937 | 0 | $self->{file} = $table; | |||||
938 | 0 | my ($dbh) = $csr->FETCH('ldap_dbh'); | |||||
939 | 0 | my $tablehash = $dbh->FETCH('ldap_tables'); | |||||
940 | 0 | 0 | return -524 unless ($tablehash->{$table}); | ||||
941 | |||||||
942 | 0 | undef %{ $self->{types} }; | |||||
0 | |||||||
943 | 0 | undef %{ $self->{lengths} }; | |||||
0 | |||||||
944 | 0 | $self->{use_fields} = 'CAT,SCHEMA,TABLE_NAME,PRIMARY_KEY'; | |||||
945 | 0 | $self->{order} = [ 'CAT', 'SCHEMA', 'TABLE_NAME', 'PRIMARY_KEY' ]; | |||||
946 | 0 | $self->{fields}->{CAT} = 1; | |||||
947 | 0 | $self->{fields}->{SCHEMA} = 1; | |||||
948 | 0 | $self->{fields}->{TABLE_NAME} = 1; | |||||
949 | 0 | $self->{fields}->{PRIMARY_KEY} = 1; | |||||
950 | 0 | undef @{ $self->{records} }; | |||||
0 | |||||||
951 | 0 | my (@keyfields) = split(/\,\s*/o, $self->{key_fields}); #JWT: PREVENT DUP. KEYS. | |||||
952 | 0 | ${$self->{types}}{CAT} = 'VARCHAR'; | |||||
0 | |||||||
953 | 0 | ${$self->{types}}{SCHEMA} = 'VARCHAR'; | |||||
0 | |||||||
954 | 0 | ${$self->{types}}{TABLE_NAME} = 'VARCHAR'; | |||||
0 | |||||||
955 | 0 | ${$self->{types}}{PRIMARY_KEY} = 'VARCHAR'; | |||||
0 | |||||||
956 | 0 | ${$self->{lengths}}{CAT} = 50; | |||||
0 | |||||||
957 | 0 | ${$self->{lengths}}{SCHEMA} = 50; | |||||
0 | |||||||
958 | 0 | ${$self->{lengths}}{TABLE_NAME} = 50; | |||||
0 | |||||||
959 | 0 | ${$self->{lengths}}{PRIMARY_KEY} = 50; | |||||
0 | |||||||
960 | 0 | ${$self->{defaults}}{CAT} = undef; | |||||
0 | |||||||
961 | 0 | ${$self->{defaults}}{SCHEMA} = undef; | |||||
0 | |||||||
962 | 0 | ${$self->{defaults}}{TABLE_NAME} = undef; | |||||
0 | |||||||
963 | 0 | ${$self->{defaults}}{PRIMARY_KEY} = undef; | |||||
0 | |||||||
964 | 0 | ${$self->{scales}}{PRIMARY_KEY} = 50; | |||||
0 | |||||||
965 | 0 | ${$self->{scales}}{PRIMARY_KEY} = 50; | |||||
0 | |||||||
966 | 0 | ${$self->{scales}}{PRIMARY_KEY} = 50; | |||||
0 | |||||||
967 | 0 | ${$self->{scales}}{PRIMARY_KEY} = 50; | |||||
0 | |||||||
968 | 0 | my $results; | |||||
969 | 0 | my $keycnt = scalar(@keyfields); | |||||
970 | 0 | while (@keyfields) | |||||
971 | { | ||||||
972 | 0 | push (@{$results}, [0, 0, $table, shift(@keyfields)]); | |||||
0 | |||||||
973 | } | ||||||
974 | 0 | unshift (@$results, $keycnt); | |||||
975 | 0 | return $results; | |||||
976 | } | ||||||
977 | |||||||
978 | sub alter #SQL COMMAND NOT IMPLEMENTED. | ||||||
979 | { | ||||||
980 | 0 | 0 | 0 | $@ = 'SQL "alter" command is not (yet) implemented!'; | |||
981 | 0 | return 0; | |||||
982 | } | ||||||
983 | |||||||
984 | sub insert | ||||||
985 | { | ||||||
986 | #my ($self, $query) = @_; | ||||||
987 | 0 | 0 | 0 | my ($self, $csr, $query) = @_; | |||
988 | 0 | my ($i, $path, $table, $columns, $values, $status); | |||||
989 | |||||||
990 | 0 | $path = $self->{path}; | |||||
991 | 0 | 0 | if ($query =~ /^insert\s+into\s+ # Keyword | ||||
992 | ($path)\s* # Table | ||||||
993 | (?:\((.+?)\)\s*)? # Keys | ||||||
994 | values\s* # 'values' | ||||||
995 | \((.+)\)$/ixo) | ||||||
996 | { #JWT: MAKE COLUMN LIST OPTIONAL! | ||||||
997 | |||||||
998 | 0 | ($table, $columns, $values) = ($1, $2, $3); | |||||
999 | 0 | my ($dbh) = $csr->FETCH('ldap_dbh'); | |||||
1000 | 0 | my ($tablehash) = $dbh->FETCH('ldap_tables'); | |||||
1001 | 0 | 0 | $table =~ tr/A-Z/a-z/ unless ($self->{CaseTableNames}); #JWT:TABLE-NAMES ARE NOW CASE-INSENSITIVE! | ||||
1002 | 0 | $self->{file} = $table; | |||||
1003 | 0 | 0 | return (-524) unless ($tablehash->{$table}); | ||||
1004 | 0 | my ($base, $objfilter, $dnattbs, $allattbs, $alwaysinsert) = split(/\:/,$tablehash->{$table}); | |||||
1005 | 0 | $columns =~ s/\s//go; | |||||
1006 | 0 | 0 | $columns ||= $allattbs; | ||||
1007 | 0 | 0 | $columns = join(',', @{ $self->{order} }) unless ($columns =~ /\S/o); #JWT | ||||
0 | |||||||
1008 | |||||||
1009 | 0 | 0 | unless ($columns =~ /\S/o) | ||||
1010 | { | ||||||
1011 | 0 | return ($self->display_error (-509)); | |||||
1012 | } | ||||||
1013 | 0 | $values =~ s/\\\\/\x02/go; #PROTECT "\\" | |||||
1014 | 0 | $values =~ s/\\\'/\x03/go; #PROTECT '', AND \'. | |||||
1015 | |||||||
1016 | 0 | $values =~ s/\'(.*?)\'/ | |||||
1017 | 0 | my ($j)=$1; | |||||
1018 | 0 | $j=~s|,|\x04|go; #PROTECT "," IN QUOTES. | |||||
1019 | 0 | "'$j'" | |||||
1020 | /eg; | ||||||
1021 | 0 | @values = split(/,/o, $values); | |||||
1022 | 0 | $values = ''; | |||||
1023 | 0 | for $i (0..$#values) | |||||
1024 | { | ||||||
1025 | 0 | $values[$i] =~ s/^\s+//o; #STRIP LEADING & TRAILING SPACES. | |||||
1026 | 0 | $values[$i] =~ s/\s+$//o; | |||||
1027 | 0 | $values[$i] =~ s/\x03/\'/go; #RESTORE PROTECTED SINGLE QUOTES HERE. | |||||
1028 | 0 | $values[$i] =~ s/\x02/\\/go; #RESTORE PROTECTED SLATS HERE. | |||||
1029 | 0 | $values[$i] =~ s/\x04/,/go; #RESTORE PROTECTED COMMAS HERE. | |||||
1030 | } | ||||||
1031 | 0 | chop($values); | |||||
1032 | |||||||
1033 | 0 | $status = $self->insert_data ($csr, $base, $dnattbs, $alwaysinsert, $columns, @values); | |||||
1034 | |||||||
1035 | 0 | return $status; | |||||
1036 | } | ||||||
1037 | else | ||||||
1038 | { | ||||||
1039 | 0 | return (-508); | |||||
1040 | } | ||||||
1041 | } | ||||||
1042 | |||||||
1043 | sub insert_data | ||||||
1044 | { | ||||||
1045 | 0 | 0 | 0 | my ($self, $csr, $base, $dnattbs, $alwaysinsert, $column_string, @values) = @_; | |||
1046 | 0 | my (@columns, @attblist, $loop, $column, $j, $k); | |||||
1047 | 0 | $column_string =~ tr/A-Z/a-z/; | |||||
1048 | 0 | $dnattbs =~ tr/A-Z/a-z/; | |||||
1049 | 0 | @columns = split (/\,/o, $column_string); | |||||
1050 | |||||||
1051 | 0 | 0 | if ($#columns = $#values) | ||||
1052 | { | ||||||
1053 | 0 | my $dn = ''; | |||||
1054 | 0 | my @t = split(/,/o, $dnattbs); | |||||
1055 | 0 | while (@t) | |||||
1056 | { | ||||||
1057 | 0 | $j = shift (@t); | |||||
1058 | 0 | J1: for (my $i=0;$i<=$#columns;$i++) | |||||
1059 | { | ||||||
1060 | 0 | 0 | if ($columns[$i] eq $j) | ||||
1061 | { | ||||||
1062 | 0 | $dn .= $columns[$i] . '='; | |||||
1063 | 0 | 0 | if ($values[$i] =~ /\Q$self->{ldap_inseparator}\E/) | ||||
1064 | { | ||||||
1065 | 0 | $dn .= (split(/\Q$self->{ldap_inseparator}\E/,$values[$i]))[0]; | |||||
1066 | } | ||||||
1067 | else | ||||||
1068 | { | ||||||
1069 | 0 | $dn .= $values[$i]; | |||||
1070 | } | ||||||
1071 | 0 | $dn .= ', '; | |||||
1072 | 0 | last J1; | |||||
1073 | } | ||||||
1074 | } | ||||||
1075 | } | ||||||
1076 | 0 | $dn =~ s/\'//go; | |||||
1077 | 0 | $dn .= $base; | |||||
1078 | 0 | for (my $i=0;$i<=$#columns;$i++) | |||||
1079 | { | ||||||
1080 | 0 | @l = split(/\Q$self->{ldap_inseparator}\E/,$values[$i]); | |||||
1081 | 0 | while (@l) | |||||
1082 | { | ||||||
1083 | 0 | $j = shift(@l); | |||||
1084 | 0 | $j =~ s/^\'//o; | |||||
1085 | 0 | $j =~ s/([^\\\'])\'$/$1/; | |||||
1086 | 0 | 0 | 0 | unless (!length($j) || $j eq "'" || $columns[$i] eq 'dn') | |||
0 | |||||||
1087 | { | ||||||
1088 | 0 | 0 | $j = "'" if ($j eq "''"); | ||||
1089 | 0 | push (@attblist, $columns[$i]); | |||||
1090 | 0 | push (@attblist, $j); | |||||
1091 | } | ||||||
1092 | } | ||||||
1093 | } | ||||||
1094 | # $alwaysinsert .= ',' . $base; #CHGD TO NEXT 200780719 PER REQUEST. | ||||||
1095 | 0 | 0 | $alwaysinsert .= ',' . $base if ($self->{ldap_appendbase2ins}); | ||||
1096 | 0 | my ($i1, $found, $col, $vals, $j); | |||||
1097 | 0 | @_ = split(/\,\s*/o, $alwaysinsert); | |||||
1098 | 0 | while (@_) | |||||
1099 | { | ||||||
1100 | 0 | ($col, $vals) = split(/\=/o, shift); | |||||
1101 | 0 | @l = split(/\Q$self->{ldap_inseparator}\E/, $vals); | |||||
1102 | 0 | VALUE: for (my $i=0;$i<=$#l;$i++) | |||||
1103 | { | ||||||
1104 | 0 | for ($j=0;$j<=$#attblist;$j+=2) | |||||
1105 | { | ||||||
1106 | 0 | 0 | if ($attblist[$j] eq $col) | ||||
1107 | { | ||||||
1108 | 0 | 0 | next VALUE if ($attblist[$j+1] eq $l[$i]); | ||||
1109 | } | ||||||
1110 | } | ||||||
1111 | 0 | push (@attblist, $col); | |||||
1112 | 0 | push (@attblist, $l[$i]); | |||||
1113 | } | ||||||
1114 | } | ||||||
1115 | 0 | my ($ldap) = $csr->FETCH('ldap_ldap'); | |||||
1116 | |||||||
1117 | 0 | my $entry = Net::LDAP::Entry->new; | |||||
1118 | 0 | $entry->dn($dn); | |||||
1119 | |||||||
1120 | 0 | my $result = $entry->add(@attblist); | |||||
1121 | 0 | $_ = $entry->dn(); | |||||
1122 | |||||||
1123 | 0 | my ($dbh) = $csr->FETCH('ldap_dbh'); | |||||
1124 | 0 | my ($autocommit) = $dbh->FETCH('AutoCommit'); | |||||
1125 | 0 | 0 | if ($autocommit) | ||||
1126 | { | ||||||
1127 | 0 | $r2 = $entry->update($ldap); #COMMIT!!! | |||||
1128 | 0 | 0 | if ($r2->is_error) | ||||
1129 | { | ||||||
1130 | 0 | $errdetails = $r2->code . ': ' . $r2->error; | |||||
1131 | 0 | return (-523); | |||||
1132 | } | ||||||
1133 | } | ||||||
1134 | else | ||||||
1135 | { | ||||||
1136 | 0 | my ($commitqueue) = $dbh->FETCH('ldap_commitqueue'); | |||||
1137 | 0 | push (@{$commitqueue}, (\$entry, \$ldap)); | |||||
0 | |||||||
1138 | } | ||||||
1139 | |||||||
1140 | 0 | return (1); | |||||
1141 | } | ||||||
1142 | else | ||||||
1143 | { | ||||||
1144 | 0 | $errdetails = "$#columns != $#values"; #20000114 | |||||
1145 | 0 | return (-509); | |||||
1146 | } | ||||||
1147 | } | ||||||
1148 | |||||||
1149 | sub create #SQL COMMAND NOT IMPLEMENTED. | ||||||
1150 | { | ||||||
1151 | 0 | 0 | 0 | $@ = 'SQL "create" command is not (yet) implemented!'; | |||
1152 | 0 | return 0; | |||||
1153 | } | ||||||
1154 | |||||||
1155 | sub drop #SQL COMMAND NOT IMPLEMENTED. | ||||||
1156 | { | ||||||
1157 | 0 | 0 | 0 | $@ = 'SQL "drop" command is not (yet) implemented!'; | |||
1158 | 0 | return 0; | |||||
1159 | } | ||||||
1160 | |||||||
1161 | sub pscolfn | ||||||
1162 | { | ||||||
1163 | 0 | 0 | 0 | my ($self,$id) = @_; | |||
1164 | 0 | 0 | return $id unless ($id =~ /CURVAL|NEXTVAL|ROWNUM/); | ||||
1165 | 0 | my ($value) = ''; | |||||
1166 | 0 | my ($seq_file,$col) = split(/\./o, $id); | |||||
1167 | 0 | $seq_file = $self->get_path_info($seq_file) . '.seq'; | |||||
1168 | |||||||
1169 | 0 | 0 | $seq_file =~ tr/A-Z/a-z/ unless ($self->{CaseTableNames}); #JWT:TABLE-NAMES ARE NOW CASE-INSENSITIVE! | ||||
1170 | 0 | 0 | open (FILE, "<$seq_file") || return (-511); | ||||
1171 | 0 | $x = |
|||||
1172 | #chomp($x); | ||||||
1173 | 0 | $x =~ s/\s+$//o; #20000113 | |||||
1174 | 0 | ($incval, $startval) = split(/\,/o, $x); | |||||
1175 | 0 | close (FILE); | |||||
1176 | 0 | 0 | if ($id =~ /NEXTVAL/o) | ||||
1177 | { | ||||||
1178 | 0 | 0 | open (FILE, ">$seq_file") || return (-511); | ||||
1179 | 0 | 0 | $incval += ($startval || 1); | ||||
1180 | 0 | print FILE "$incval,$startval\n"; | |||||
1181 | 0 | close (FILE); | |||||
1182 | } | ||||||
1183 | 0 | $value = $incval; | |||||
1184 | 0 | return $value; | |||||
1185 | } | ||||||
1186 | |||||||
1187 | sub SYSTIME | ||||||
1188 | { | ||||||
1189 | 0 | 0 | 0 | return time; | |||
1190 | } | ||||||
1191 | |||||||
1192 | sub NUM | ||||||
1193 | { | ||||||
1194 | 0 | 0 | 0 | return shift; | |||
1195 | } | ||||||
1196 | |||||||
1197 | sub NULL | ||||||
1198 | { | ||||||
1199 | 0 | 0 | 0 | return ''; | |||
1200 | } | ||||||
1201 | |||||||
1202 | 1; |