File Coverage

blib/lib/HDB/CMDS.pm
Criterion Covered Total %
statement 9 531 1.6
branch 0 312 0.0
condition 0 44 0.0
subroutine 3 39 7.6
pod 0 28 0.0
total 12 954 1.2


line stmt bran cond sub pod time code
1             #############################################################################
2             ## Name: CMDS.pm
3             ## Purpose: HDB::CMDS
4             ## Author: Graciliano M. P.
5             ## Modified by:
6             ## Created: 14/01/2003
7             ## RCS-ID:
8             ## Copyright: (c) 2002 Graciliano M. P.
9             ## Licence: This program is free software; you can redistribute it and/or
10             ## modify it under the same terms as Perl itself
11             #############################################################################
12            
13             package HDB::CMDS ;
14 1     1   537 use HDB::Parser ;
  1         3  
  1         105  
15            
16 1     1   10 use strict qw(vars);
  1         3  
  1         63  
17 1     1   5 no warnings ;
  1         1  
  1         14493  
18            
19             our $VERSION = '1.0' ;
20            
21             ########
22             # VARS #
23             ########
24            
25             my %args_select = (
26             table => [qw(table)] ,
27             where => [qw(where w)] ,
28             limit => [qw(limit limite)] ,
29             sort => [qw(sort order)] ,
30             group => [qw(group grop)] ,
31             return => [qw(return ret r)] ,
32             col => [qw(col cols)] ,
33             cache => [[qw(cache)],1] ,
34             );
35            
36             my %DEFAULT_COLS = (
37             'address' => 200 ,
38             'age' => 'INTEGER' ,
39             'bairro' => 30 ,
40             'cep' => 9 ,
41             'cidade' => 40 ,
42             'city' => 40 ,
43             'country' => 4 ,
44             'data' => 'int(9999999999)' ,
45             'date' => 'int(9999999999)' ,
46             'descricao' => 'TEXT' ,
47             'email' => 50 ,
48             'endereco' => 200 ,
49             'estado' => 3 ,
50             'fax' => 'INTEGER' ,
51             'hits' => 'INTEGER' ,
52             'hora' => 8 ,
53             'id' => 'INTEGER' ,
54             'idade' => 'INTEGER' ,
55             'mail' => 50 ,
56             'message' => 'TEXT' ,
57             'msg' => 'TEXT' ,
58             'mensagem' => 'TEXT' ,
59             'name' => 40 ,
60             'nick' => 16 ,
61             'nome' => 40 ,
62             'pais' => 4 ,
63             'pass' => 16 ,
64             'password' => 16 ,
65             'phone' => 'INTEGER' ,
66             'preco' => 15 ,
67             'price' => 15 ,
68             'senha' => 16 ,
69             'sex' => 1 ,
70             'sexo' => 1 ,
71             'size' => 5 ,
72             'state' => 3 ,
73             'tamanho' => 5 ,
74             'tel' => 'INTEGER' ,
75             'telefone' => 'INTEGER' ,
76             'temperatura' => 4 ,
77             'time' => 10 ,
78             'titulo' => 250 ,
79             'title' => 250 ,
80             'uf' => 3 ,
81             'uid' => 8 ,
82             'url' => 250 ,
83             'username' => 16 ,
84             'user' => 16 ,
85             'zip' => 9 ,
86             );
87            
88            
89             my @DEFAULT_TYPES = qw(* TEXT INT FLOAT BOOL) ;
90            
91             my %DEFAULT_MOD = (
92             'MySQL' => 'mysql' ,
93             'SQLite' => 'sqlite' ,
94             'Oracle' => 'Oracle' ,
95             ) ;
96            
97            
98             ###################
99             # PREDEFINED_COLS #
100             ###################
101            
102 0     0 0   sub predefined_columns { return( %DEFAULT_COLS ) ;}
103            
104             #################
105             # DEFAULT_TYPES #
106             #################
107            
108 0     0 0   sub default_types { return( @DEFAULT_TYPES ) ;}
109            
110             ###############
111             # DEFAULT_MOD #
112             ###############
113            
114 0     0 0   sub default_mod { return( %DEFAULT_MOD ) ;}
115            
116             ###########
117             # ALIASES #
118             ###########
119            
120 0     0 0   sub sel { &select ;}
121 0     0 0   sub cols { &names ;}
122 0     0 0   sub creat { &create ;}
123 0     0 0   sub create_table { &create ;}
124 0     0 0   sub predefined_cols { &predefined_columns ;}
125 0     0 0   sub sql { $_[0]->{sql} ;}
126            
127             ##########
128             # SELECT #
129             ##########
130            
131             sub select {
132 0     0 0   my $this = shift ;
133 0           my (undef , $where , @args) = @_ ;
134            
135 0 0 0       if ($_[0] =~ /^table$/i) { @args = @_ ; $where = undef ;}
  0 0 0        
  0 0 0        
      0        
136             elsif ($#_ >= 2 && $#_ <= 3 && ( ref $_[2] || $_[2] =~ /^(?:(?:n|names?|c|cols?|columns?)\s*[,;]*\s*)?(?:\$?[\$\@\%]{1,2}|<[\$\@\%]>)$/i ) ) {
137 0 0         if (ref $_[2]) { @args = HDB::CORE::parse_ref($_[2]) ;}
  0 0          
138 0           elsif ($#_ == 2) { @args = ('return' , $_[2]) ;}
139             }
140             elsif ($#_ == 1 && $_[1] =~ /^(?:(?:n|names?|c|cols?|columns?)\s*[,;]*\s*)?(?:\$?[\$\@\%]{1,2}|<[\$\@\%]>)$/i ) {
141 0           @args = ('return' , $_[1]) ;
142 0           $where = undef ;
143             }
144            
145 0 0 0       if ($#_ >= 2 && $where =~ /^(?:cache|col|cols|grop|group|limit|limite|order|r|ret|return|sort|table|w|where)$/si) {
146 0           unshift (@args, $where) ;
147 0           $where = undef ;
148             }
149            
150 0           my %args ;
151 0           &HDB::CORE::parse_args(\%args , \%args_select , @args) ;
152            
153 0 0         $args{table} = $_[0] if !defined $args{table} ;
154 0 0         $args{where} = $where if !defined $args{where} ;
155            
156 0           $args{table} = _format_table_name($args{table}) ;
157            
158 0 0         if (! defined $args{return}) {
159 0 0         if ( $_[-1] =~ /^(?:(?:n|names?|c|cols?|columns?)\s*[,;]*\s*)?(?:\$?[\$\@\%]{1,2}|<[\$\@\%]>)$/i ) { $args{return} = $_[-1] ;}
  0            
160             }
161            
162 0           $this->{return} = $args{return} ;
163            
164 0           $this->{sql} = undef ;
165            
166             {
167 0           my ($cols , $db_max) ;
  0            
168            
169 0 0         if ($args{col} =~ /^\s*([<>])\s*([\w\.]+)/) {
170 0           $db_max = $1 ;
171 0           $cols = $2 ;
172             }
173 0           else { $cols = $args{col} ;}
174            
175 0 0         if ($db_max) {
    0          
176 0 0         if ($db_max eq '>') { $db_max = 'max' ;}
  0 0          
177 0           elsif ($db_max eq '<') { $db_max = 'min' ;}
178 0 0         if ($cols eq '') { $cols = "$db_max(ID) as ID" ;}
  0            
179 0           else { $cols = "$db_max($cols) as $cols" ;}
180             }
181 0           elsif ($cols eq "") { $cols = '*' ;}
182             else {
183 0           $cols =~ s/^\s*,//s ;
184 0           $cols =~ s/,\s*$//s ;
185             }
186            
187 0           my $where = &HDB::Parser::Parse_Where($args{where},$this) ;
188            
189 0           my $group ;
190 0 0         if ( $args{group} ) { $group = "GROUP BY $args{group}" ;}
  0            
191            
192 0           my $sort ;
193            
194 0 0         if ( $args{sort} ) {
195 0           ($sort) = ( $args{sort} =~ /([\w\.]+)/gs ) ;
196 0           $sort = "ORDER BY $sort" ;
197 0 0         if ($args{sort} =~ /
  0            
198             }
199             #elsif (! defined $args{sort} ) { $sort = "ORDER BY ID" ;}
200            
201 0           my $limit ;
202 0 0         if ($args{limit} ne '') {
203 0           my ($sz,$init) = ( $args{limit} =~ /(\d+)(?:\D+(\d+)|)/ );
204 0           my $into_where ;
205 0           ($limit , $into_where) = $this->LIMIT($sz,$init) ;
206 0 0         if ( $into_where ) { $where = "$where AND ($into_where)" ;}
  0            
207             }
208            
209 0           $this->{sql} = "SELECT $cols FROM $args{table}" ;
210 0 0         $this->{sql} .= " $where" if $where ne '' ;
211 0 0         $this->{sql} .= " $group" if $group ne '' ;
212 0 0         $this->{sql} .= " $sort" if $sort ne '' ;
213 0 0         $this->{sql} .= " $limit" if $limit ne '' ;
214             }
215            
216 0           $this->_undef_sth ;
217            
218 0           eval{
219 0           $this->{sth} = $this->dbh->prepare( $this->{sql} ) ;
220 0           $this->{sth}->{ShowErrorStatement} = 1 ;
221 0           $this->{sth}->execute ;
222 0           $this->{sth}->err ;
223             };
224            
225 0 0         return $this->Error("SQL error: $this->{sql}") if $@ ;
226            
227 0           return $this->Return( $args{return} ) ;
228             }
229            
230             ##########
231             # INSERT #
232             ##########
233            
234             sub insert {
235 0     0 0   my $this = shift ;
236            
237 0           my ($table , @up) = @_ ;
238            
239 0           $table = _format_table_name($table) ;
240            
241 0 0         if ($#_ == 1) { @up = HDB::CORE::parse_ref($_[1]) ;}
  0            
242            
243 0 0         return $this->Error('Invalid table!') if !$table ;
244 0 0         return $this->Error('Nothing to insert!') if !@up ;
245            
246 0           my @names = $this->names($table) ;
247            
248 0           my @cols ;
249 0 0         if (ref($_[1]) eq 'HASH') {
250 0           my %up = @up ;
251 0           @up = () ;
252            
253 0           foreach my $names_i ( @names ) {
254 0 0         if (defined $up{$names_i}) { push(@up , $up{$names_i}) ; push(@cols , $names_i) ;}
  0 0          
  0 0          
    0          
255 0           elsif (defined $up{uc($names_i)}) { push(@up , $up{uc($names_i)}) ; push(@cols , $names_i) ;}
  0            
256 0           elsif (defined $up{lc($names_i)}) { push(@up , $up{lc($names_i)}) ; push(@cols , $names_i) ;}
  0            
257 0           elsif (defined $up{"\u\L$names_i\E"}) { push(@up , $up{"\u\L$names_i\E"}) ; push(@cols , $names_i) ;}
  0            
258             }
259             }
260 0           else { @cols = @names ;}
261            
262 0           foreach my $up_i ( @up ) {
263 0 0         if (ref($up_i) eq 'HASH') { $up_i = &HDB::Encode::Pack_HASH($up_i) ;}
  0 0          
264 0           elsif (ref($up_i) eq 'ARRAY') { $up_i = &HDB::Encode::Pack_ARRAY($up_i) ;}
265 0           &HDB::Parser::filter_null_bytes($up_i) ;
266             }
267            
268 0           $this->_undef_sth ;
269            
270             {
271 0           my @ins_pnt = ('?') x @up ;
  0            
272 0           $this->{sql} = "INSERT INTO $table (". join(',',@cols) .") VALUES (". join(',',@ins_pnt) .")" ;
273 0           eval { $this->{sth} = $this->dbh->prepare( $this->{sql} ) };
  0            
274             }
275            
276 0           $this->{sth}->{ShowErrorStatement} = 1 ;
277            
278 0           eval {
279 0 0         $this->lock_table($table) if $this->{SQL}{LOCK_TABLE} ;
280 0           $this->{sth}->execute(@up) ;
281 0 0         $this->unlock_table($table) if $this->{SQL}{LOCK_TABLE} ;
282 0           $this->{sth}->err ;
283             };
284            
285 0           $this->_undef_sth ;
286            
287 0 0         return $this->Error("SQL error: $this->{sql}\nERROR MSG:\n$@") if $@ ;
288            
289 0 0         $this->ON_INSERT(\@cols,\@up) if $this->can('ON_INSERT') ;
290            
291 0           return 1 ;
292             }
293            
294             ##########
295             # UPDATE #
296             ##########
297            
298             sub update {
299 0     0 0   my $this = shift ;
300 0           my ($table , $where , %up) = @_ ;
301            
302 0           $table = _format_table_name($table) ;
303            
304 0 0         if ($#_ == 2) { %up = HDB::CORE::parse_ref($_[2]) ;}
  0            
305            
306 0 0         if (! $table) { $this->Error('Invalid table!') ;}
  0            
307 0 0         if (! %up) { $this->Error('Nothing to update!') ;}
  0            
308            
309 0           $where = &HDB::Parser::Parse_Where($where,$this) ;
310            
311 0           my ($set_cols,@up) ;
312            
313 0           my @names = $this->names($table) ;
314            
315 0           foreach my $names_i ( @names ) {
316 0 0         if (defined $up{$names_i}) { push(@up , $up{$names_i}) ; $set_cols .= "$names_i = ? , " ;}
  0 0          
  0 0          
    0          
317 0           elsif (defined $up{uc($names_i)}) { push(@up , $up{uc($names_i)}) ; $set_cols .= "\U$names_i\E = ? , " ;}
  0            
318 0           elsif (defined $up{lc($names_i)}) { push(@up , $up{lc($names_i)}) ; $set_cols .= "\L$names_i\E = ? , " ;}
  0            
319 0           elsif (defined $up{"\u\L$names_i\E"}) { push(@up , $up{"\u\L$names_i\E"}) ; $set_cols .= "\u\L$names_i\E = ? , " ;}
  0            
320             }
321            
322 0 0         return if !@up ;
323            
324 0           foreach my $up_i ( @up ) {
325 0 0         if (ref($up_i) eq 'HASH') { $up_i = &HDB::Encode::Pack_HASH($up_i) ;}
  0 0          
326 0           elsif (ref($up_i) eq 'ARRAY') { $up_i = &HDB::Encode::Pack_ARRAY($up_i) ;}
327 0           &HDB::Parser::filter_null_bytes($up_i) ;
328             }
329            
330 0           $set_cols =~ s/ , $// ;
331            
332 0           $this->{sql} = "UPDATE $table SET $set_cols $where" ;
333            
334 0           $this->_undef_sth ;
335 0           eval { $this->{sth} = $this->dbh->prepare( $this->{sql} ) };
  0            
336            
337 0           eval {
338 0 0         $this->lock_table($table) if $this->{SQL}{LOCK_TABLE} ;
339 0           $this->{sth}->execute(@up) ;
340 0 0         $this->unlock_table($table) if $this->{SQL}{LOCK_TABLE} ;
341             };
342            
343 0           $this->_undef_sth ;
344            
345 0 0         return $this->Error("SQL error: $this->{sql}\nERROR MSG:\n$@") if $@ ;
346 0           return 1 ;
347             }
348            
349             ##########
350             # DELETE #
351             ##########
352            
353             sub delete {
354 0     0 0   my $this = shift ;
355 0           my ($table , $where) = @_ ;
356            
357 0           $table = _format_table_name($table) ;
358            
359 0 0         if (! $table) { $this->Error('Invalid table!') ;}
  0            
360            
361 0           $where = &HDB::Parser::Parse_Where($where,$this) ;
362            
363 0           $this->{sql} = "DELETE FROM $table $where" ;
364            
365 0           eval {
366 0 0         $this->lock_table($table) if $this->{SQL}{LOCK_TABLE} ;
367 0           $this->dbh->do( $this->{sql} ) ;
368 0 0         $this->unlock_table($table) if $this->{SQL}{LOCK_TABLE} ;
369             };
370            
371 0 0         return $this->Error("SQL error: $this->{sql}\nERROR MSG:\n$@") if $@ ;
372 0           return 1 ;
373             }
374            
375             ##########
376             # CREATE #
377             ##########
378            
379             sub create {
380 0     0 0   my $this = shift ;
381 0           my ($table , @cols) = @_ ;
382            
383 0           $table = _format_table_name($table) ;
384            
385 0 0         if ($#_ == 1) { @cols = HDB::CORE::parse_ref($_[1]) ;}
  0            
386            
387 0 0         if (! $table) { $this->Error('Invalid table!') ;}
  0            
388 0 0         if (! @cols) { $this->Error('Cols not paste!') ;}
  0            
389            
390 0           my %tables = map { ("\L$_\E") => 1 } ($this->tables) ;
  0            
391 0 0         if ( $tables{"\L$table\E"} ) { return ;}
  0            
392            
393 0           my (%cols,@order) ;
394            
395 0           for (my $i = 0 ; $i <= $#cols ; $i+=1) {
396 0           my $name = $cols[$i] ;
397 0           my $type ;
398            
399 0 0         if (ref($name)) {
400 0           $name = HDB::CORE::parse_ref($name) ;
401 0           $type = 'DEFAULT' ;
402             }
403 0           else { $type = $cols[$i+1] ; $i++ ;}
  0            
404            
405 0           my $is_primary ;
406 0 0         if ($name =~ /^\s*\*/) { $name =~ s/^\s*\*\s*//gs ; $is_primary = 1 ;}
  0            
  0            
407            
408 0           $name =~ s/^\s+//gs ;
409 0           $name =~ s/\s+$//gs ;
410            
411 0           $type = $this->get_type( $type , $name ) ;
412            
413 0 0         if ($is_primary) { $type = $this->Set_PRIMARYKEY($type) ;}
  0            
414            
415 0           push(@order , $name) ;
416 0           $cols{$name} = $type ;
417             }
418            
419 0 0         if (ref($_[1]) eq 'HASH') { @order = sort @order ;}
  0            
420            
421 0 0         if (! $cols{id}) {
422 0           push(@order , 'id') ;
423 0           $cols{id} = $this->AUTOINCREMENT() ;
424 0 0         if ($cols{id} !~ /PRIMARY[\s_-]*KEY/si) { $cols{id} .= ' PRIMARY KEY' ;}
  0            
425             }
426            
427 0           $this->{sql} = "CREATE TABLE $table (" ;
428            
429 0           my $c ;
430 0           foreach my $order_i ( @order ) {
431 0 0         if (++$c > 1) { $this->{sql} .= " , " ;}
  0            
432 0           $this->{sql} .= "$order_i $cols{$order_i}" ;
433             }
434            
435 0           $this->{sql} .= ")" ;
436            
437 0           eval { $this->dbh->do( $this->{sql} ) };
  0            
438            
439 0 0         return $this->Error("SQL error: $this->{sql}\nERROR MSG:\n$@") if $@ ;
440            
441 0 0         $this->ON_CREATE($table,\%cols,\@order) if $this->can('ON_CREATE') ;
442            
443 0           return 1 ;
444             }
445            
446             #######
447             # CMD #
448             #######
449            
450             sub cmd {
451 0     0 0   my $this = shift ;
452            
453 0           $this->{sql} = $_[0] ;
454 0           my $return = $_[1] ;
455            
456 0           $this->_undef_sth ;
457            
458 0           eval{
459 0           $this->{sth} = $this->dbh->prepare( $this->{sql} ) ;
460 0           $this->{sth}->execute ;
461             };
462            
463 0 0         return $this->Error("SQL error: $this->{sql}") if $@ ;
464            
465 0           return $this->Return( $return ) ;
466             }
467            
468             #########
469             # NAMES #
470             #########
471            
472             sub names {
473 0     0 0   my $this = shift ;
474 0           my ( $table ) = @_ ;
475            
476 0           $table = _format_table_name($table) ;
477            
478 0 0         if (! $table) { return $this->Error('Invalid table!') ;}
  0 0          
479 0           elsif ( $this->{CACHE}{names}{$table} ) { return @{ $this->{CACHE}{names}{$table} } ;}
  0            
480            
481 0 0         if ( $this->{SQL}{SHOW} ) { $this->{sql} = "SHOW COLUMNS FROM $table" ;}
  0 0          
482 0           elsif ( $this->{SQL}{LIMIT} ) { $this->{sql} = "SELECT * FROM $table LIMIT 1" ;}
483 0           else { $this->{sql} = "SELECT * FROM $table" ;}
484            
485 0           $this->_undef_sth ;
486 0           eval{
487 0           $this->{sth} = $this->dbh->prepare( $this->{sql} ) ;
488 0           $this->{sth}->execute ;
489             };
490            
491 0 0         return $this->Error("SQL error: $this->{sql}") if $@ ;
492            
493 0           my @names ;
494            
495 0 0         if ( $this->{SQL}{SHOW} ) {
496 0           while (my $ref = $this->{sth}->fetchrow_arrayref) { push(@names , @$ref[0]) ;}
  0            
497             }
498             else {
499             ## substr() to make a copy of the value and avoid DBI bug!
500 0           eval { @names = map { substr($_ , 0) } @{ $this->{sth}->{'NAME'} } };
  0            
  0            
  0            
501             #eval { @names = @{ $this->{sth}->{'NAME'} } };
502             }
503            
504 0           $this->_undef_sth ;
505            
506 0 0         return () if !@names ;
507            
508 0 0         if ( $this->{cache} ) {
509 0           $this->{CACHE}{names}{$table} = \@names ;
510             }
511            
512 0           return @names ;
513             }
514            
515             ##########
516             # TABLES #
517             ##########
518            
519             sub tables {
520 0     0 0   my $this = shift ;
521            
522 0           my @tables = map {
523 0           $_ =~ s/.*\.//;
524 0           $_ =~ s/(['"`])(.*)\1/$2/gs; ## some DB return quoted.
525 0           $_
526             } $this->dbh->tables() ;
527            
528 0           return( sort @tables ) ;
529             }
530            
531             ###############
532             # TABLES_HASH #
533             ###############
534            
535             sub tables_hash {
536 0     0 0   return map { $_ => 1 } $_[0]->tables ;
  0            
537             }
538            
539             ################
540             # TABLE_EXISTS #
541             ################
542            
543             sub table_exists {
544 0     0 0   my %tables = $_[0]->tables ;
545 0 0         return 1 if $tables{$_[1]} ;
546 0           return ;
547             }
548            
549             #################
550             # TABLE_COLUMNS #
551             #################
552            
553             sub table_columns {
554 0     0 0   my $this = shift ;
555 0           my ( $table ) = @_ ;
556            
557 0 0         if (! $table) { $this->Error('Invalid table!') ; return ;}
  0            
  0            
558            
559 0           return $this->dbh->table_info($table) ;
560             }
561            
562             ########
563             # DROP #
564             ########
565            
566             sub drop {
567 0     0 0   my $this = shift ;
568 0           my ( $table ) = @_ ;
569            
570 0           $table = _format_table_name($table) ;
571            
572 0 0         if (! $table) { $this->Error('Invalid table!') ; return ;}
  0            
  0            
573            
574 0           my %tables = map { ("\L$_\E") => 1 } ($this->tables) ;
  0            
575 0 0         if (! $tables{"\L$table\E"} ) { return ;}
  0            
576            
577 0           $this->flush_table_cache($table) ;
578            
579 0           eval{ $this->dbh->do("DROP TABLE $table") };
  0            
580            
581 0 0         return $this->Error("DROP ERROR: table $table") if $@ ;
582            
583 0 0         $this->ON_DROP($table) if $this->can('ON_DROP') ;
584            
585 0           return 1 ;
586             }
587            
588             ##############
589             # DUMP_TABLE #
590             ##############
591            
592             sub dump_table {
593 0     0 0   my $this = shift ;
594 0           my ( $table ) = @_ ;
595            
596 0           $table = _format_table_name($table) ;
597            
598 0 0         if (!$table) { $this->Error('Invalid table!') ; return ;}
  0            
  0            
599            
600 0           my $dump ;
601            
602 0           $dump .= "TABLE $table:\n\n" ;
603            
604 0           my %cols = $this->table_columns($table) ;
605 0           my @cols = $this->names($table) ;
606            
607 0           foreach my $Key (@cols) {
608 0           $dump .= " $Key = $cols{$Key}\n" ;
609             }
610            
611 0           $dump .= "\nROWS:\n\n" ;
612            
613 0           my @sel = $this->select( $table , '@$' ) ;
614 0           foreach my $sel_i ( @sel ) {
615 0           $dump .= "$sel_i\n" ;
616             }
617            
618 0           return $dump ;
619             }
620            
621             ###############
622             # FLUSH_CACHE #
623             ###############
624            
625             sub flush_cache {
626 0 0   0 0   if ( !$_[0]->{CACHE} ) { return ;}
  0            
627 0           my @sth = $_[0]->_get_cache_sth ;
628 0           delete $_[0]->{CACHE} ;
629 0 0         foreach my $sth_i ( @sth ) { $sth_i->finish if $sth_i ;}
  0            
630 0           return 1 ;
631             }
632            
633             #####################
634             # FLUSH_TABLE_CACHE #
635             #####################
636            
637             sub flush_table_cache {
638 0     0 0   my $this = shift ;
639 0           my ( $table ) = @_ ;
640            
641 0           $table = _format_table_name($table) ;
642            
643 0 0         if ( !$this->{CACHE} ) { return ;}
  0            
644            
645 0           my @sth = $this->_get_cache_table_sth($table) ;
646            
647 0           delete $this->{CACHE}{names}{$table} ;
648 0           delete $this->{CACHE}{insert}{$table} ;
649 0           delete $this->{CACHE}{update}{$table} ;
650            
651 0 0         foreach my $sth_i ( @sth ) { $sth_i->finish if $sth_i ;}
  0            
652            
653 0           return 1 ;
654             }
655            
656             ######################
657             # _FORMAT_TABLE_NAME #
658             ######################
659            
660             sub _format_table_name {
661 0     0     my ( $table ) = @_ ;
662 0           $table =~ s/(?:\.|::)/_/gs ;
663 0           $table =~ s/[^\w\.]//gs ;
664 0           return $table ;
665             }
666            
667             #######################
668             # _FORMAT_COLUMN_NAME #
669             #######################
670            
671             sub _format_column_name {
672 0     0     my ( $col ) = @_ ;
673 0           $col =~ s/(?:\.|::)/_/gs ;
674 0           $col =~ s/[^\w\.]//gs ;
675 0           return $col ;
676             }
677            
678             ##################
679             # _GET_CACHE_STH #
680             ##################
681            
682             sub _get_cache_sth {
683 0     0     my $cache = $_[0]->{CACHE} ;
684 0           my @types = qw(insert update) ;
685            
686 0           my @sth ;
687            
688 0           foreach my $types_i ( @types ) {
689 0           foreach my $Key ( keys %{$$cache{$types_i}} ) {
  0            
690 0           push(@sth , $$cache{$types_i}{$Key}{sth} ) ;
691             }
692             }
693            
694 0           return @sth ;
695             }
696            
697             ########################
698             # _GET_CACHE_TABLE_STH #
699             ########################
700            
701             sub _get_cache_table_sth {
702 0     0     my $cache = $_[0]->{CACHE} ;
703 0           my $table = $_[1] ;
704 0           my @types = qw(insert update) ;
705            
706 0           my @sth ;
707            
708 0           foreach my $types_i ( @types ) {
709 0           push(@sth , $$cache{$types_i}{$table}{sth} ) ;
710             }
711            
712 0           return @sth ;
713             }
714            
715             ##############
716             # _UNDEF_STH #
717             ##############
718            
719             sub _undef_sth {
720 0 0   0     if ( $_[0]->{sth} ) {
721 0           $_[0]->{sth}->finish ;
722 0           $_[0]->{sth} = undef ;
723             }
724             }
725            
726             ##########
727             # RETURN #
728             ##########
729            
730             sub Return {
731 0     0 0   my $this = shift ;
732 0           my ( $return ) = @_ ;
733            
734 0           my $ret_names ;
735            
736 0           $return =~ s/\s//gs ;
737 0 0         if ($return =~ /^(?:n|c)/si ) {
738 0           $ret_names = 1 ;
739 0           $return =~ s/[^\$\@\%<>]//gs ;
740             }
741            
742 0 0         if ($return !~ /^(?:\$?[\$\@\%]{1,2}|<[\$\@\%]>)$/ ) { $return = '$' ;}
  0            
743            
744 0           $return =~ s/^\$\$\%$/\$\$\@/ ;
745 0           $return =~ s/^\%\%$/\$\%/ ;
746            
747 0   0       my $sth = $_[1] || $this->{sth} ;
748 0 0         return undef if !$sth ;
749            
750 0 0         if ($return =~ /<\s*([\$\@\%])\s*>\s*$/) {
751 0           my $type = $1 ;
752 0           local(*HANDLE);
753 0           tie(*HANDLE, 'HDB::CMDS::TieHandle',$sth,$type) ;
754 0           return( \*HANDLE ) ;
755             }
756            
757 0           my $ret_type ;
758 0 0         if ($return =~ /\@$/) { $ret_type = 1 ;}
  0 0          
759 0           elsif ($return =~ /\%$/) { $ret_type = 2 ;}
760            
761 0           my @names ;
762            
763 0           eval{
764 0           my $names = $sth->{'NAME'} ;
765 0           @names = @{$names} ;
  0            
766             };
767            
768 0 0         if (! @names) { $this->_undef_sth ; return undef ;}
  0            
  0            
769            
770 0           my @rows ;
771 0           while (my $ref = $sth->fetchrow_arrayref) {
772 0           foreach my $ref_i ( @$ref ) {
773 0           &HDB::Parser::unfilter_null_bytes($ref_i) ;
774            
775 0 0         if ( &HDB::Encode::Is_Packed_HASH($ref_i) ) { $ref_i = &HDB::Encode::UnPack_HASH($ref_i) ;}
  0 0          
776 0           elsif ( &HDB::Encode::Is_Packed_ARRAY($ref_i) ) { $ref_i = &HDB::Encode::UnPack_ARRAY($ref_i) ;}
777             }
778 0 0         if ($ret_type == 1) { push(@rows , [@$ref]) ;}
  0 0          
779             elsif ($ret_type == 2) {
780 0           my %hash ;
781 0           for my $i (0..$#names) { $hash{ $names[$i] } = $$ref[$i] ;}
  0            
782 0           push(@rows , \%hash) ;
783             }
784 0           else { push(@rows , join("::" , @$ref ) ) ;}
785             }
786            
787 0           $this->_undef_sth ;
788            
789 0           my @ret_names ;
790            
791 0 0         if ($ret_names) { @ret_names = \@names ;}
  0            
792            
793 0 0         if ($return =~ /^[\@\%\$]$/) {
    0          
    0          
    0          
    0          
    0          
794 0 0         if (wantarray) { return( @ret_names , @rows ) ;}
  0            
795 0           else { return( $rows[0] ) ;}
796             }
797 0           elsif ($return =~ /^\$\$$/) { return( @ret_names , $rows[0] ) ;}
798 0           elsif ($return =~ /^\$\@$/) { return( @ret_names , @{ $rows[0] } ) ;}
  0            
799 0           elsif ($return =~ /^\$\%$/) { return( @ret_names , %{ $rows[0] } ) ;}
  0            
800             elsif ($return =~ /^\$\$\@$/) {
801 0 0         if ( ref( @{$rows[0]}[0] ) eq 'HASH' ) { return( @ret_names , %{@{$rows[0]}[0]} ) ;}
  0 0          
  0            
  0            
  0            
  0            
802 0           elsif ( ref( @{$rows[0]}[0] ) eq 'ARRAY' ) { return( @ret_names , @{@{$rows[0]}[0]} ) ;}
  0            
  0            
803 0           else { return( @ret_names , @{ $rows[0] } ) ;}
  0            
804             }
805 0           elsif ($return =~ /^\@[\@\%\$]$/) { return( @ret_names , @rows ) ;}
806             }
807            
808             # $
809             # @
810             # %
811             # @@
812             # @%
813             # %%
814            
815             ############
816             # GET_TYPE #
817             ############
818            
819             sub get_type {
820 0     0 0   my $this = shift ;
821 0           my ( $type , $name ) = @_ ;
822            
823 0           $type =~ s/^\s+//gs ;
824 0           $type =~ s/\s+$//gs ;
825            
826             ## *
827            
828 0 0         if ($type =~ /^(?:\*|)$/s) { $type = 'TEXT' ;}
  0            
829            
830            
831             ## TEXT
832            
833 0 0 0       if ($type eq 'TEXT' || $type =~ /^(?:TEXT\s*)?(\d+|\(\s*\d+\s*\))$/s) {
834 0           my $sz = $1 ; $sz =~ s/\D//gs ;
  0            
835 0 0         $sz = 65535 if $sz eq '' ;
836            
837 0 0         if ( !$this->Accept_Type('TEXT') ) { $type = $this->Type_TEXT($sz) ;}
  0            
838             else {
839 0 0         if ($sz == 0) { $type = "INTEGER" ;}
  0 0          
    0          
    0          
    0          
840 0           elsif ($sz <= 255) { $type = "VARCHAR($sz)" ;}
841 0           elsif ($sz <= 65535 ) { $type = 'TEXT' ;}
842 0           elsif ($sz <= 16777215 ) { $type = 'MEDIUMTEXT' ;}
843 0           elsif ($sz <= 4294967295 ) { $type = 'LONGTEXT ' ;}
844 0 0         if ( !$this->Accept_Type($type) ) { $type = $this->Type_TEXT($sz) ;}
  0            
845             }
846             }
847            
848             ## INTEGER
849            
850 0 0         if ($type =~ /^(?:INTEGER|INT)\s*(?:\(?([\+\-]?\d+|\w+)\)?|)$/si) {
    0          
    0          
    0          
    0          
    0          
851 0           my $sz = $1 ;
852            
853 0 0         if ( !$this->Accept_Type('INTEGER') ) { $type = $this->Type_INTEGER($sz) ;}
  0            
854             else {
855 0 0         if (!$sz) { $type = "INTEGER" ;}
  0 0          
    0          
    0          
    0          
    0          
856 0           elsif ($sz =~ /^(?:t|tin|shor)/i) { $type = "TINYINT" ;}
857 0           elsif ($sz =~ /^(?:s|sma)/i) { $type = "SMALLINT" ;}
858 0           elsif ($sz =~ /^(?:m|med)/i) { $type = "MEDIUMINT" ;}
859 0           elsif ($sz =~ /^(?:b|big)/i) { $type = "BIGINT" ;}
860             elsif ($sz =~ /^[\+\-]?\d+$/) {
861 0 0 0       if ($sz >= -127 && $sz <= 127) { $type = "TINYINT" ;}
  0 0 0        
    0 0        
    0 0        
    0 0        
862 0           elsif ($sz >= -32768 && $sz <= 32767) { $type = "SMALLINT" ;}
863 0           elsif ($sz >= -8388608 && $sz <= 8388607) { $type = "MEDIUMINT" ;}
864 0           elsif ($sz >= -2147483648 && $sz <= 2147483647) { $type = "INTEGER" ;}
865 0           elsif ($sz < -2147483648 || $sz > 2147483647) { $type = "BIGINT" ;}
866             }
867 0 0         if (! $this->Accept_Type($type)) { $type = $this->Type_INTEGER($sz) ;}
  0            
868             }
869             }
870            
871             ## FLOAT
872            
873             elsif ($type =~ /^(\s*[\+\-]\s*(?:FLOATING|FLOAT|DOUBLE))\s*(?:\((.*?)\)|())$/si) {
874 0           $type = $this->Type_FLOAT($1,$2) ;
875             }
876            
877             ## INT
878            
879             elsif ($type =~ /\w+INT$/si) {
880 0 0         if (! $this->Accept_Type($type)) { $type = 'INTEGER' ;}
  0            
881             }
882            
883             ## BOOLEAN
884            
885 0           elsif ($type =~ /^(?:boolean|boo?l)$/si) { $type = 'BOOLEAN' ;}
886            
887             ## AUTO
888            
889 0           elsif ($type =~ /^(?:AUTOINCREMENT|AUTO)$/si) { $type = $this->AUTOINCREMENT() ;}
890            
891             ## DEF
892            
893             elsif ($type =~ /^(?:DEFAULT|DEF)$/si) {
894 0   0       $type = $DEFAULT_COLS{$name} || 'TEXT' ;
895 0           $type = $this->get_type($type) ;
896             }
897            
898             ## TYPE MASK:
899            
900 0 0 0       if ( $this->{SQL}{TYPES_MASK} && $this->{SQL}{TYPES_MASK}{$type} ) {
901 0           $type = $this->{SQL}{TYPES_MASK}{$type} ;
902             }
903            
904 0           return( $type ) ;
905             }
906            
907             ##################
908             # SET_PRIMARYKEY #
909             ##################
910            
911             sub Set_PRIMARYKEY {
912 0     0 0   my $this = shift ;
913 0           my ( $type ) = @_ ;
914            
915 0           my $primarykey = $this->PRIMARYKEY() ;
916 0           my $primarykey_re = $primarykey ;
917 0           $primarykey_re =~ s/\s+/\\s\+/gs ;
918            
919 0 0         if ($type !~ /$primarykey_re/si) { $type .= " $primarykey" ;}
  0            
920            
921 0           return( $type ) ;
922             }
923            
924             ###############
925             # ACCEPT_TYPE #
926             ###############
927            
928             sub Accept_Type {
929 0     0 0   my $this = shift ;
930 0           my $type = "\L$_[0]\E" ;
931            
932 0 0         if (ref($this->{SQL}{TYPES}) eq 'ARRAY') {
933 0           my %types = map { ("\L$_\E") => 1 } @{ $this->{SQL}{TYPES} } ;
  0            
  0            
934 0           $this->{SQL}{TYPES} = \%types ;
935             }
936            
937 0 0 0       if ( $this->{SQL}{TYPES}{$type} || $this->{SQL}{TYPES}{'*'} ) { return( 1 ) ;}
  0            
938 0           return( undef ) ;
939             }
940            
941             ########################
942             # HDB::CMDS::TIEHANDLE #
943             ########################
944            
945             package HDB::CMDS::TieHandle ;
946            
947             sub TIEHANDLE {
948 0     0     my $class = shift ;
949 0           my $this = { sth => $_[0] , type => $_[1] } ;
950 0           bless($this , $class) ;
951             }
952            
953             sub READLINE {
954 0     0     my $this = shift ;
955 0           my $sth = $this->{sth} ;
956            
957 0 0         if ($this->{type} eq "\$") {
    0          
    0          
958 0 0         my $ref = $sth->fetchrow_arrayref ; return if !$ref ;
  0            
959 0           return( join("::" , @$ref ) ) ;
960             }
961             elsif ($this->{type} eq "\@") {
962 0 0         my $ref = $sth->fetchrow_arrayref ; return if !$ref ;
  0            
963 0           foreach my $ref_i ( @$ref ) {
964 0           &HDB::Parser::unfilter_null_bytes($ref_i) ;
965            
966 0 0         if ( &HDB::Encode::Is_Packed_HASH($ref_i) ) { $ref_i = &HDB::Encode::UnPack_HASH($ref_i) ;}
  0 0          
967 0           elsif ( &HDB::Encode::Is_Packed_ARRAY($ref_i) ) { $ref_i = &HDB::Encode::UnPack_ARRAY($ref_i) ;}
968             }
969 0           return( @$ref ) ;
970             }
971             elsif ($this->{type} eq "\%") {
972 0 0         my $ref = $sth->fetchrow_hashref ; return if !$ref ;
  0            
973 0           foreach my $Key ( keys %$ref ) {
974 0           &HDB::Parser::unfilter_null_bytes($$ref{$Key}) ;
975            
976 0 0         if ( &HDB::Encode::Is_Packed_HASH($$ref{$Key}) ) { $$ref{$Key} = &HDB::Encode::UnPack_HASH($$ref{$Key}) ;}
  0 0          
977 0           elsif ( &HDB::Encode::Is_Packed_ARRAY($$ref{$Key}) ) { $$ref{$Key} = &HDB::Encode::UnPack_ARRAY($$ref{$Key}) ;}
978             }
979 0           return( %$ref ) ;
980             }
981            
982 0           return ;
983             }
984            
985 0     0     sub DESTROY {
986            
987             }
988            
989             #######
990             # END #
991             #######
992            
993             1;
994            
995             __END__