Re: Using a DBI connection in many places (in the code)
- From: Dodger <el.dodgero@xxxxxxxxx>
- Date: Tue, 5 Aug 2008 17:58:15 -0700 (PDT)
On Aug 4, 2:29 pm, Joe Linux <dvaldena...@xxxxxxxxx> wrote:
Thanks a lot, it works.
Corrected source is now :
test.pl
--------------------
#!/usr/bin/perl
use strict;
use DBI;
my $dbh = DBI->connect ( 'DBI:mysql:DB_NAME:SERVER_IP:SERVER_PORT',
'DB_USER', 'DB_PASSWORD',
{ RaiseError => 1, AutoCommit => 0 }
);
use myclass;
print "Hello, i'm the main program, connected via ".$dbh."\n";
my $OBJECT = "OBJECT_NAME";
my $object = new myclass();
$object->set_name($OBJECT);
print "Hello, i'm object, my name is : ".$object->get_name()."\n";
$object->set_dbh($dbh);
print "I'm connected to DB via : ".$object->get_dbh()."\n";
$object->validate();
$dbh->disconnect;
-------
myclass.pm
-------
package myclass;
use strict;
# non-exported package globals go here
use vars qw($dbh $name);
$dbh = '';
$name = 'default';
sub new {
bless ( { }, shift );
}
sub set_name {
shift;
$name = shift;
}
sub set_dbh {
shift;
$dbh = shift;
}
sub get_name {
return $name;
}
sub get_dbh {
return $dbh;
}
sub validate {
my $sth_select;
my @row;
$sth_select = $dbh->prepare(q{
SELECT OBJECT_ID FROM OBJECTS WHERE OBJECT_NAME=?
}) or die $dbh->errstr;
$sth_select->execute($name) or die $dbh->errstr;
if ($@){
print $@."\n";
exit;
}
@row = $sth_select->fetchrow_array;
if ($row[0] eq ''){
print "Object '$name' not found. Need update!!!\n";
exit;
}
else{
print "Object '$name' found, ID=$row[0]\n";
}
$sth_select->finish;
}
END {}
1;
-------
Hope this helps someone...
On 4 août, 19:09, xhos...@xxxxxxxxx wrote:
Joe Linux <dvaldena...@xxxxxxxxx> wrote:
And when i use strict.... it's even worse....
Global symbol "$sth_select" requires explicit package name at ./
test.pl line 26.
You are using $sth_select without declaring it. This is a pretty
standard error under "use strict", nothing to do with DBI.
Perfectly true, my friend. I found it was an copy-paste error. Sorry
about that.
$object->set_dbh(bless $dbh, DBI);
Why are doing this? DBI blesses the dbh into the class it *should*
be in. What do you hope to accomplish by reblessing it into some other,
inappropriate, class? This is why you get the error that it cannot locate
"prepare", because you told it to search the wrong package.
$object->set_dbh($dbh);
I did this.
myclass.pm :
-------------
package myclass;
use strict;
use DBI;
Since the other package is passing in a dbh handle, you probably don't
need to explicitly load DBI. The other package should have done it
already.
I suppress this use DBI;
sub set_name($$) {
I don't think defining prototypes for methods does much good.
I will blindly follow this advice.
Xho
--
I personally don't like having to tell my one object to fetch me a
variable for my other object if one is intrinsically needed by the
other. As in, I'd rather not ask Whatever for a DBH back explicitly,
and prefer to have one nice little compact method that gives me back a
DBH even if I didn't pass one in.
Have you considered doing things more like:
package Whatever;
use DBI;
sub new {
croak "Don't call a constructor from an object" if ref $_[0];
my $class = shift;
my $obj = {};
while (@_) {
my ($k, $v) = (shift, shift);
last unless defined $v;
$k =~ s/^\-//;
$obj->{$k} = $v;
}
return bless $obj, $class;
}
sub dbh {
my $self = shift;
return $self->{dbh} = shift if @_;
return $self->{dbh} || ($self->{dbh} = DBI->connect($self-
{db_dsn}, $self->{db_user}, $self->{db_pass}));}
That way you can either pass in a dbh object in the constructor like:
my $thingy = new Whatever(dbh => $dbh);
Or you can pass in the connection info like:
my $thingy = new Whatever(db_dsn => 'DBI:mysql:mydb', db_user => 'me',
db_pass => 'lovesexgod');
And in both cases you can simply call:
$thingy->dbh
As a database handle.
This lets you do things like:
my $query = <<"EOF";
SELECT *
FROM flarp
WHERE foo = ?
EOF
my $statement = $thingy->dbh->prepare($query) or barf($thingy->dbh-
errstr, 'prepare');
my $rows = $statement->execute($bar) or barf($statement->errstr,
'execute');
print "No results\n" and exit unless $rows+0;
print <<"EOF";
<table border="1">
<tr>
@{[map "<th>$_</th>", @NAME]}
</tr>
@{[getrows($statement)]}
</table>
EOF
sub getrows {
my $st = shift or return undef;
my @ob;
while (my $row = $st->fetchrow_hashref) {
push @ob, <<"EOF";
<tr>
@{[map "<td>$row->{$_}</td>", @NAME]}
</tr>
EOF
return wantarray ? @ob : "@{[@ob]}";
}
sub barf {
my $errmsg = shift;
my $errtype = shift || 'unknown';
print <<"EOF" and exit;
<div class="error">
<div class="error_message">$errtype error</div>
<div class="error_detail">$errmsg</div>
</div>
EOF
}
You could even add in a method that would let you specify something
like Whatever->new(db_config => '/some_directory/my_db_config.file
') and then if neither dbh nor db_user/db_password/db_dsn were
defined, it would go read the file thus defined to get your connection
info.
I dunno, just some ideas there that might make your stuff easier to
use later.
--
Sean 'Dodger' Cannon
.
- References:
- Using a DBI connection in many places (in the code)
- From: Joe Linux
- Re: Using a DBI connection in many places (in the code)
- From: Claudio Calvelli
- Re: Using a DBI connection in many places (in the code)
- From: Joe Linux
- Re: Using a DBI connection in many places (in the code)
- From: xhoster
- Re: Using a DBI connection in many places (in the code)
- From: Joe Linux
- Using a DBI connection in many places (in the code)
- Prev by Date: Re: XML::Simple XMLIn() and odd chars
- Next by Date: Re: XML::Simple XMLIn() and odd chars
- Previous by thread: Re: Using a DBI connection in many places (in the code)
- Next by thread: Question: How to use SAX::Machines to get back sub-document as XML
- Index(es):
Relevant Pages
|