| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package Apache::BabyConnect; | 
| 2 |  |  |  |  |  |  |  | 
| 3 |  |  |  |  |  |  | our @ISA = qw(); | 
| 4 |  |  |  |  |  |  | our $VERSION = '0.93'; | 
| 5 |  |  |  |  |  |  |  | 
| 6 | 1 |  |  | 1 |  | 44637 | use strict; | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 118 |  | 
| 7 |  |  |  |  |  |  |  | 
| 8 |  |  |  |  |  |  | die " | 
| 9 |  |  |  |  |  |  | Apache::BabyConnect cannot start without setting the environment | 
| 10 |  |  |  |  |  |  | variable BABYCONNECT. You may have forgotten to set BABYCONNECT | 
| 11 |  |  |  |  |  |  | environment variable prior to loading the Apache::BabyConnect | 
| 12 |  |  |  |  |  |  | module. | 
| 13 |  |  |  |  |  |  | In the /etc/httpd/conf.d/perl.conf you need to setup the environment | 
| 14 |  |  |  |  |  |  | variable before loading the Apache::BabyConnect module. For instance, | 
| 15 |  |  |  |  |  |  | if you have loaded the Apache::BabyConnect from a startup script | 
| 16 |  |  |  |  |  |  | using the PerlRequire directive, you can setup the BABYCONNECT | 
| 17 |  |  |  |  |  |  | environment variable simply by using the directive PerlSetEnv prior | 
| 18 |  |  |  |  |  |  | to loading the startup script: | 
| 19 |  |  |  |  |  |  |  | 
| 20 |  |  |  |  |  |  | PerlSetEnv BABYCONNECT /opt/DBI-BabyConnect-$VERSION/configuration | 
| 21 |  |  |  |  |  |  | PerlRequire /opt/DBI-BabyConnect-$VERSION/startupscripts/babystartup.pl | 
| 22 |  |  |  |  |  |  | Alias /perl /var/www/perl | 
| 23 |  |  |  |  |  |  |  | 
| 24 |  |  |  |  |  |  | SetHandler perl-script | 
| 25 |  |  |  |  |  |  | PerlResponseHandler ModPerl::Registry | 
| 26 |  |  |  |  |  |  | PerlOptions +ParseHeaders | 
| 27 |  |  |  |  |  |  | Options +ExecCGI | 
| 28 |  |  |  |  |  |  |  | 
| 29 |  |  |  |  |  |  |  | 
| 30 |  |  |  |  |  |  | " unless $ENV{BABYCONNECT}; | 
| 31 | 1 | 50 | 33 |  |  | 289 | use constant MP2 => (exists $ENV{MOD_PERL_API_VERSION} && | 
| 32 | 1 |  |  | 1 |  | 6 | $ENV{MOD_PERL_API_VERSION} == 2) ? 1 : 0; | 
|  | 1 |  |  |  |  | 2 |  | 
| 33 |  |  |  |  |  |  |  | 
| 34 |  |  |  |  |  |  | BEGIN { | 
| 35 | 1 | 50 |  | 1 |  | 25 | if (MP2) { | 
| 36 |  |  |  |  |  |  | require mod_perl2; | 
| 37 |  |  |  |  |  |  | require Apache2::Module; | 
| 38 |  |  |  |  |  |  | require Apache2::ServerUtil; | 
| 39 |  |  |  |  |  |  | } | 
| 40 | 0 | 50 | 33 |  |  | 0 | elsif (defined $modperl::VERSION && $modperl::VERSION > 1 && | 
| 41 |  |  |  |  |  |  | $modperl::VERSION < 1.99) { | 
| 42 | 0 |  |  |  |  | 0 | require Apache; | 
| 43 |  |  |  |  |  |  | } | 
| 44 |  |  |  |  |  |  | } | 
| 45 |  |  |  |  |  |  |  | 
| 46 |  |  |  |  |  |  | ######################################################################################## | 
| 47 |  |  |  |  |  |  | # DBI::BabyConnect needs to be called with caching and persistence enabled | 
| 48 | 1 |  |  | 1 |  | 692 | use DBI::BabyConnect(1,1); | 
|  | 0 |  |  |  |  |  |  | 
|  | 0 |  |  |  |  |  |  | 
| 49 |  |  |  |  |  |  |  | 
| 50 |  |  |  |  |  |  | use Carp (); | 
| 51 |  |  |  |  |  |  |  | 
| 52 |  |  |  |  |  |  | $Apache::BabyConnect::VERSION = '1.00'; | 
| 53 |  |  |  |  |  |  |  | 
| 54 |  |  |  |  |  |  | $Apache::BabyConnect::DEBUG = 3; | 
| 55 |  |  |  |  |  |  |  | 
| 56 |  |  |  |  |  |  | my @ChildConnect; # connections to be established with each httpd child | 
| 57 |  |  |  |  |  |  | my $parent_pid; | 
| 58 |  |  |  |  |  |  |  | 
| 59 |  |  |  |  |  |  | ######################################################################################## | 
| 60 |  |  |  |  |  |  | ######################################################################################## | 
| 61 |  |  |  |  |  |  | sub debug { | 
| 62 |  |  |  |  |  |  | print STDERR "$_[1]\n" if $Apache::BabyConnect::DEBUG >= $_[0]; | 
| 63 |  |  |  |  |  |  | } | 
| 64 |  |  |  |  |  |  |  | 
| 65 |  |  |  |  |  |  | ######################################################################################## | 
| 66 |  |  |  |  |  |  | ######################################################################################## | 
| 67 |  |  |  |  |  |  | # connect_on_init is called in the script babystartup.pl to provide a PerlChildInitHandler | 
| 68 |  |  |  |  |  |  | # that will be hooked to a DBI::BabyConnect instance. | 
| 69 |  |  |  |  |  |  | # | 
| 70 |  |  |  |  |  |  | # The connect_on_init will request a DBI::BabyConnect instance to manage a DBI connection whose | 
| 71 |  |  |  |  |  |  | # parameters are being described with the database descriptor. Each child | 
| 72 |  |  |  |  |  |  | # is hooked to such an instance, and the instance is being persisted during the | 
| 73 |  |  |  |  |  |  | # life time of the child. | 
| 74 |  |  |  |  |  |  | # Because all childs are being started with the same database descriptor, therefore | 
| 75 |  |  |  |  |  |  | # they can access the database concurrently. You should be careful on how to use | 
| 76 |  |  |  |  |  |  | # the connection. Refer to Apache::BabyConnect documentation, and the script testbaby.pl | 
| 77 |  |  |  |  |  |  | # to understand how the pool of connections work. | 
| 78 |  |  |  |  |  |  | # You can request new connection from any Perl script, and the connection will be cached | 
| 79 |  |  |  |  |  |  | # only if the database descriptor cannot be found within the child (httpd child) own | 
| 80 |  |  |  |  |  |  | # DBI::BabyConnect instance cache. | 
| 81 |  |  |  |  |  |  | # The caching of connection per each httpd child (or its hooked instance DBI::BabyConnect instance) | 
| 82 |  |  |  |  |  |  | # is maintained within the DBI::BabyConnect itself, and each entry in the cache is | 
| 83 |  |  |  |  |  |  | # identified with the concatenation of the child kernel process ID and the database descriptor. | 
| 84 |  |  |  |  |  |  | # | 
| 85 |  |  |  |  |  |  | sub connect_on_init { | 
| 86 |  |  |  |  |  |  | if (MP2) { | 
| 87 |  |  |  |  |  |  | if (!@ChildConnect) { | 
| 88 |  |  |  |  |  |  | my $s = Apache2::ServerUtil->server; | 
| 89 |  |  |  |  |  |  | debug(1, "\n***!!!!!!!!! $$ connect_on_init / MP2 Apache2::ServerUtil->server NOT ChildConnect === @ChildConnect\n\n"); | 
| 90 |  |  |  |  |  |  | $s-> push_handlers(PerlChildInitHandler => \&childinit); | 
| 91 |  |  |  |  |  |  | } | 
| 92 |  |  |  |  |  |  | } | 
| 93 |  |  |  |  |  |  | else { | 
| 94 |  |  |  |  |  |  | Carp::carp("Apache.pm was not loaded\n") | 
| 95 |  |  |  |  |  |  | and return unless $INC{'Apache.pm'}; | 
| 96 |  |  |  |  |  |  |  | 
| 97 |  |  |  |  |  |  | if (!@ChildConnect and Apache->can('push_handlers')) { | 
| 98 |  |  |  |  |  |  | Apache->push_handlers(PerlChildInitHandler => \&childinit); | 
| 99 |  |  |  |  |  |  | } | 
| 100 |  |  |  |  |  |  | } | 
| 101 |  |  |  |  |  |  |  | 
| 102 |  |  |  |  |  |  | debug(1, "\n*** connect_on_init / store connections ===  $$   @_\n\n"); | 
| 103 |  |  |  |  |  |  |  | 
| 104 |  |  |  |  |  |  | # store connections | 
| 105 |  |  |  |  |  |  | $parent_pid = $$; | 
| 106 |  |  |  |  |  |  | push @ChildConnect, [@_]; | 
| 107 |  |  |  |  |  |  | #foreach (@ChildConnect) { print STDERR "************** Childconnect: @$_\n"; #} | 
| 108 |  |  |  |  |  |  | } | 
| 109 |  |  |  |  |  |  |  | 
| 110 |  |  |  |  |  |  | ######################################################################################## | 
| 111 |  |  |  |  |  |  | ######################################################################################## | 
| 112 |  |  |  |  |  |  | # The PerlChildInitHandler creates all connections during server startup. | 
| 113 |  |  |  |  |  |  | # Note: this handler runs in every child server, but not in the main server. | 
| 114 |  |  |  |  |  |  | sub childinit { | 
| 115 |  |  |  |  |  |  | my $prefix = "	   $$ Apache::BabyConnect			"; | 
| 116 |  |  |  |  |  |  | debug(2, "$prefix PerlChildInitHandler"); | 
| 117 |  |  |  |  |  |  |  | 
| 118 |  |  |  |  |  |  | while (@ChildConnect) { | 
| 119 |  |  |  |  |  |  | for my $aref (@ChildConnect) { | 
| 120 |  |  |  |  |  |  | debug(2, "\n\n************** Childconnect: @$aref"); | 
| 121 |  |  |  |  |  |  | my @da = @$aref; | 
| 122 |  |  |  |  |  |  | shift @da; | 
| 123 |  |  |  |  |  |  | my %da; | 
| 124 |  |  |  |  |  |  | while (my($l,$r)=splice @da, 0, 2) { | 
| 125 |  |  |  |  |  |  | $da{$l} = $r; | 
| 126 |  |  |  |  |  |  | } | 
| 127 |  |  |  |  |  |  | my ($arg_iconf,$arg_errlog,$arg_tralog,$arg_tralev) = | 
| 128 |  |  |  |  |  |  | @{ %da } { qw(DESCRIPTOR ERROR_FILE TRACE_FILE TRACE_LEVEL) }; | 
| 129 |  |  |  |  |  |  | $arg_errlog ||= ""; | 
| 130 |  |  |  |  |  |  | $arg_tralog ||= ""; | 
| 131 |  |  |  |  |  |  | $arg_tralev ||= ""; | 
| 132 |  |  |  |  |  |  | #my $arg_iconf = ${@$aref}[1]; | 
| 133 |  |  |  |  |  |  | #my $arg_errlog = ${@$aref}[2] || ""; | 
| 134 |  |  |  |  |  |  | #my $arg_tralog = ${@$aref}[3] || ""; | 
| 135 |  |  |  |  |  |  | #my $arg_tralev = ${@$aref}[4] || ""; | 
| 136 |  |  |  |  |  |  | debug(2, "        Child / ${@$aref}[0] requesting an instance of Apache::BabyConnect($arg_iconf) "); | 
| 137 |  |  |  |  |  |  | debug(2, "              HookError($arg_errlog)"); | 
| 138 |  |  |  |  |  |  | debug(2, "              HookTracing($arg_tralog)  with TraceLevel=$arg_tralev) "); | 
| 139 |  |  |  |  |  |  | my $cnn = DBI::BabyConnect->new($arg_iconf); | 
| 140 |  |  |  |  |  |  | # this redirection seems to work, but the need need debugging because it is altering the args!!!!!!!! | 
| 141 |  |  |  |  |  |  | length($arg_errlog) > 2 && $cnn ->HookError(">>$arg_errlog"); | 
| 142 |  |  |  |  |  |  | #${@$aref}[2] && $cnn ->HookError(">>$arg_errlog"); | 
| 143 |  |  |  |  |  |  | $arg_tralev ||= 1; # if trace level not specified then assume 1 | 
| 144 |  |  |  |  |  |  | length($arg_tralog) > 2 && $cnn ->HookTracing(">>$arg_tralog",$arg_tralev); | 
| 145 |  |  |  |  |  |  | #${@$aref}[3] && $cnn ->HookTracing(">>$arg_tralog",$arg_tralev); | 
| 146 |  |  |  |  |  |  | } | 
| 147 |  |  |  |  |  |  | shift @ChildConnect; | 
| 148 |  |  |  |  |  |  | # fudge this for now, need debugging!!!!!!!! | 
| 149 |  |  |  |  |  |  | last if @ChildConnect == 1; | 
| 150 |  |  |  |  |  |  | } | 
| 151 |  |  |  |  |  |  |  | 
| 152 |  |  |  |  |  |  | 1; | 
| 153 |  |  |  |  |  |  | } | 
| 154 |  |  |  |  |  |  |  | 
| 155 |  |  |  |  |  |  | ######################################################################################## | 
| 156 |  |  |  |  |  |  | ######################################################################################## | 
| 157 |  |  |  |  |  |  | # The cleanup phase from within mod_perl will execute some code immediately after the | 
| 158 |  |  |  |  |  |  | # request has been served (the client went away) and before the request object is destroyed. | 
| 159 |  |  |  |  |  |  | # | 
| 160 |  |  |  |  |  |  | # The PerlCleanupHandler does nothing since Apache::BabyConnect relies on DBI::BabyConnect | 
| 161 |  |  |  |  |  |  | # to handle all DBI functions such as rollback when AutoCommit is off | 
| 162 |  |  |  |  |  |  | sub cleanup { | 
| 163 |  |  |  |  |  |  |  | 
| 164 |  |  |  |  |  |  | 1; | 
| 165 |  |  |  |  |  |  | } | 
| 166 |  |  |  |  |  |  |  | 
| 167 |  |  |  |  |  |  | ######################################################################################## | 
| 168 |  |  |  |  |  |  | ######################################################################################## | 
| 169 |  |  |  |  |  |  | # ref: http://perl.apache.org/docs/2.0/api/Apache2/ServerUtil.html | 
| 170 |  |  |  |  |  |  |  | 
| 171 |  |  |  |  |  |  | sub get_child_init_handlers { | 
| 172 |  |  |  |  |  |  | my $s = Apache2::ServerUtil->server; | 
| 173 |  |  |  |  |  |  | my $handlers_list = $s-> get_handlers('PerlChildInitHandler'); | 
| 174 |  |  |  |  |  |  | #a list of references to the handler subroutines | 
| 175 |  |  |  |  |  |  | return $handlers_list; | 
| 176 |  |  |  |  |  |  | } | 
| 177 |  |  |  |  |  |  |  | 
| 178 |  |  |  |  |  |  | sub get_child_exit_handlers { | 
| 179 |  |  |  |  |  |  | my $s = Apache2::ServerUtil->server; | 
| 180 |  |  |  |  |  |  | my $handlers_list = $s-> get_handlers('PerlChildExitHandler') || []; | 
| 181 |  |  |  |  |  |  | return $handlers_list; | 
| 182 |  |  |  |  |  |  | } | 
| 183 |  |  |  |  |  |  |  | 
| 184 |  |  |  |  |  |  | sub parent_pid { | 
| 185 |  |  |  |  |  |  | return $parent_pid; | 
| 186 |  |  |  |  |  |  | } | 
| 187 |  |  |  |  |  |  |  | 
| 188 |  |  |  |  |  |  | sub cpids { | 
| 189 |  |  |  |  |  |  | my @a = split(/\n/,`ps  --ppid $parent_pid`); | 
| 190 |  |  |  |  |  |  | my @cpid; | 
| 191 |  |  |  |  |  |  | foreach (@a) { | 
| 192 |  |  |  |  |  |  | if ($_ =~ m/^(\d+)/) { | 
| 193 |  |  |  |  |  |  | push(@cpid,$1); | 
| 194 |  |  |  |  |  |  | } | 
| 195 |  |  |  |  |  |  | } | 
| 196 |  |  |  |  |  |  | return @cpid; | 
| 197 |  |  |  |  |  |  | } | 
| 198 |  |  |  |  |  |  | ######################################################################################## | 
| 199 |  |  |  |  |  |  | ######################################################################################## | 
| 200 |  |  |  |  |  |  |  | 
| 201 |  |  |  |  |  |  | if (MP2) { | 
| 202 |  |  |  |  |  |  | if (Apache2::Module::loaded('Apache2::Status')) { | 
| 203 |  |  |  |  |  |  | Apache2::Status->menu_item( | 
| 204 |  |  |  |  |  |  | 'BabyConnect' => 'BabyConnet for DBI connections', | 
| 205 |  |  |  |  |  |  | ); | 
| 206 |  |  |  |  |  |  | } | 
| 207 |  |  |  |  |  |  | } | 
| 208 |  |  |  |  |  |  | else { | 
| 209 |  |  |  |  |  |  | if ($INC{'Apache.pm'}		# is Apache loaded? | 
| 210 |  |  |  |  |  |  | and Apache->can('module')   # really loaded? | 
| 211 |  |  |  |  |  |  | and Apache->module('Apache::Status')) { # and has an Apache::Status? | 
| 212 |  |  |  |  |  |  | Apache::Status->menu_item( | 
| 213 |  |  |  |  |  |  | 'BabyConnect' => 'BabyConnect for DBI connections', | 
| 214 |  |  |  |  |  |  | ); | 
| 215 |  |  |  |  |  |  | } | 
| 216 |  |  |  |  |  |  | } | 
| 217 |  |  |  |  |  |  |  | 
| 218 |  |  |  |  |  |  | 1; | 
| 219 |  |  |  |  |  |  |  | 
| 220 |  |  |  |  |  |  | __END__ |