Re: [cgiapp] Re: Apache::DBI and CGI::Application with lots of modules.

2002-10-15 Thread Eric Frazier

Hi,

I am learning lots of new things, but still working on the problem itself.
It seems to be the case that even when I am running under ./httpd -X 
I have trouble getting the search  query to get stuck. If I do something
from the mysql monitor like set an order on hold directly with a query, then
the search results won't show the updated status of the order. Yet if from
the web interface, I set the order on hold, then reload, the correct status
is shown. If I restart apache, then the correct status shows. 

Thanks for your advice, I am thinking besides the general advice I have
received, Apache::DB will be my next most helpfull item.

Eric 

At 02:33 PM 10/14/02 -0400, William McKee wrote:
On 14 Oct 2002 at 9:12, Eric Frazier wrote:
 That I am not so sure of. I will do some more investigation. It seems like
 the only variables that could be causing this are the result set from the
 query and the scalar which holds the html template.  I feel like I know
 absolutly nothing now :(   I installed Apache::DB but don't yet know what
 to make of it. 

Hey Eric,

I empathize with you! Getting myself up-to-speed with mod_perl development 
has been a demanding task. At the moment, my apps have stabilized but I'm 
sure to hit another hurdle down the road.

As for Apache::DB, read the mod_perl guide at perl.apache.org. The 
debugger is a pain to learn but has helped me to solve several problems. 
There is good documentation on using the debugger in the camel book as 
well. One trick I learned was to let the script run through once using the 
'c' command. That will load all the scripts and modules into memory which 
will let you set breaks in your code without having to watch every line go 
by.

Also, I noticed some folks pointing out some global variables. If you're 
having troubles tracking these down in your script, you can see all the 
variables your script has instantiated by using perl-status and looking at 
the Loaded Modules. Find your CGI::App module in the list and click it to 
get a detailed list of the arrays, functions, hashes, etc. that it loads.

Good luck,
William

-- 
 Lead Developer
 Knowmad Services Inc. || Internet Applications  Database Integration
 http://www.knowmad.com
 


(250) 655 - 9513 (PST Time Zone)

Inquiry is fatal to certainty. -- Will Durant 







Re: Apache::DBI and CGI::Application with lots of modules.

2002-10-15 Thread Eric Frazier

Hi,

I had to read that over a few times to get it. And now I see that I do
indeed have that situation, there are a number of times when I call
my $holdstatus = new Holds(); from within a module that also has a new
method. What I don't understand is how does my code work at all? 


Thanks,


Eric 

At 07:13 PM 10/14/02 +0200, Rafiq Ismail wrote:
On Mon, 14 Oct 2002, Eric Frazier wrote:
 That looks like voodoo code copied from a man page.  If you call this as
 Holds-new(), you don't need that junk about ref.  (And most people
 recommend against the new Holds syntax.)

 I wanted the DBH to be global since just about every sub in Holds does a
 query of some sort. I guess it doesn't matter either way if I do the connect
 in the new() vs  up top outside of a sub.

Boredom break:

As for your dbh, stick it whereever its scope applies, however I don't
like declaring globals, so I've found that if I make the dbh accessible
via an object, usually together with Apache::DBI in the background, I can
often do clean up stuff, such as closing the handle (incase Apache::DBI
isn't in place with a particular invokation of the package), last system
logging updates/inserts, or whatever the job requires in a DESTROY method.

 What is the problem with the my $holdcheck = new Holds() type of syntax?
 I never read anything about that either way.
It's in the book which I think should be called, 'the guy in the silly hat
book,' ie. Damien's OO book, pretty much saying that,

The indirect object syntax does, however, suffer from the same type of
ambiguity problems that sometime befuddles print 

   my $cd3 = new get_classname() (@data) #Compilation Error

...

   parapharased type=badly
   Assuming you have $cd=MyPackage and:
   get_name $cd;

   This is usually equivalent to:
   $cd-get_name;

   However, let's say that you have a method in the invoking script
named 'get_name', then:

   get_name $cd;

   Gets interpreted as:

   get_name(MyPackage)

   Which is not what you're after.
   /paraphrase
 - from the guy in the silly hat book

-- 
Senior Programmer
Bookings.nl
--
Me::[EMAIL PROTECTED]||www.dreamthought.com
Budget hosting on my 10Mbit/backbone::[EMAIL PROTECTED]



(250) 655 - 9513 (PST Time Zone)

Inquiry is fatal to certainty. -- Will Durant 







Re: [cgiapp] Re: Apache::DBI and CGI::Application with lots of modules.

2002-10-15 Thread William McKee

On 15 Oct 2002 at 7:12, Eric Frazier wrote:
 I am learning lots of new things, but still working on the problem itself.
 It seems to be the case that even when I am running under ./httpd -X I have
 trouble getting the search  query to get stuck. If I do something from the
 mysql monitor like set an order on hold directly with a query, then the
 search results won't show the updated status of the order. Yet if from the
 web interface, I set the order on hold, then reload, the correct status is
 shown. If I restart apache, then the correct status shows. 

That sounds like trouble. The only problem I've had running httpd -X is 
when I compiled mod_ssl into my server. Apparently, it doesn't like to run 
in single processor mode (although I haven't confirmed this). Otherwise, 
the single processor mode should work just like multi-processor. I'd start 
looking into the code that checks that status.

Good luck,
William

-- 
 Lead Developer
 Knowmad Services Inc. || Internet Applications  Database Integration
 http://www.knowmad.com
 




Re: Apache::DBI and CGI::Application with lots of modules.

2002-10-14 Thread Perrin Harkins

Eric Frazier wrote:
 Here is the kind of thing that is driving me nuts. Please see: 
 http://perl.apache.org/docs/general/perl_reference/perl_reference.html#Remed
 ies_for_Inner_Subroutines
 
 If what this says is true, then either I don't have a closure type problem,
 or else what is says isn't true.

That documentation refers to one particular problem involving nested 
subs.  You don't need to have nested subs to have closures, and closures 
may not even be the problem.

You need to do some debugging.  Narrow things down by verifying your 
assumptions one by one.  Is CGI.pm really giving you the values you 
expect?  (Some people have experienced issues with params not being 
reset when using CGI.pm in certain ways.)  Is your SQL query being built 
correctly each time?  Is the data that you're passing to the template 
correct?  Throw in some warn statements.  Run it in the debugger if you 
need to.

- Perrin




Re: Apache::DBI and CGI::Application with lots of modules.

2002-10-14 Thread Eric Frazier

At 11:58 AM 10/14/02 -0400, Perrin Harkins wrote:
Eric Frazier wrote:
 Here is the kind of thing that is driving me nuts. Please see: 
 http://perl.apache.org/docs/general/perl_reference/perl_reference.html#Remed
 ies_for_Inner_Subroutines
 
 If what this says is true, then either I don't have a closure type problem,
 or else what is says isn't true.

That documentation refers to one particular problem involving nested 
subs.  You don't need to have nested subs to have closures, and closures 
may not even be the problem.

You need to do some debugging.  Narrow things down by verifying your 
assumptions one by one.  Is CGI.pm really giving you the values you 
expect?  (Some people have experienced issues with params not being 
reset when using CGI.pm in certain ways.)  Is your SQL query being built 
correctly each time?

I have checked the above, and I have lots of warns spaced around so I can
watch things in the error log. 

  Is the data that you're passing to the template 
correct?

That I am not so sure of. I will do some more investigation. It seems like
the only variables that could be causing this are the result set from the
query and the scalar which holds the html template.  I feel like I know
absolutly nothing now :(   I installed Apache::DB but don't yet know what to
make of it. 


Thanks again,

Eric 

  Throw in some warn statements.  Run it in the debugger if you 
need to.

- Perrin


(250) 655 - 9513 (PST Time Zone)

Inquiry is fatal to certainty. -- Will Durant 







Re: Apache::DBI and CGI::Application with lots of modules.

2002-10-14 Thread Eric Frazier

Perrin,

I am starting to feel guilty about bugging you so much, but you are the only
person to have responded, and I watch the list enough to value your advice
quite a bit. 

sub new { 
my $invocant = shift;
my $class = ref($invocant) || $invocant;


That looks like voodoo code copied from a man page.  If you call this as 
Holds-new(), you don't need that junk about ref.  (And most people 
recommend against the new Holds syntax.)

my $self  = { _ };
bless ($self, $class);
$dbh = db_connect();


You don't seem to need this.  You aren't using the database handle for 
anything in this sub and you aren't gaining anything by calling it here.


I wanted the DBH to be global since just about every sub in Holds does a
query of some sort. I guess it doesn't matter either way if I do the connect
in the new() vs  up top outside of a sub. 

What is the problem with the my $holdcheck = new Holds() type of syntax?
I never read anything about that either way. 


sub GetProcessed {

my $self = shift;

 This has a bug, somtimes the cached query doesn't stick around.


If you lose your database connection, Apache::DBI will reconnect.  Any 
prepared queries will be lost.  You *must* prepare every time, but see 
below...

sub db_connect {

require DBI;


You don't need that.  You should have already loaded it in startup.pl.

my $dbname = 'CS';
my ($dbuser, $dbpasswd) = ('myuser', 'mypass');


Probably should be in a config file, rather than buried in here.

my $dbh = DBI-connect(DBI:mysql:$dbname, $dbuser, $dbpasswd)
   or die can't connect: $DBI::errstr\n;
   
   # we need these waiting for queries, so we are going to prepare them
ahead of
 time, and yes
   # horror of horror they will be global. Sorry Mom I tried :( 
   $processed_hnd = $dbh-prepare_cached(select ord_tpak_processed from
orders
where ord_num=?) or confess(can't get tpak processed);
   $status_hnd = $dbh-prepare_cached(select is_hold_set,holdstate from
holds where ord_num=?) or confess(can't get hold status);
   #DBI-trace(2,/usr/local/apache/htdocs/out.log);
   return $dbh;


Don't put those in globals.  The prepare_cached call already stores them 
for the life of your database connection.  Apache::DBI will keep that 
connection alive (in a global hash) as long as it can and reconnect if 
the connection is lost.  If the connection does get lost, the statement 
handles in these globals will stop working.  You do recreate them every 
time since you call this sub every time, but you could lose the 
connection between the time this sub is called and the time you use 
these handles.


I did this, I was a little scared about calling $dbh-finish() but I did
what you said, and yes life is good I don't notice a speed difference. 

4. I know the way I have done these db connects is sloppy. But I can't seem
to find a better way. Could I make one db_connect sub,and inherite it all
though my modules? 


Make one sub that returns a database handle and use it from everywhere. 
 Doesn't need to be inherited, you can just stick it in a module that 
all the other modules call.

I have no idea why I put off doing that for so long. But that is done now as
well. 



Hope some of that was helpful,
Perrin


(250) 655 - 9513 (PST Time Zone)

Inquiry is fatal to certainty. -- Will Durant 







Re: Apache::DBI and CGI::Application with lots of modules.

2002-10-14 Thread Perrin Harkins

Eric Frazier wrote:
 I wanted the DBH to be global since just about every sub in Holds does a
 query of some sort.

Three options:
1) Pass it to every sub
2) Make a utility sub that returns a dbh and call it from each sub. 
(Sounds like you already made one of these.)
3) Stuff it in $r-pnotes(), where it will get cleaned up after each 
request.

 What is the problem with the my $holdcheck = new Holds() type of syntax?
 I never read anything about that either way.

It's been discussed quite a bit in various places.  It is now documented 
in the perlobj man page: 
http://perldoc.com/perl5.8.0/pod/perlobj.html#Indirect-Object-Syntax

- Perrin




Re: Apache::DBI and CGI::Application with lots of modules.

2002-10-14 Thread Rafiq Ismail

On Mon, 14 Oct 2002, Eric Frazier wrote:
 That looks like voodoo code copied from a man page.  If you call this as
 Holds-new(), you don't need that junk about ref.  (And most people
 recommend against the new Holds syntax.)

 I wanted the DBH to be global since just about every sub in Holds does a
 query of some sort. I guess it doesn't matter either way if I do the connect
 in the new() vs  up top outside of a sub.

Boredom break:

As for your dbh, stick it whereever its scope applies, however I don't
like declaring globals, so I've found that if I make the dbh accessible
via an object, usually together with Apache::DBI in the background, I can
often do clean up stuff, such as closing the handle (incase Apache::DBI
isn't in place with a particular invokation of the package), last system
logging updates/inserts, or whatever the job requires in a DESTROY method.

 What is the problem with the my $holdcheck = new Holds() type of syntax?
 I never read anything about that either way.
It's in the book which I think should be called, 'the guy in the silly hat
book,' ie. Damien's OO book, pretty much saying that,

The indirect object syntax does, however, suffer from the same type of
ambiguity problems that sometime befuddles print 

my $cd3 = new get_classname() (@data) #Compilation Error

...

parapharased type=badly
Assuming you have $cd=MyPackage and:
get_name $cd;

This is usually equivalent to:
$cd-get_name;

However, let's say that you have a method in the invoking script
named 'get_name', then:

get_name $cd;

Gets interpreted as:

get_name(MyPackage)

Which is not what you're after.
/paraphrase
 - from the guy in the silly hat book

-- 
Senior Programmer
Bookings.nl
--
Me::[EMAIL PROTECTED]||www.dreamthought.com
Budget hosting on my 10Mbit/backbone::[EMAIL PROTECTED]





Re: Apache::DBI and CGI::Application with lots of modules. (fwd)

2002-10-14 Thread Rafiq Ismail


On Mon, 14 Oct 2002, Eric Frazier wrote:
 That looks like voodoo code copied from a man page.  If you call this as
 Holds-new(), you don't need that junk about ref.  (And most people
 recommend against the new Holds syntax.)

 I wanted the DBH to be global since just about every sub in Holds does a
 query of some sort. I guess it doesn't matter either way if I do the connect
 in the new() vs  up top outside of a sub.

Boredom break:

As for your dbh, stick it whereever its scope applies, however I don't
like declaring globals, so I've found that if I make the dbh accessible
via an object, usually together with Apache::DBI in the background, I can
often do clean up stuff, such as closing the handle (incase Apache::DBI
isn't in place with a particular invokation of the package), last system
logging updates/inserts, or whatever the job requires in a DESTROY method.

 What is the problem with the my $holdcheck = new Holds() type of syntax?
 I never read anything about that either way.
It's in the book which I think should be called, 'the guy in the silly hat
book,' ie. Damien's OO book, pretty much saying that,

The indirect object syntax does, however, suffer from the same type of
ambiguity problems that sometime befuddles print 

my $cd3 = new get_classname() (@data) #Compilation Error

...

parapharased type=badly
Assuming you have $cd=MyPackage and:
get_name $cd;

This is usually equivalent to:
$cd-get_name;

However, let's say that you have a method in the invoking script
named 'get_name', then:

get_name $cd;

Gets interpreted as:

get_name(MyPackage)

Which is not what you're after.
/paraphrase
 - from the guy in the silly hat book

-- 
Senior Programmer
Bookings.nl
--
Me::[EMAIL PROTECTED]||www.dreamthought.com
Budget hosting on my 10Mbit/backbone::[EMAIL PROTECTED]






Re: [cgiapp] Re: Apache::DBI and CGI::Application with lots of modules.

2002-10-14 Thread William McKee

On 14 Oct 2002 at 9:12, Eric Frazier wrote:
 That I am not so sure of. I will do some more investigation. It seems like
 the only variables that could be causing this are the result set from the
 query and the scalar which holds the html template.  I feel like I know
 absolutly nothing now :(   I installed Apache::DB but don't yet know what
 to make of it. 

Hey Eric,

I empathize with you! Getting myself up-to-speed with mod_perl development 
has been a demanding task. At the moment, my apps have stabilized but I'm 
sure to hit another hurdle down the road.

As for Apache::DB, read the mod_perl guide at perl.apache.org. The 
debugger is a pain to learn but has helped me to solve several problems. 
There is good documentation on using the debugger in the camel book as 
well. One trick I learned was to let the script run through once using the 
'c' command. That will load all the scripts and modules into memory which 
will let you set breaks in your code without having to watch every line go 
by.

Also, I noticed some folks pointing out some global variables. If you're 
having troubles tracking these down in your script, you can see all the 
variables your script has instantiated by using perl-status and looking at 
the Loaded Modules. Find your CGI::App module in the list and click it to 
get a detailed list of the arrays, functions, hashes, etc. that it loads.

Good luck,
William

-- 
 Lead Developer
 Knowmad Services Inc. || Internet Applications  Database Integration
 http://www.knowmad.com
 




RE: Apache::DBI and CGI::Application with lots of modules.

2002-10-14 Thread Jesse Erlbaum

Hey Eric --

 I wanted the DBH to be global since just about every sub in Holds does a
 query of some sort. I guess it doesn't matter either way if I do
 the connect
 in the new() vs  up top outside of a sub.

CGI::Application has a facility which is intended to solve exactly this type
of problem -- the param() method.  The param() method allows you to stash a
property (such as a $dbh) in your CGI::Application-based object which can be
retrieved anywhere.  I typically connect to the database in my setup()
method and stash my $dbh for use later:

  package My::WebApp;
  use strict;
  use base qw/CGI::Application/;

  sub setup {
my $self = shift;

$self-start_mode('start');
$self-run_modes(
  'start' = 'run_mode_method'
);

my $dbh = $self-connect_to_database();
$self-param('DBH', $dbh);
  }

  sub run_mode_method {
my $self = shift;

# Get database handle
my $dbh = $self-param('DBH');

my $output = '';

# ...etc

return $output;
  }


Furthermore, in order to disconnect, the teardown() method may be used:

  sub teardown {
my $self = shift;

# Get database handle
my $dbh = $self-param('DBH');

$dbh-disconnect();
  }


Refer to the CGI::Application POD for details on teardown() and param().


Regarding connecting to the database, I also urge you to encapsulate your
connection code.  On my projects I always get things started by creating a
Perl module which I use whenever I need a database connection:

  package My::DatabaseCreds;
  use DBI;
  sub new_dbh {
my $dbh = DBI-connect()
die (Can't connect: .$DBI::errstr) unless ($dbh);
return $dbh;
  }

(This isn't exactly the code I use -- I actually have a module which I
sub-class, but you get the idea.)

The benefit of creating a module is that (1) all your Perl code can use this
module so that (2) should it ever have to change you can change it in one
place.


 What is the problem with the my $holdcheck = new Holds() type of syntax?
 I never read anything about that either way.

My guess is that Perrin was referring to your use of the indirect
notation, as opposed to the arrow notation:

Indirect:

  my $holdcheck = new Holds()

Arrow:

  my $holdcheck = Holds-new()


Many people (myself included) prefer the arrow notation.  In general, the
arrow notation tends to be less ambiguous, particularly when it comes to
combining method calls with arguments.


HTH,

-Jesse-


--

  Jesse Erlbaum
  The Erlbaum Group
  [EMAIL PROTECTED]
  Phone: 212-684-6161
  Fax: 212-684-6226





Re: Apache::DBI and CGI::Application with lots of modules.

2002-10-13 Thread Eric Frazier

Hi,

Here is the kind of thing that is driving me nuts. Please see: 
http://perl.apache.org/docs/general/perl_reference/perl_reference.html#Remed
ies_for_Inner_Subroutines

If what this says is true, then either I don't have a closure type problem,
or else what is says isn't true. It says that 
if I have this situation, I will get a warning. I am not getting any
warnings, but I am getting this behaviour with my search queries getting stuck


The only thing I do is again, copied from the perltoot 


package Searches;

use strict;
use Carp;
use vars qw($dbh);
use gentimeid; # generate time id based
use Calc_Price; # get totals  
use warnings;
# use DBIx::XHTML_Table;  # maybe later
use QueryPrint;

#use Data::Dumper;



# These searches are restricted to user level searches, there will be a
admin level search for 
# managment reports 

$dbh = db_connect();


# requires a $q query object to be init.



sub new {
my $self  = {};
my $proto = shift;
my $class = ref($proto) || $proto;
$self-{queryobject}   = undef;
$self-{isDomestic} = undef;
$self-{isInternational} = undef;
$self-{isShippingSame} = undef;
$self-{CustIsInserted} = undef;
$self-{OrderIsInserted} = undef;
$self-{CustNum} = undef;
$self-{OrderNum} = undef;
bless ($self, $class);
return $self;
}


sub queryobject {
  
  my $self = shift;
  if (_) { $self-{queryobject} = shift }
  return $self-{queryobject};
}


 Other stuff not used yet



sub LookupOrder {

my $self = shift;
my $q = $self-{queryobject};
my $output = '';
my $hasparameter = 0;



... Build a query from CGI.pm vars passed in though queryobject





... 


$order_name_qu .=  ORDER BY $orderby ; # the query string is here


if ($hasparameter == 1) {  # if something was filled in the search form

my $sth = $dbh-prepare($order_name_qu) or confess(Main search
failed $order_name_qu);
$sth-execute() or confess(Main search failed $order_name_qu);  

my $headers = $sth-{'NAME'};   

my rows= $sth-fetchall_arrayref();

my $resulthtml = new QueryPrint(ResultSet = rows,
Action = 'customer',
ColumnList = $headers);

my $html = $resulthtml-SetAction();  # sets a template type in the
QueryPrint module
$output = $resulthtml-QueryPrint();  
$sth-finish();
#warn QUERY - $order_name_qu;
undef rows;
undef $resulthtml;
undef $order_name_qu;
return $output;

} else {


return no query to do;

}


Then this is all called from my CGI::Application module

sub customer_display{

my $self = shift;
my $q = $self-query();

my $customersearch = new Searches();
$customersearch-queryobject($q); # set the query

my $header = parse_header($self);
return $header . $customersearch-LookupCustName(); 

}


So going nuts now, where is the problem?  My QueryPrint module is pretty
much the same, so if this is ok, it should be as well. 


Thanks,

Eric 



Are you using any modules that have subs with sub ref prototypes, like 
Error.pm?  That can do it.

All I have read says that because I am using oop
modules and use strict along with use vars that should not happen.


It's actually really easy to create closures.  Here is a closure:

my $holdtype = $q-param('holdstate');
display_holdtype();

sub display_holdtype {
print holdtype: $holdtype in process $$\n;
}

This will always print whatever the value was the first time, no matter 
what you change it to later.  (The first time for that process, that 
is.)  Watch out for things like that.  You should always pass params 
explicitly.

4. I know the way I have done these db connects is sloppy. But I can't seem
to find a better way. Could I make one db_connect sub,and inherite it all
though my modules? 


Make one sub that returns a database handle and use it from everywhere. 
 Doesn't need to be inherited, you can just stick it in a module that 
all the other modules call.

Hope some of that was helpful,
Perrin


(250) 655 - 9513 (PST Time Zone)

Inquiry is fatal to certainty. -- Will Durant 







Re: Apache::DBI and CGI::Application with lots of modules.

2002-10-12 Thread Perrin Harkins

I'm just going to point out a few problems.  These are not all related 
to your questions.

package Holds;


The case of Holds doesn't match the example sub you posted above.  I'm 
assuming that was a typo.

use strict;
use Carp;
use warnings;
use QueryPrint;
use vars qw($dbh $processed_hnd $status_hnd);
use gentimeid; # generate time id based


sub new { 
my $invocant = shift;
my $class = ref($invocant) || $invocant;


That looks like voodoo code copied from a man page.  If you call this as 
Holds-new(), you don't need that junk about ref.  (And most people 
recommend against the new Holds syntax.)

my $self  = { _ };
bless ($self, $class);
$dbh = db_connect();


You don't seem to need this.  You aren't using the database handle for 
anything in this sub and you aren't gaining anything by calling it here.

sub GetProcessed {

my $self = shift;

 This has a bug, somtimes the cached query doesn't stick around.


If you lose your database connection, Apache::DBI will reconnect.  Any 
prepared queries will be lost.  You *must* prepare every time, but see 
below...

sub db_connect {

require DBI;


You don't need that.  You should have already loaded it in startup.pl.

my $dbname = 'CS';
my ($dbuser, $dbpasswd) = ('myuser', 'mypass');


Probably should be in a config file, rather than buried in here.

my $dbh = DBI-connect(DBI:mysql:$dbname, $dbuser, $dbpasswd)
   or die can't connect: $DBI::errstr\n;
   
   # we need these waiting for queries, so we are going to prepare them ahead of
 time, and yes
   # horror of horror they will be global. Sorry Mom I tried :( 
   $processed_hnd = $dbh-prepare_cached(select ord_tpak_processed from orders
where ord_num=?) or confess(can't get tpak processed);
   $status_hnd = $dbh-prepare_cached(select is_hold_set,holdstate from
holds where ord_num=?) or confess(can't get hold status);
   #DBI-trace(2,/usr/local/apache/htdocs/out.log);
   return $dbh;


Don't put those in globals.  The prepare_cached call already stores them 
for the life of your database connection.  Apache::DBI will keep that 
connection alive (in a global hash) as long as it can and reconnect if 
the connection is lost.  If the connection does get lost, the statement 
handles in these globals will stop working.  You do recreate them every 
time since you call this sub every time, but you could lose the 
connection between the time this sub is called and the time you use 
these handles.

 2. Every once in a while I get an out of memory error.


You can control process growth over time in a number of ways.  They are 
documented in the mod_perl guide.

3. My main search result page is getting cached, the closure type of
problem.


Are you using any modules that have subs with sub ref prototypes, like 
Error.pm?  That can do it.

All I have read says that because I am using oop
modules and use strict along with use vars that should not happen.


It's actually really easy to create closures.  Here is a closure:

my $holdtype = $q-param('holdstate');
display_holdtype();

sub display_holdtype {
print holdtype: $holdtype in process $$\n;
}

This will always print whatever the value was the first time, no matter 
what you change it to later.  (The first time for that process, that 
is.)  Watch out for things like that.  You should always pass params 
explicitly.

4. I know the way I have done these db connects is sloppy. But I can't seem
to find a better way. Could I make one db_connect sub,and inherite it all
though my modules? 


Make one sub that returns a database handle and use it from everywhere. 
 Doesn't need to be inherited, you can just stick it in a module that 
all the other modules call.

Hope some of that was helpful,
Perrin




Apache::DBI and CGI::Application with lots of modules.

2002-10-12 Thread Eric Frazier

Hi,

I am glad to see the list traffic has been picking up lately. It makes me
have higher hope about posting this. 

First some background info.

I have a fairly large CGI::Application module about 30 run modes that pretty
much follows the example mailform module. I am also using HTML::Template
within the module. I am running on, FreeBSD 4.6 1G mem mysql 4.02 with
Innodb tables.

A typical run mode looks like this.

sub doug_holds {

my $self = shift;
my $q = $self-query();
my $holdtype = $q-param('holdstate');

my $holdsearch = new holds();
$holdsearch-HoldType($holdtype); # set hold type for the query

my $header = parse_header($self);
return $header . $holdsearch-getAllHolds();


}


Of course many of other subs look like this 

sub customer_name_search {

my $self = shift;

my $index_page = $self-param('CUSTOMER_NAME_SEARCH_TMPL');

my $output='';

my $tmpl_obj = $self-load_tmpl($index_page, 
 die_on_bad_params = 0,
 cache = 1,
 stack_debug =$debug
) or confess(could not create template);
  $tmpl_obj-param(base = $self-param('base'));
  $tmpl_obj-param(RUNMODE = 'customer_display');  
  $tmpl_obj-param(USER  =  $selected_user);
  my $header = parse_header($self);
  
  
  return $header . $tmpl_obj-output;
 
}

But that isn't relavent to my problem. 


In the first sub, I create a new holds instance. Each of these modules like
holds work like this 

package Holds;

use strict;
use Carp;
use warnings;
use QueryPrint;
use vars qw($dbh $processed_hnd $status_hnd);
use gentimeid; # generate time id based


sub new { 
my $invocant = shift;
my $class = ref($invocant) || $invocant;
my $self  = { _ };
bless ($self, $class);
$dbh = db_connect(); 
#die $self-{OrdNum}, $self-{HoldReason};
return $self;
}


sub OrdNum {
  
  my $self = shift;
  if (_) { $self-{OrdNum} = shift }
  return $self-{OrdNum};
}

sub GetProcessed {

my $self = shift;

 This has a bug, somtimes the cached query doesn't stick around.

$processed_hnd-execute($self-{OrdNum}) or confess (can't execute
processed);

my ($isprocessed) = $processed_hnd-fetchrow_array;
$processed_hnd-finish();

if ($isprocessed){  
$self-{ProcessStatus} = 1; 
return #4EEE94;
}else{
$self-{ProcessStatus} = 0; 
return FF;
}

}
   

..



sub db_connect {

require DBI;

my $dbname = 'CS';
my ($dbuser, $dbpasswd) = ('myuser', 'mypass');

my $dbh = DBI-connect(DBI:mysql:$dbname, $dbuser, $dbpasswd)
   or die can't connect: $DBI::errstr\n;
   
   # we need these waiting for queries, so we are going to prepare them ahead of
 time, and yes
   # horror of horror they will be global. Sorry Mom I tried :( 
   $processed_hnd = $dbh-prepare_cached(select ord_tpak_processed from orders
where ord_num=?) or confess(can't get tpak processed);
   $status_hnd = $dbh-prepare_cached(select is_hold_set,holdstate from
holds where ord_num=?) or confess(can't get hold status);
   #DBI-trace(2,/usr/local/apache/htdocs/out.log);
   return $dbh; 

}


Most of the modules just have simple subs called db_connect that don't have
prepared statments sitting like this. I did this because I have to check the
status of a LOT of rows and return the display fast. This seemed to work
well at the time. It was defiantly faster that preparing the statement over
and over. 



I am running under mod perl 1.x Apache 1.3x, and loading my CGI::App module
and other modules from a start.pl
I am using Apache::DBI and connect_on_init. So I have these problems, they
all seem to be related, but how?? 

1. Connections are getting lost. I get errors in the log about fetch without
an execute which indicate this. Either the user sees an internal server
error, or else I believe DBI will try to reconnect and the query will then
succeed. But that slows things down when it happens. All I have to do to
these kinds of errors is reload a page very quickly. click, click, click fast.. 

2. Every once in a while I get an out of memory error. 

3. My main search result page is getting cached, the closure type of
problem. ***Sometimes*** All I have read says that because I am using oop
modules and use strict along with use vars that should not happen. I have
not gotten any this variable will not stay shared types of warnings.
for this I have tried specificly undefing the display scalars, the result
sets etc. I just can't seem to find out what var is causing the problem, and
I can't find any examples of closures. 
4. I know the way I have done these db connects is sloppy. But I can't seem
to find a better way. Could I make one db_connect sub,and 

Re: Apache::DBI and CGI::Application with lots of modules.

2002-10-12 Thread Eric Frazier

Perrin,

I am going to read over this closely, thanks for all of the advice! 

What frustrats me about the search getting cached/closure thing is that I
just don't have any global variables that have anything to do at all with
the search results. I have read over and over examples with closures,
recognize the example you included as one, but I still can't seem to find it
in my own code. I guess I need to take a fresh look again. I did -X httpd
and it is happening every time. I think part of what is getting me is I have
used mod_perl for smaller things, but now it is a pretty big system. I don't
seem to  be able to get away with as much :) Also, I am really trying to
bring my code level up a notch, but as you pointed out, there are some
things I am doing that  I don't really understand well enough yet. 

Thanks,

Eric 

http://www.kwinternet.com/eric
(250) 655 - 9513 (PST Time Zone)

Inquiry is fatal to certainty. -- Will Durant