File Coverage

blib/lib/DBI/BabyConnect.pm
Criterion Covered Total %
statement 64 1882 3.4
branch 5 576 0.8
condition 0 310 0.0
subroutine 20 126 15.8
pod 46 71 64.7
total 135 2965 4.5


line stmt bran cond sub pod time code
1             package DBI::BabyConnect;
2              
3 1     1   22231 use strict;
  1         2  
  1         35  
4 1     1   5 use Carp;
  1         1  
  1         86  
5 1     1   5 use warnings;
  1         5  
  1         25  
6              
7 1     1   2237 use DBI;
  1         41441  
  1         76  
8 1     1   1295 use Time::HiRes ();
  1         1932  
  1         24  
9 1     1   7782 use Time::localtime; # needed for iso_date() function
  1         8014  
  1         99  
10              
11              
12             our @ISA = qw();
13             our $VERSION = '0.93';
14              
15             #BEGIN{ $0 =~ /(.*)(\\|\/)/; push @INC, $1 if $1; }
16              
17             # DEPRECATED: THE CONFIGURATION DATA IS READ FROM >>>>>>>>>>.. VS_CONFIG.PM
18             # /usr/lib/perl5/site_perl/5.8/VS_HOME.pm
19             #use VS_CONFIG;
20             #use constant DBSETTING_FORCE_SINGLESPACE_FOR_EMPTY_STRING => VS_CONFIG::DBSETTING_FORCE_SINGLESPACE_FOR_EMPTY_STRING;
21             #my $DATABASE_CONFIGURATION_DIR = VS_CONFIG::DB_CONFIG_DIR;
22             #my $SCHEMA_REPOS = VS_CONFIG::CONFIG_DIR . '/SQL/TABLES';
23              
24              
25             #The following signals have been redefined in the IO Section in this file
26             #$SIG{__DIE__} = sub { print STDERR "DIE: $_[0]" };
27             #$SIG{__WARN__} = sub { print STDERR "WARN: $_[0]" };
28              
29             # This is an internal flag that enforces the connection/disconnection
30             #use constant CALLER_DISCONNECT => 1;
31              
32             # This is an internal flag used by the author to enable debug
33             # info when ending this class
34             #use constant PRT_CEND => 0;
35              
36              
37             # to monitor the internal state of a BabyConnect object handle (during run time)
38             # and setting the state to ISTATE_CRISIS allows to build a logical plan
39             # of execution to know what to do next (i.e. when ON_FAILED_DBIEXECUTE_ROLLBACK_AND_EXIT)
40 1     1   9 use constant ISTATE_UNDEF => 0;
  1         2  
  1         181  
41 1     1   6 use constant ISTATE_GOOD => 1;
  1         2  
  1         51  
42 1     1   5 use constant ISTATE_CRISIS => -1;
  1         3  
  1         60  
43              
44             # The $SKELETON is a struc to hold basic skeletal table by database type
45             # and it is used by many of the author applications, for example when
46             # creating dynamic table for webProcessors (Varisphere Processing Server)
47              
48 1     1   6 use constant SKELETON_MYSQL => <
  1         1  
  1         202  
49             drop table <<>>
50             ~
51             CREATE TABLE <<>> (
52             ID bigint(20) unsigned NOT NULL AUTO_INCREMENT,
53             LOOKUP varchar(14) default NULL,
54             <<>>
55             RECORDDATE_T timestamp(14) NOT NULL,
56             PRIMARY KEY (ID), UNIQUE KEY ID (ID) ) TYPE=MyISAM
57              
58             SKELETON_MYSQL
59              
60 1     1   6 use constant SKELETON_ORA => <
  1         2  
  1         11624  
61              
62             drop trigger BIR_<<>>
63             ~
64             drop sequence <<>>_SEQ
65             ~
66             drop table <<>>
67              
68             ~
69             create table <<>> (
70             ID number(20) NOT NULL,
71             LOOKUP varchar(14) DEFAULT NULL,
72             <<>>
73             RECORDDATE_T timestamp NOT NULL
74             )
75              
76             ~
77             -- create a sequence
78             create sequence <<>>_SEQ
79              
80             ~
81             -- do not forget the ; at the end of the trigger
82             create trigger BIR_<<>>
83             before insert on <<>>
84             for each row
85             begin
86             select <<>>_SEQ.nextval into :new.ID from dual;
87             end;
88              
89             ~alter table <<>> add constraint <<>>_PK primary key(ID)
90             SKELETON_ORA
91              
92             my $SKELETON =
93             {
94             ora => SKELETON_ORA,
95             mysql => SKELETON_MYSQL,
96             };
97              
98              
99             # export BABYCONNECT=/opt/DBI-BabyConnect/configuration
100             my $ENV_BABYCONNECT = $ENV{BABYCONNECT};
101             $ENV_BABYCONNECT ||= "./configuration";
102              
103             my $DATABASE_CONFIGURATION_DIR = $ENV_BABYCONNECT . "/dbconf";
104             my $SCHEMA_REPOS = $ENV_BABYCONNECT. '/SQL/TABLES';
105              
106             die "
107             Cannot read configuration directory: $ENV_BABYCONNECT!
108             You may have not set the BABYCONNECT environment variable. You need
109             to set and export the environment variable BABYCONNECT to point to the
110             directory where your configuration files reside. For example:
111             export BABYCONNECT=/opt/DBI-BabyConnect-0.93/configuration
112             If you are using Apache::BabyConnect then you need to export the
113             environment variable prior to loading this module, for example:
114             PerlSetEnv BABYCONNECT /opt/DBI-BabyConnect-0.93/configuration
115             PerlRequire /opt/DBI-BabyConnect-0.93/startupscripts/babystartup.pl
116              
117             Refer to the documentation of this module to understand how the
118             configuration directory is structured.
119              
120             " unless -d $ENV_BABYCONNECT;
121              
122             die "
123             now I am using the environment variable BABYCONNECT as being set to: $ENV_BABYCONNECT
124             but I do not seem be able o locate the database configuration directory: $DATABASE_CONFIGURATION_DIR
125              
126             " unless -d $DATABASE_CONFIGURATION_DIR;
127              
128             #die "Cannot read the ..." unless -d $SCHEMA_REPOS;
129              
130              
131             # a set of parameters that will affect the whole behavior of a BabyConnect object
132             my @xprm =
133             qw(
134             DBSETTING_FORCE_SINGLESPACE_FOR_EMPTY_STRING
135             CALLER_DISCONNECT
136             ON_FAILED_DBIEXECUTE_ROLLBACK_AND_EXIT
137             ENABLE_STATISTICS_ON_DO
138             ENABLE_STATISTICS_ON_SPC
139             PRT_CEND
140             );
141              
142             my %xprm = map{$_=>0}@xprm;
143              
144              
145             {
146             # if the globalconf.pl is found then parse its parameters
147             my $file = "$DATABASE_CONFIGURATION_DIR/globalconf.pl";
148             if (-f $file) {
149             open (F, "<$file") || die __PACKAGE__, " EXITING BECAUSE CANNOT OPEN THE GLOBAL CONFIG FILE $file!\n";
150             while() {
151             s/\r//; s/\n//;
152             next if ($_ =~ /^#/) || ($_ =~ /^$/);
153             my ($l,$r) = split(/=/,$_);
154             # attn, if a param is redefined then will pick on the last one read
155             foreach my $p ( @xprm ) {
156             ($l eq $p) && ($xprm{$p} = $r);
157             }
158             }
159             close F;
160             }
161             }
162              
163             # $db_ref hold a reference to a set of DB identifiers called descriptors.
164             # When using Apache::BabyConnect, the programmer will use these descriptors to effectively
165             # cache instances of DBI::BabyConnect objects, since it is simpler to keep
166             # track of what he is doing.
167             my $db_ref;
168             {
169             # TODO: glob all *.conf files and build the $db_ref
170             my $file = "$DATABASE_CONFIGURATION_DIR/databases.pl";
171             if (! -f $file) {
172             $db_ref = {};
173             # it is not nevessary to have the databases.pl file.
174             #die __PACKAGE__, " EXITING BECAUSE CANNOT FIND FILE $file!\n";
175             }
176             else {
177             # if there is such a databases.pl file, then try to open it
178             open (F, "<$file") || die __PACKAGE__, " EXITING BECAUSE CANNOT OPEN THE DATABASE DESCRIPTORS FILE $file!\n";
179             my $s; while() { $s .= $_; } close F;
180             $db_ref = eval $s;
181             if ($@) {
182             die "
183             I located the file $file
184             and tried to evaluate it as being a Perl struct
185             bu the eval failed with the following error:
186             $@
187              
188             ";
189             }
190             }
191             }
192              
193             # glob $ENV{CONFIG}/db_ref/*.conf and get a hash
194             # mapping descriptor-file-name to fully-specified-file-name
195             my %dbR;
196             {
197             #my $baseDir = $ENV{CONFIG} || '/app/lcdbdev/config';
198             my $baseDir = $DATABASE_CONFIGURATION_DIR;
199             my(@files)=glob("$baseDir/*.conf");
200             foreach my $f (@files) {
201             my $dsc = $f;
202             $dsc =~ s/^$baseDir\///;
203             $dsc =~ s/\.conf$//;
204             $dbR{$dsc} = $f;
205             }
206             }
207              
208              
209              
210             # a dbiParams object that is set to default values
211             # but can be overwritten when parsing the
212             # config file (_confFromFile) or loading the config
213             # object (_confFromObject called via reconnect() )
214             ##my $Driver = "mysql";
215             ##my $Server = "";
216              
217             my $dbiParams = {
218             Driver => "",
219             Server => "",
220             UserName => "",
221             Password => "",
222             DataName => "",
223              
224             # Driver => "mysql",
225             # Server => "",
226             # UserName => "dadada",
227             # Password => "dedede",
228             # DataName => "testdb",
229              
230             # PrintError => 0,
231             # RaiseError => 0,
232             # AutoCommit => 1,
233             # AutoRollback => 1, # handled within this class
234             # LongTruncOk=>1,
235             # LongReadLen=>900000,
236              
237             #Connections = 1,
238             #PollingInterval = 5000,
239             };
240              
241             # The database handle attributes are defined within the
242             # object $dbiLags. These attributes can be passed when
243             # getting an initial db handle from the DBI, except for
244             # the AutoRollback attribute whose behavior is programmed
245             # within this class.
246             my $dbiLags =
247             {
248             PrintError => 0,
249             RaiseError => 0,
250             AutoCommit => 0, # when this is 0 then rollback is possible, otherwise it is ineffective
251             AutoRollback => 1, # handled within this class
252             LongTruncOk=>1,
253             LongReadLen=>900000,
254             };
255              
256              
257              
258 0     0   0 sub _no_filter { return $_[0]; }
259              
260             my $statCC = {};
261             my $ENABLE_CACHING = 0;
262             my $PERSISTENT_OBJECT_ENABLED = 0;
263             sub import {
264 1     1   12 my ($class, $enableCaching, $disableDestroy) = @_;
265 1 50       3 $enableCaching && ($ENABLE_CACHING = $enableCaching);
266 1 50       13 $disableDestroy && ($PERSISTENT_OBJECT_ENABLED = $disableDestroy);
267             }
268             # check for the persistent database connection Apache::BabyConnect
269             #if ($INC{'Apache/BabyConnect.pm'}) {
270             # $DBI::BabyConnect::connect_via = "Apache::BabyConnect::connect";
271             #}
272             my %CACHED_CONN=();
273              
274              
275             ########################################################################################
276             ########################################################################################
277             #
278             sub new {
279 0     0 1 0 my $class = shift;
280 0         0 my $conf = shift;
281              
282             #my %args = @_;
283              
284              
285             #print STDERR "*** DBI::BabyConnect NEW, ENABLE_CACHING=$ENABLE_CACHING PERSISTENT_OBJECT_ENABLED=$PERSISTENT_OBJECT_ENABLED ", caller, "\n";
286              
287             #my $dbi_connect_method = ($DBI::BabyConnect::connect_via eq "Apache::BabyConnect::connect")
288             # ? 'Apache::BabyConnect::connect' : 'connect_cached';
289             #use Apache::BabyConnect;
290             #if ($DBI::BabyConnect::connect_via eq "Apache::BabyConnect::connect") {
291             # ##return $dbi_connect_method($conf,%args);
292             # foreach my $cn (keys %CACHED_CONN) {
293             # if ($cn eq $conf) {
294             # print STDERR "******************** FOUND A CACHED CONNECTION FOR: $cn\n";
295             # return $CACHED_CONN{$conf};
296             # }
297             # }
298             #}
299 0 0       0 if ($ENABLE_CACHING) {
300 0         0 my $s1 = $$ . $conf;
301 0         0 foreach (keys %CACHED_CONN) {
302             #print STDERR "[$s1] iCOMPARE\n[$_]\n\n";
303 0 0       0 if ($s1 eq $_) {
304             #print STDERR "******************** FOUND A CACHED CONNECTION FOR: $$ + $conf with DESCRIPTOR ${$$statCC{$$ . $conf}}{descriptor}\n";
305             #print STDERR "****** CACHED CLASS = ${$CACHED_CONN{$$ . $conf}}{class} \n";
306 0         0 _statCC($$,$conf);
307             #return $CACHED_CONN{$conf};
308 0         0 return ${$CACHED_CONN{$$ . $conf}}{class};
  0         0  
309             }
310             }
311             }
312             #print STDERR " ****************************** MAKING NEW CONNECTION FOR $conf\n";
313              
314              
315 0         0 my $self = {
316             };
317              
318 0   0     0 bless $self, ref $class || $class ;
319              
320             # We will hold a reference to a hash to cache the configuration data into an object
321             # as this is useful when we need to reconnect() in such a situation where a thread is
322             # being used. This is useful for a database whose driver does not support sharing
323             # connection via threads. Quite typical, that a db will not be able to update concurrently
324             # a db record from two different threads. Threads can also run on multiple CPU, but
325             # updating a record should be done from a single point ...
326 0         0 my %_CONF;
327 0         0 $self->{_CONF}=\%_CONF;
328              
329              
330             # getting a connection, from 1 to 4
331             # as curly {...}
332 0 0       0 if (ref $conf eq 'HASH') {
    0          
    0          
333 0         0 $self-> _confFromObject($conf);
334             }
335             # as a file '/cygdrive/c/opt/DBI-BabyConnect/configuration/dbconf/WEBPROCESSORS_MYSQL.conf'
336             elsif (-f $conf) {
337 0         0 $self-> _confFromFile($conf);
338             }
339             # as a reference within our evaled' loaded-hashref (/cygdrive/c/opt/DBI-BabyConnect/configuration/dbconf/databases.pl)
340             elsif (exists $$db_ref{$conf}) {
341 0         0 $self-> _confFromRef($conf);
342             }
343             # as a lastresort, try as a descriptor (i.e. 'WEBPROCESSORS_MYSQL')
344             #elsif (defined $dbR{$conf}) {
345             else {
346 0   0     0 my ($src_pkg,$src_file,$src_line,$src_meth) = (caller,(caller 1)[3] || '');
347 0         0 print STDERR "(CALLER)\n\t++ $src_pkg\n\t++ $src_meth\n\t++ $src_file\n\t++ $src_line\n(END)\n";
348              
349 0 0       0 die __PACKAGE__,"!! ERROR: NO SUCH DATABASE DESCRIPTOR TO ESTABLISH A CONNECTION [$conf]. PROGRAM EXITING.
350              
351             AS A LAST RESORT OF GETTING A CONNECTION, CANNOT LOCATE AN OBJECT FOR THAT DESCRIPTOR $conf.
352             WHEN GETTING A CONNECTION, THE PARAMETER PROVIDED IS VERIFIED IN THE FOLLOWING ORDER:
353             1- AS AN OBJECT REFERENCE THAT HOLD THE CONNECTION
354             2- AS A CONFIGURATION FILE THAT HOLD THE CONNECTION IF SUCH A FILE EXIST
355             3- AS AN IDENTIFIER (ALSO CALLED DESCRIPTOR) TO A DB CONNECTION SAVED IN databases.pl
356             4- AS A LAST RESORT, AS A DESCRIPTOR MAPPED INTO THE \$ENV{BABYCONNECT}/dbconf/*.conf
357              
358             WHEN USING Apache::BabyConnect IT IS RECOMMENDED TO USE THE IDENTIFIER OR DESCRIPTOR AS STRESSED IN (3).
359            
360             \n" unless $dbR{$conf};
361 0         0 $self-> _parseDBIAttributesFile($dbR{$conf});
362             }
363              
364             #TRUE FOR ORACLE ONLY! die "DATABASE SERVER IS NOT SPECIFIED!\n" unless defined $$dbiParams{Server};
365              
366             # Verify that the driver is loadable and get it, yet if it cannot be found then try the ODBC
367             {
368 0         0 my $drv = $$dbiParams{Driver};
  0         0  
369 0         0 my $driver;
370 0         0 my @globDBD = DBI->available_drivers;
371             # Good way to exit the loop following an assertion. Voila!
372             # Try to locate the specified driver
373 0 0 0     0 foreach (@globDBD) { !$driver && ($_ =~ /$drv/i) && ($driver = $_); }
  0         0  
374             # If the specified driver is not found, then try to load an ODBC
375 0 0 0     0 foreach (@globDBD) { !$driver && ($_ =~ /ODBC/i) && ($driver = $_); }
  0         0  
376 0 0       0 $driver || die "CANNOT FIND AN ($drv OR ODBC) DRIVER IN ( @globDBD )!\n";
377 0         0 $$dbiParams{Driver} = $driver;
378             }
379 0 0       0 $$dbiParams{Server} = "" unless defined $$dbiParams{Server};
380              
381             {
382 0         0 my $dbipath = 'DBI';
  0         0  
383 0 0       0 $dbipath .= ':' . $$dbiParams{Driver} if $$dbiParams{Driver};
384 0 0       0 $dbipath .= ':' . $$dbiParams{DataName} if $$dbiParams{DataName};
385 0 0       0 $dbipath .= ':' . $$dbiParams{Server} if $$dbiParams{Server};
386             #my $dbipath = 'DBI:';
387             # . $$dbiParams{Driver}
388             # . ':'
389             # . $$dbiParams{DataName}
390             # . ':'
391             # . $$dbiParams{Server};
392              
393             # use the temporary %dbiHandleAttr, clean the AutoRollback that is programmed in this class
394 0         0 my %dbiHandleAttr = %$dbiLags;
395 0         0 delete $dbiHandleAttr{AutoRollback};
396             #my $dbiconnection = DBI->connect($dbipath, $$dbiParams{UserName},$$dbiParams{Password},
397             # { RaiseError => $$dbiParams{RaiseError}, PrintError => $$dbiParams{PrintError}, AutoCommit => $$dbiParams{AutoCommit} });
398              
399              
400 0         0 my $dbiconnection = DBI->connect(
401             $dbipath,
402             $$dbiParams{UserName},$$dbiParams{Password},
403             \%dbiHandleAttr,
404             );
405              
406 0 0       0 if (!$dbiconnection)
407             {
408             # This is a critical error, and there is no reason why to continue with this object
409             #die "ERROR: ConnectionManager cannot connect to database: $DBI::errstr !\n";
410              
411             #warn "ERROR: ConnectionManager cannot connect to database: $DBI::errstr !\n";
412             #return undef;
413 0         0 $self-> _set_connection(undef);
414 0         0 $self-> _internal_state(ISTATE_UNDEF);
415 0         0 $self-> state('UNDEF');
416 0         0 $self-> status($DBI::errstr);
417 0         0 die "
418             ERROR: ConnectionManager cannot connect to database: $DBI::errstr!
419             Make sure that the aimed SQL server is up and running.
420             ";
421             }
422             else #TODO TODO TODO When we reconnect() we need to set the following as well
423             {
424             # Set the connection handle for this class, this is the handle
425             # for the process instanciating this handle
426             #$self->{connection} = $dbiconnection;
427 0         0 $self-> _set_connection($dbiconnection);
428            
429             # set a simple Bean to gather info during run-time
430             # (although that can be guessed from %$dbiParams after setup)
431 0         0 $self-> _set_dbname($$dbiParams{DataName});
432 0         0 $self-> _set_dbserver($$dbiParams{Server});
433 0         0 $self-> _set_dbdriver($$dbiParams{Driver});
434 0         0 $self-> _set_dbusername($$dbiParams{UserName});
435 0         0 $self-> _set_dbpassword($$dbiParams{Password});
436              
437             # these two cannot be varied
438 0         0 $self-> _set_longtruncok($$dbiLags{LongTruncOk});
439 0         0 $self-> _set_longreadlen($$dbiLags{LongReadLen});
440              
441             # and here goes the Lags
442 0         0 $self-> raiseerror($$dbiLags{RaiseError});
443 0         0 $self-> printerror($$dbiLags{PrintError});
444 0         0 $self-> autocommit($$dbiLags{AutoCommit});
445 0         0 $self-> autorollback($$dbiLags{AutoRollback});
446              
447             # get a copy of the original Lags needed in the function resetLags()
448 0         0 $self-> {_bk_raiseerror_0} = $$dbiLags{RaiseError};
449 0         0 $self-> {_bk_printerror_0} = $$dbiLags{PrintError};
450 0         0 $self-> {_bk_autocommit_0} = $$dbiLags{AutoCommit};
451 0         0 $self-> {_bk_autorollbak_0} = $$dbiLags{AutoRollback};
452              
453             # TODO: added w/o verifying the impact on reconnect!
454             # and here goes my special purpose typ_'sub
455 0 0       0 $self->{dbb} =
    0          
456             $$dbiParams{Driver} =~ /Oracle/i ? 'ora' :
457             $$dbiParams{Driver} =~ /Mysql/i ? 'mysql' :
458             die "UNKNOWN DATA BASE WITH DRIVER $$dbiParams{Driver} IS NOT SUPPORTED!\n";
459             #$self->{SKELETON} = $self->{dbb} eq 'ora' ? $SKELETON_ORA : $SKELETON_MYSQL;
460 0         0 $self->{SKELETON} = $$SKELETON{ $self->{dbb} };
461 0 0       0 $self->{SYSDATE}=
462             $self->{dbb} eq 'ora' ? 'SYSDATE' : 'SYSDATE()';
463            
464 0         0 $self-> _internal_state(ISTATE_GOOD);
465 0         0 $self-> state('CONNECTED');
466 0         0 $self-> status('CONNECTED');
467 0         0 $self->{clock0} = Time::HiRes::clock();
468 0         0 $self->{time0} = [Time::HiRes::gettimeofday];
469             #$self->{time0} = time;
470 0         0 $self->{cumu_conrun} = 0;
471              
472             # when the hook is active, one can setup anything within
473             # a filter as an anonymous sub (e.g. character filtering,
474             # email notification, even a new connection, and much more).
475             # TODO have the filter code settable from the global configuration file
476             # $self->{in_filter} = $args{in} || \&_no_filter,
477             # $self->{out_filter} = $args{out} || \&_no_filter,
478             }
479             }
480              
481 0 0 0     0 $ENABLE_CACHING && (${$CACHED_CONN{$$ . $conf}}{class} = $self) && (_statCCreset($$,$conf));
  0         0  
482 0         0 return $self;
483             }
484              
485             ##############################################################################
486             ##############################################################################
487             ##############################################################################
488             #
489             sub HookTracing {
490 0     0 1 0 my($class) = shift;
491 0         0 my($deb) = shift;
492 0         0 my($level) = shift;
493              
494             #my(%h) = @_;
495 0         0 my %h; # filter disabled
496              
497             # Hookup tracing if requested
498 0 0 0     0 if ( (defined($deb)) && ($deb ne '') ) {
499             #$class->{debhook} = (defined(%h)) ? DBI::BabyConnect::Deb->new(file=>"$deb",%h) : DBI::BabyConnect::Deb->new(file=>"$deb");
500 0 0       0 $class->{debhook} = %h ? DBI::BabyConnect::Deb->new(file=>"$deb",%h) : DBI::BabyConnect::Deb->new(file=>"$deb");
501 0         0 $class->{tracing} = 1;
502             # in case we call reconnect()
503 0         0 $class->{_debfilename} = $deb;
504 0         0 my $time = iso_date();
505 0 0       0 if ($level) {
506 0         0 my $dbilog = $deb;
507 0         0 $dbilog =~ s/>{1,}//;
508 0         0 DBI->trace( $level , "$dbilog");
509 0         0 $class->{debhook}->print("Started at $time (with DBI trace level set to [$level]\n\n");
510             # in case we call reconnect()
511 0         0 $class->{_tracelevel} = $level;
512             }
513             else {
514 0         0 $class->{debhook}->print("Started at $time (without DBI trace level)\n\n");
515             }
516             }
517             else {
518 0         0 $class->{tracing} = 0;
519             }
520             }
521              
522              
523             ##############################################################################
524             #
525             sub HookError {
526 0     0 1 0 my($class) = shift;
527 0         0 my($errlog) = shift;
528             # my($level) = shift;
529              
530             #my(%h) = @_;
531 0         0 my %h; # filter disabled
532              
533             # Hookup tracing if requested
534 0 0 0     0 if ( (defined($errlog)) && ($errlog ne '') ) {
535             #$class->{debhook} = (defined(%h)) ? DBI::BabyConnect::Deb->new(file=>"$deb",%h) : DBI::BabyConnect::Deb->new(file=>"$deb");
536 0 0       0 $class->{errloghook} = %h ? DBI::BabyConnect::Deb->new(file=>"$errlog",%h) : DBI::BabyConnect::Deb->new(file=>"$errlog");
537 0         0 *STDERR = $class->{errloghook};
538 0         0 $class->{redirect_error_log} = 1;
539             # if ($level) {
540             # my $dbilog = $errlog;
541             # $dbilog =~ s/>{1,}//;
542             # DBI->trace( $level , "$dbilog");
543             # }
544 0         0 my $time = iso_date();
545 0         0 print STDERR "Started at $time\n";
546             # in case we call reconnect()
547 0         0 $class->{_errfilename} = $errlog;
548             }
549             else {
550 0         0 $class->{redirect_error_log} = 0;
551             }
552             }
553              
554              
555             ##############################################################################
556             ##############################################################################
557             ##############################################################################
558             ##############################################################################
559              
560             #EXPERIMENTAL
561             ##############################################################################
562             # a DBI::BabyConnect object cache its connection parameter within its object,
563             # and calling the reconnect() method establishes the connection seemlessly with
564             # the same parameters.
565             # reconnect() uses the cached configuration object to re-establish a DBI connection
566             # similar to new() except that the parameters are read from the cache.
567             sub reconnect {
568 0     0 0 0 my $class = shift;
569              
570             #$class-> _confFromObject($class->{_CONF},\$dbDriver,\$dbServer,\$dbUserName,\$dbPassword,\$dbName,
571             # \$dbPrintError,\$dbRaiseError,\$dbAutoCommit,\$dbConnections,\$dbPollingInterval);
572 0         0 $class-> _confFromObject($class->{_CONF});
573              
574 0 0       0 $$dbiParams{Server} = "" unless defined $$dbiParams{Server};
575              
576 0         0 my $dbipath = 'DBI:' . $$dbiParams{Driver} . ':' . $$dbiParams{DataName} . ':' . $$dbiParams{Server};
577             #my $dbiconnection = DBI->connect("DBI:$dbDriver:$dbName:$dbServer", $dbUserName,$dbPassword,
578 0         0 my $dbiconnection = DBI->connect($dbipath, $$dbiParams{UserName},$$dbiParams{Password},
579             #{RaiseError => $dbRaiseError, PrintError => $dbPrintError, AutoCommit => $dbAutoCommit});
580             { RaiseError => $$dbiParams{RaiseError}, PrintError => $$dbiParams{PrintError}, AutoCommit => $$dbiParams{AutoCommit} });
581              
582 0 0       0 if (!$dbiconnection)
583             {
584             # This is a critical error, and there is no reason why to continue with this object
585             #die "ERROR: ConnectionManager cannot connect to database: $DBI::errstr !\n";
586              
587             #warn "ERROR: ConnectionManager cannot connect to database: $DBI::errstr !\n";
588             #return undef;
589 0         0 $class-> _set_connection(undef);
590 0         0 $class-> _internal_state(ISTATE_UNDEF);
591 0         0 $class-> state('UNDEF');
592 0         0 $class-> status($DBI::errstr);
593             }
594             else
595             {
596             #$class->{connection} = $dbiconnection;
597 0         0 $class-> _set_connection($dbiconnection);
598 0         0 $class-> _internal_state(ISTATE_GOOD);
599 0         0 $class-> state('CONNECTED');
600 0         0 $class-> status('CONNECTED');
601             #OK: $class->{in_filter} = $args{in} || \&_no_filter,
602             #OK: $class->{out_filter} = $args{out} || \&_no_filter,
603             }
604              
605             # Re-hook in case HookTracing() HookError() have been called on the previous
606             # object, and prior to calling reconnect()
607            
608             ###my $ccc = [caller]; print " @{$ccc} \n";
609             ###print ">>>>>>>>>>>>>>>>>>>> $class->{_debfilename} ++ $class->{_tracelevel} ========= $dbPassword == $class->{_CONF} \n"; exit;
610 0         0 $class->HookTracing($class->{_debfilename},$class->{_tracelevel});
611 0         0 $class->HookError($class->{_errfilename});
612             #$class->{tracing} = $class->{tracing};
613              
614             # Tracing
615 0   0     0 $class->{src} = [caller]; push(@{$class->{src}},(caller 1)[3] || '');
  0         0  
  0         0  
616 0         0 $class-> _tracing("RECONNECT:\n\n");
617              
618 0         0 return $class;
619             }
620              
621             # CONNECTION ATTRIBUTES FUNCTIONS
622             ##############################################################################
623             ##############################################################################
624             ##############################################################################
625             ##############################################################################
626              
627             # *getHandleFlags
628             sub getActiveDescriptor {
629 0     0 1 0 my $class = shift;
630              
631 0 0       0 my $bean_flags = @_ ? shift : undef;
632              
633 0         0 my $wanthash = 0;
634 0 0       0 $bean_flags && ($wanthash = 1);
635             #$bean_flags ||= {};
636              
637             #(ref $rshr eq 'HASH') && (%$rshr = map{$_=>$$statCC{$_}} (keys %$statCC)) && (return $rshr);
638              
639             #$bean_flags = {
640 0         0 my $t_bean_flags = {
641             Driver=> $class-> dbdriver,
642             Server=> $class-> dbserver,
643             UserName=> $class-> dbusername,
644             Password=> $class-> dbpassword,
645             DataName=> $class-> dbname,
646             PrintError=> $class-> printerror,
647             RaiseError=> $class-> raiseerror,
648             AutoRollback=> $class-> autorollback,
649             AutoCommit=> $class-> autocommit,
650              
651             LongTruncOk=> $class-> longtruncok,
652             LongReadLen=> $class-> longreadlen,
653              
654             DBIhandle=> $class->connection,
655             #Connection=> $class->connection,
656             Connection=> $class,
657             ###$class->dbilags($dbiLags),
658             _internal_state => $class-> _internal_state,
659             State=> $class-> state,
660             Status=> $class-> status,
661             };
662 0 0 0     0 $wanthash && (%$bean_flags = map{$_=>$$t_bean_flags{$_}} (keys %$t_bean_flags)) && (return $bean_flags);
  0         0  
663             #$wanthash && return $bean_flags;
664 0         0 my $info;
665 0         0 foreach my $k (keys %$t_bean_flags) {
666 0         0 $info .= "$k\t $$t_bean_flags{$k}\n";
667             }
668 0         0 return $info;
669             }
670              
671             sub saveLags {
672 0     0 1 0 my $class = shift;
673             #my $bean_flags = {
674 0         0 $class->{_bk_raiseerror} = $class->raiseerror,
675             $class->{_bk_printerror} = $class->printerror,
676             $class->{_bk_autocommit} = $class->autocommit,
677             $class->{_bk_autorollbak} = $class->autorollback,
678             #DataName=> $class->dbname,
679             #Server=> $class->server,
680             #Driver=> $class->driver,
681             #Connection=> $class->connection,
682             ###$class->dbilags($dbiLags),
683             #_internal_state=> $class-> _internal_state,
684             #State=> $class-> state,
685             #Status=> $class->status,
686             #};
687             }
688              
689             sub restoreLags {
690 0     0 1 0 my $class = shift;
691              
692 0         0 $class->raiseerror( $class->{_bk_raiseerror} );
693 0         0 $class->printerror( $class->{_bk_printerror} );
694 0         0 $class->autocommit( $class->{_bk_autocommit} );
695 0         0 $class->autorollback( $class->{_bk_autorollbak} );
696             #DataName=> $class->dbname,
697             #Server=> $class->server,
698             #Driver=> $class->driver,
699             #Connection=> $class->connection,
700             ###$class->dbilags($dbiLags),
701             #_internal_state=> $class-> _internal_state,
702             #State=> $class->state,
703             #Status=> $class->status,
704              
705             }
706              
707             sub resetLags {
708 0     0 1 0 my $class = shift;
709              
710 0         0 $class->raiseerror( $class->{_bk_raiseerror_0} );
711 0         0 $class->printerror( $class->{_bk_printerror_0} );
712 0         0 $class->autocommit( $class->{_bk_autocommit_0} );
713 0         0 $class->autorollback( $class->{_bk_autorollbak_0} );
714             }
715              
716             ##############################################################################
717             #
718             #connection()
719              
720             sub connection {
721 0     0 1 0 my $class = shift;
722 0         0 return $class->{connection};
723             }
724             sub _set_connection {
725 0     0   0 my $class = shift;
726 0         0 my $dbiconnection = shift;
727 0         0 $class->{connection} = $dbiconnection;
728             }
729            
730             sub _internal_state {
731 0     0   0 my $class = shift;
732 0 0       0 if (@_)
733             {
734 0         0 my $state = shift;
735 0         0 $class->{_internal_state} = $state;
736             }
737             else
738             {
739 0         0 return $class->{_internal_state};
740             }
741             }
742              
743             # used internally
744             sub state {
745 0     0 0 0 my $class = shift;
746 0 0       0 if (@_)
747             {
748 0         0 my $state = shift;
749 0         0 $class->{state} = $state;
750             }
751             else
752             {
753 0         0 return $class->{state};
754             }
755             }
756            
757             sub status {
758 0     0 0 0 my $class = shift;
759 0 0       0 if (@_)
760             {
761 0         0 my $status = shift;
762 0         0 $class->{status} = $status;
763             }
764             else
765             {
766 0         0 return $class->{status};
767             }
768             }
769            
770             sub dbierror {
771 0     0 1 0 my $class = shift;
772 0         0 return "DBI ERROR No:", $DBI::err , " -- " , $DBI::errstr;
773             }
774              
775             sub babyconfess {
776 0     0 0 0 my $class = shift;
777 0         0 eval { confess('') };
  0         0  
778 0         0 my @stack = split m/\n/, $@;
779 0         0 shift @stack for 1..3;
780 0         0 my $stack = join "\n", @stack;
781 0         0 return "$stack\n\n";
782             }
783              
784              
785             sub raiseerror {
786 0     0 1 0 my $class = shift;
787 0 0       0 if(@_) {
788 0         0 $class->{dbraiseerror} = shift;
789             }
790 0         0 return $class->{dbraiseerror};
791             }
792              
793             sub is_RaiseError {
794 0     0 0 0 my $class = shift;
795 0         0 return $class->raiseerror;
796             }
797              
798              
799             sub printerror {
800 0     0 1 0 my $class = shift;
801 0 0       0 if(@_) {
802 0         0 $class->{dbprinterror} = shift;
803             }
804 0         0 return $class->{dbprinterror};
805             }
806             sub is_PrintError
807             {
808 0     0 0 0 my $class = shift;
809 0         0 return $class->printerror;
810             }
811              
812              
813             sub autocommit {
814 0     0 1 0 my $class = shift;
815 0 0       0 if(@_) {
816 0         0 $class->{dbautocommit} = shift;
817             }
818 0         0 return $class->{dbautocommit};
819             }
820              
821             sub is_AutoCommit {
822 0     0 0 0 my $class = shift;
823 0         0 return $class->autocommit;
824             }
825              
826             sub are_commited {
827 0     0 0 0 my $class = shift;
828 0         0 die "NOT IMPLEMENTED -- NEED DBI::BabiesTransactionBundle!\n";
829             }
830              
831             sub are_rolled {
832 0     0 0 0 my $class = shift;
833 0         0 die "NOT IMPLEMENTED -- NEED DBI::BabiesTransactionBundle!\n";
834             }
835              
836             sub autorollback {
837 0     0 1 0 my $class = shift;
838 0 0       0 if(@_) {
839 0         0 $class->{dbrollback} = shift;
840             }
841 0         0 return $class->{dbrollback};
842             }
843             sub is_AutoRollback {
844 0     0 0 0 my $class = shift;
845 0         0 return $class->autorollback;
846             }
847              
848              
849              
850             sub _set_longtruncok {
851 0     0   0 my $class = shift;
852 0 0       0 if(@_) {
853 0         0 $class->{longtruncok} = shift;
854             }
855 0         0 return $class->{longtruncok};
856             }
857             sub longtruncok {
858 0     0 1 0 my $class = shift;
859 0         0 return $class->{longtruncok};
860             }
861              
862              
863              
864             sub _set_longreadlen {
865 0     0   0 my $class = shift;
866 0 0       0 if(@_) {
867 0         0 $class->{longreadlen} = shift;
868             }
869 0         0 return $class->{longreadlen};
870             }
871             sub longreadlen {
872 0     0 1 0 my $class = shift;
873 0         0 return $class->{longreadlen};
874             }
875              
876              
877              
878            
879             sub _set_dbname {
880 0     0   0 my $class = shift;
881 0 0       0 if(@_) {
882 0         0 $class->{dbname} = shift;
883             }
884 0         0 return $class->{dbname};
885             }
886             sub dbname {
887 0     0 1 0 my $class = shift;
888 0         0 return $class->{dbname};
889             }
890              
891              
892             sub _set_dbserver {
893 0     0   0 my $class = shift;
894 0 0       0 if(@_) {
895 0         0 $class->{dbserver} = shift;
896             }
897 0         0 return $class->{dbserver};
898             }
899             sub dbserver {
900 0     0 1 0 my $class = shift;
901 0         0 return $class->{dbserver};
902             }
903              
904            
905             sub _set_dbdriver {
906 0     0   0 my $class = shift;
907 0 0       0 if(@_) {
908 0         0 $class->{dbdriver} = shift;
909             }
910 0         0 return $class->{dbdriver};
911             }
912             sub dbdriver {
913 0     0 1 0 my $class = shift;
914 0         0 return $class->{dbdriver};
915             }
916              
917             sub _set_dbusername {
918 0     0   0 my $class = shift;
919 0 0       0 if(@_) {
920 0         0 $class->{dbusername} = shift;
921             }
922 0         0 return $class->{dbusername};
923             }
924             sub dbusername {
925 0     0 1 0 my $class = shift;
926 0         0 return $class->{dbusername};
927             }
928             sub _set_dbpassword {
929 0     0   0 my $class = shift;
930 0 0       0 if(@_) {
931 0         0 $class->{dbpassword} = shift;
932             }
933 0         0 return $class->{dbpassword};
934             }
935             sub dbpassword {
936 0     0 0 0 my $class = shift;
937 0         0 return $class->{dbpassword};
938             }
939              
940              
941              
942             sub _parseDBIAttributesFile {
943 0     0   0 my $class = shift;
944 0         0 my $conf = shift;
945 0         0 my $line;
946 0 0       0 open(F,"$conf") or die "Cannot open the config file ($conf)\n" ;
947 0         0 while ($line = ) {
948 0         0 $line =~ s/\r//; $line =~ s/\n//;
  0         0  
949 0 0 0     0 if ( !(($line =~ /^#/) || ($line =~ /^$/)) ) {
950 0         0 my $pos1 = index($line,":"); my $head = substr($line,0,$pos1);
  0         0  
951 0         0 my $rest = substr($line,$pos1+1,length($line));
952 0         0 my @parts = split(/,/,$rest);
953 0         0 foreach (qw(Driver Server UserName Password DataName PrintError RaiseError AutoCommit AutoRollback LongTruncOk LongReadLen)) {
954 0 0       0 ($head eq $_) && ($$dbiParams{$_} = $parts[0]);
955             }
956             }
957             }
958 0         0 close(F);
959 0         0 foreach my $k (keys %$dbiParams) {
960 0         0 ${$class->{_CONF}}{$k} = $$dbiParams{$k};
  0         0  
961             }
962 0         0 foreach my $k (keys %$dbiLags) {
963 0         0 ${$class->{_CONF}}{$k} = $$dbiLags{$k};
  0         0  
964             }
965             }
966              
967             # PRIVATE! next release
968             sub getSKELETON {
969 0     0 0 0 my $class = shift;
970 0         0 return $class->{SKELETON};
971             }
972              
973             ##############################################################################
974             # _confFromFile() opens the initial configuration file, and set up the
975             # config params, and cache these config params within an object.
976             sub _confFromFile {
977 0     0   0 my $class = shift;
978 0         0 my $conf = shift;
979              
980             # %$dbiParams are already set to default, but will be overriden from config file
981 0         0 my $line;
982 0 0       0 open(F,"$conf") or die "Cannot open the config file ($conf)\n" ;
983 0         0 flock F,1;
984 0         0 while ($line = ) {
985 0         0 $line =~ s/\r//; $line =~ s/\n//;
  0         0  
986 0 0 0     0 if ( !(($line =~ /^#/) || ($line =~ /^$/)) ) {
987 0         0 my $pos1 = index($line,":");
988 0         0 my $head = substr($line,0,$pos1);
989 0         0 my $rest = substr($line,$pos1+1,length($line));
990 0         0 my @parts = split(/,/,$rest);
991 0         0 foreach (qw(Driver Server UserName Password DataName PrintError RaiseError AutoCommit AutoRollback LongTruncOk LongReadLen)) {
992 0 0       0 ($head eq $_) && ($$dbiParams{$_} = $parts[0]);
993             }
994             #elsif ($head eq 'LongReadLen') { $$dbiLags{LongReadLen} = $parts[0]; }
995             ###elsif ($head eq 'Connections') { $$dbiParams{Connections} = $parts[0]; }
996             ###elsif ($head eq 'PollingInterval') { $$dbiParams{PollingInterval} = $parts[0]; }
997             }
998             }
999 0         0 close(F);
1000 0         0 foreach my $k (keys %$dbiParams) {
1001 0         0 ${$class->{_CONF}}{$k} = $$dbiParams{$k};
  0         0  
1002             }
1003 0         0 foreach my $k (keys %$dbiLags) {
1004 0         0 ${$class->{_CONF}}{$k} = $$dbiLags{$k};
  0         0  
1005             }
1006              
1007             #${$class->{_CONF}}{Driver} = $dbDriver;
1008             #${$class->{_CONF}}{Server} = $dbServer;
1009             #${$class->{_CONF}}{UserName} = $dbUserName;
1010             #${$class->{_CONF}}{Password} = $dbPassword;
1011             #${$class->{_CONF}}{DataName} = $dbName;
1012             #${$class->{_CONF}}{PrintError} = $dbPrintError;
1013             #${$class->{_CONF}}{RaiseError} = $dbRaiseError;
1014             #${$class->{_CONF}}{AutoCommit} = $dbAutoCommit;
1015             #${$class->{_CONF}}{Connections} = $dbConnections;
1016             #${$class->{_CONF}}{PollingInterval} = $dbPollingInterval;
1017             }
1018              
1019             ##############################################################################
1020             # () used when calling reconnect() method that is
1021             # called after the instantiation of the class
1022             sub _confFromRef {
1023 0     0   0 my $class = shift;
1024 0         0 my $lookup_db_descriptor = shift;
1025              
1026 0 0       0 die __PACKAGE__, " DATABASE DESCRIPTOR IS NOT DEFINED FOR [$lookup_db_descriptor]. PROGRAM EXITING.
1027              
1028             AS A LAST RESORT OF GETTING A CONNECTION, CANNOT LOCATE AN OBJECT FOR THAT DESCRIPTOR $lookup_db_descriptor.
1029             WHEN GETTING A CONNECTION, THE PARAMTER PROVIDED IS VERIFIED IN THE FOLLOWING ORDER:
1030             1- AS AN OBJECT REFERENCE THAT HOLD THE CONNECTION
1031             2- AS A CONFIGURATION FILE THAT HOLD THE CONNECTION IF SUCH A FILE EXIST
1032             3- AS AN IDENTIFIER TO A DB CONNECTION SAVED IN databases.conf
1033             4- AS A LAST RESORT, AS A DESCRIPTOR MAPPED INTO THE ./dbconf/*.conf
1034              
1035             "
1036             unless $$db_ref{ $lookup_db_descriptor };
1037 0         0 my $conf = $$db_ref{ $lookup_db_descriptor };
1038 0         0 foreach my $k (keys %$dbiParams) {
1039 0 0       0 $$dbiParams{$k} = $$conf{$k} if defined $$conf{$k};
1040             # set'em in the class
1041 0         0 ${$class->{_CONF}}{$k} = $$dbiParams{$k};
  0         0  
1042             }
1043 0         0 foreach my $k (keys %$dbiLags) {
1044 0 0       0 $$dbiLags{$k} = $$conf{$k} if defined $$conf{$k};
1045             # set'em in the class
1046 0         0 ${$class->{_CONF}}{$k} = $$dbiLags{$k};
  0         0  
1047             }
1048             }
1049              
1050              
1051             ##############################################################################
1052             # _get_db_config_object() may be needed for debugging
1053             sub _get_db_config_object {
1054 0     0   0 my $class = shift;
1055 0         0 return %{$class->{_CONF}};
  0         0  
1056             }
1057              
1058             ##############################################################################
1059             # _confFromObject() used when calling reconnect() method that is
1060             # called after the instantiation of the class
1061             sub _confFromObject {
1062 0     0   0 my $class = shift;
1063 0         0 my $conf = shift;
1064              
1065             # %$dbiParams are already set to default, but will be overridden from config file
1066             ##foreach my $k (keys %$dbiDefaultParams) {
1067             ## $$dbiParams{$k} = $$dbiDefaultParams{$k};
1068             ##}
1069              
1070             # override from conf object
1071             #foreach my $k (keys %$conf) {
1072             # $$dbiParams{$k} = $$conf{$k};
1073             #}
1074              
1075             # override from conf object
1076 0         0 foreach my $k (keys %$dbiParams) {
1077 0 0       0 $$dbiParams{$k} = $$conf{$k} if defined $$conf{$k};
1078             # set'em in the class
1079 0         0 ${$class->{_CONF}}{$k} = $$dbiParams{$k};
  0         0  
1080             }
1081             # override from conf object
1082 0         0 foreach my $k (keys %$dbiLags) {
1083 0 0       0 $$dbiLags{$k} = $$conf{$k} if defined $$conf{$k};
1084             # set'em in the class
1085 0         0 ${$class->{_CONF}}{$k} = $$dbiLags{$k};
  0         0  
1086             }
1087              
1088             }
1089              
1090              
1091             # IO Section
1092             ########################################################################################
1093             ########################################################################################
1094             ########################################################################################
1095             ########################################################################################
1096             sub _traceln {
1097 0     0   0 my $class = shift;
1098 0         0 my $s = shift;
1099 0 0       0 return unless $class->{debhook};
1100 0         0 $class->{debhook}->print("$s");
1101             }
1102              
1103             $SIG{__DIE__} = sub {
1104             #print STDERR "DIE: $_[0]"
1105             my $s = shift;
1106             my ($cur_pkg,$cur_file,$cur_line,$cur_meth) = (caller, (caller 1)[3] || '');
1107             #my ($src_pkg,$src_file,$src_line,$src_meth) = @_ ? @_ : (undef,undef,undef,undef)
1108             #my ($src_pkg,$src_file,$src_line,$src_meth) = (caller, (caller 2)[3]);
1109              
1110             my $time = iso_date();
1111             print STDERR "\n\nDIE =================================== $time \n";
1112             print STDERR "msg=". $s."\n";
1113             print STDERR "\t++ $cur_pkg\n\t++ $cur_meth\n\t++ $cur_file\n\t++ $cur_line\n(END)\n";
1114             #$src_pkg && print STDERR "\n\t++ $src_pkg\n\t++ $src_meth\n\t++ $src_file\n\t++ $src_line\n";
1115             #print STDERR "DBI STATUS: DBI::err=\t".$DBI::err."\n\t DBI::errstr=:\t".$DBI::errstr."\n\t DBI LED=\t".$DBI::state."\n\n";
1116              
1117             eval { confess('') };
1118             my @stack = split m/\n/, $@;
1119             shift @stack for 1..3;
1120             my $stack = join "\n", @stack;
1121             print STDERR $stack,"\n\n";
1122             };
1123              
1124             $SIG{__WARN__} = sub {
1125             #print STDERR "WARN: $_[0]"
1126             my $s = shift;
1127             my ($cur_pkg,$cur_file,$cur_line,$cur_meth) = (caller, (caller 1)[3] || '');
1128             #my ($src_pkg,$src_file,$src_line,$src_meth) = (caller, (caller 0)[3]);
1129              
1130             my $time = iso_date();
1131             print STDERR "WARN =================================== $time \n";
1132             print STDERR "msg=" , $s ,"\n";
1133             print STDERR "\t++ $cur_pkg\n\t++ $cur_meth\n\t++ $cur_file\n\t++ $cur_line\n(END)\n";
1134             #print STDERR "++ $src_pkg\n++ $src_meth\n++ $src_file\n++ $src_line\n";
1135             #print STDERR "DBI STATUS: DBI::err=\t".$DBI::err."\n\t DBI::errstr=:\t".$DBI::errstr."\n\t DBI LED=\t".$DBI::state."\n\n";
1136             };
1137              
1138             # when calling w/o beginning and ending, use this _tracing
1139             sub _tracing {
1140 0     0   0 my $class = shift;
1141 0         0 my $cumu_conrun = $class->{cumu_conrun};
1142 0 0       0 return unless $class->{debhook};
1143             #return unless $class->{tracing};
1144             #if ($class->{tracing} ) {
1145 0         0 my $s = shift;
1146 0   0     0 my ($cur_pkg,$cur_file,$cur_line,$cur_meth) = (caller, (caller 1)[3] || '');
1147 0         0 my ($src_pkg,$src_file,$src_line,$src_meth) = @{$class->{src}};
  0         0  
1148              
1149 0         0 my $time = iso_date();
1150 0         0 $class->{debhook}->print("=================================== $time (CUMU: $cumu_conrun)\n");
1151 0         0 $class->{debhook}->print("msg=".$s."\n");
1152 0         0 $class->{debhook}->print("\t++ $cur_pkg\n\t++ $cur_meth\n\t++ $cur_file\n\t++ $cur_line\n");
1153 0         0 $class->{debhook}->print("\t++ $src_pkg\n\t++ $src_meth\n\t++ $src_file\n\t++ $src_line\n");
1154             #$class->{debhook}->print("DBI STATUS: DBI::err=\t$DBI::err\n\t DBI::errstr=:\t$DBI::errstr\n\t DBI LED=\t$DBI::state\n\n");
1155 0         0 $class->{debhook}->print("\tDBI STATUS: DBI::err=\t".$DBI::err."\n\t DBI::errstr=:\t".$DBI::errstr."\n\t DBI LED=\t".$DBI::state."\n");
1156 0         0 $class->{debhook}->print("(END)\n\n");
1157             }
1158              
1159              
1160             #beginning a trace
1161             sub _tracingB {
1162 0     0   0 my $class = shift;
1163 0         0 my $cumu_conrun = $class->{cumu_conrun};
1164             # return unless this hook is enabled
1165 0 0       0 return unless $class->{debhook};
1166 0         0 my $s = shift;
1167 0   0     0 my ($cur_pkg,$cur_file,$cur_line,$cur_meth) = (caller, (caller 1)[3] || '');
1168 0         0 my ($src_pkg,$src_file,$src_line,$src_meth) = @{$class->{src}};
  0         0  
1169              
1170 0         0 my $time = iso_date();
1171 0         0 $class->{debhook}->print("=================================== $time (CUMU: $cumu_conrun)\n");
1172 0         0 $class->{debhook}->print("msg=".$s."\n");
1173 0         0 $class->{debhook}->print("\t++ $cur_pkg\n\t++ $cur_meth\n\t++ $cur_file\n\t++ $cur_line\n");
1174 0         0 $class->{debhook}->print("\t++ $src_pkg\n\t++ $src_meth\n\t++ $src_file\n\t++ $src_line\n");
1175             }
1176              
1177             # closing a trace
1178             sub _tracingE {
1179 0     0   0 my $class = shift;
1180             # return unless this hook is enabled
1181 0 0       0 return unless $class->{debhook};
1182 0         0 my $cumu_conrun = $class->{cumu_conrun};
1183 0         0 my $s = shift;
1184 0         0 my $time = iso_date();
1185 0         0 $class->{debhook}->print("\n$s\n($time (CUMU: $cumu_conrun)\n(END)\n\n");
1186             }
1187              
1188             ########################################################################################
1189             ########################################################################################
1190             ########################################################################################
1191             ########################################################################################
1192              
1193              
1194             ########################################################################################
1195             # Creating tables dynamically during the product runtime is vital for the application.
1196             # For this reason, this class provides two useful functions that allow the creation
1197             # of database tables:
1198             # recreateTable to create table reading'em from $DATABASE_CONFIGURATION_DIR . '/SQL/TABLES/'
1199             # recreateTableFromString to create table from input string
1200             #
1201              
1202             # recreateTable() drops (silently) the table first, then it will recreate the table.
1203             # the table dll is found in the $ENV{BABYCONNECT}/SQL/TABLES
1204             sub recreateTable {
1205 0     0 1 0 my $class=shift;
1206 0         0 my $SCHEMA_TABLENAME = shift;
1207 0         0 my $TABLENAME = shift;
1208 0 0       0 my $ATTRIBUTES = @_ ? shift : undef;
1209              
1210             #my $SCHEMA_FILENAME = $DATABASE_CONFIGURATION_DIR . '/SQL/TABLES/' . $SCHEMA_TABLENAME;
1211 0         0 my $SCHEMA_FILENAME = $SCHEMA_REPOS . '/' . $SCHEMA_TABLENAME;
1212 0         0 my $dbtablespec;
1213 0 0       0 open(F,"<$SCHEMA_FILENAME") || die "ERROR: Cannot open table file $SCHEMA_FILENAME!\n";
1214             # remove all comments, these are lines starting with --
1215 0         0 while() {
1216 0 0       0 next if $_ =~ /^\s*--/;
1217 0         0 $dbtablespec .= $_;
1218             }
1219 0         0 close(F);
1220 0         0 $dbtablespec .= "\n";
1221              
1222 0 0       0 $SCHEMA_TABLENAME = $TABLENAME if $dbtablespec =~ /<<>>/;
1223 0         0 $dbtablespec =~ s/<<>>/$TABLENAME/g;
1224 0 0       0 $dbtablespec =~ s/<<>>/$ATTRIBUTES/g if defined $ATTRIBUTES;
1225              
1226 0   0     0 $class->{src} = [caller]; push(@{$class->{src}},(caller 1)[3] || '');
  0         0  
  0         0  
1227 0         0 $class-> _tracingB("recreateTable: $TABLENAME\n");
1228 0         0 print "RECREATING TABLE: $SCHEMA_TABLENAME\n"; # to ACTIVITY file
1229              
1230 0 0       0 if ($dbtablespec =~ /\~/) {
1231 0         0 my @sql = split(/\~/,$dbtablespec);
1232 0         0 foreach my $sql (@sql) {
1233 0 0 0     0 if ((length($sql) > 1) && ($sql =~ /drop/i)) {
    0          
1234             # for the drop command, do it silently, suppressing any error
1235             # or warning message whether table to be dropped exists or not
1236 0         0 $class-> saveLags;
1237             #>>> $class-> printerror(1);
1238 0         0 $class-> printerror(0);
1239 0         0 $class-> raiseerror(0); # do not exit if no ta
1240 0         0 $class-> autorollback(0);
1241 0         0 $class-> autocommit(1);
1242             #$class-> do($sql) || return 0;
1243 0         0 $class-> do($sql);
1244 0         0 $class-> restoreLags;
1245             }
1246             elsif (length($sql) > 1) {
1247 0 0       0 defined $class-> do($sql) || return 0;
1248             }
1249             }
1250             }
1251             else {
1252             # for the drop command, do it silently, suppressing any error
1253             # or warning message whether table to be dropped exists or not
1254 0         0 $class-> saveLags;
1255 0         0 $class-> printerror(0);
1256 0         0 $class-> raiseerror(0); # do not exit if no table exists to be dropped
1257 0         0 $class-> autorollback(0);
1258 0         0 $class-> autocommit(1);
1259             # Call the do() from this class itself, since it will localize the variables
1260             #$class-> do("drop table $SCHEMA_TABLENAME") || return 0;
1261 0         0 $class-> do("drop table $SCHEMA_TABLENAME");
1262             # Do not call the do() from DBI unless you want to localize everything once again!
1263             #eval {
1264             # local ...
1265             # $class->{connection}->do("drop table $SCHEMA_TABLENAME");
1266             #};
1267             #$@ && $class->{dberr}->println();
1268             #$@ && $class-> printerror && print STDERR ">>>> $@\n";
1269 0         0 $class-> restoreLags;
1270              
1271 0 0       0 defined $class->{connection}->do($dbtablespec) || return 0;
1272             }
1273 0         0 $class-> _tracingE("recreateTable: $TABLENAME\n");
1274 0         0 return 1;
1275             }
1276              
1277              
1278             ########################################################################################
1279             # recreateTableFromString drops (silently) the table first, then it will recreate the table.
1280             # the table dll is found in the configuration-directory/SQL/TABLES
1281             sub recreateTableFromString {
1282 0     0 1 0 my $class=shift;
1283 0         0 my $dbtablespec = shift; # my $SCHEMA_STRING = shift;
1284 0         0 my $TABLENAME = shift;
1285              
1286 0         0 $dbtablespec =~ s/<<>>/$TABLENAME/g;
1287              
1288 0   0     0 $class->{src} = [caller]; push(@{$class->{src}},(caller 1)[3] || '');
  0         0  
  0         0  
1289 0         0 $class-> _tracingB("recreateTableFromString: $TABLENAME\n");
1290 0         0 print "RECREATING TABLE: $TABLENAME\n"; # to ACTIVITY file
1291              
1292 0 0       0 if ($dbtablespec =~ /\~/) {
1293 0         0 my @sql = split(/\~/,$dbtablespec);
1294 0         0 foreach my $sql (@sql) {
1295 0 0 0     0 if ((length($sql) > 1) && ($sql =~ /drop/i)) {
    0          
1296             # WARNING: must exclude "drop" from table name.
1297             # for the drop command, do it silently, suppressing any error
1298             # or warning message whether table to be dropped exists or not
1299 0         0 $class-> saveLags;
1300             #>>> $class-> printerror(1);
1301 0         0 $class-> printerror(0);
1302 0         0 $class-> raiseerror(0);
1303 0         0 $class-> autorollback(0);
1304 0         0 $class-> autocommit(1);
1305              
1306 0         0 $class-> do($sql);
1307 0         0 $class-> restoreLags;
1308             }
1309             elsif (length($sql) > 1) {
1310 0 0       0 defined $class-> do($sql) || return 0;
1311             }
1312             }
1313             }
1314             else {
1315             # for the drop command, do it silently, suppressing any error
1316             # or warning message whether table to be dropped exists or not
1317 0         0 $class-> saveLags;
1318 0         0 $class-> printerror(0);
1319 0         0 $class-> raiseerror(0); # do not exit if no table exists to be dropped
1320 0         0 $class-> autorollback(0);
1321 0         0 $class-> autocommit(1);
1322             # Call the do() from this class itself, since it will localize the variables
1323 0         0 $class-> do("drop table $TABLENAME"); # $class-> do("drop table $SCHEMA_TABLENAME");
1324             # Do not call the do() from DBI unless you want to localize everything once again!
1325             #eval {
1326             # local ...
1327             # $class->{connection}->do("drop table $SCHEMA_TABLENAME");
1328             #};
1329             #$@ && $class->{dberr}->println();
1330             #$@ && $class-> printerror && print STDERR ">>>> $@\n";
1331 0         0 $class-> restoreLags;
1332              
1333 0 0       0 defined $class->{connection}->do($dbtablespec) || return 0;
1334             }
1335              
1336 0         0 $class-> _tracingE("recreateTableFromString: $TABLENAME\n");
1337 0         0 return 1;
1338             }
1339              
1340              
1341              
1342              
1343             ########################################################################################
1344             # getTcount($table,$col,$where)
1345             # returns the count records from $table on column=$col where $where condition apply
1346             # returns a positive integer on success, 0 if no record is found, -1 if DBI error
1347              
1348             sub getTcount {
1349 0     0 1 0 my $class = shift;
1350              
1351 0         0 my $table = shift;
1352 0         0 my $oncol = shift;
1353 0         0 my $s = shift;
1354              
1355 0 0       0 $oncol = '*' unless defined($oncol);
1356              
1357 0 0 0     0 my $q = ( (defined($s)) && ($s ne '')) ?
1358             "SELECT COUNT($oncol) FROM $table WHERE $s" : # $s;"
1359             "SELECT COUNT($oncol) FROM $table" ; # $s;"
1360             #"SELECT COUNT(*) FROM $table WHERE $s;" :
1361             #"SELECT COUNT(*) FROM $table;" ;
1362              
1363 0   0     0 $class->{src} = [caller]; push(@{$class->{src}},(caller 1)[3] || '');
  0         0  
  0         0  
1364 0         0 $class->_tracingB("GET_COUNT:\n\tfrom TABLE $table\n\t$q\n\n");
1365              
1366 0         0 my $cursor = $class->{connection}->prepare( $q );
1367              
1368 0         0 $class->{cursor} = $cursor;
1369 0         0 $class->{cursor}->execute();
1370              
1371 0 0       0 if ($DBI::err) {
1372 0         0 $class-> _tracingE("getTcount Failure: (CRISIS) $DBI::err -- $DBI::errstr\n returning FALSE (-1)\n");
1373             # on error return -1, the caller need to check if -1 and get error with $dbhandle->dbierror()
1374             # example DBI ERROR No:1146 -- Table 'varigene.C001_S00_44751de1cfca9' doesn't exist
1375 0         0 $class-> _internal_state(ISTATE_CRISIS);
1376 0         0 return -1;
1377             }
1378              
1379 0         0 my $count;
1380 0 0       0 if (my $temp = $class->{cursor}->fetchrow_hashref()) {
1381 0         0 my %hr = %$temp;
1382 0         0 $count = $hr{"COUNT($oncol)"};
1383             #$count = $hr{'COUNT(*)'};
1384             }
1385              
1386 0         0 $class->{rows} = $class->{cursor}->rows;
1387 0         0 $class->{cursor}->finish();
1388              
1389 0         0 $class->_tracingE("(getTcount OK: >> returning $count\n");
1390 0         0 return $count;
1391             }
1392              
1393             ########################################################################################
1394             ########################################################################################
1395             #DEPRECATED
1396             # will not work with numbers, used to store dyna-matrix data.
1397             # quote everything except attributes ending with _t, _d, _n, _NULL
1398             #*insert=\&insertdumb;
1399             # DEPRECATED, do not document, it is used by the author applications
1400             sub insertdumb {
1401 0     0 0 0 my $class = shift;
1402              
1403 0         0 my $table = shift;
1404 0         0 my %h = @_;
1405            
1406 0         0 my ($s1, $s2, $key);
1407              
1408 0         0 foreach $key (keys %h) {
1409 0 0       0 if ($h{$key} ne '') {
1410 0         0 $s1 .= "$key,";
1411 0         0 my(@T)= split(/_/,$key);
1412 0         0 my($type)=$T[$#T];
1413             # $class->{src} = [caller]; push(@{$class->{src}},(caller 1)[3] || '');
1414             # $class->_tracing("TYPE ================== $key ++ [$type] ++ $h{$key} \n\n");
1415 0 0 0     0 if ( ($type eq 't') || ($type eq 'T') ||
      0        
      0        
      0        
      0        
      0        
1416             ($type eq 'd') || ($type eq 'D') ||
1417             ($type eq 'n') || ($type eq 'N') ||
1418             ($h{$key} eq 'NULL') ) {
1419 0         0 $s2 .= "$h{$key},";
1420             }
1421             else {
1422 0         0 $s2 .= "'$h{$key}',";
1423             }
1424             }
1425             else {
1426 0         0 $s1 .= "$key,";
1427 0         0 $s2 .= "\'\',";
1428             }
1429             }
1430 0         0 chop($s1);
1431 0         0 chop($s2);
1432              
1433 0         0 my $q = "INSERT INTO $table ($s1) VALUES ($s2) ";
1434              
1435 0   0     0 $class->{src} = [caller]; push(@{$class->{src}},(caller 1)[3] || '');
  0         0  
  0         0  
1436 0         0 $class-> _tracingB("INSERTDUMB:\n\t in TABLE $table\n\t$q\n\n");
1437              
1438 0         0 my $cursor = $class->{connection}->prepare( $q );
1439              
1440             # hold the cursor in case we will call the insert from within this class
1441             # my $holdCursor = $class->{cursor};
1442 0         0 $class->{cursor} = $cursor;
1443              
1444 0 0       0 if ($class->{cursor}->execute() ) {
1445 0         0 $class->{rows} = $class->{cursor}->rows;
1446 0         0 $class->{cursor}->finish();
1447              
1448 0   0     0 $class->{src} = [caller]; push(@{$class->{src}},(caller 1)[3] || '');
  0         0  
  0         0  
1449 0         0 $class-> _tracingE("INSERTDUMB PASSED:\n\t in TABLE $table\n\t$q\n\n");
1450              
1451             # $class->{cursor} = $holdCursor;
1452 0         0 return 1;
1453             }
1454             else {
1455 0         0 $class-> _tracingE("INSERTDUMB FAILED: ERROR in DBI !\n\t DBI FAILED ON:\t$DBI::err\n\t DBI REASON:\t$DBI::errstr\n\t DBI LED:\t$DBI::state\n\n");
1456              
1457              
1458 0         0 $class->{rows} = 0;
1459              
1460             # $class->{cursor} = $holdCursor;
1461 0         0 return 0;
1462             }
1463              
1464             }
1465              
1466              
1467             ########################################################################################
1468             ########################################################################################
1469             # insertrec is CS (based in insertnum where you need to quote scalars).
1470             # inserts numerical values, and none of them are being quoted. For non-numerical
1471             # attribute, the caller should explicitly quote the value, e.g. $H{lookup} = "'$UID0'";
1472             #
1473             # insertrec() insert a record into a single table name.
1474             # insertrec() takes two arguments:
1475             # 1- a table name
1476             # 2- a record as a Perl hash whose attributes correspond to the table column names
1477             # it is the Perl data type of each attribute that is effectively used by this method to know
1478             # how to handle the insert. Specify SCALAR references for strings
1479             # Numerical data can be simply specified as is.
1480             # If an attribute is a SCALAR reference, insertrec() will dereference the data
1481              
1482              
1483             # Although the %rec is passed by value, one can always effectively do insert of large records
1484             # by having these attributes that hold large block of data (i.e. BLOB) points their corresponding string.
1485             # The method insertrec() will dereference these string and bind them.
1486              
1487             # Refer to method (that will save you even more memory)
1488             sub insertrec {
1489 0     0 1 0 my $class = shift;
1490              
1491 0         0 my $table = shift;
1492 0         0 my %h = @_;
1493            
1494 0         0 my ($s1, $s2, $key);
1495              
1496 0         0 my @bind_data_bins=();
1497              
1498 0         0 foreach $key (keys %h) {
1499 0 0       0 if (ref $h{$key} eq 'SCALAR') {
1500 0         0 $s1 .= "$key,";
1501 0         0 $s2 .= "?,";
1502             #push(@bind_data_bins,${$h{$key}});
1503 0         0 push(@bind_data_bins,qq{${$h{$key}}});
  0         0  
1504             }
1505             else {
1506 0         0 $s1 .= "$key,";
1507 0         0 $s2 .= "$h{$key},";
1508             }
1509             }
1510 0         0 chop($s1);
1511 0         0 chop($s2);
1512              
1513 0         0 my $q = "INSERT INTO $table ($s1) VALUES ($s2) ";
1514              
1515 0   0     0 $class->{src} = [caller]; push(@{$class->{src}},(caller 1)[3] || '');
  0         0  
  0         0  
1516 0         0 $class-> _tracingB("insertrec():\n\t in TABLE $table\n\t$q\n\n");
1517              
1518             # localize variables
1519 0 0       0 local $class->{connection}->{PrintError} if $class->printerror == 0;
1520 0 0       0 local $class->{connection}->{RaiseError} if $class->raiseerror == 0;
1521 0         0 $class->{connection}->{PrintError}=$class->printerror;
1522 0         0 $class->{connection}->{RaiseError}=$class->raiseerror;
1523 0 0       0 local $class->{connection}->{AutoCommit} if $class->autocommit == 0;
1524 0         0 $class->{connection}->{AutoCommit}=$class->autocommit;
1525              
1526 0         0 my $cursor = $class->{connection}->prepare( $q );
1527              
1528             # hold the cursor in case we will call the insert from within this class
1529             #my $holdCursor = $class->{cursor};
1530 0         0 $class->{cursor} = $cursor;
1531              
1532 0 0       0 if ( $class->{cursor}->execute(@bind_data_bins) )
1533             {
1534 0         0 $class->{rows} = $class->{cursor}->rows;
1535 0         0 $class->{cursor}->finish();
1536              
1537 0   0     0 $class->{src} = [caller]; push(@{$class->{src}},(caller 1)[3] || '');
  0         0  
  0         0  
1538 0         0 $class-> _tracingE("insertrec() PASSED (DONE)\n\n");
1539              
1540             #$class->{cursor} = $holdCursor;
1541 0         0 return 1;
1542             }
1543             else {
1544             #$class->{rows} = 0;
1545             ###$class->{cursor} = $holdCursor;
1546             #$class-> _tracingE("insertrec() FAILED: ERROR in DBI !\n\t DBI FAILED ON:\t$DBI::err\n\t DBI REASON:\t$DBI::errstr\n\t DBI LED:\t$DBI::state\n");
1547             #return 0;
1548              
1549 0         0 $class-> _tracingE("insertrec() FAILED: ERROR in DBI !\n\t DBI FAILED ON:\t$DBI::err\n\t DBI REASON:\t$DBI::errstr\n\t DBI LED:\t$DBI::state\n");
1550             # explicit rollback and disconnect
1551 0 0       0 $class-> autorollback && $class-> _traceln("<-++ rollback AUTOROLLBACK is set to 1, ALAS ROLLING-BACK\n\n");
1552 0 0       0 !$xprm{ON_FAILED_DBIEXECUTE_ROLLBACK_AND_EXIT} && $class-> _traceln("<-++ BUT ON_FAILED_DBIEXECUTE_ROLLBACK_AND_EXIT=0 THEN WE WILL NOT EXIT AND ROLLBACK -- YOU NEED TO DO IT YOURSELF\n\n");
1553             #DONE IN DESTROY $class-> autorollback && $class-> rollback;
1554             # $class-> autorollback && $class-> rollback;
1555 0         0 $class-> _internal_state(ISTATE_CRISIS);
1556             #########$xprm{DIE_AFTER_ROLLBACK} && $class-> autorollback && $class-> disconnect;
1557             #######$xprm{DIE_AFTER_ROLLBACK} && $class-> autorollback && die "CRITICAL ERROR IN DO()... ROLLED BACK r> DISCONNECTED DBHANDLE d> PROGRAM TERMINATED x>\n";
1558             #return 0;
1559             #$xprm{ON_FAILED_DBIEXECUTE_ROLLBACK_AND_EXIT} && (exit);
1560             #$xprm{ON_FAILED_DBIEXECUTE_ROLLBACK_AND_EXIT} && ($class-> DESTROY);
1561              
1562             # if ON_FAILED_DBIEXECUTE_ROLLBACK_AND_EXIT is 1 then check to see whichever exit will be called
1563 0 0 0     0 $xprm{ON_FAILED_DBIEXECUTE_ROLLBACK_AND_EXIT} && ($PERSISTENT_OBJECT_ENABLED) && ($class-> _persistent_exit);
1564 0 0       0 $xprm{ON_FAILED_DBIEXECUTE_ROLLBACK_AND_EXIT} && (exit);
1565             # otherwise return undef
1566 0         0 return undef;
1567             }
1568              
1569             }
1570              
1571              
1572              
1573             ########################################################################################
1574             ########################################################################################
1575             # PRIVATE!
1576             sub sqlRawbnd {
1577 0     0 0 0 my $class = shift;
1578 0         0 my $q = shift;
1579 0   0     0 $class->{src} = [caller]; push(@{$class->{src}},(caller 1)[3] || '');
  0         0  
  0         0  
1580 0         0 $class-> _tracingB("sqlRawbnd(): $q\n");
1581             #$class-> _tracingB("sqlRawbnd(): $q ++ @_\n");
1582            
1583             # localize variables
1584 0 0       0 local $class->{connection}->{PrintError} if $class->printerror == 0;
1585 0 0       0 local $class->{connection}->{RaiseError} if $class->raiseerror == 0;
1586 0         0 $class->{connection}->{PrintError}=$class->printerror;
1587 0         0 $class->{connection}->{RaiseError}=$class->raiseerror;
1588 0 0       0 local $class->{connection}->{AutoCommit} if $class->autocommit == 0;
1589 0         0 $class->{connection}->{AutoCommit}=$class->autocommit;
1590              
1591             #my $tm0 = time;
1592 0         0 my $tm0 = Time::HiRes::clock();
1593 0         0 my $cursor = $class->{connection}->prepare( $q );
1594 0         0 $class->{cursor} = $cursor;
1595 0         0 my @bind_data_bins=();
1596 0 0       0 if (@_) {
1597             #@bind_data_bins = @_;
1598 0         0 foreach (@_) {
1599             # passing string ref is possible, check for these ref and dereference 'em
1600             #my $bnd = ref $_ eq 'SCALAR' ? ${$_} : $_;
1601             # WARNING: because this may not work for Oracle, where the qq{} is needed for the string or varchar...
1602             # in that case use the sqlbnd, or have it done this way!!!
1603 0 0       0 my $bnd = ref $_ eq 'SCALAR' ? qq{${$_}} : $_;
  0         0  
1604 0         0 push(@bind_data_bins, $bnd);
1605             }
1606             }
1607             #if ( $binding && ( $class->{cursor}->execute(@bind_data_bins) ) ) {
1608 0 0       0 if ( $class->{cursor}->execute(@bind_data_bins) ) {
1609 0         0 $class->{rows} = $class->{cursor}->rows;
1610 0         0 $class->{cursor}->finish();
1611             #$class->{cumu_conrun} += time - $tm0;
1612 0         0 my $tm1 = Time::HiRes::clock();
1613 0         0 $class->{cumu_conrun} += $tm1 - $tm0;
1614 0         0 my $elapsed = $tm1 - $tm0;
1615 0         0 $class-> _tracingE("sqlRawbnd() PASSED (DONE)(SYSTEM TIME=$elapsed)\n\n");
1616 0         0 return 1;
1617             }
1618             else {
1619             # if we did not exited due to raiseerror, then rolling back is possible
1620             # and this is useful in complex $q statement where multiple insert may be embedded!
1621 0 0 0     0 if ($class-> autorollback && !$class-> autocommit) {
1622 0         0 $class-> _traceln("<-r rollback AUTOROLLBACK IS SET TO 1, ALAS ROLLING-BACK\n\n");
1623 0         0 $class-> rollback;
1624             ##$class-> disconnect;
1625             ##die "CRITICAL ERROR WHEN INSERTING... ROLLED BACK\n"; }
1626 0         0 $class-> _tracingE("sqlRawbnd() FAILED (ROLLBACK IN EFFECT -- ALAS ROLLING-BACK): ERROR in DBI !\n\t DBI FAILED ON:\t$DBI::err\n\t DBI REASON:\t$DBI::errstr\n\t DBI LED:\t$DBI::state\n\n");
1627             }
1628             else {
1629 0         0 $class->{rows} = 0;
1630             #$class->{cursor} = $holdCursor;
1631 0         0 $class-> _tracingE("sqlRawbnd() FAILED: ERROR in DBI !\n\t DBI FAILED ON:\t$DBI::err\n\t DBI REASON:\t$DBI::errstr\n\t DBI LED:\t$DBI::state\n\n");
1632             }
1633             #$class->{cumu_conrun} += time - $tm0;
1634 0         0 my $tm1 = Time::HiRes::clock();
1635 0         0 $class->{cumu_conrun} += $tm1 - $tm0;
1636             #return undef;
1637 0         0 return 0;
1638             }
1639             }
1640              
1641              
1642             ########################################################################################
1643             ########################################################################################
1644             #
1645             #
1646             # http://www.physiol.ox.ac.uk/Computing/Online_Documentation/DBI.html
1647             # http://www.easysoft.com/developer/languages/perl/dbi-debugging.html
1648             #use DBD::Oracle qw(:ora_types);
1649             #*insertbnd
1650             sub sqlbnd {
1651 0     0 1 0 my $class = shift;
1652             # start with a good state upon each entry
1653 0         0 $class-> _internal_state(ISTATE_GOOD);
1654              
1655 0         0 my $q = shift;
1656 0 0 0     0 my $o_bnd = (@_ && (ref $_[0] eq 'ARRAY') && (ref ${$_[0]}[0] eq 'HASH')) ? shift : undef;
1657 0 0 0     0 my $o_typ = (@_ && (ref $_[0] eq 'HASH')) ? shift : undef;
1658              
1659 0   0     0 $class->{src} = [caller]; push(@{$class->{src}},(caller 1)[3] || '');
  0         0  
  0         0  
1660 0         0 $class-> _tracingB("sqlbnd(): $q\n");
1661             #$class-> _tracingB("SQLSQL: $q ++ @_\n");
1662            
1663             # localize variables
1664 0 0       0 local $class->{connection}->{PrintError} if $class->printerror == 0;
1665 0 0       0 local $class->{connection}->{RaiseError} if $class->raiseerror == 0;
1666 0         0 $class->{connection}->{PrintError}=$class->printerror;
1667 0         0 $class->{connection}->{RaiseError}=$class->raiseerror;
1668 0 0       0 local $class->{connection}->{AutoCommit} if $class->autocommit == 0;
1669 0         0 $class->{connection}->{AutoCommit}=$class->autocommit;
1670              
1671             #my $tm0 = time;
1672 0         0 my $tm0 = Time::HiRes::clock();
1673              
1674             # if $o is a pseudo hash then go for the binding
1675 0 0 0     0 if ((ref $o_bnd eq 'ARRAY') && (ref $$o_bnd[0] eq 'HASH')) {
1676             #my $b_canonical;
1677 0         0 my @ord = sort values %{$$o_bnd[0]};
  0         0  
1678 0         0 my %ord = reverse %{$$o_bnd[0]};
  0         0  
1679             #for (my $i=1; $i<=@ord; $i++) {
1680             # $b_canonical .= ':' . $ord{$i} . ',';
1681             #}
1682             #chop($b_canonical);
1683             #my $sql = "BEGIN $pkgspc($b_canonical); END;";
1684             #my $cursor = $class->{connection}->prepare($sql) or die "Cannot prepare $sql\n";
1685 0 0       0 my $cursor = $class->{connection}->prepare($q) or die "Cannot prepare $q\n";
1686 0         0 $class->{cursor} = $cursor;
1687 0         0 for (my $i=1; $i<=@ord; $i++) {
1688             #if ($o->[$i]) {
1689 0         0 my $str;
1690 0 0       0 $str = (ref $o_bnd->[$i] eq 'SCALAR') ? ${$o_bnd->[$i]} : $o_bnd->[$i];
  0         0  
1691             # Escape as in /usr/lib/perl5/site_perl/5.8/cygwin/DBD/File.pm : sub quote
1692             #$str =~ s/\\/\\\\/sg; $str =~ s/\0/\\0/sg;
1693             #$str =~ s/\'/\\\'/sg; $str =~ s/\n/\\n/sg; $str =~ s/\r/\\r/sg;
1694             #"'$str'";
1695              
1696 0 0       0 if ( exists $$o_typ{ $ord{$i} } ) {
1697 0         0 $class-> _traceln("................------------------------------........................................ binding $i :$ord{$i} ($$o_typ{ $ord{$i} })\n");
1698             #$cursor->bind_param($i, qq{$o_bnd->[$i]}, {ora_type=>ORA_BLOB} );
1699             #$cursor->bind_param($i, qq{$o_bnd->[$i]}, { ora_type=>$o_typ{ $ord{$i} } } );
1700 0         0 $cursor->bind_param($i, qq{$str}, { ora_type=>$$o_typ{ $ord{$i} } } );
1701             }
1702             else {
1703 0         0 $class-> _traceln("....................................................................................... binding $i :$ord{$i}\n");
1704             #$cursor->bind_param($i, qq{$o_bnd->[$i]} );
1705 0         0 $cursor->bind_param($i, qq{$str} );
1706             }
1707             }
1708 0 0       0 $cursor->execute or die __PACKAGE__, "::sqlbnd Cannot execute $q\n", caller,"\n";
1709 0         0 $cursor->finish();
1710             }
1711             else {
1712 0         0 my $cursor = $class->{connection}->prepare( $q );
1713 0         0 $class->{cursor} = $cursor;
1714 0         0 my @bind_data_bins=();
1715 0 0       0 if (@_) {
1716             #@bind_data_bins = @_;
1717 0         0 foreach (@_) {
1718             # passing string ref is possible, check for these ref and dereference 'em
1719 0 0       0 my $bnd = ref $_ eq 'SCALAR' ? ${$_} : $_;
  0         0  
1720 0         0 push(@bind_data_bins, $bnd);
1721             }
1722             }
1723             #if ( $binding && ( $class->{cursor}->execute(@bind_data_bins) ) ) {
1724 0 0       0 if ( $class->{cursor}->execute(@bind_data_bins) ) {
1725 0         0 $class->{rows} = $class->{cursor}->rows;
1726 0         0 $class->{cursor}->finish();
1727             #$class->{cumu_conrun} += time - $tm0;
1728 0         0 my $tm1 = Time::HiRes::clock();
1729 0         0 $class->{cumu_conrun} += $tm1 - $tm0;
1730 0         0 my $elapsed = $tm1 - $tm0;
1731 0         0 $class-> _tracingE("sqlbnd() PASSED (DONE)(SYSTEM TIME=$elapsed)\n\n");
1732 0         0 return 1;
1733             }
1734             else {
1735             # if we did not exit due to raiseerror, then rolling back is possible
1736             # and this is useful in complex $q statement where multiple insert may be embedded!
1737 0 0 0     0 if ($class-> autorollback && !$class-> autocommit) {
1738 0         0 $class-> _traceln("<-r rollback AUTOROLLBACK IS SET TO 1, ALAS ROLLING-BACK\n\n");
1739 0         0 $class-> rollback;
1740             ##$class-> disconnect;
1741             ##die "CRITICAL ERROR WHEN INSERTING... ROLLED BACK\n"; }
1742 0         0 $class-> _tracingE("sqlbnd() FAILED (ROLLBACK IN EFFECT -- ALAS ROLLING-BACK): ERROR in DBI !\n\t DBI FAILED ON:\t$DBI::err\n\t DBI REASON:\t$DBI::errstr\n\t DBI LED:\t$DBI::state\n\n");
1743             }
1744             else {
1745 0         0 $class->{rows} = 0;
1746             #$class->{cursor} = $holdCursor;
1747 0         0 $class-> _tracingE("sqlbnd() FAILED: ERROR in DBI !\n\t DBI FAILED ON:\t$DBI::err\n\t DBI REASON:\t$DBI::errstr\n\t DBI LED:\t$DBI::state\n\n");
1748             }
1749             #$class->{cumu_conrun} += time - $tm0;
1750 0         0 my $tm1 = Time::HiRes::clock();
1751 0         0 $class->{cumu_conrun} += $tm1 - $tm0;
1752             #return undef;
1753 0         0 return 0;
1754             }
1755             }
1756             }
1757              
1758             # DATATY
1759             ########################################################################################
1760             ########################################################################################
1761             ########################################################################################
1762             ########################################################################################
1763             ########################################################################################
1764             ########################################################################################
1765             # need type mapping table, next release
1766             # Test this one with Oracle
1767             #
1768 1     1   11 use constant BBNNDD => 0;
  1         2  
  1         19880  
1769             sub typ_insertbnd { #rslt params
1770 0     0 0 0 my $class = shift;
1771 0         0 my $table = shift;
1772 0         0 my $UID0 = shift;
1773 0         0 my $targcolumns = shift;
1774 0         0 my $CoL_href = shift;
1775 0         0 my $El2Ty_href = shift;
1776              
1777 0         0 my @columns = @{$targcolumns};
  0         0  
1778              
1779             #my %H;
1780 0         0 my %H2O;
1781 0         0 my $xcol; my $yval;
1782 0         0 $xcol = 'LOOKUP,'; $yval = "'$UID0',";
  0         0  
1783              
1784             ###$H{LOOKUP} = "'$UID0'";
1785             #$H{LOOKUP} = \$UID0;
1786              
1787             #Ideally: foreach (@RsColumns) { $H{$_} = \"$$CoL_href{$_}"; }
1788             #my $El2Ty_href = $class->{_rsltEl2Ty};
1789 0         0 foreach (@columns) {
1790             #foreach (keys %$CoL_href) {
1791 0         0 BBNNDD && print "................................................................................................$_ ++ $$El2Ty_href{$_} ++ $$CoL_href{$_} \n";
1792 0 0 0     0 if (($$El2Ty_href{$_} =~ /STRING/i) && ($$El2Ty_href{$_} !~ /STRING\(\s*\^\s*\)/i)) {
    0          
    0          
1793             # avoid inserting a NULL by default for empty string
1794 0 0 0     0 my $v = ($$CoL_href{$_} eq '') && $xprm{DBSETTING_FORCE_SINGLESPACE_FOR_EMPTY_STRING}
1795             #? \"' '"
1796             #: \"'$$CoL_href{$_}'";
1797             ? "' '"
1798             : "'$$CoL_href{$_}'";
1799 0         0 $xcol .= $_ . ',';
1800 0         0 $yval .= $v . ',';
1801             }
1802             elsif ($$El2Ty_href{$_} =~ /STRING\(\s*\^\s*\)/) {
1803             # this is a ref of type string pointer STRING(^)=BLOB=~/_sref$/i
1804 0         0 $xcol .= $_ . ',';
1805 0         0 $yval .= '?,';
1806 0         0 $H2O{$_} = $$CoL_href{$_}; # ${ $$CoL_href{$_} }
1807             }
1808             elsif ($$El2Ty_href{$_} =~ /CBOOL/) {
1809             # this is a ref of type string pointer STRING(^)=BLOB=~/_sref$/i
1810 0         0 $xcol .= $_ . ',';
1811 0         0 $yval .= "'$$CoL_href{$_}'" . ',';
1812             }
1813             else {
1814 0         0 $xcol .= $_ . ',';
1815 0         0 $yval .= $$CoL_href{$_} . ',';
1816             }
1817             }
1818 0         0 $xcol .= 'RECORDDATE_T'; $yval .= $class-> {SYSDATE};
  0         0  
1819             #chop($xcol);
1820             #chop($yval);
1821              
1822 0         0 my $SQL = "INSERT INTO $table ($xcol) VALUES ($yval)";
1823 0         0 my $pseudoLeft; my @pseudoRight; my $fldTyp;
  0         0  
1824 0         0 my $i=0;
1825 0         0 foreach my $k (sort keys %H2O) {
1826 0         0 $pseudoLeft .= "$k=>". ++$i . ",";
1827             #@pseudoRight = (@pseudoRight, $H2O{$k});
1828 0         0 push(@pseudoRight , $H2O{$k});
1829 0         0 $fldTyp .= "$k=>103,";
1830             }
1831 0         0 chop($pseudoLeft);
1832 0         0 chop($fldTyp);
1833            
1834 0         0 BBNNDD && print "aaaaaa************************************************************************************\n";
1835 0         0 BBNNDD && print "aaaaaa************************************************************************************ $pseudoLeft\n";
1836 0         0 BBNNDD && print "aaaaaa************************************************************************************ $fldTyp\n";
1837             #my %pseudoLeft = eval "%{$pseudoLeft}";
1838 0         0 my %pseudoLeft = eval "($pseudoLeft)";
1839 0         0 my $o_bnd = [ {%pseudoLeft} , @pseudoRight ];
1840             #my %fldTyp = eval $fldTyp;
1841 0         0 my %fldTyp = eval "($fldTyp)";
1842 0         0 my $o_typ = \%fldTyp;
1843 0 0 0     0 if ((ref $o_bnd eq 'ARRAY') && (ref $$o_bnd[0] eq 'HASH')) {
1844 0         0 BBNNDD && print "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy $o_bnd\n";
1845 0         0 my @ord = sort values %{$$o_bnd[0]};
  0         0  
1846 0         0 my %ord = reverse %{$$o_bnd[0]};
  0         0  
1847 0         0 for (my $i=1; $i<=@ord; $i++) {
1848 0         0 my $str;
1849 0 0       0 $str = (ref $o_bnd->[$i] eq 'SCALAR') ? ${$o_bnd->[$i]} : $o_bnd->[$i];
  0         0  
1850 0 0       0 if ( exists $$o_typ{ $ord{$i} } ) {
1851 0         0 BBNNDD && print ".............................................. binding $i ++ :$ord{$i} ($$o_typ{ $ord{$i} })\n";
1852             }
1853             else {
1854 0         0 BBNNDD && print ".............................................. binding $i ++ :$ord{$i}\n";
1855             }
1856             }
1857             }
1858 0         0 BBNNDD && print "0>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $SQL\n";
1859 0         0 BBNNDD && print "1>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $pseudoLeft\n";
1860 0         0 BBNNDD && print "2>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @pseudoRight\n";
1861 0         0 BBNNDD && print "3>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $fldTyp\n";
1862 0         0 BBNNDD && print "************************************************************************************\n";
1863              
1864              
1865             # start with a good state upon each entry
1866 0         0 $class-> _internal_state(ISTATE_GOOD);
1867              
1868             # localize variables
1869 0 0       0 local $class->{connection}->{PrintError} if $class->printerror == 0;
1870 0 0       0 local $class->{connection}->{RaiseError} if $class->raiseerror == 0;
1871 0         0 $class->{connection}->{PrintError}=$class->printerror;
1872 0         0 $class->{connection}->{RaiseError}=$class->raiseerror;
1873             # when $class->autocommit==0 STORE('AutoCommit' undef)= 1
1874 0 0       0 local $class->{connection}->{AutoCommit} if $class->autocommit == 0;
1875             # when $class->autocommit==0 STORE('AutoCommit' '0')= 1
1876 0         0 $class->{connection}->{AutoCommit}=$class->autocommit;
1877              
1878              
1879 0         0 my $tm0 = Time::HiRes::clock();
1880             #if ($class->{_dbhandle}->sqlbnd($SQL, $o_bnd, $o_typ) ) {
1881 0 0       0 if ($class-> sqlbnd($SQL, $o_bnd) ) {
1882 0         0 my $tm1 = Time::HiRes::clock();
1883 0         0 $class->{cumu_conrun} += $tm1 - $tm0;
1884 0         0 my $elapsed = $tm1 - $tm0;
1885             }
1886             else {
1887             # $FATAL && die "INTERNAL ERROR ....\n";
1888 0         0 my $err = "INTERBAL ERROR WHEN WRITING TO $table failed: ERROR in DBI !\n\t DBI FAILED ON:\t$DBI::err\n\t DBI REASON:\t$DBI::errstr\n\t DBI LED:\t$DBI::state\n\n";
1889 0         0 BBNNDD && print STDOUT $err;
1890 0         0 print STDERR $err;
1891 0         0 return 0;
1892             }
1893              
1894             #$H{RECORDDATE_T}=$SYSDATE;
1895             #if ($class->{_dbhandle}->insertrec($BASETAB_RSLT_PARAMS, %H)) {}
1896             #else {
1897             # die "INTERNAL ERROR MatrixMapper > storeRSO_MatricesIndexTable! ", $class->{_dbhandle}->dbierror(), "\n";
1898             #}
1899             }
1900              
1901             ########################################################################################
1902             # PRIVATE
1903             # need type mapping table, next release
1904             sub typ_updatebnd { #rslt params
1905 0     0 0 0 my $class = shift;
1906 0         0 my $table = shift;
1907             # my $UID0 = shift;
1908             # my $targcolumns = shift;
1909 0         0 my $CoL_href = shift;
1910 0         0 my $El2Ty_href = shift;
1911 0         0 my $wherecond = shift;
1912              
1913              
1914             # start with a good state upon each entry
1915 0         0 $class-> _internal_state(ISTATE_GOOD);
1916              
1917 0   0     0 $class->{src} = [caller]; push(@{$class->{src}},(caller 1)[3] || '');
  0         0  
  0         0  
1918 0         0 $class-> _tracingB("typ_updatebnd(): $table\n");
1919              
1920             # localize variables
1921 0 0       0 local $class->{connection}->{PrintError} if $class->printerror == 0;
1922 0 0       0 local $class->{connection}->{RaiseError} if $class->raiseerror == 0;
1923 0         0 $class->{connection}->{PrintError}=$class->printerror;
1924 0         0 $class->{connection}->{RaiseError}=$class->raiseerror;
1925             # when $class->autocommit==0 STORE('AutoCommit' undef)= 1
1926 0 0       0 local $class->{connection}->{AutoCommit} if $class->autocommit == 0;
1927             # when $class->autocommit==0 STORE('AutoCommit' '0')= 1
1928 0         0 $class->{connection}->{AutoCommit}=$class->autocommit;
1929              
1930             #my $TOTAL_ELAPSETIME = sprintf("%.2f", Time::HiRes::tv_interval($INVOTIME0));
1931             #${$$statCC{$caconn}}{starttime} = [Time::HiRes::gettimeofday];
1932             #my $tm0 = [Time::HiRes::gettimeofday];
1933             #my $tm0 = time;
1934 0         0 my $tm0 = Time::HiRes::clock();
1935              
1936             # my @columns = @{$targcolumns};
1937              
1938             #my %H;
1939 0         0 my %H2O;
1940             # my $xcol; my $yval;
1941 0         0 my $xcol_yval = '';
1942             #$xcol = 'LOOKUP,'; $yval = "'$UID0',";
1943              
1944             ###$H{LOOKUP} = "'$UID0'";
1945             #$H{LOOKUP} = \$UID0;
1946              
1947             #Ideally: foreach (@RsColumns) { $H{$_} = \"$$CoL_href{$_}"; }
1948             #my $El2Ty_href = $class->{_rsltEl2Ty};
1949             #foreach (@columns) {
1950 0         0 foreach (keys %$CoL_href) {
1951 0         0 BBNNDD && print "................................................................................................$_ ++ $$El2Ty_href{$_} ++ $$CoL_href{$_} \n";
1952 0 0 0     0 if (($$El2Ty_href{$_} =~ /STRING/i) && ($$El2Ty_href{$_} !~ /STRING\(\s*\^\s*\)/i)) {
    0          
    0          
1953             # avoid inserting a NULL by default for empty string
1954 0 0 0     0 my $v = ($$CoL_href{$_} eq '') && $xprm{DBSETTING_FORCE_SINGLESPACE_FOR_EMPTY_STRING}
1955             #? \"' '"
1956             #: \"'$$CoL_href{$_}'";
1957             ? "' '"
1958             : "'$$CoL_href{$_}'";
1959             # $xcol .= $_ . ',';
1960             # $yval .= $v . ',';
1961 0         0 $xcol_yval .= $_ . '=' . $v . ','
1962             }
1963             elsif ($$El2Ty_href{$_} =~ /STRING\(\s*\^\s*\)/) {
1964             # this is a ref of type string pointer STRING(^)=BLOB=~/_sref$/i
1965             # $xcol .= $_ . ',';
1966             # $yval .= '?,';
1967 0         0 $xcol_yval .= $_ . '=?,';
1968 0         0 $H2O{$_} = $$CoL_href{$_}; # ${ $$CoL_href{$_} }
1969             }
1970             elsif ($$El2Ty_href{$_} =~ /CBOOL/) {
1971             # this is a ref of type string pointer STRING(^)=BLOB=~/_sref$/i
1972             # $xcol .= $_ . ',';
1973             # $yval .= "'$$CoL_href{$_}'" . ',';
1974 0         0 $xcol_yval .= $_ . "='$$CoL_href{$_}',";
1975             }
1976             else {
1977             # $xcol .= $_ . ',';
1978             # $yval .= $$CoL_href{$_} . ',';
1979 0         0 $xcol_yval .= $_ . '=' . $$CoL_href{$_} . ',';
1980             }
1981             }
1982             #$xcol .= 'RECORDDATE_T'; $yval .= $class-> {SYSDATE};
1983 0         0 $xcol_yval .= 'CHANGEDATE_T' . '=' . $class-> {SYSDATE};
1984             #chop($xcol);
1985             #chop($yval);
1986              
1987             #UPDATE VS001NY_PRSS_JN_INFO SET DISPLAYNAME = 'yyyyyyyyy' WHERE EXISTS (SELECT 1 FROM VS001NY_PRSS_REGISTRY a WHERE VS001NY_PRSS_JN_INFO.LOOKUP = a.LOOKUP);
1988              
1989             #my $SQL = "INSERT INTO $table ($xcol) VALUES ($yval)";
1990 0         0 my $SQL = "UPDATE $table SET $xcol_yval WHERE $wherecond";
1991              
1992 0         0 my $pseudoLeft; my @pseudoRight; my $fldTyp;
  0         0  
1993 0         0 my $i=0;
1994 0         0 foreach my $k (sort keys %H2O) {
1995 0         0 $pseudoLeft .= "$k=>". ++$i . ",";
1996             #@pseudoRight = (@pseudoRight, $H2O{$k});
1997 0         0 push(@pseudoRight , $H2O{$k});
1998 0         0 $fldTyp .= "$k=>103,";
1999             }
2000 0         0 chop($pseudoLeft);
2001 0         0 chop($fldTyp);
2002            
2003 0         0 BBNNDD && print "aaaaaa************************************************************************************\n";
2004 0         0 BBNNDD && print "aaaaaa************************************************************************************ $pseudoLeft\n";
2005 0         0 BBNNDD && print "aaaaaa************************************************************************************ $fldTyp\n";
2006             #my %pseudoLeft = eval "%{$pseudoLeft}";
2007 0         0 my %pseudoLeft = eval "($pseudoLeft)";
2008 0         0 my $o_bnd = [ {%pseudoLeft} , @pseudoRight ];
2009             #my %fldTyp = eval $fldTyp;
2010 0         0 my %fldTyp = eval "($fldTyp)";
2011 0         0 my $o_typ = \%fldTyp;
2012 0 0 0     0 if ((ref $o_bnd eq 'ARRAY') && (ref $$o_bnd[0] eq 'HASH')) {
2013 0         0 BBNNDD && print "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy $o_bnd\n";
2014 0         0 my @ord = sort values %{$$o_bnd[0]};
  0         0  
2015 0         0 my %ord = reverse %{$$o_bnd[0]};
  0         0  
2016 0         0 for (my $i=1; $i<=@ord; $i++) {
2017 0         0 my $str;
2018 0 0       0 $str = (ref $o_bnd->[$i] eq 'SCALAR') ? ${$o_bnd->[$i]} : $o_bnd->[$i];
  0         0  
2019 0 0       0 if ( exists $$o_typ{ $ord{$i} } ) {
2020 0         0 BBNNDD && print ".............................................. binding $i ++ :$ord{$i} ($$o_typ{ $ord{$i} })\n";
2021             }
2022             else {
2023 0         0 BBNNDD && print ".............................................. binding $i ++ :$ord{$i}\n";
2024             }
2025             }
2026             }
2027 0         0 BBNNDD && print "0>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $SQL\n";
2028 0         0 BBNNDD && print "1>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $pseudoLeft\n";
2029 0         0 BBNNDD && print "2>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @pseudoRight\n";
2030 0         0 BBNNDD && print "3>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $fldTyp\n";
2031 0         0 BBNNDD && print "************************************************************************************\n";
2032             #if ($class->{_dbhandle}->sqlbnd($SQL, $o_bnd, $o_typ) ) {
2033 0 0       0 if ($class-> sqlbnd($SQL, $o_bnd) ) {
2034 0         0 my $tm1 = Time::HiRes::clock();
2035 0         0 $class->{cumu_conrun} += $tm1 - $tm0;
2036 0         0 my $elapsed = $tm1 - $tm0;
2037 0         0 $class-> _tracingE("typ_updatebnd() PASSED (DONE)(SYSTEM TIME=$elapsed)\n\n");
2038             }
2039             else {
2040 0         0 $class-> _tracingE("typ_updatebnd() FAILED (ROLLBACK IN EFFECT -- ALAS ROLLING-BACK): ERROR in DBI !\n\t DBI FAILED ON:\t$DBI::err\n\t DBI REASON:\t$DBI::errstr\n\t DBI LED:\t$DBI::state\n\n");
2041             # $FATAL && die "INTERNAL ERROR ....\n";
2042 0         0 my $err = "INTERBAL ERROR WHEN WRITING TO $table failed: ERROR in DBI !\n\t DBI FAILED ON:\t$DBI::err\n\t DBI REASON:\t$DBI::errstr\n\t DBI LED:\t$DBI::state\n\n";
2043 0         0 BBNNDD && print STDOUT $err;
2044 0         0 print STDERR $err;
2045 0         0 return 0;
2046             }
2047              
2048             #$H{RECORDDATE_T}=$SYSDATE;
2049             #if ($class->{_dbhandle}->insertrec($BASETAB_RSLT_PARAMS, %H)) {}
2050             #else {
2051             # die "INTERNAL ERROR MatrixMapper > storeRSO_MatricesIndexTable! ", $class->{_dbhandle}->dbierror(), "\n";
2052             #}
2053             }
2054              
2055              
2056             ########################################################################################
2057             ########################################################################################
2058             ########################################################################################
2059             ########################################################################################
2060             ########################################################################################
2061             ########################################################################################
2062             #
2063             # On success:
2064             # return the number of rows affected
2065             #
2066             # On failure:
2067             # return undef on failure if raiseerror=0 and autorollback=0
2068             # will die (calling destroy) and will explicit-rollback and will not return if raiseerror=0 and autorollback=1
2069             # will die (calling destroy) and will not return if raiseerror=1 and autorollback=0
2070             #
2071             sub do {
2072 0     0 1 0 my $class = shift;
2073              
2074             # start with a good state upon each entry
2075 0         0 $class-> _internal_state(ISTATE_GOOD);
2076              
2077 0         0 my $q = shift;
2078            
2079 0   0     0 $class->{src} = [caller]; push(@{$class->{src}},(caller 1)[3] || '');
  0         0  
  0         0  
2080 0         0 $class-> _tracingB("DO:\n\t $q\n\n");
2081              
2082             # localize variables
2083 0 0       0 local $class->{connection}->{PrintError} if $class->printerror == 0;
2084 0 0       0 local $class->{connection}->{RaiseError} if $class->raiseerror == 0;
2085 0         0 $class->{connection}->{PrintError}=$class->printerror;
2086 0         0 $class->{connection}->{RaiseError}=$class->raiseerror;
2087             # when $class->autocommit==0 STORE('AutoCommit' undef)= 1
2088 0 0       0 local $class->{connection}->{AutoCommit} if $class->autocommit == 0;
2089             # when $class->autocommit==0 STORE('AutoCommit' '0')= 1
2090 0         0 $class->{connection}->{AutoCommit}=$class->autocommit;
2091              
2092             #my $TOTAL_ELAPSETIME = sprintf("%.2f", Time::HiRes::tv_interval($INVOTIME0));
2093             #${$$statCC{$caconn}}{starttime} = [Time::HiRes::gettimeofday];
2094             #my $tm0 = [Time::HiRes::gettimeofday];
2095             #my $tm0 = time;
2096 0         0 my $tm0 = Time::HiRes::clock();
2097             #eval {
2098              
2099             #my $second = undef;
2100             #my @p;
2101             #if (@_) { $second = shift; }
2102             #while (@_) {
2103             # my $next = shift;
2104             # my $p = ref $next eq 'SCALAR' ? qq{$$next} : $next;
2105             # push(@p,$p);
2106             #}
2107             #my $rr = $class->{connection}->do( $q, $second, @p );
2108              
2109             ###if ($class->{connection}->do( $q, @_ ) && ! $DBI::err ) {
2110 0         0 my $rr_do = $class->{connection}->do( $q, @_ );
2111             # turn old mule "0E0" into plain 0; otherwise number of afftected columns; otherwise undef for false
2112              
2113             # turn "0E0" into 0
2114 0 0 0     0 my $rr = defined $rr_do && $rr_do eq '0E0' ? 0 : $rr_do ? $rr_do : undef;
    0          
2115              
2116             #TODO: need to benchmark the do() and see if the following assertions may cause a slow down in
2117             # a long do() harness
2118             # Add DOCUMENTATION in POD: Warn the user of the behavior of DROP (also used in recreateTable),
2119             #
2120             #whenever raiseerror is 0, for a DROP sttm force the return result $rr to 0, so we do not exit
2121             #because dropping a non-existent table will return undef
2122 0 0 0     0 ($class->raiseerror == 0) && (!defined $rr) && ($q =~ /^\s*drop\s+/i) && ($rr = 0);
      0        
2123            
2124 0 0       0 if (defined $rr) {
2125 0         0 $class->_tracingE("DO: PASSED WITH RR=$rr\n");
2126             #$class->autocommit && $class->{connection}->commit;
2127              
2128             # my $elap = time - $tm0;
2129             #$class->{cumu_conrun} += time - $tm0;
2130 0         0 my $tm1 = Time::HiRes::clock();
2131 0         0 $class->{cumu_conrun} += $tm1 - $tm0;
2132 0 0       0 if ($xprm{ENABLE_STATISTICS_ON_DO}) {
2133             # Adjust statistics for arriving queries
2134 0 0       0 $class->{_qryStat}{$q}{count} = (defined $class->{_qryStat}{$q}) ? $class->{_qryStat}{$q}{count}+1 : 1;
2135 0         0 $class->{_qryStat}{$q}{tm0} = $tm0;
2136             #$class->{_qryStat}{$q}{tm1} = time;
2137 0         0 $class->{_qryStat}{$q}{tm1} = Time::HiRes::clock();
2138             }
2139             #return 1;
2140 0         0 return $rr;
2141             }
2142             else {
2143 0         0 $class-> _tracingE("DO: FAILED\nERROR in DBI !\n\t DBI FAILED ON:\t$DBI::err\n\t DBI REASON:\t$DBI::errstr\n\t DBI LED:\t$DBI::state\n\n");
2144              
2145             # explicit rollback and disconnect
2146 0 0       0 $class-> autorollback && $class-> _traceln("<-++ rollback AUTOROLLBACK is set to 1, ALAS ROLLING-BACK\n\n");
2147 0 0       0 !$xprm{ON_FAILED_DBIEXECUTE_ROLLBACK_AND_EXIT} && $class-> _traceln("<-++ BUT ON_FAILED_DBIEXECUTE_ROLLBACK_AND_EXIT=0 THEN WE WILL NOT EXIT AND ROLLBACK -- YOU NEED TO DO IT YOURSELF\n\n");
2148             #DONE IN DESTROY $class-> autorollback && $class-> rollback;
2149             # $class-> autorollback && $class-> rollback;
2150 0         0 $class-> _internal_state(ISTATE_CRISIS);
2151             #########$xprm{DIE_AFTER_ROLLBACK} && $class-> autorollback && $class-> disconnect;
2152             #######$xprm{DIE_AFTER_ROLLBACK} && $class-> autorollback && die "CRITICAL ERROR IN DO()... ROLLED BACK r> DISCONNECTED DBHANDLE d> PROGRAM TERMINATED x>\n";
2153             #return 0;
2154             #$xprm{ON_FAILED_DBIEXECUTE_ROLLBACK_AND_EXIT} && (exit);
2155             #$xprm{ON_FAILED_DBIEXECUTE_ROLLBACK_AND_EXIT} && ($class-> DESTROY);
2156              
2157             # if ON_FAILED_DBIEXECUTE_ROLLBACK_AND_EXIT is 1 then check to see whichever exit will be called
2158 0 0 0     0 $xprm{ON_FAILED_DBIEXECUTE_ROLLBACK_AND_EXIT} && ($PERSISTENT_OBJECT_ENABLED) && ($class-> _persistent_exit);
2159 0 0       0 $xprm{ON_FAILED_DBIEXECUTE_ROLLBACK_AND_EXIT} && (exit);
2160             # otherwise return undef
2161 0         0 return undef; # same as return $rr;
2162             }
2163             #};
2164              
2165             #if ($@) {
2166             # print "ERROR: \t $@ \n\n";
2167             # $class->autorollback && $class->{connection}->rollback;
2168             # return 0;
2169             #}
2170             #return 1;
2171              
2172             }
2173              
2174              
2175            
2176             ########################################################################################
2177             ########################################################################################
2178             # Calls the stored procedure $stproc. The first parameter $o can be either a pseudo-hash
2179             # or a scalar. Passing a pseudo-hash is documented as above, passing a scalar need to be
2180             # documented later.
2181             sub spc {
2182 0     0 1 0 my $class = shift;
2183 0         0 my $o = shift;
2184 0         0 my $pkgspc = shift;
2185              
2186             # localize variables
2187 0 0       0 local $class->{connection}->{PrintError} if $class->printerror == 0;
2188 0 0       0 local $class->{connection}->{RaiseError} if $class->raiseerror == 0;
2189 0         0 $class->{connection}->{PrintError}=$class->printerror;
2190 0         0 $class->{connection}->{RaiseError}=$class->raiseerror;
2191 0   0     0 $class->{src} = [caller]; push(@{$class->{src}},(caller 1)[3] || '');
  0         0  
  0         0  
2192 0         0 $class-> _tracingB("spc()/EXECUTING STORED PROCEDURE:\n\t $pkgspc\n\n");
2193 0         0 my $tm0 = Time::HiRes::clock();
2194              
2195             # if $o is a pseudo hash then go for the binding
2196 0 0 0     0 if ((ref $o eq 'ARRAY') && (ref $$o[0] eq 'HASH')) {
2197 0         0 my $b_canonical;
2198 0         0 my @ord = sort values %{$$o[0]};
  0         0  
2199 0         0 my %ord = reverse %{$$o[0]};
  0         0  
2200 0         0 for (my $i=1; $i<=@ord; $i++) {
2201 0         0 $b_canonical .= ':' . $ord{$i} . ',';
2202             }
2203              
2204 0         0 chop($b_canonical);
2205 0         0 my $sql = "BEGIN $pkgspc($b_canonical); END;";
2206 0 0       0 my $cursor = $class->{connection}->prepare($sql) or die "Cannot prepare $sql\n";
2207 0         0 $class->{cursor} = $cursor;
2208             # go in order and bind the parameters, if a parameter is defined then bind_param otherwise bind_param_inout
2209 0         0 for (my $i=1; $i<=@ord; $i++) {
2210 0 0       0 if ($o->[$i]) {
2211 0         0 $cursor->bind_param(":$ord{$i}", $o->[$i]);
2212             }
2213             else {
2214             #$cursor->bind_param_inout(":$ord{$i}", \$o->[$i], 1) unless $o>;
2215 0         0 $cursor->bind_param_inout(":$ord{$i}", \$o->[$i], 10);
2216             }
2217             }
2218             # die if spc execute fails; users need to test that their spc packages are valids and functioning properly
2219 0 0       0 $cursor-> execute or die __PACKAGE__, "::spc Cannot execute $sql\n";
2220 0         0 $cursor-> finish();
2221              
2222 0 0       0 if ($o->[1]) {
2223             # my $elap = time - $tm0;
2224             #$class->{cumu_conrun} += time - $tm0;
2225 0         0 my $tm1 = Time::HiRes::clock();
2226 0         0 $class->{cumu_conrun} += $tm1 - $tm0;
2227 0 0       0 if ($xprm{ENABLE_STATISTICS_ON_SPC}) {
2228             # Adjust statistics for arriving spc's
2229 0 0       0 $class->{_spcStat}{$pkgspc}{count} = (defined $class->{_spcStat}{$pkgspc}) ? $class->{_spcStat}{$pkgspc}{count}+1 : 1;
2230 0         0 $class->{_spcStat}{$pkgspc}{tm0} = $tm0;
2231             #$class->{_spcStat}{$pkgspc}{tm1} = time;
2232 0         0 $class->{_spcStat}{$pkgspc}{tm1} = Time::HiRes::clock();
2233             }
2234 0         0 $class-> _tracingE("spc() PASSED (DONE)\n\n");
2235 0         0 return 1;
2236             }
2237             #$o->[1] && return 1;
2238             }
2239             #elsif (ref $o eq 'ARRAY') { # simple array list, then simple binding with ?
2240             #}
2241             else { # $o is a SCALAR
2242 0         0 my $sql = "BEGIN $pkgspc(?); END;";
2243 0 0       0 my $cursor = $class->{connection}->prepare($sql) or die "Cannot prepare $sql\n";
2244 0         0 $class->{cursor} = $cursor;
2245              
2246 0 0       0 $cursor-> execute($o) or die __PACKAGE__, "::spc Cannot execute $sql\n";
2247 0         0 $cursor-> finish();
2248              
2249             # my $elap = time - $tm0;
2250             #$class->{cumu_conrun} += time - $tm0;
2251 0         0 my $tm1 = Time::HiRes::clock();
2252 0         0 $class->{cumu_conrun} += $tm1 - $tm0;
2253 0 0       0 if ($xprm{ENABLE_STATISTICS_ON_SPC}) {
2254             # Adjust statistics for arriving spc's
2255 0 0       0 $class->{_spcStat}{$pkgspc}{count} = (defined $class->{_spcStat}{$pkgspc}) ? $class->{_spcStat}{$pkgspc}{count}+1 : 1;
2256 0         0 $class->{_spcStat}{$pkgspc}{tm0} = $tm0;
2257             #$class->{_spcStat}{$pkgspc}{tm1} = time;
2258 0         0 $class->{_spcStat}{$pkgspc}{tm1} = Time::HiRes::clock();
2259             }
2260 0         0 $class-> _tracingE("spc() PASSED (DONE)\n\n");
2261 0         0 return 1;
2262             }
2263              
2264 0         0 return 0;
2265             }
2266              
2267              
2268              
2269             ########################################################################################
2270             #DEPRE
2271             #used in chopping cart!
2272             # select $s1 from $table where $s2;
2273             # go over elements from each fetched record, and form a colon ":" seperated string
2274             # push each colon seperated string on the list reference $L
2275             # *retrieve_inlist {
2276             sub fetchTda_inCoList {
2277 0     0 0 0 my $class = shift;
2278              
2279 0         0 my $table = shift;
2280 0         0 my $s1 = shift;
2281 0         0 my $s2 = shift;
2282              
2283 0         0 my $elements = shift;
2284 0         0 my $L = shift;
2285              
2286 0   0     0 $class->{src} = [caller]; push(@{$class->{src}},(caller 1)[3] || '');
  0         0  
  0         0  
2287 0         0 $class-> _tracingB("fetchTda_inCoList():\n\t $table\n$s1\n$s2\n\n");
2288              
2289 0         0 my @flds = [];
2290 0 0       0 if ( ($elements =~ /,/) ) {
2291 0         0 @flds = split(/,/,$elements);
2292             }
2293            
2294 0         0 my $q = "SELECT $s1 FROM $table WHERE $s2;";
2295              
2296              
2297 0         0 my $cursor = $class->{connection}->prepare( $q );
2298              
2299 0         0 $class->{cursor} = $cursor;
2300              
2301 0         0 $class->{cursor}->execute();
2302 0         0 $class->{rows} = $class->{cursor}->rows;
2303 0         0 my $temp;
2304             my $key;
2305 0         0 my $i = 0;
2306 0         0 while ($temp = $class->{cursor}->fetchrow_hashref()) {
2307 0         0 my %hr = %$temp;
2308 0 0       0 if ($elements =~ /,/) {
2309 0         0 my $s;
2310             my $t;
2311 0         0 foreach $t (@flds) {
2312 0         0 $s .= $hr{$t} . ':';
2313              
2314             }
2315 0 0       0 chop($s) if $s =~ /:$/;
2316 0         0 push(@$L,$s);
2317              
2318             }
2319             else {
2320 0         0 push(@$L,$hr{$elements});
2321             }
2322 0         0 $i++;
2323             }
2324 0         0 $class->{cursor}->finish();
2325              
2326 0         0 $class-> _tracingE("fetchTda_inCoList() PASSED (DONE)\n\n");
2327              
2328 0         0 return $i;
2329             }
2330              
2331              
2332             ########################################################################################
2333             # DEPRE
2334             # Fetch data from a table that got an extra pseudo ordered column (i.e. ordre).
2335             # After retrieving the records from that table, these records are kept in a hash
2336             # that is reordered properly and pushed to a list. The final result is an ordered
2337             # list.
2338             # The current method work on a single column and is used by Varisphere.
2339             # *retrieve_inOrderedList
2340             sub fetchTda_inOrderedList {
2341 0     0 0 0 my $class = shift;
2342              
2343 0         0 my $table = shift;
2344 0         0 my $s1 = shift;
2345 0         0 my $os2 = shift;
2346 0         0 my $s3 = shift;
2347              
2348 0         0 my $L = shift;
2349              
2350 0         0 my $q = "SELECT $s1,$os2 FROM $table WHERE $s3 order by $os2;";
2351              
2352 0   0     0 $class->{src} = [caller]; push(@{$class->{src}},(caller 1)[3] || '');
  0         0  
  0         0  
2353 0         0 $class-> _tracingB("retrieve_inOrderedList(): \n\tfrom TABLE $table\n\t$q\n\n");
2354              
2355 0         0 my $cursor = $class->{connection}->prepare( $q );
2356              
2357 0         0 $class->{cursor} = $cursor;
2358              
2359 0         0 $class->{cursor}->execute();
2360 0         0 $class->{rows} = $class->{cursor}->rows;
2361 0         0 my $temp;
2362             my %hr;
2363 0         0 while ($temp = $class->{cursor}->fetchrow_hashref()) {
2364 0         0 $hr{ $$temp{$os2} } = $$temp{$s1};
2365             }
2366 0         0 foreach my $k (sort keys %hr) {
2367 0         0 push(@$L,$hr{$k});
2368             }
2369              
2370 0         0 $class->{cursor}->finish();
2371              
2372 0         0 $class-> _tracingE("retrieve_inOrderedList() PASSED (DONE)\n\n");
2373              
2374 0         0 return scalar(@$L);
2375             }
2376              
2377              
2378             ########################################################################################
2379             #DEPRE
2380             #
2381             #use it when records are unique, since it returns a single (first encountered) record
2382             #record result is in \%H
2383             #return 1 on success, 0 if no record is found, -1 if DBI error
2384             #
2385             #my @flds = (SKUARCHIVE,TOPICHEAD,TITLE,AUTHOR);
2386             #if ( ($dbhandle->fetchTda_inHash('ARCHIVE', ' SKUARCHIVE,TOPICHEAD,TITLE,AUTHOR,SYNOPSIS ' ," SKUARCHIVE=\'$skuarchive\' ",\%dbhash, \@flds)) ) {}
2387             #
2388             #if ( ($class->{_dbhandle}->fetchTda_inHash($DBTABLENAME," * " ," id=$i ",\%H) > 0) ) {
2389             # *retrieve_inhash
2390              
2391             sub fetchTda_inHash {
2392 0     0 0 0 my $class = shift;
2393 0         0 my $table = shift;
2394 0         0 my $s1 = shift;
2395 0         0 my $s2 = shift;
2396 0         0 my $hh = shift;
2397              
2398 0 0       0 my $list = @_ ? shift : [];
2399            
2400 0         0 my $q = "SELECT $s1 FROM $table WHERE $s2"; # $s2;"
2401              
2402 0   0     0 $class->{src} = [caller]; push(@{$class->{src}},(caller 1)[3] || '');
  0         0  
  0         0  
2403 0         0 $class-> _tracingB("fetchTda_inHash(): \n\tfrom TABLE $table\n\t$q\n\n");
2404              
2405 0         0 my $cursor = $class->{connection}->prepare( $q );
2406              
2407 0         0 $class->{cursor} = $cursor;
2408 0         0 $class->{cursor}->execute();
2409 0 0       0 if ($DBI::err) {
2410 0         0 $class-> _tracingE("fetchTda_inHash() Failed: (CRISIS) $DBI::err -- $DBI::errstr\n returning FALSE (-1)\n");
2411 0         0 $class-> _internal_state(ISTATE_CRISIS);
2412 0         0 return -1;
2413             }
2414              
2415 0         0 $class->{rows} = $class->{cursor}->rows;
2416 0         0 my $key;
2417              
2418 0 0       0 if (my $temp = $class->{cursor}->fetchrow_hashref()) {
2419 0         0 my %hr = %$temp;
2420 0 0       0 if (@{$list}) {
  0         0  
2421 0         0 for (my $j=0; $j < @{$list}; $j++) {
  0         0  
2422 0         0 $key = $$list[$j];
2423 0         0 $$hh{$key} = $hr{$key};
2424             # $class->{debhook}->print("++++++++++++++++++++++++>>> $key ++ $$hh{$key} <<<\n");
2425             }
2426             }
2427             else {
2428 0         0 %$hh = %hr;
2429             }
2430 0         0 $class->{cursor}->finish();
2431 0         0 $class-> _tracingE("fetchTda_inHash(): returned TRUE \n");
2432 0         0 return 1;
2433             }
2434             else {
2435 0         0 $class->{cursor}->finish();
2436 0         0 $class-> _tracingE("fetchTda_inHash(): returned FALSE \n");
2437 0         0 return 0;
2438             }
2439             }
2440              
2441              
2442              
2443             ########################################################################################
2444             #
2445             sub fetchQdaO {
2446 0     0 1 0 my $class = shift;
2447 0         0 my $q = shift;
2448             #my $hrf = shift;
2449 0 0       0 my $hrf = (ref $_[0] eq 'HASH') ? shift : {};
2450              
2451             #my $list = (@_ && ref $_[0] eq 'ARRAY') ? shift : undef; # [];
2452 0 0       0 my $list = (ref $_[0] eq 'ARRAY') ? shift : undef; # [];
2453              
2454 0         0 my @bindparams = @_;
2455            
2456 0 0 0     0 die "RETURNING AND DOING NOTHING FROM getdaO: CANNOT HAVE * AND SPECIFY LIST!\n" if ($list) && $q =~ /SELECT\s+\*\s+/i;
2457              
2458 0   0     0 $class->{src} = [caller]; push(@{$class->{src}},(caller 1)[3] || '');
  0         0  
  0         0  
2459 0         0 $class-> _tracingB("fetchQdaO(): \n\t$q\n\n");
2460              
2461              
2462             # localize these Lags
2463 0 0       0 local $class->{connection}->{PrintError} if $class->printerror == 0;
2464 0 0       0 local $class->{connection}->{RaiseError} if $class->raiseerror == 0;
2465 0         0 $class->{connection}->{PrintError}=$class->printerror;
2466 0         0 $class->{connection}->{RaiseError}=$class->raiseerror;
2467            
2468             #my $tm0 = time;
2469 0         0 my $tm0 = Time::HiRes::clock();
2470             #$class->{_qryStat}{$q}{tm0} = time;
2471              
2472              
2473              
2474 0         0 my $cursor = $class->{connection}->prepare( $q );
2475 0         0 $class->{cursor} = $cursor;
2476              
2477 0         0 my $i=1;
2478 0         0 foreach (@bindparams) {
2479 0         0 $class-> _traceln("\tfetchQdaO() BINDING: $i ---to---> $_\n");
2480 0         0 $class->{cursor}->bind_param($i++,$_);
2481             }
2482              
2483              
2484 0         0 $class->{cursor}->execute();
2485 0 0       0 if ($DBI::err) {
2486 0         0 $class-> _tracingE("getdaO Failure: (CRISIS) $DBI::err -- $DBI::errstr\n returning FALSE (-1)\n");
2487 0         0 $class-> _internal_state(ISTATE_CRISIS);
2488 0         0 return undef;
2489             }
2490              
2491 0         0 $class->{rows} = $class->{cursor}->rows;
2492              
2493             #if (@{$list}) {
2494 0 0       0 if ($list) {
    0          
2495             #print "1- In list context <<<<<<<<<<<<<<<<<<<<\n";
2496 0         0 my %temp;
2497 0         0 for (my $j=0; $j < @{$list}; $j++) {
  0         0  
2498             #print "........................................................... binding $j+1 --to--> hrf $$list[$j]\n";
2499             #DOES NOT WORK! $class->{cursor}-> bind_col($j+1, \$$hrf{ $$list[$j] });
2500 0         0 $class->{cursor}-> bind_col($j+1, \$temp{ $$list[$j] });
2501             }
2502             # eval {};
2503 0         0 $class->{cursor}-> fetch;
2504 0         0 $class->{cursor}-> finish();
2505             #if ($@) {}
2506 0 0       0 if ($class->{cursor}->rows) {
2507 0         0 foreach my $k (keys %temp) { $$hrf{$k} = \$temp{$k}; }
  0         0  
2508              
2509 0         0 my $tm1 = Time::HiRes::clock();
2510 0         0 $class->{cumu_conrun} += $tm1 - $tm0;
2511 0         0 my $elapsed = $tm1 - $tm0;
2512 0         0 $class-> _tracingE("fetchQdaO(): returned A RECORD with BINDING (SYSTEM TIME=$elapsed)\n");
2513 0         0 return $hrf;
2514             #return 1;
2515             }
2516             else {
2517             #print "Eeeeeeeeeeeeeeeeeempttttttttttyyyyyyyyyyy\n";
2518 0         0 return $hrf;
2519             #return 0;
2520             }
2521             }
2522             elsif (my $temp = $class->{cursor}->fetchrow_hashref()) {
2523             #print "2- in default <<<<<<<<<<<<<<<<<<<<\n";
2524             ##%$hrf = %$temp;
2525             # get the addresses not the values (not this %$hrf = %$temp;)
2526 0         0 foreach my $k (keys %$temp) { $$hrf{$k} = \$$temp{$k}; }
  0         0  
2527 0         0 $class->{cursor}->finish();
2528 0         0 my $tm1 = Time::HiRes::clock();
2529 0         0 $class->{cumu_conrun} += $tm1 - $tm0;
2530 0         0 my $elapsed = $tm1 - $tm0;
2531 0         0 $class-> _tracingE("fetchQdaO(): returned A RECORD without any BINDING (SYSTEM TIME=$elapsed)\n");
2532 0         0 return $hrf;
2533             #return 1;
2534             }
2535             else {
2536             #print "3- zero <<<<<<<<<<<<<<<<<<<<\n";
2537 0         0 $class->{cursor}->finish();
2538 0         0 my $tm1 = Time::HiRes::clock();
2539 0         0 $class->{cumu_conrun} += $tm1 - $tm0;
2540 0         0 my $elapsed = $tm1 - $tm0;
2541 0         0 $class-> _tracingE("fetchQdaO(): returned NO RECORD (SYSTEM TIME=$elapsed)\n");
2542 0         0 return $hrf;
2543             #return 0;
2544             }
2545             }
2546              
2547              
2548              
2549             ########################################################################################
2550             sub fetchQdaAA
2551             {
2552 0     0 1 0 my $class = shift;
2553 0         0 my $q = shift;
2554              
2555             #$q = qq{begin $q; end;};
2556             #my $hash;
2557             #$hash = shift @params if ($#params >= 0 && ref($params[0]) eq 'HASH');
2558             #my %h = %{$hash} if $hash;
2559              
2560             # recalling and passing an array ref allow to extend the referenced list, otherwise start fresh
2561 0 0 0     0 my $rows = (@_ && ref $_[0] eq 'ARRAY') ? shift : [];
2562             # have a recalled flag ready
2563 0 0 0     0 my $recalled = (@_ && ref $_[0] eq 'ARRAY' && defined ${$_[0]}[0]) ? 1 : 0;
2564              
2565             #my $extras = shift if ref @_[0] eq 'HASH';
2566 0 0       0 my $extras = shift if ref $_[0] eq 'HASH';
2567 0         0 my @bindparams = @_;
2568              
2569 0   0     0 $class->{src} = [caller]; push(@{$class->{src}},(caller 1)[3] || '');
  0         0  
  0         0  
2570 0         0 $class-> _tracingB("fetchQdaAA():\n\t $q\n\n");
2571              
2572             # localize these Lags
2573 0 0       0 local $class->{connection}->{PrintError} if $class->printerror == 0;
2574 0 0       0 local $class->{connection}->{RaiseError} if $class->raiseerror == 0;
2575 0         0 $class->{connection}->{PrintError}=$class->printerror;
2576 0         0 $class->{connection}->{RaiseError}=$class->raiseerror;
2577            
2578             #my $tm0 = time;
2579 0         0 my $tm0 = Time::HiRes::clock();
2580             #$class->{_qryStat}{$q}{tm0} = time;
2581              
2582             #TODO: eval and report error!
2583 0         0 my $cursor = $class->{connection}->prepare($q); # or die "Cannot prepare $q\n";
2584 0         0 $class->{cursor} = $cursor;
2585              
2586 0         0 my $i=1;
2587 0         0 foreach (@bindparams) {
2588 0         0 $class-> _traceln("\tfetchQdaAA() BINDING: $i ---to---> $_\n");
2589 0         0 $class->{cursor}->bind_param($i++,$_);
2590             }
2591              
2592 0         0 eval{
2593 0         0 $class->{cursor}->execute();
2594             };
2595 0 0       0 ($@) && die "ERROR: $@\n";
2596              
2597 0         0 $class->{rows} = $class->{cursor}->rows;
2598              
2599 0 0 0     0 if ( !$recalled && (($$extras{INCLUDE_HEADER}) || !(defined $$extras{INCLUDE_HEADER})) )
      0        
2600             {
2601 0         0 my @header = ();
2602 0         0 for (my $i=0;$i<$class->{cursor}->{NUM_OF_FIELDS};$i++)
2603             {
2604 0         0 push(@header,$class->{cursor}->{NAME}->[$i]);
2605             }
2606 0         0 push(@$rows,\@header);
2607             }
2608             #my $cnt = 0;
2609 0         0 my $cnt = -1;
2610 0         0 while (my @r = $class->{cursor}->fetchrow_array)
2611             #while(my $r = $class->{cursor}->fetchrow_arrayref)
2612             {
2613             #$class-> _traceln("\t RETRIEVED $cnt ROWS -- \n");
2614             #print STDERR "\t RETRIEVED $cnt ROWS -- \n";
2615             #push(@$rows,$r); # << FASTER push(@$rows,\@r);
2616 0         0 $cnt++;
2617 0         0 push(@$rows,\@r);
2618             #$cnt++;
2619 0 0       0 ($cnt%100 == 0) && $class-> _traceln("\t RETRIEVED $cnt ROWS\n");
2620 0 0 0     0 ($$extras{MAX_ROWS} && $cnt >= $$extras{MAX_ROWS}) &&
      0        
2621             $class->{cursor}->finish && last;
2622             }
2623             #$class->{cumu_conrun} += time - $tm0;
2624 0         0 my $tm1 = Time::HiRes::clock();
2625 0         0 $class->{cumu_conrun} += $tm1 - $tm0;
2626 0         0 my $elapsed = $tm1 - $tm0;
2627              
2628 0         0 $class-> _tracingE("fetchQdaAA/SELECT_TO_ARRAY (with ROWS=$rows) (SYSTEM TIME=$elapsed)\n");
2629              
2630 0 0       0 return undef if $cnt == -1;
2631 0         0 return $rows;
2632             }
2633              
2634              
2635             ########################################################################################
2636             ########################################################################################
2637              
2638             sub fetchTdaAA
2639             {
2640 0     0 1 0 my $class = shift;
2641             # my $q = shift;
2642             # my $flags = shift if ref @_[0] eq 'HASH';
2643             # my @bindparams = @_;
2644              
2645 0         0 my $table = shift;
2646 0         0 my $selection = shift;
2647 0         0 my $where = shift;
2648              
2649 0 0 0     0 my $aarf = (@_ && ref $_[0] eq 'ARRAY') ? shift : []; # passing an array ref allow to extend the referenced list, otherwise start fresh
2650 0         0 my @bindparams = @_;
2651              
2652 0         0 my $s1 = '';
2653              
2654 0         0 my $seeked = 'all';
2655 0         0 my(@A) = ();
2656            
2657              
2658             # passing the attributes as an array ref. return a 2D array for the table pointed to by aarf
2659 0 0       0 if (ref($selection) eq 'ARRAY')
    0          
    0          
    0          
2660             {
2661 0         0 for (my $j=0; $j < @{$selection}; $j++)
  0         0  
2662             {
2663 0         0 push(@A,$$selection[$j]);
2664 0         0 $s1 .= $$selection[$j] . ',';
2665             }
2666 0         0 chop($s1); $s1 .= ' ';
  0         0  
2667 0         0 $seeked = 'array';
2668             }
2669             # a ref to a hash of attributes; (TODO: !!! return an array of hashes)
2670             elsif (ref($selection) eq 'HASH')
2671             {
2672 0         0 my $sel = '';
2673 0         0 foreach (keys %$selection) {
2674             #$sel .= $_ . ','
2675 0         0 $sel .= $$selection{$_} . ','
2676             }
2677 0         0 chop($sel);
2678 0         0 $s1 = $sel;
2679 0         0 $seeked = 'skeemamap';
2680             #@A = split(/,/,$selection);
2681             #foreach (@A) { s/^\s+//; s/\s+$//; } # trim starting and ending spaces
2682             #$s1 = $selection;
2683             #$seeked = 'listed';
2684             }
2685             # a wildcard * for everything; (TODO: !!! return an array of hashes)
2686             elsif ($selection =~ /^[\s]*\*[\s]*$/)
2687             {
2688 0         0 $seeked = 'all';
2689 0         0 $s1 = ' * ';
2690             }
2691             # a string of attributes; (TODO: !!! return an array of hashes)
2692             elsif ($selection =~ /\w/)
2693             {
2694 0         0 @A = split(/,/,$selection);
2695 0         0 foreach (@A) { s/^\s+//; s/\s+$//; } # trim starting and ending spaces
  0         0  
  0         0  
2696 0         0 $s1 = $selection;
2697 0         0 $seeked = 'listed';
2698             }
2699              
2700            
2701 0         0 my $q;
2702 0 0 0     0 if (defined($where) && (length($where)) && !($where =~ /^\s+$/)) {
      0        
2703 0         0 $q = "SELECT $s1 FROM $table WHERE $where";
2704             }
2705             else {
2706 0         0 $q = "SELECT $s1 FROM $table";
2707             }
2708              
2709 0   0     0 $class->{src} = [caller]; push(@{$class->{src}},(caller 1)[3] || '');
  0         0  
  0         0  
2710 0         0 $class-> _tracingB("fetchTdaAA():\n\t $q\n\n");
2711              
2712             # localize these Lags
2713 0 0       0 local $class->{connection}->{PrintError} if $class->printerror == 0;
2714 0 0       0 local $class->{connection}->{RaiseError} if $class->raiseerror == 0;
2715 0         0 $class->{connection}->{PrintError}=$class->printerror;
2716 0         0 $class->{connection}->{RaiseError}=$class->raiseerror;
2717             #my $tm0 = time;
2718 0         0 my $tm0 = Time::HiRes::clock();
2719             #$class->{_qryStat}{$q}{tm0} = time;
2720              
2721 0         0 my $cursor = $class->{connection}->prepare( $q );
2722 0         0 $class->{cursor} = $cursor;
2723 0         0 for (my $i=0; $i<@bindparams; $i++) {
2724 0         0 $b = $i + 1;
2725 0         0 $class-> _traceln("\t BINDING:$b --to--> $bindparams[$i]\n");
2726 0         0 $class->{cursor}->bind_param($b ,$bindparams[$i]);
2727             }
2728              
2729 0         0 eval{
2730 0         0 $class->{cursor}->execute();
2731             };
2732 0 0       0 ($@) && die "ERROR: $@\n";
2733              
2734 0         0 $class->{rows} = $class->{cursor}->rows;
2735              
2736 0         0 my $temp;
2737             my $key;
2738 0         0 my $i = -1; # -1 if nothing returned, but incremented and therefore starting at 0
2739              
2740 0         0 my $cnt = 0;
2741              
2742             #my @rows;
2743             #if ($$flags{INCLUDE_HEADER})
2744             {
2745 0         0 my @header = ();
  0         0  
2746 0         0 for (my $i=0;$i<$class->{cursor}->{NUM_OF_FIELDS};$i++)
2747             {
2748 0         0 push(@header,$class->{cursor}->{NAME}->[$i]);
2749             }
2750             #push(@rows,\@header);
2751 0         0 push(@{$aarf},\@header);
  0         0  
2752             }
2753              
2754 0         0 while(my @r = $class->{cursor}->fetchrow_array) {
2755             #while ($temp = $class->{cursor}->fetchrow_hashref()) {
2756 0         0 $i++; # start counting at 0
2757             #my %hr = %$temp;
2758              
2759 0 0 0     0 if ( ($seeked eq 'all') || ($seeked eq 'array') || ($seeked eq 'listed') || ($seeked eq 'skeemamap') )
      0        
      0        
2760             {
2761             #foreach my $key (keys %hr) { $$aarf[$i]{$key} = $hr{$key}; }
2762 0         0 push(@{$aarf},\@r); # Equivalent
  0         0  
2763             }
2764             # $cnt++;
2765             # ($cnt%100 == 0) && $class->_tracing("\t RETRIEVED $cnt ROWS\n");
2766             # ($$flags{MAX_ROWS} && $cnt >= $$flags{MAX_ROWS}) &&
2767             # $class->{cursor}->finish && last;
2768              
2769             #elsif ($seeked eq 'array')
2770             #{ # array are ordered following the listed attributes, get them (in order) from @A
2771             # foreach my $j (0..$#A) {
2772             # #AS 2D ARRAY FOR FASTER ACCESS
2773             # $$aarf[$i][$j]=$hr{$A[$j]};
2774             # }
2775             #}
2776             }
2777 0         0 $class->{cursor}->finish();
2778              
2779             #for (my $j=0; $j < $i; $j++){
2780             # print "$j ++ ";
2781             # foreach my $k (keys %{$$aarf[$j]}){
2782             # print "$k=", $$aarf[$j]{$k}, " + ";
2783             # }
2784             # print "\n";
2785             #}
2786             #exit;
2787              
2788             #$class->{cumu_conrun} += time - $tm0;
2789 0         0 my $tm1 = Time::HiRes::clock();
2790 0         0 $class->{cumu_conrun} += $tm1 - $tm0;
2791 0         0 $class-> _tracingE("fetchTdaAA():\n\tfrom TABLE $table -- ROWS OK = $class->{rows}\n");
2792              
2793             #return $class->{rows};
2794             #return $i; # return number of records
2795 0 0       0 return undef if $i == -1; # return number of records
2796 0         0 return $aarf;
2797             }
2798              
2799              
2800              
2801             ########################################################################################
2802             #
2803             #
2804             # July 2005: changed the following to start with an array index at 0: $ahrf[0]{}
2805             # @ahrf is an array of hash that is returned for all records found. @ahrf start counting at 0
2806             # and that used to be undef before the change (see below)
2807             # *retrieve_in_aobj = *retrieve_inobjects = \&fetchTdaAO;
2808             sub fetchTdaAO {
2809 0     0 1 0 my $class = shift;
2810              
2811             # start with a good state upon each entry
2812 0         0 $class-> _internal_state(ISTATE_GOOD);
2813              
2814 0         0 my $table = shift;
2815 0         0 my $selection = shift;
2816 0         0 my $where = shift;
2817              
2818 0 0       0 my $ahrf = @_ ? shift : []; # passing an array ref allow to extend the referenced list, otherwise start fresh
2819              
2820 0         0 my $s1 = '';
2821              
2822 0         0 my $seeked = 'all';
2823 0         0 my(@A) = ();
2824            
2825              
2826             # passing the attributes as an array ref. return a 2D array for the table pointed to by ahrf
2827 0 0       0 if (ref($selection) eq 'ARRAY')
    0          
    0          
    0          
2828             {
2829 0         0 for (my $j=0; $j < @{$selection}; $j++)
  0         0  
2830             {
2831 0         0 push(@A,$$selection[$j]);
2832 0         0 $s1 .= $$selection[$j] . ',';
2833             }
2834 0         0 chop($s1); $s1 .= ' ';
  0         0  
2835 0         0 $seeked = 'array';
2836             }
2837             # a ref to a hash of attributes; return an array of hashes
2838             elsif (ref($selection) eq 'HASH')
2839             {
2840 0         0 my $sel = '';
2841 0         0 foreach (keys %$selection) {
2842             #$sel .= $_ . ','
2843 0         0 $sel .= $$selection{$_} . ','
2844             }
2845 0         0 chop($sel);
2846 0         0 $s1 = $sel;
2847 0         0 $seeked = 'skeemamap';
2848             #@A = split(/,/,$selection);
2849             #foreach (@A) { s/^\s+//; s/\s+$//; } # trim starting and ending spaces
2850             #$s1 = $selection;
2851             #$seeked = 'listed';
2852             }
2853             # a wildcard * for everything; return an array of hashes
2854             elsif ($selection =~ /^[\s]*\*[\s]*$/)
2855             {
2856 0         0 $seeked = 'all';
2857 0         0 $s1 = ' * ';
2858             }
2859             # a string of attributes; return an array of hashes
2860             elsif ($selection =~ /\w/)
2861             {
2862 0         0 @A = split(/,/,$selection);
2863 0         0 foreach (@A) { s/^\s+//; s/\s+$//; } # trim starting and ending spaces
  0         0  
  0         0  
2864 0         0 $s1 = $selection;
2865 0         0 $seeked = 'listed';
2866             }
2867              
2868            
2869 0         0 my $q;
2870 0 0 0     0 if (defined($where) && (length($where)) && !($where =~ /^\s+$/)) {
      0        
2871             #MYSQL $q = "SELECT $s1 FROM $table WHERE $where;";
2872 0         0 $q = "SELECT $s1 FROM $table WHERE $where";
2873             }
2874             else {
2875             #MYSQL $q = "SELECT $s1 FROM $table;";
2876 0         0 $q = "SELECT $s1 FROM $table";
2877             }
2878              
2879 0   0     0 $class->{src} = [caller]; push(@{$class->{src}},(caller 1)[3] || '');
  0         0  
  0         0  
2880 0         0 $class-> _tracingB("fetchTdaAO/RETRIEVE_IN_AOBJ:\n\t $q\n\n");
2881              
2882             # localize these Lags
2883 0 0       0 local $class->{connection}->{PrintError} if $class->printerror == 0;
2884 0 0       0 local $class->{connection}->{RaiseError} if $class->raiseerror == 0;
2885 0         0 $class->{connection}->{PrintError}=$class->printerror;
2886 0         0 $class->{connection}->{RaiseError}=$class->raiseerror;
2887             #my $tm0 = time;
2888 0         0 my $tm0 = Time::HiRes::clock();
2889             #$class->{_qryStat}{$q}{tm0} = time;
2890              
2891 0         0 my $cursor = $class->{connection}->prepare( $q );
2892              
2893 0         0 $class->{cursor} = $cursor;
2894              
2895 0         0 $class->{cursor}->execute();
2896 0         0 $class->{rows} = $class->{cursor}->rows;
2897 0         0 my $temp;
2898             my $key;
2899 0         0 my $i = -1; # -1 if nothing returned, but incremented and therefore starting at 0
2900              
2901 0         0 while ($temp = $class->{cursor}->fetchrow_hashref()) {
2902 0         0 $i++; # start counting at 0, and old start counting at 1 IS DEPRECATED
2903 0         0 my %hr = %$temp;
2904              
2905 0 0 0     0 if ( ($seeked eq 'all') || ($seeked eq 'listed') || ($seeked eq 'skeemamap') )
    0 0        
2906             {
2907             #foreach my $key (keys %hr)
2908             #{
2909             # $$ahrf[$i]{$key} = $hr{$key};
2910             #}
2911 0         0 push(@{$ahrf},\%hr); # Equivalent
  0         0  
2912             }
2913             elsif ($seeked eq 'array')
2914             { # array are ordered following the listed attributes, get them (in order) from @A
2915 0         0 foreach my $j (0..$#A) {
2916             #AS 2D ARRAY FOR FASTER ACCESS
2917 0         0 $$ahrf[$i][$j]=$hr{$A[$j]};
2918             }
2919             }
2920             }
2921 0         0 $class->{cursor}->finish();
2922              
2923             #for (my $j=0; $j < $i; $j++){
2924             # print "$j ++ ";
2925             # foreach my $k (keys %{$$ahrf[$j]}){
2926             # print "$k=", $$ahrf[$j]{$k}, " + ";
2927             # }
2928             # print "\n";
2929             #}
2930             #exit;
2931              
2932             # my $elap = time - $tm0;
2933             #$class->{cumu_conrun} += time - $tm0;
2934 0         0 my $tm1 = Time::HiRes::clock();
2935 0         0 $class->{cumu_conrun} += $tm1 - $tm0;
2936 0         0 $class-> _tracingE("fetchTdaAO/retrieve_in_aobj:\n\tfrom TABLE $table -- ROWS OK = $class->{rows}\n");
2937              
2938             #return $class->{rows};
2939             #return $i; # return number of records
2940 0 0       0 return undef if $i == -1; # return number of records
2941 0         0 return $ahrf;
2942             }
2943              
2944             ########################################################################################
2945             ########################################################################################
2946             ########################################################################################
2947             ########################################################################################
2948              
2949             ########################################################################################
2950             sub commit {
2951 0     0 1 0 my $class = shift;
2952 0   0     0 $class->{src} = [caller]; push(@{$class->{src}},(caller 1)[3] || '');
  0         0  
  0         0  
2953 0         0 $class-> _tracingB("COMMIT (CALLED EXPLICITLY) \n\n");
2954              
2955             # localize variables
2956 0 0       0 local $class->{connection}->{PrintError} if $class->printerror == 0;
2957 0 0       0 local $class->{connection}->{RaiseError} if $class->raiseerror == 0;
2958 0         0 $class->{connection}->{PrintError}=$class->printerror;
2959 0         0 $class->{connection}->{RaiseError}=$class->raiseerror;
2960             # when $class->autocommit==0 STORE('AutoCommit' undef)= 1
2961 0 0       0 local $class->{connection}->{AutoCommit} if $class->autocommit == 0;
2962             # when $class->autocommit==0 STORE('AutoCommit' '0')= 1
2963 0         0 $class->{connection}->{AutoCommit}=$class->autocommit;
2964              
2965 0         0 eval {
2966 0         0 $class->{connection}->commit;
2967             };
2968 0 0       0 if ($@) {
2969 0         0 $class-> status($DBI::errstr);
2970 0   0     0 $class->{src} = [caller]; push(@{$class->{src}},(caller 1)[3] || '');
  0         0  
  0         0  
2971 0         0 $class-> _tracingE("COMMIT: ERROR in DBI !\n\t DBI FAILED ON:\t$DBI::err\n\t DBI REASON:\t$DBI::errstr\n\t DBI LED:\t$DBI::state\n\n");
2972 0         0 return 0;
2973             }
2974 0         0 $class-> _tracingE("COMMIT ok\n");
2975 0         0 return 1;
2976             }
2977              
2978              
2979              
2980             ########################################################################################
2981             sub rollback {
2982 0     0 1 0 my $class = shift;
2983              
2984 0   0     0 $class->{src} = [caller]; push(@{$class->{src}},(caller 1)[3] || '');
  0         0  
  0         0  
2985 0         0 $class-> _tracingB("***rollback() CALLED (DELEGATED TO DBI)*** \n\n");
2986              
2987             # localize variables
2988 0 0       0 local $class->{connection}->{PrintError} if $class->printerror == 0;
2989 0 0       0 local $class->{connection}->{RaiseError} if $class->raiseerror == 0;
2990 0         0 $class->{connection}->{PrintError}=$class->printerror;
2991 0         0 $class->{connection}->{RaiseError}=$class->raiseerror;
2992             # when $class->autocommit==0 STORE('AutoCommit' undef)= 1
2993 0 0       0 local $class->{connection}->{AutoCommit} if $class->autocommit == 0;
2994             # when $class->autocommit==0 STORE('AutoCommit' '0')= 1
2995 0         0 $class->{connection}->{AutoCommit}=$class->autocommit;
2996              
2997              
2998             #if (!$class-> is_RaiseError && !$class-> is_AutoCommit && $class-> is_AutoRollback) {
2999 0 0 0     0 if (!$class-> is_AutoCommit && $class-> is_AutoRollback) {
3000 0         0 eval {
3001 0         0 $class->{connection}->rollback;
3002             };
3003 0 0       0 if ($@) {
3004             ###NO state=CONNECTED|DISCONNETED|UNDEF $class-> state('ERROR');
3005             ##$class-> _inside_state(CRISIS); # use constant CRISIS => 1
3006 0         0 $class-> status($DBI::errstr);
3007 0         0 $class-> _tracingE("rollback(): ERROR in DBI !\n\t DBI FAILED ON:\t$DBI::err\n\t DBI REASON:\t$DBI::errstr\n\t DBI LED:\t$DBI::state\n\n");
3008 0         0 return 0;
3009             }
3010 0         0 $class-> _tracingE("ROLLBACK ok\n");
3011 0         0 return 1;
3012             }
3013             else {
3014 0         0 $class-> _tracingE("rollback() -- CANNOT CALL ROLLBACK BECAUSE THE FOLLOWING CONDITION IS NOT SATISFIED: RaiseError=0 AutoCommit=0 AutoRollback=1\n");
3015             }
3016             }
3017              
3018              
3019             ########################################################################################
3020             # to finish an opened cursor handle
3021             #
3022             sub finish {
3023 0     0 1 0 my $class = shift;
3024              
3025 0   0     0 $class->{src} = [caller]; push(@{$class->{src}},(caller 1)[3] || '');
  0         0  
  0         0  
3026 0         0 $class-> _tracing("FINISH");
3027 0         0 $class->{cursor}->finish();
3028             }
3029              
3030              
3031             ########################################################################################
3032             sub disconnect {
3033 0     0 1 0 my $class = shift;
3034              
3035 0 0       0 if ($PERSISTENT_OBJECT_ENABLED) {
3036 0         0 print STDERR
3037             "
3038             You should never call the disconnect on a persistent DBI::BabyConnect object, although
3039             it is possible to call this function, but because many DBI::BabyConnect objects may
3040             be cached by one or more child processes, then you won't be able to keep track of
3041             which one has disconnected, (unless you check the state of DBI::BabyConnect object ...)
3042             and this will lead to more confusion. Let's keep it simple, hence I will not disconnect
3043             this handle because PERSISTENT_OBJECT_ENABLED is 1.
3044             "
3045             }
3046              
3047 0   0     0 $class->{src} = [caller]; push(@{$class->{src}},(caller 1)[3] || '');
  0         0  
  0         0  
3048 0         0 $class-> _tracingB("DISCONNECT");
3049              
3050 0 0       0 $xprm{PRT_CEND} && print STDOUT "ent-> disconnect() ***", $class-> state, "\n";
3051              
3052             #$class->{connection}->disconnect() or die "CONNECTION MANAGER: disconnect() failed: $DBI::errstr\n";
3053             #return;
3054             #goto OOO;
3055              
3056 0 0 0     0 die "
3057             disconnect() PROBLEM:
3058             CALLING disconnect() ON ALREADY DISCONNECTED HANDLER --
3059             ALTHOUGH THE CODE WILL NOT FAIL, BUT DISCONNECT MUST BE
3060             CALLED ONCE FOR PROPER CODING. (state= $class->state)
3061             " if ($xprm{CALLER_DISCONNECT} && ($class-> state eq 'DISCONNECTED'));
3062              
3063 0 0 0     0 die "
3064             disconnect() PROBLEM:
3065             SHOULD NOT CALL DISCONNECT ON AN UNDEF.
3066             THERE HAS NEVER BEEN A CONNECTION ANYWAY!
3067             " if ($xprm{CALLER_DISCONNECT} && ($class-> state eq 'UNDEF'));
3068              
3069             #$dbiconnection->disconnect();
3070             #commit ineffective with AutoCommit enabled:
3071             #$class->{connection}->commit();
3072             #OOO:
3073 0         0 $class-> state('DISCONNECTED');
3074 0         0 $class-> status('DISCONNECTED');
3075              
3076             #TODO make sure that DBI:: disconnect() return false on failure
3077             #$class->{connection}->disconnect() or die "CONNECTION MANAGER: disconnect() failed: $DBI::errstr\n";
3078 0 0       0 if (! $class->{connection}->disconnect()) {
3079 0         0 $class-> _tracingE("DISCONNECT FAILED (AND PROGRAM EXITING)\nERROR in DBI !\n\t DBI FAILED ON:\t$DBI::err\n\t DBI REASON:\t$DBI::errstr\n\t DBI LED:\t$DBI::state\n\n");
3080 0         0 die "CONNECTION MANAGER: disconnect() failed: $DBI::errstr\n";
3081             }
3082              
3083 0 0       0 $xprm{PRT_CEND} && print STDOUT "<-don disconnect() ***", $class-> state, "\n";
3084 0         0 $class-> _tracingE("DISCONNECT");
3085              
3086             #do not undef the connection yet, DESTROY will do this:
3087             #$class->{connection} = undef;
3088              
3089             }
3090              
3091              
3092             ########################################################################################
3093             # DESTROY_HOOK() garbage collect the OO file handle if any has been requested
3094             # during the instantiation with new()
3095             sub DESTROY_HOOK
3096             {
3097 0     0 0 0 my $class = shift;
3098 0   0     0 $class->{src} = [caller]; push(@{$class->{src}},(caller 1)[3] || '');
  0         0  
  0         0  
3099 0         0 $class-> _traceln("hstdlog-d> HOOK DESTROY: ALAS NO MORE WRITING!\n");
3100 0 0       0 return unless $class->{debhook};
3101             #$class->{debhook}->close();
3102 0         0 $class->{debhook}->DESTROY;
3103 0         0 $class->{debhook} = undef;
3104             }
3105              
3106              
3107              
3108              
3109             ########################################################################################
3110             sub _persistent_exit
3111             {
3112 0     0   0 my $class = shift;
3113              
3114             # It is possible to force the execution of the body of this sub DESTROY by calling
3115             # DESTROY(1), that is setting the $FORCE_USUAL_DESTRUCTION to 1, even if
3116             # the class has been loaded with DISABLE_DESTROY enabled (set to 1, typically
3117             # needed when persisting with Apache::BabyConnect).
3118 0 0       0 my $FORCE_USUAL_DESTRUCTION = @_ ? shift : 0;
3119              
3120 0   0     0 $class->{src} = [caller]; push(@{$class->{src}},(caller 1)[3] || '');
  0         0  
  0         0  
3121 0         0 $class-> _tracingB("ent-> DESTROY (CONNECTION STATUS=".$class-> state.")\n");
3122 0         0 $class-> _traceln("_persistent_exit (CONNECTION STATUS=".$class-> state.") FORCE_DESTRUCTION=$FORCE_USUAL_DESTRUCTION, DISABLE_DESTROY=$PERSISTENT_OBJECT_ENABLED\n");
3123              
3124              
3125             #return if ($PERSISTENT_OBJECT_ENABLED and !$FORCE_USUAL_DESTRUCTION);
3126             #return if $PERSISTENT_OBJECT_ENABLED;
3127 0 0 0     0 if ($PERSISTENT_OBJECT_ENABLED and !$FORCE_USUAL_DESTRUCTION) {
3128 0 0 0     0 if (!$class-> is_RaiseError &&
      0        
      0        
3129             !$class-> is_AutoCommit &&
3130             $class-> is_AutoRollback &&
3131             ($class-> _internal_state eq ISTATE_CRISIS)) {
3132 0         0 print STDERR "!!!!!ERROR STATE IN CRISIS, MAY BE DUE TO A FAILING DO!!!!!\n";
3133 0         0 print STDERR "!!!!!WE ARE GOING TO ROLLBACK!!!!!\n";
3134             #($class-> rollback)
3135             # || die "STATUS IS IN ERROR AND CANNOT ROLLBACK: ", $class->{connection}->errstr, "\n";
3136 0 0       0 ($class-> rollback)
3137             || _traceln("DBI FAILED TO ROLLBACK WITH REASON: ". $class->{connection}->errstr . "\n");
3138             #$class->{connection}->disconnect || die "ERROR WHEN DESTROY>DISCONNECT: ", $class->{connection}->errstr, "\n";
3139             #$class->{connection}->DESTROY;
3140 0         0 $class-> _tracingE("<-don DESTROY/PERSISTENT_OBJECT_ENABLED ** (CRISIS) ENDED WITH ERROR (CONNECTION STATUS=".$class-> state.") ******** \n");
3141             #$class-> DESTROY_HOOK;
3142             #die "EXITING WITH ERROR: CRISIS, AND ENDING THIS HANDLER CLASS!\n";
3143             }
3144             #return;
3145             }
3146             # to get to this point you need to have ON_FAILED_DBIEXECUTE_ROLLBACK_AND_EXIT and PERSISTENT_OBJECT_ENABLED,
3147             # which is typical with mod_perl with Apache::BabyConnect, in which case the following exit() is redirected to
3148             # the Apache::exit() that will terminate the script only
3149 0         0 exit;
3150             }
3151              
3152              
3153              
3154              
3155              
3156              
3157             ########################################################################################
3158             # When $PERSISTENT_OBJECT_ENABLED = 1 (i.e. when using Apache::BabyConnect), the DESTROY
3159             # will also be executed to cleanup the state of the handle. For instance, if
3160             # the ISTATE_CRISIS and Autorollback then the autorollback is called.
3161             # When $PERSISTENT_OBJECT_ENABLED = 1, the DESTROY will never call the disconnect.
3162             #
3163             # it is the reponsibility of the caller to disconnect the dbi handle; therefore,
3164             # the DESTROY of this class will never disconnect the dbhandle.
3165             #sub DESTROY {}
3166             #sub DUNNO_DESTROY
3167             sub DESTROY
3168             {
3169 0     0   0 my $class = shift;
3170              
3171             # It is possible to force the execution of the body of this sub DESTROY by calling
3172             # DESTROY(1), that is setting the $FORCE_USUAL_DESTRUCTION to 1, even if
3173             # the class has been loaded with DISABLE_DESTROY enabled (set to 1, typically
3174             # needed when persisting with Apache::BabyConnect).
3175 0 0       0 my $FORCE_USUAL_DESTRUCTION = @_ ? shift : 0;
3176              
3177 0   0     0 $class->{src} = [caller]; push(@{$class->{src}},(caller 1)[3] || '');
  0         0  
  0         0  
3178 0         0 $class-> _tracingB("ent-> DESTROY (CONNECTION STATUS=".$class-> state.")\n");
3179 0         0 $class-> _traceln("DESTROY (CONNECTION STATUS=".$class-> state.") FORCE_DESTRUCTION=$FORCE_USUAL_DESTRUCTION, DISABLE_DESTROY=$PERSISTENT_OBJECT_ENABLED\n");
3180              
3181              
3182             #return if ($PERSISTENT_OBJECT_ENABLED and !$FORCE_USUAL_DESTRUCTION);
3183             #return if $PERSISTENT_OBJECT_ENABLED;
3184 0 0 0     0 if ($PERSISTENT_OBJECT_ENABLED and !$FORCE_USUAL_DESTRUCTION) {
3185 0 0 0     0 if (!$class-> is_RaiseError &&
      0        
      0        
3186             !$class-> is_AutoCommit &&
3187             $class-> is_AutoRollback &&
3188             ($class-> _internal_state eq ISTATE_CRISIS)) {
3189 0         0 print STDERR "!!!!!ERROR STATE IN CRISIS, MAY BE DUE TO A FAILING DO!!!!!\n";
3190 0         0 print STDERR "!!!!!WE ARE GOING TO ROLLBACK!!!!!\n";
3191             #($class-> rollback)
3192             # || die "STATUS IS IN ERROR AND CANNOT ROLLBACK: ", $class->{connection}->errstr, "\n";
3193 0 0       0 ($class-> rollback)
3194             || _traceln("DBI FAILED TO ROLLBACK WITH REASON: ". $class->{connection}->errstr . "\n");
3195             #$class->{connection}->disconnect || die "ERROR WHEN DESTROY>DISCONNECT: ", $class->{connection}->errstr, "\n";
3196             #$class->{connection}->DESTROY;
3197 0         0 $class-> _tracingE("<-don DESTROY/PERSISTENT_OBJECT_ENABLED ** (CRISIS) ENDED WITH ERROR (CONNECTION STATUS=".$class-> state.") ******** \n");
3198             #$class-> DESTROY_HOOK;
3199             #die "EXITING WITH ERROR: CRISIS, AND ENDING THIS HANDLER CLASS!\n";
3200             }
3201 0         0 return;
3202             }
3203              
3204              
3205              
3206             # when $xprm{CALLER_DISCONNECT}, it is mandatory to have the caller disconnecting ...
3207             #die "IT IS THE RESPONSIBILITY OF THE CALLER TO THIS HANDLER TO DISCONNECT (UNLESS RaiseError!!!)!!!!!!!!!!\n"
3208             # if ($xprm{CALLER_DISCONNECT} && ($class-> state ne 'DISCONNECTED'));
3209              
3210              
3211             # return if $class-> state eq 'DISCONNECTED';
3212              
3213             #if ($class-> state eq 'DISCONNECTED') {
3214 0 0 0     0 if ($xprm{CALLER_DISCONNECT} && $class-> state eq 'DISCONNECTED') {
    0 0        
    0          
3215             #if (!$class-> is_RaiseError && !$class-> is_AutoCommit && $class-> is_AutoRollback && ($class-> _internal_state eq ISTATE_CRISIS)) {
3216             # ... in CRISIS but handle already disconnected, then we can do nothing. (should be that the caller is handling this error)
3217             #}
3218             #else {
3219 0         0 $class->{connection}->DESTROY;
3220 0         0 $class-> _tracingE("<-don DESTROY ** ENDED CLEANLY WITH (CONNECTION STATUS=".$class-> state." _internal_state=".$class-> _internal_state.") ******** \n");
3221             # gone for good, alas, no more logging
3222 0         0 $class-> DESTROY_HOOK;
3223             }
3224             elsif ($class-> state eq 'UNDEF') {
3225             #die "STATE of connection is UNDEF!\n";
3226             }
3227             elsif ($xprm{CALLER_DISCONNECT} && $class-> state eq 'CONNECTED') {
3228 0 0 0     0 if ($class-> is_RaiseError && $DBI::err) { # due to DBI die, but also check ...
    0 0        
      0        
      0        
3229 0 0       0 $xprm{PRT_CEND} && print STDOUT "**Rollback**Rollback**Rollback**Rollback**Rollback**Rollback**Rollback** in DESTROY\n";
3230 0 0 0     0 ($class-> is_AutoRollback && !$class-> is_AutoCommit)
      0        
3231             && (($class-> rollback)
3232             || die "STATUS IS IN ERROR AND CANNOT ROLLBACK: ", $class->{connection}->errstr);
3233 0 0       0 $class->{connection}->disconnect || die "ERROR WHEN DESTROY>DISCONNECT: ", $class->{connection}->errstr, "\n";
3234 0         0 $class->{connection}->DESTROY;
3235             # gone for good, alas, no more logging
3236             #if ( $class->{debhook} ) {
3237             # #$class->{debhook}->close();
3238             # $class->{debhook}->DESTROY;
3239             # $class->{debhook} = undef;
3240             #}
3241 0         0 $class-> _tracingE("<-don DESTROY ** ENDED WITH DBI-RAISING ERROR ** ROLLBACK OK (CONNECTION STATUS=".$class-> state.") ******** \n");
3242 0         0 $class-> DESTROY_HOOK;
3243 0         0 die "FATAL ERROR: WE ARE IN ERROR DUE TO ROLLBACK, WE ROLLED BACK, AND DIE NOW!\n";
3244             }
3245             # TODO: CRISIS whenever _inside_state, i.e. check "sub do"
3246             # if still CONNECTED and Lags are properly set for rollback and the _inside_state is in CRISIS then rollback
3247             elsif (!$class-> is_RaiseError && !$class-> is_AutoCommit && $class-> is_AutoRollback && ($class-> _internal_state eq ISTATE_CRISIS)) {
3248 0         0 print STDERR "!!!!!ERROR STATE IN CRISIS, MAY BE DUE TO A FAILING DO!!!!!\n";
3249 0         0 print STDERR "!!!!!WE ARE GOING TO ROLLBACK, THEN DISCONNECT AND DIE!!!!!\n";
3250 0 0       0 $xprm{PRT_CEND} && print STDOUT "!!!!!ERROR STATE IN CRISIS, MAY BE DUE TO A FAILING DO!!!!!\n";
3251 0 0       0 $xprm{PRT_CEND} && print STDOUT "!!!!!WE ARE GOING TO ROLLBACK, THEN DISCONNECT AND DIE!!!!!\n";
3252 0 0       0 ($class-> rollback)
3253             || die "STATUS IS IN ERROR AND CANNOT ROLLBACK: ", $class->{connection}->errstr, "\n";
3254 0 0       0 $class->{connection}->disconnect || die "ERROR WHEN DESTROY>DISCONNECT: ", $class->{connection}->errstr, "\n";
3255 0         0 $class->{connection}->DESTROY;
3256 0         0 $class-> _tracingE("<-don DESTROY ** (CRISIS) ENDED WITH ERROR (CONNECTION STATUS=".$class-> state.") ******** \n");
3257 0         0 $class-> DESTROY_HOOK;
3258 0         0 die "EXITING WITH ERROR: CRISIS, AND ENDING THIS HANDLER CLASS!\n";
3259             }
3260             else {
3261 0         0 print STDERR "!!!!!IT IS THE RESPONSIBILITY OF THE CALLER TO THIS HANDLER TO DISCONNECT!!!!!\n";
3262 0         0 print STDERR "!!!!!WE ARE GOING TO DISCONNECT ANYWAY, AND DIE!!!!!\n";
3263 0 0       0 $xprm{PRT_CEND} && print STDOUT "!!!!!IT IS THE RESPONSIBILITY OF THE CALLER TO THIS HANDLER TO DISCONNECT!!!!!\n";
3264 0 0       0 $xprm{PRT_CEND} && print STDOUT "!!!!!WE ARE GOING TO DISCONNECT ANYWAY, AND DIE!!!!!\n";
3265 0         0 $class->{connection}->disconnect;
3266 0         0 $class->{connection}->DESTROY;
3267             # gone for good, alas, no more logging
3268 0         0 $class-> _tracingE("<-don DESTROY ** ENDED WITH ERROR (CONNECTION STATUS=".$class-> state.") ******** \n");
3269 0         0 $class-> DESTROY_HOOK;
3270 0         0 die "EXITING WITH ERROR: CALLER MUST DISCONNECT BEFORE ENDING THIS HANDLER CLASS!\n";
3271             }
3272             }
3273              
3274             #my $c = [caller];
3275             #print STDOUT "@{$c} -- \n DESSSSSSSSSsssssssssssssssssssssstroyed \n\n";
3276             }
3277              
3278             ########################################################################################
3279             ########################################################################################
3280             ########################################################################################
3281             ########################################################################################
3282              
3283              
3284             # STATISTICS Section
3285             ########################################################################################
3286             ########################################################################################
3287             ########################################################################################
3288             ########################################################################################
3289             #
3290              
3291             sub _statCCreset {
3292 0     0   0 my $kprocess = shift;
3293 0         0 my $desc = shift;
3294 0         0 my $caconn = "$kprocess$desc";
3295 0         0 ${$$statCC{$caconn}}{kprocess} = $kprocess;
  0         0  
3296 0         0 ${$$statCC{$caconn}}{descriptor} = $desc;
  0         0  
3297 0         0 ${$$statCC{$caconn}}{counter} = 1;
  0         0  
3298             #${$$statCC{$caconn}}{systime};
3299             #${$$statCC{$caconn}}{dbtime};
3300             #Time::HiRes::clock();
3301             #Time::HiRes::clock();
3302              
3303             #my $TOTAL_ELAPSETIME = sprintf("%.2f", Time::HiRes::tv_interval($INVOTIME0));
3304             #${$$statCC{$caconn}}{starttime} = [Time::HiRes::gettimeofday];
3305             #${$$statCC{$caconn}}{starttime} = localtime;
3306 0         0 ${$$statCC{$caconn}}{starttime} = iso_date();
  0         0  
3307 0         0 ${$$statCC{$caconn}}{hires0} = [Time::HiRes::gettimeofday];
  0         0  
3308 0         0 ${$$statCC{$caconn}}{clock0} = Time::HiRes::clock();
  0         0  
3309             }
3310              
3311             sub _statCC {
3312 0     0   0 my $kprocess = shift;
3313 0         0 my $desc = shift;
3314 0         0 my $caconn = "$kprocess$desc";
3315             ##${$$statCC{$caconn}}{kprocess} =
3316             #${$$statCC{$caconn}}{descriptor} =
3317 0         0 ++${$$statCC{$caconn}}{counter};
  0         0  
3318             #${$$statCC{$caconn}}{systime};
3319             #${$$statCC{$caconn}}{dbtime};
3320             #${$$statCC{$caconn}}{starttime} = ;
3321             }
3322              
3323             sub getStatCC {
3324             #my $caconn = shift;
3325 0     0 1 0 my $class = shift;
3326 0 0       0 my $rshr = @_ ? shift : undef;
3327              
3328 0         0 foreach my $caconn (keys %$statCC) {
3329             #my $elapse = sprintf("%.2f", Time::HiRes::tv_interval(${$$statCC{$caconn}}{starttime}));
3330 0         0 ${$$statCC{$caconn}}{clock1} = Time::HiRes::clock();
  0         0  
3331             #my $clock = ${$$statCC{$caconn}}{clock1} - ${$$statCC{$caconn}}{clock0};
3332 0         0 ${$$statCC{$caconn}}{clock} = ${$$statCC{$caconn}}{clock1} - ${$$statCC{$caconn}}{clock0};
  0         0  
  0         0  
  0         0  
3333              
3334             #my ${$$statCC{$caconn}}{hires1} = [Time::HiRes::gettimeofday];
3335             #my $elapse = sprintf("%.2f", Time::HiRes::tv_interval(${$$statCC{$caconn}}{hires0}));
3336 0         0 ${$$statCC{$caconn}}{elapse} = sprintf("%.2f", Time::HiRes::tv_interval(${$$statCC{$caconn}}{hires0}));
  0         0  
  0         0  
3337             }
3338              
3339 0 0 0     0 (ref $rshr eq 'HASH') && (%$rshr = map{$_=>$$statCC{$_}} (keys %$statCC)) && (return $rshr);
  0         0  
3340 0         0 my $th={};
3341 0 0 0     0 (length($rshr) > 2) && (%$th = map{$_=>$$statCC{$_}}(keys %{$$statCC{$rshr}})) && (return $th);
  0         0  
  0         0  
3342              
3343             #return $statCC;
3344              
3345 0         0 my $info;
3346 0         0 foreach my $caconn (keys %$statCC) {
3347 0         0 $info .= "
3348 0         0 $caconn
3349 0         0 ${$$statCC{$caconn}}{kprocess}
3350 0         0 ${$$statCC{$caconn}}{descriptor}
3351 0         0 ${$$statCC{$caconn}}{counter}
3352 0         0 ${$$statCC{$caconn}}{starttime}
3353 0         0 elapse: ${$$statCC{$caconn}}{elapse}
3354             time: ${$$statCC{$caconn}}{clock}
3355              
3356             ";
3357             }
3358 0         0 return $info;
3359             }
3360              
3361             sub htmlStatCC {
3362             #my $caconn = shift;
3363 0     0 1 0 my $class = shift;
3364              
3365 0         0 foreach my $caconn (keys %$statCC) {
3366             #my $elapse = sprintf("%.2f", Time::HiRes::tv_interval(${$$statCC{$caconn}}{starttime}));
3367 0         0 ${$$statCC{$caconn}}{clock1} = Time::HiRes::clock();
  0         0  
3368             #my $clock = ${$$statCC{$caconn}}{clock1} - ${$$statCC{$caconn}}{clock0};
3369 0         0 ${$$statCC{$caconn}}{clock} = ${$$statCC{$caconn}}{clock1} - ${$$statCC{$caconn}}{clock0};
  0         0  
  0         0  
  0         0  
3370              
3371             #my ${$$statCC{$caconn}}{hires1} = [Time::HiRes::gettimeofday];
3372             #my $elapse = sprintf("%.2f", Time::HiRes::tv_interval(${$$statCC{$caconn}}{hires0}));
3373 0         0 ${$$statCC{$caconn}}{elapse} = sprintf("%.2f", Time::HiRes::tv_interval(${$$statCC{$caconn}}{hires0}));
  0         0  
  0         0  
3374             }
3375              
3376              
3377 0         0 print "
3378              
3379             The table below shows the cached connection of this http server process. The columns designation
3380             summary is as follow:
3381            
3382            
  • id -- unique ID of the connection object formed of kernel process ID + database descriptor
  • 3383            
  • kprocess -- kernel process ID
  • 3384            
  • counter -- number of times the DBI::BabyObject has been requested
  • 3385            
  • starttime -- start time is ISO date format
  • 3386            
  • elapse -- number of seconds since the DBI::BabyObject object has been created
  • 3387            
  • clock -- system+user system time consumed by the specified cached DBI::BabyObject object
  • 3388            
    3389              
    3390             ' , map("", @fields) , ""; ", map("",@fields) , "";
    3391              
    3392             ";
    3393 0         0 my @fields = qw(id kprocess counter starttime elapse clock);
    3394 0         0 print '
    $_
    3395 0         0 shift @fields;
    3396              
    3397 0         0 foreach my $caconn (keys %$statCC) {
    3398 0         0 print "
    $caconn${$$statCC{$caconn}}{$_}
      0         0  
    3399             }
    3400              
    3401 0         0 print "
    ";
    3402              
    3403             }
    3404              
    3405              
    3406              
    3407             sub iso_date {
    3408 2     2 0 21 my $date = (localtime->year() + 1900).'-'._two_digit(localtime->mon() + 1).'-'._two_digit(localtime->mday());
    3409 2         23 my $time = _two_digit(localtime->hour()).':'._two_digit(localtime->min()).':'._two_digit(localtime->sec());
    3410 2         13 return "$date $time";
    3411             }
    3412              
    3413             sub _two_digit {
    3414 10     10   2145 my $value = $_[0];
    3415 10 100       34 $value = '0'.$value if( length($value) == 1 );
    3416 10         46 return $value;
    3417             }
    3418              
    3419              
    3420              
    3421             sub get_running_time {
    3422 0     0 1 0 my $class = shift;
    3423            
    3424 0         0 my $clock1 = Time::HiRes::clock();
    3425 0         0 my $totclock = $clock1 - $class->{clock0};
    3426              
    3427             #my $totrun = time - $class->{time0};
    3428             #[Time::HiRes::gettimeofday];
    3429             #my $totrun = Time::HiRes::tv_interval($class->{time0});
    3430 0         0 my $totrun = sprintf("%.2f", Time::HiRes::tv_interval($class->{time0}));
    3431 0         0 my $conrun = $class->{cumu_conrun};
    3432 0         0 return "$conrun / $totclock / $totrun";
    3433             }
    3434              
    3435              
    3436             ########################################################################################
    3437              
    3438             sub get_do_stat {
    3439 0     0 0 0 my $class = shift;
    3440 0 0       0 my $rshr = @_ ? shift : undef;
    3441              
    3442 0         0 my $th={};
    3443 0 0 0     0 (ref $rshr eq 'HASH') && (%$rshr = map{$_=>$class-> {_qryStat}{$_}}(keys %{$class-> {_qryStat}})) && (return $rshr);
      0         0  
      0         0  
    3444 0 0 0     0 (length($rshr) > 2) && (%$th = map{$_=>$class-> {_qryStat}{$_}}(keys %{${$class-> {_qryStat}}{$rshr}})) && (return $th);
      0         0  
      0         0  
      0         0  
    3445              
    3446 0         0 my $info;
    3447 0         0 foreach my $k (keys %{$class-> {_qryStat}}) {
      0         0  
    3448 0         0 my $elap = $class-> {_qryStat}{$k}{tm1} - $class-> {_qryStat}{$k}{tm0};
    3449 0         0 $info .= "
    3450             Query: $k
    3451             count: ". $class-> {_qryStat}{$k}{count}."
    3452             tm0: ". $class-> {_qryStat}{$k}{tm0}."
    3453             tm1: ". $class-> {_qryStat}{$k}{tm1}."
    3454             elapse: ". $elap."
    3455              
    3456             ";
    3457             }
    3458              
    3459 0         0 return $info;
    3460             }
    3461            
    3462             ########################################################################################
    3463             sub get_spc_stat {
    3464 0     0 0 0 my $class = shift;
    3465 0 0       0 my $rshr = @_ ? shift : undef;
    3466              
    3467 0         0 my $th={};
    3468 0 0 0     0 (ref $rshr eq 'HASH') && (%$rshr = map{$_=>$class-> {_spcStat}{$_}}(keys %{$class-> {_spcStat}})) && (return $rshr);
      0         0  
      0         0  
    3469 0 0 0     0 (length($rshr) > 2) && (%$th = map{$_=>$class-> {_spcStat}{$_}}(keys %{${$class-> {_spcStat}}{$rshr}})) && (return $th);
      0         0  
      0         0  
      0         0  
    3470              
    3471 0         0 my $info;
    3472 0         0 foreach my $k (keys %{$class-> {_spcStat}}) {
      0         0  
    3473 0         0 my $elap = $class-> {_spcStat}{$k}{tm1} - $class-> {_spcStat}{$k}{tm0};
    3474 0         0 $info .= "
    3475             Spc: $k
    3476             count: ". $class-> {_spcStat}{$k}{count}."
    3477             tm0: ". $class-> {_spcStat}{$k}{tm0}."
    3478             tm1: ". $class-> {_spcStat}{$k}{tm1}."
    3479             elapse: ". $elap."
    3480              
    3481             ";
    3482             }
    3483              
    3484 0         0 return $info;
    3485             }
    3486              
    3487             ########################################################################################
    3488             ########################################################################################
    3489             ########################################################################################
    3490             ########################################################################################
    3491              
    3492              
    3493             # META Section
    3494             ########################################################################################
    3495             ########################################################################################
    3496             ########################################################################################
    3497             ########################################################################################
    3498             sub snapTableDescription {
    3499 0     0 1 0 my $class = shift;
    3500 0         0 my $table = shift;
    3501              
    3502 0 0       0 return unless ($class-> dbdriver =~ /Mysql/i);
    3503              
    3504             #my $tabinfo = $class->{connection}->table_info();
    3505              
    3506             # Use the cursor to get a description of the 'onusers' table
    3507             #my $cursor = $class->{connection}->prepare( $q );
    3508 0         0 my $cursor = $class->{connection}->prepare("DESCRIBE $table");
    3509 0         0 $cursor->execute();
    3510 0         0 my $info = sprintf "%s", DBI::dump_results($cursor);
    3511 0         0 $cursor->finish();
    3512             #print DBI::dump_results($cursor);
    3513              
    3514             #open(FILE,">foo");
    3515             #print DBI::dump_results($cursor,undef,undef,undef,*FILE);
    3516             #close(FILE);
    3517             #$cursor->finish();
    3518              
    3519 0   0     0 $class->{src} = [caller]; push(@{$class->{src}},(caller 1)[3] || '');
      0         0  
      0         0  
    3520 0         0 $class->_tracingB("(snapTableDescription) RETRIEVE TABLE DESCRIPTION FOR $table:\n\tTABLE $info\n\n");
    3521 0         0 $class->_tracingE("\n");
    3522              
    3523 0         0 return $info;
    3524             }
    3525              
    3526             ########################################################################################
    3527              
    3528             sub snapTablesInfo {
    3529 0     0 1 0 my $class = shift;
    3530              
    3531 0 0       0 return unless ($class-> dbdriver =~ /Mysql/i);
    3532              
    3533 0         0 my $tabinfo = $class->{connection}->table_info();
    3534              
    3535 0         0 my $info = "\n\n";
    3536 0         0 $info .= "Table Name Type Qualifier Owner Remarks\n";
    3537 0         0 $info .= "============================ ======= ========= ============ ================\n";
    3538 0         0 while (my ($qual,$owner,$name,$type,$remarks) = $tabinfo->fetchrow_array() ) {
    3539 0         0 foreach ($qual,$owner,$name,$type,$remarks) {
    3540 0 0       0 $_ = "NULL" unless defined $_;
    3541             }
    3542             #$info .= sprintf "%-28s %-7s %-9s %-12s %-16s\n", $name,$type,$qual,$owner,$remarks;
    3543 0         0 $info .= sprintf "%-28s %7s %9s %12s %16s\n", $name,$type,$qual,$owner,$remarks;
    3544             #$info .= "$qual $owner $name $type $remarks \n";
    3545             }
    3546              
    3547 0   0     0 $class->{src} = [caller]; push(@{$class->{src}},(caller 1)[3] || '');
      0         0  
      0         0  
    3548 0         0 $class->_tracingB("(snapTablesInfo) RETRIEVE ALL TABLES INFO:\n\tTABLE $info\n\n");
    3549 0         0 $class->_tracingE("");
    3550              
    3551 0         0 return $info;
    3552             }
    3553              
    3554             my %SQLTY_COMMON_MAP = (
    3555             SQL_CHAR => 1,
    3556             SQL_NUMERIC => 2,
    3557             SQL_DECIMAL => 3,
    3558             SQL_INTEGER => 4,
    3559             SQL_SMALLINT => 5,
    3560             SQL_FLOAT => 6,
    3561             SQL_REAL => 7,
    3562             SQL_DOUBLE => 8,
    3563             SQL_DATE => 9,
    3564             SQL_TIME => 10,
    3565             SQL_TIMESTAMP => 11,
    3566             SQL_VARCHAR => 12,
    3567             SQL_LONGVARCHAR => -1,
    3568             SQL_BINARY => -2,
    3569             SQL_VARBINARY => -3,
    3570             SQL_LONGVARBINARY => -4,
    3571             SQL_BIGINT => -5,
    3572             SQL_TINYINT => -6,
    3573             SQL_BIT => -7,
    3574             SQL_WCHAR => -8,
    3575             SQL_WVARCHAR => -9,
    3576             SQL_WLONGVARCHAR => -10,
    3577             );
    3578              
    3579             my %SQLTY_INV = _inverse_hash (%SQLTY_COMMON_MAP);
    3580              
    3581             sub _inverse_hash
    3582             {
    3583 1     1   7 my (%hash) = @_;
    3584 1         1 my (%inv);
    3585 1         5 foreach my $key (keys %hash)
    3586             {
    3587 22         23 my $val = $hash{$key};
    3588 22 50       50 die "Double mapping for key value $val ($inv{$val}, $key)!"
    3589             if (defined $inv{$val});
    3590 22         40 $inv{$val} = $key;
    3591             }
    3592 1         16 return %inv;
    3593             }
    3594             # Refer to t_const.pl
    3595              
    3596             # /usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi/DBI.pm
    3597             # /usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi/DBD/File.pm
    3598             # /usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi/DBI/PurePerl.pm
    3599             # /usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi/auto/DBI/dbi_sql.h
    3600             # /usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi/DBD/Sponge.pm
    3601             # in File.pm: sub quote , sub type_info_all
    3602              
    3603             ########################################################################################
    3604              
    3605             sub snapTableMetadata {
    3606 0     0 1   my $class = shift;
    3607 0           my $table = shift;
    3608              
    3609 0 0         return unless ($class-> dbdriver =~ /Mysql/i);
    3610              
    3611 0           my $info = "\nMETADATA FOR TABLE $table\n\n";
    3612 0           $info .= "ATTRIBUTE NAME TYPE PREC SCALE NULLABLE\n";
    3613 0           $info .= "============================ ================= ===== ===== ========\n";
    3614              
    3615 0           my $q = "SELECT * FROM $table;";
    3616              
    3617 0           my $cursor = $class->{connection}->prepare( $q );
    3618 0           $cursor->execute();
    3619 0           my $fields = $cursor->{NUM_OF_FIELDS};
    3620              
    3621 0           my ($name,$scale,$precision,$type,$nullable);
    3622 0           for (my $i=0; $i<$fields; $i++) {
    3623 0           $name = $cursor->{NAME}->[$i];
    3624 0           $scale = $cursor->{SCALE}->[$i];
    3625 0           $precision = $cursor->{PRECISION}->[$i];
    3626 0           $type = $SQLTY_INV{ $cursor->{TYPE}->[$i] }; # %5d or %-17s
    3627 0           $nullable = ('No','NULL','Unknown')[$cursor->{NULLABLE}->[$i]];
    3628 0           $info .= sprintf "%-28s %17s %5d %5d %8s\n", $name,$type,$precision,$scale,$nullable;
    3629             # %32s %4d %4d %-17s %-7s
    3630             }
    3631 0           $info .= "\n\n";
    3632 0           $cursor->finish();
    3633              
    3634 0   0       $class->{src} = [caller]; push(@{$class->{src}},(caller 1)[3] || '');
      0            
      0            
    3635 0           $class-> _tracingB("(snapTableMetadata) RETRIEVE TABLE META DATA FOR:\n\tTABLE $table\n\n");
    3636 0           $class-> _tracingE("");
    3637              
    3638 0           return $info;
    3639             }
    3640              
    3641             ########################################################################################
    3642             # To retrieve the meta data of a table info
    3643              
    3644             sub strucTableMetadata {
    3645 0     0 1   my $class = shift;
    3646 0           my $table = shift;
    3647 0           my @TI;
    3648              
    3649 0           my $q = "SELECT * FROM $table;";
    3650              
    3651 0           my $cursor = $class->{connection}->prepare( $q );
    3652 0           $cursor->execute();
    3653 0           my $fields = $cursor->{NUM_OF_FIELDS};
    3654              
    3655 0           for (my $i=0; $i<$fields; $i++) {
    3656 0           $TI[$i]{NAME} = $cursor->{NAME}->[$i];
    3657 0           $TI[$i]{SCALE} = $cursor->{SCALE}->[$i];
    3658 0           $TI[$i]{PRECISION} = $cursor->{PRECISION}->[$i];
    3659 0           $TI[$i]{TYPE} = $SQLTY_INV{ $cursor->{TYPE}->[$i] }; # %5d or %-17s
    3660             #$TI[$i]{NULLABLE} = ('NoNULL','NULL','Unknown')[$cursor->{NULLABLE}->[$i]];
    3661 0           $TI[$i]{NULLABLE} = $cursor->{NULLABLE}->[$i];
    3662             # %32s %4d %4d %-17s %-7s
    3663             }
    3664 0           $cursor->finish();
    3665              
    3666 0   0       $class->{src} = [caller]; push(@{$class->{src}},(caller 1)[3] || '');
      0            
      0            
    3667 0           $class-> _tracingB("(getstruct_tableMetadata) RETRIEVE TABLE META DATA FOR:\n\tTABLE $table\n\n");
    3668 0           $class-> _tracingE("");
    3669              
    3670 0           return \@TI;
    3671             }
    3672              
    3673              
    3674             ########################################################################################
    3675             ########################################################################################
    3676             # TODO: move this function from OraPool.
    3677             #oraDBMS_getDLL
    3678             #C works only with Oracle. This method uses Oracle DBMS to
    3679             #get the DLL of a specific table.
    3680             #
    3681             #*oraDBMS=\&oraDBMS_getDLL;
    3682             #*dbms=\&oraDBMS_getDLL;
    3683             sub oraDBMS_getDLL {
    3684 0     0 0   my $class = shift;
    3685 0           my $table = shift;
    3686              
    3687 0 0         return unless ($class-> dbdriver =~ /Oracle/i);
    3688              
    3689 0           my $username = uc $class-> dbusername;
    3690 0           my $qry = qq{select dbms_metadata.get_ddl('TABLE','$table','$username') from dual};
    3691             #$class->{connection}-> do($qry);
    3692              
    3693 0           my $cursor = $class->{connection}->prepare( $qry );
    3694              
    3695 0           $class->{cursor} = $cursor;
    3696              
    3697 0           $class->{cursor}->execute();
    3698 0           $class->{rows} = $class->{cursor}->rows;
    3699 0           my $temp;
    3700             my $key;
    3701 0           my $i = -1; # -1 is nothing fetched
    3702              
    3703 0           while ($temp = $class->{cursor}->fetchrow_hashref()) {
    3704 0           $i++; # start counting at 0
    3705 0           my %hr = %$temp;
    3706              
    3707             ###push(@{$hh},\%hr); # Equivalent
    3708             #foreach my $k (keys %hr) {
    3709             # print "$k <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n $hr{$k} ----\n\n";
    3710             #}
    3711             }
    3712 0           $class->{cursor}->finish();
    3713              
    3714             #my $info = "\n\n";
    3715             #$info .= "TABLE_SCHEMA TABLE_NAME TABLE_ROWS CREATE_TIME UPDATE_TIME\n";
    3716             #$info .= "============== ======================================== ========== ==================== ====================\n";
    3717             #for (my $i=0; $i < @$hh; $i++) {
    3718             # $info .= sprintf "%-14s %-40s %-10s %-20s %-20s\n", $$hh[$i]{TABLE_SCHEMA}, $$hh[$i]{TABLE_NAME},$$hh[$i]{TABLE_ROWS},$$hh[$i]{CREATE_TIME} ,$$hh[$i]{UPDATE_TIME};
    3719             #}
    3720              
    3721             #$class->{src} = [caller]; push(@{$class->{src}},(caller 1)[3] || '');
    3722             #$class->_tracing("RETRIEVE_INOBJECTS:\n\tfrom TABLE $infotable -- ROWS OK = $class->{rows} \n\t$q\n\n");
    3723              
    3724             }
    3725              
    3726             ##############################################################################
    3727             #
    3728             # schema1.txt
    3729              
    3730             #*dbstatus {
    3731             sub dbschema {
    3732 0     0 1   my $class = shift;
    3733              
    3734             #TODO: die unless $dbb eq 'mysql' ... CHECK AS WELL THE VERSION!
    3735 0 0         return unless ($class-> dbdriver =~ /Mysql/i);
    3736              
    3737 0           my $infotable = 'INFORMATION_SCHEMA.TABLES';
    3738              
    3739 0           my $dbname = shift;
    3740              
    3741 0           my $tablelike = shift;
    3742              
    3743 0           my $s2 = "TABLE_SCHEMA = '$dbname' AND TABLE_NAME LIKE '$tablelike\%'";
    3744              
    3745 0           my $hh = shift;
    3746              
    3747 0           my $seeked = 'all';
    3748 0           my(@A) = ();
    3749            
    3750 0           my $s1 = '';
    3751 0           my @infoelms = qw(TABLE_SCHEMA TABLE_NAME CREATE_TIME UPDATE_TIME TABLE_ROWS);
    3752 0           for (my $j=0; $j < @infoelms; $j++)
    3753             {
    3754 0           push(@A,$infoelms[$j]);
    3755 0           $s1 .= $infoelms[$j] . ',';
    3756             }
    3757 0           chop($s1); $s1 .= ' ';
      0            
    3758              
    3759 0           my $q = "SELECT $s1 FROM $infotable WHERE $s2;";
    3760              
    3761 0           my $cursor = $class->{connection}->prepare( $q );
    3762              
    3763 0           $class->{cursor} = $cursor;
    3764              
    3765 0           $class->{cursor}->execute();
    3766 0           $class->{rows} = $class->{cursor}->rows;
    3767 0           my $temp;
    3768             my $key;
    3769 0           my $i = -1; # -1 is nothing fetched
    3770              
    3771 0           while ($temp = $class->{cursor}->fetchrow_hashref()) {
    3772 0           $i++; # start counting at 0
    3773 0           my %hr = %$temp;
    3774              
    3775 0           push(@{$hh},\%hr); # Equivalent
      0            
    3776             }
    3777 0           $class->{cursor}->finish();
    3778              
    3779 0           my $info = "\n\n";
    3780 0           $info .= "TABLE_SCHEMA TABLE_NAME TABLE_ROWS CREATE_TIME UPDATE_TIME\n";
    3781 0           $info .= "============== ============================== ========== ==================== ====================\n";
    3782 0           for (my $i=0; $i < @$hh; $i++) {
    3783 0           $info .= sprintf "%-14s %-30s %-10s %-20s %-20s\n", $$hh[$i]{TABLE_SCHEMA}, $$hh[$i]{TABLE_NAME},$$hh[$i]{TABLE_ROWS},$$hh[$i]{CREATE_TIME} ,$$hh[$i]{UPDATE_TIME};
    3784             }
    3785              
    3786 0   0       $class->{src} = [caller]; push(@{$class->{src}},(caller 1)[3] || '');
      0            
      0            
    3787 0           $class-> _tracingB("RETRIEVE_INOBJECTS:\n\tfrom TABLE $infotable -- ROWS OK = $class->{rows} \n\t$q\n\n");
    3788              
    3789 0           return $info;
    3790             }
    3791              
    3792             ##############################################################################
    3793             #
    3794             # schema2.txt
    3795              
    3796             sub getInfoSchema {
    3797 0     0 0   my $class = shift;
    3798              
    3799             #mysql> describe INFORMATION_SCHEMA.statistics;
    3800             # select SEQ_IN_INDEX,TABLE_SCHEMA,TABLE_NAME,CARDINALITY,COLUMN_NAME from INFORMATION_SCHEMA.statistics WHERE TABLE_SCHEMA='VARIGENE' AND TABLE_NAME='VS00000001_PROCESSORS_RSLTPARAMS';
    3801 0           my @infsch_statistics = qw(
    3802             TABLE_CATALOG
    3803             TABLE_SCHEMA
    3804             TABLE_NAME
    3805             NON_UNIQUE
    3806             INDEX_SCHEMA
    3807             INDEX_NAME
    3808             SEQ_IN_INDEX
    3809             COLUMN_NAME
    3810             COLLATION
    3811             CARDINALITY
    3812             SUB_PART
    3813             PACKED
    3814             NULLABLE
    3815             INDEX_TYPE
    3816             COMMENT
    3817             );
    3818              
    3819             #mysql> describe INFORMATION_SCHEMA.columns;
    3820 0           my @infsch_columns = qw(
    3821             TABLE_CATALOG
    3822             TABLE_SCHEMA
    3823             TABLE_NAME
    3824             COLUMN_NAME
    3825             ORDINAL_POSITION
    3826             COLUMN_DEFAULT
    3827             IS_NULLABLE
    3828             DATA_TYPE
    3829             CHARACTER_MAXIMUM_LENGTH
    3830             CHARACTER_OCTET_LENGTH
    3831             NUMERIC_PRECISION
    3832             NUMERIC_SCALE
    3833             CHARACTER_SET_NAME
    3834             COLLATION_NAME
    3835             COLUMN_TYPE
    3836             COLUMN_KEY
    3837             EXTRA
    3838             PRIVILEGES
    3839             COLUMN_COMMENT
    3840             );
    3841              
    3842 0           die "ConnectionManager > getInfoSchema IS NOT IMPLEMENTED!\n";
    3843             }
    3844             ########################################################################################
    3845             ########################################################################################
    3846             ########################################################################################
    3847             ########################################################################################
    3848             sub textFormattedAO {
    3849 0     0 1   my $class = shift;
    3850 0           my $ah = shift;
    3851 0           my $_titlen = shift;
    3852 0 0         my $labmap = @_ ? shift : undef;
    3853              
    3854 0 0         my @_titlen = $_titlen ? @$_titlen : ();
    3855             #my @_titlen = @$_titlen;
    3856 0           my $titlen = \@_titlen;
    3857              
    3858             # to keep order and for any reason nothing is given, then ...
    3859 0           my @realmap;
    3860             my @reallen;
    3861 0           foreach my $k (sort keys %{$$ah[0]}) {
      0            
    3862 0           push(@realmap,$k);
    3863 0           my $len = 18;
    3864 0           push(@reallen,$len);
    3865             }
    3866              
    3867 0           my @titmap;
    3868             my @titlen;
    3869 0           while (my($tit,$len)=splice @$titlen, 0, 2) {
    3870 0           push(@titmap,$tit);
    3871 0           push(@titlen,$len);
    3872             }
    3873             # If for any reason nothing is given, then ...
    3874 0 0         if (!@titmap) { @titmap=@realmap; @titlen=@reallen; }
      0            
      0            
    3875              
    3876 0 0         my @labmap = $labmap ? map($$labmap{ $titmap[$_] },(0..@titmap)) : @titmap;
    3877              
    3878 0           my @sprt;
    3879 0           my $underline = '';
    3880 0           my $info = "\n\n";
    3881 0           for (my $i=0; $i< @titmap; $i++) {
    3882             # my $tit = $titmap[$i];
    3883 0           my $tit = $labmap[$i];
    3884 0           my $len = $titlen[$i];
    3885 0 0         my $clab = (length($tit) <= $len) ? $tit : substr $tit,0,$len;
    3886 0           $info .= $clab;
    3887 0           my $hump = $len - length($tit) + 1;
    3888 0           $info .= ' ' x $hump;
    3889 0           $underline .= '*' x $len;
    3890 0           $underline .= ' ';
    3891 0           push(@sprt, "%-" . $len . 's');
    3892             }
    3893 0           $info .= "\n";
    3894 0           $info .= $underline;
    3895 0           $info .= "\n";
    3896             # $info .= "Processorid Author Prss Type\n";
    3897             # $info .= "********************** ********************* ****************\n";
    3898              
    3899             #my @a = qw(processorid author prsstype);
    3900             #my @a = @$titmap;
    3901             #my $ah = $prrg->listProcessors();
    3902             #my $count = @$ah;
    3903 0           for (my $i=0; $i < @$ah; $i++) {
    3904 0           my(@a) = @{ %{$$ah[$i]} } { @titmap };
      0            
      0            
    3905             #$info .= sprintf "%-22s %-22s %-16s \n", $processorid,$author,$prsstype;
    3906 0           for (my $i=0; $i<@a; $i++) {
    3907 0           my $sprt = $sprt[$i];
    3908 0           my $val = $a[$i];
    3909             #$info .= sprintf "%-22s ",$_;
    3910 0           $info .= sprintf "$sprt ",$val;
    3911             }
    3912 0           $info .= "\n";
    3913             }
    3914 0 0         return @$ah ? $info : '';
    3915             #print $info if @$ah;
    3916             }
    3917              
    3918              
    3919             ########################################################################################
    3920             ########################################################################################
    3921             sub datalinesFormattedAO {
    3922 0     0 1   my $class = shift;
    3923 0           my $ah = shift;
    3924 0           my $_titlen = shift;
    3925 0 0         my $labmap = @_ ? shift : undef;
    3926              
    3927 0 0         my @_titlen = $_titlen ? @$_titlen : ();
    3928             #my @_titlen = @$_titlen;
    3929 0           my $titlen = \@_titlen;
    3930              
    3931 0           my $lninfo = {
    3932             TITLE_LINE => '',
    3933             UNDERLINE => '',
    3934             DATA_LINES => [],
    3935             };
    3936              
    3937             # to keep order and for any reason nothing is given, then ...
    3938 0           my @realmap;
    3939             my @reallen;
    3940 0           foreach my $k (sort keys %{$$ah[0]}) {
      0            
    3941 0           push(@realmap,$k);
    3942 0           my $len = 18;
    3943 0           push(@reallen,$len);
    3944             }
    3945              
    3946 0           my @titmap;
    3947             my @titlen;
    3948 0           while (my($tit,$len)=splice @$titlen, 0, 2) {
    3949 0           push(@titmap,$tit);
    3950 0           push(@titlen,$len);
    3951             }
    3952             # If for any reason nothing is given, then ...
    3953 0 0         if (!@titmap) { @titmap=@realmap; @titlen=@reallen; }
      0            
      0            
    3954              
    3955 0 0         my @labmap = $labmap ? map($$labmap{ $titmap[$_] },(0..@titmap)) : @titmap;
    3956              
    3957 0           my @sprt;
    3958 0           my $underline = '';
    3959 0           my $info = "\n\n";
    3960 0           for (my $i=0; $i< @titmap; $i++) {
    3961             # my $tit = $titmap[$i];
    3962 0           my $tit = $labmap[$i];
    3963 0           my $len = $titlen[$i];
    3964 0 0         my $clab = (length($tit) <= $len) ? $tit : substr $tit,0,$len;
    3965 0           $info .= $clab;
    3966 0           my $hump = $len - length($tit) + 1;
    3967 0           $info .= ' ' x $hump;
    3968 0           $underline .= '*' x $len;
    3969 0           $underline .= ' ';
    3970 0           push(@sprt, "%-" . $len . 's');
    3971             }
    3972 0           $info .= "\n";
    3973 0           $$lninfo{TITLE_LINE} = $info;
    3974 0           $info .= $underline;
    3975 0           $info .= "\n";
    3976 0           $$lninfo{UNDERLINE} = "$underline\n";
    3977             #$info .= "Processorid Author Prss Type\n";
    3978             #$info .= "********************** ********************* ****************\n";
    3979              
    3980             #my @a = qw(processorid author prsstype);
    3981             #my @a = @$titmap;
    3982             #my $ah = $prrg->listProcessors();
    3983             #my $count = @$ah;
    3984 0           for (my $i=0; $i < @$ah; $i++) {
    3985 0           my $ln;
    3986 0           my(@a) = @{ %{$$ah[$i]} } { @titmap };
      0            
      0            
    3987             #$info .= sprintf "%-22s %-22s %-16s \n", $processorid,$author,$prsstype;
    3988 0           for (my $i=0; $i<@a; $i++) {
    3989 0           my $sprt = $sprt[$i];
    3990 0           my $val = $a[$i];
    3991             #$info .= sprintf "%-22s ",$_;
    3992 0           $info .= sprintf "$sprt ",$val;
    3993 0           $ln .= sprintf "$sprt ",$val;
    3994             }
    3995 0           $info .= "\n";
    3996 0           $ln .= "\n";
    3997 0           push(@{$$lninfo{DATA_LINES}},$ln);
      0            
    3998             }
    3999 0 0         return @$ah ? $lninfo : undef;
    4000             #return @$ah ? $info : '';
    4001             #print $info if @$ah;
    4002             }
    4003              
    4004              
    4005             ########################################################################################
    4006             ########################################################################################
    4007             sub textFormattedAA {
    4008 0     0 1   my $class = shift;
    4009 0           my $aa = shift;
    4010 0           my $_titlen = shift;
    4011 0 0         my $labmap = @_ ? shift : undef;
    4012              
    4013 0 0         my @_titlen = $_titlen ? @$_titlen : ();
    4014             #my @_titlen = @$_titlen;
    4015 0           my $titlen = \@_titlen;
    4016              
    4017             # to keep order and for any reason nothing is given, then ...
    4018 0           my @realmap;
    4019             my @reallen;
    4020 0           my $i=0;
    4021 0           my(@a) = @{ $$aa[$i] };
      0            
    4022 0           for (my $i=0; $i<@a; $i++) {
    4023 0           push(@realmap,$a[$i]);
    4024 0           my $len = 18;
    4025 0           push(@reallen,$len);
    4026             }
    4027              
    4028 0           my @titmap;
    4029             my @titlen;
    4030 0           while (my($tit,$len)=splice @$titlen, 0, 2) {
    4031 0           push(@titmap,$tit);
    4032 0           push(@titlen,$len);
    4033             }
    4034             # If for any reason nothing is given, then ...
    4035 0 0         if (!@titmap) { @titmap=@realmap; @titlen=@reallen; }
      0            
      0            
    4036              
    4037              
    4038 0 0         my @labmap = $labmap ? map($$labmap{ $titmap[$_] },(0..@titmap)) : @titmap;
    4039              
    4040 0           my @sprt;
    4041 0           my $underline = '';
    4042 0           my $info = "\n\n";
    4043 0           for (my $i=0; $i< @titmap; $i++) {
    4044             # my $tit = $titmap[$i];
    4045 0           my $tit = $labmap[$i];
    4046 0           my $len = $titlen[$i];
    4047 0 0         my $clab = (length($tit) <= $len) ? $tit : substr $tit,0,$len;
    4048 0           $info .= $clab;
    4049 0           my $hump = $len - length($tit) + 1;
    4050 0           $info .= ' ' x $hump;
    4051 0           $underline .= '*' x $len;
    4052 0           $underline .= ' ';
    4053 0           push(@sprt, "%-" . $len . 's');
    4054             }
    4055 0           $info .= "\n";
    4056 0           $info .= $underline;
    4057 0           $info .= "\n";
    4058              
    4059             #for (my $i=0; $i < @$aa; $i++) {
    4060 0           for (my $i=1; $i < @$aa; $i++) {
    4061             #my(@a) = @{ %{$$aa[$i]} } { @titmap };
    4062 0           my(@a) = @{ $$aa[$i] };
      0            
    4063 0           my %rec = map{$realmap[$_]=>$a[$_]}(0..@realmap);
      0            
    4064 0           my @z = @{ %rec } { @titmap };
      0            
    4065             #for (my $i=0; $i<@a; $i++) {
    4066 0           for (my $i=0; $i<@z; $i++) {
    4067 0           my $sprt = $sprt[$i];
    4068             #my $val = $a[$i];
    4069 0           my $val = $z[$i];
    4070 0           $info .= sprintf "$sprt ",$val; # "%-22s ",$_
    4071             }
    4072 0           $info .= "\n";
    4073             }
    4074 0 0         return @$aa ? $info : '';
    4075             }
    4076              
    4077              
    4078             ########################################################################################
    4079             ########################################################################################
    4080             sub datalinesFormattedAA {
    4081 0     0 1   my $class = shift;
    4082 0           my $aa = shift;
    4083 0           my $_titlen = shift;
    4084 0 0         my $labmap = @_ ? shift : undef;
    4085              
    4086             #PERL 6!: return $class-> textFormattedAA($aa,$_titlen,$labmap) unless wanthash();
    4087              
    4088              
    4089 0 0         my @_titlen = $_titlen ? @$_titlen : ();
    4090 0           my $titlen = \@_titlen;
    4091              
    4092 0           my $lninfo = {
    4093             TITLE_LINE => '',
    4094             UNDERLINE => '',
    4095             DATA_LINES => [],
    4096             };
    4097              
    4098             # to keep order and for any reason nothing is given, then ...
    4099 0           my @realmap;
    4100             my @reallen;
    4101 0           my $i=0;
    4102 0           my(@a) = @{ $$aa[$i] };
      0            
    4103 0           for (my $i=0; $i<@a; $i++) {
    4104 0           push(@realmap,$a[$i]);
    4105 0           my $len = 18;
    4106 0           push(@reallen,$len);
    4107             }
    4108              
    4109 0           my @titmap;
    4110             my @titlen;
    4111 0           while (my($tit,$len)=splice @$titlen, 0, 2) {
    4112 0           push(@titmap,$tit);
    4113 0           push(@titlen,$len);
    4114             }
    4115             # If for any reason nothing is given, then ...
    4116 0 0         if (!@titmap) { @titmap=@realmap; @titlen=@reallen; }
      0            
      0            
    4117              
    4118 0 0         my @labmap = $labmap ? map($$labmap{ $titmap[$_] },(0..@titmap)) : @titmap;
    4119              
    4120 0           my @sprt;
    4121 0           my $underline = '';
    4122 0           my $info = "\n\n";
    4123 0           for (my $i=0; $i< @titmap; $i++) {
    4124             # my $tit = $titmap[$i];
    4125 0           my $tit = $labmap[$i];
    4126 0           my $len = $titlen[$i];
    4127 0 0         my $clab = (length($tit) <= $len) ? $tit : substr $tit,0,$len;
    4128 0           $info .= $clab;
    4129 0           my $hump = $len - length($tit) + 1;
    4130 0           $info .= ' ' x $hump;
    4131 0           $underline .= '*' x $len;
    4132 0           $underline .= ' ';
    4133 0           push(@sprt, "%-" . $len . 's');
    4134             }
    4135 0           $info .= "\n";
    4136 0           $$lninfo{TITLE_LINE} = $info;
    4137 0           $info .= $underline;
    4138 0           $info .= "\n";
    4139 0           $$lninfo{UNDERLINE} = "$underline\n";
    4140              
    4141             #for (my $i=0; $i < @$aa; $i++) {
    4142 0           for (my $i=1; $i < @$aa; $i++) {
    4143 0           my $ln;
    4144             #my(@a) = @{ %{$$aa[$i]} } { @titmap };
    4145 0           my(@a) = @{ $$aa[$i] };
      0            
    4146 0           my %rec = map{$realmap[$_]=>$a[$_]}(0..@realmap);
      0            
    4147 0           my @z = @{ %rec } { @titmap };
      0            
    4148             #for (my $i=0; $i<@a; $i++) {
    4149 0           for (my $i=0; $i<@z; $i++) {
    4150 0           my $sprt = $sprt[$i];
    4151             #my $val = $a[$i];
    4152 0           my $val = $z[$i];
    4153 0           $info .= sprintf "$sprt ",$val; # "%-22s ",$_
    4154 0           $ln .= sprintf "$sprt ",$val;
    4155             }
    4156 0           $info .= "\n";
    4157 0           $ln .= "\n";
    4158 0           push(@{$$lninfo{DATA_LINES}},$ln);
      0            
    4159             }
    4160             #return @$aa ? $info : '';
    4161 0 0         return @$aa ? $lninfo : undef;
    4162             }
    4163              
    4164             ########################################################################################
    4165             ########################################################################################
    4166             ########################################################################################
    4167             ########################################################################################
    4168              
    4169             1;
    4170              
    4171             ########################################################################################
    4172             {
    4173             package DBI::BabyConnect::Deb;
    4174              
    4175             # IO::Socket needed for the autoflush() in the PRINT sub
    4176             # we will include this once and for all, instead of including
    4177             # it in the caller packages (in particular need by the author
    4178             # application to debug Varisphere multithread DVARs)
    4179 1     1   1187 use IO::Socket;
      1         41123  
      1         5  
    4180              
    4181 1     1   666 use strict;
      1         2  
      1         29  
    4182             #use Carp;
    4183 1     1   4 use Symbol;
      1         1  
      1         664  
    4184              
    4185 0     0     sub _no_filter { return $_[0]; }
    4186              
    4187             sub TIEHANDLE
    4188             {
    4189 0     0     my ($class, %args) = @_;
    4190 0           my $handle = gensym();
    4191              
    4192 0           my $impl = bless {handle => gensym() }, $class;
    4193 0           $impl->OPEN(%args);
    4194 0           return $impl;
    4195             }
    4196              
    4197             sub OPEN {
    4198 0     0     my ($impl, %args) = @_;
    4199             #open $impl->{handle}, $args{file} or croak "Could not open that '$args{file}'";
    4200 0 0         open $impl->{handle}, $args{file} or die "Could not open that '$args{file}'";
    4201 0   0       $impl->{in_filter} = $args{in} || \&_no_filter,
          0        
    4202             $impl->{out_filter} = $args{out} || \&_no_filter,
    4203             }
    4204              
    4205             sub SEEK {
    4206 0     0     my ($impl, $position, $whence) = @_;
    4207 0           return sysseek($impl->{handle}, $position, $whence);
    4208             }
    4209              
    4210             sub WRITE {
    4211 0     0     my ($impl, $buffer, $length, $offset) = @_;
    4212 0           $buffer = $impl->{out_filter}->($buffer);
    4213 0   0       syswrite($impl->{handle}, $buffer, $length, $offset||0);
    4214             }
    4215              
    4216             sub PRINT {
    4217 0     0     my ($impl, @data) = @_;
    4218 0           my $filter = $impl->{out_filter};
    4219 0           @data = map { $filter->($_) } @data;
      0            
    4220 0           print { $impl->{handle} } @data;
      0            
    4221             #$|=1;
    4222 0           $impl->{handle}->autoflush();
    4223             }
    4224              
    4225             sub PRINTF {
    4226 0     0     my ($impl, $format, @data) = @_;
    4227 0           my $filter = $impl->{out_filter};
    4228 0           print { $impl->{handle} } $filter->(sprintf $format, @data);
      0            
    4229             #$impl->{handle}->autoflush();
    4230             }
    4231              
    4232             sub READ {
    4233 0     0     my ($impl, $data, $length, $offset) = @_;
    4234 0           my $result = sysread($impl->{handle}, $data, $length);
    4235 0   0       substr($_[1],$offset||0,$length) = $impl->{in_filter}->($data);
    4236 0           return $result;
    4237             }
    4238              
    4239             sub GETC {
    4240 0     0     my ($impl) = @_;
    4241 0           $impl->{in_filter}->(getc $impl->{handle});
    4242             }
    4243              
    4244             sub READLINE {
    4245 0     0     my $impl = @_;
    4246 0           $impl->{in_filter}->(scalar readline *{$impl->{handle}});
      0            
    4247             }
    4248              
    4249             sub CLOSE {
    4250 0     0     my $impl = @_;
    4251 0           close $impl->{handle};
    4252             }
    4253              
    4254              
    4255             sub new {
    4256 0     0     my ($class, %args) = @_;
    4257 0           my $self = gensym();
    4258 0           tie *{$self}, $class, %args;
      0            
    4259 0           bless $self, $class;
    4260             }
    4261              
    4262             sub AUTOLOAD {
    4263 1     1   6 use vars qw( $AUTOLOAD ); # keep use strict
      1         2  
      1         237  
    4264 0     0     my ($self, @args) = @_;
    4265 0 0         return if $AUTOLOAD =~ /::DESTROY$/;
    4266 0           $AUTOLOAD =~ s/.*:://;
    4267 0           $AUTOLOAD =~ tr/a-z/A-Z/;
    4268 0           tied(*{$self})->$AUTOLOAD(@args);
      0            
    4269             }
    4270              
    4271             1;
    4272              
    4273             }
    4274              
    4275              
    4276             ########################################################################################
    4277             # Pooling, package DBI::BabyConnect::BabiesPool
    4278             #
    4279             # DBI::BabyConnect::BabiesPool
    4280             # DBI::BabyConnect::BabiesPool::InitAndLoad
    4281             # DBI::BabyConnect::BabiesPool::Free
    4282             # DBI::BabyConnect::BabiesPool::ReconnectConnector
    4283             # DBI::BabyConnect::BabiesPool::DupConnector
    4284             # DBI::BabyConnect::BabiesPool::AddConnector
    4285             # DBI::BabyConnect::BabiesPool::FreeConnector
    4286             # DBI::BabyConnect::BabiesPool::StatConnector
    4287             # DBI::BabyConnect::BabiesPool::ChildConnector
    4288             # DBI::BabyConnect::BabiesPool::Stat
    4289             #
    4290              
    4291             __END__