re-blessing a blessed reference

Discussion in 'Perl Misc' started by Jon, Jul 25, 2005.

  1. Jon

    Jon Guest

    Hiya,

    I'm trying to tidy up my code a bit by creating an 'SQL' package. At the
    moment to interface with my db I'm doing something like..

    sub checkpass
    {
    my ($username, $password) = @_;

    my $dbh = DBI->connect("DBI:mysql:database", "username", "password")
    unless ($dbh) { die($DBI::errstr); }

    my $sql = "SELECT id FROM users WHERE username=? AND password=?";
    my $sth = $dbh->prepare($sql);
    $sth->execute( $username, $password) || die($sth->errstr());

    my $rows = $sth->rows;

    $sth->finish();
    $dbh->disconnect();

    return $rows;
    }

    I'd like to be able to create a package so I only need to connect the
    database once and I can disconnect when the script has finished. eg:

    my $dbh = SQL->new();

    if ($dbh->checkpass()) { #authed } else { #notauthed }

    I've tried the code below but get it dies with "Can't locate object method
    "prepare" via package "SQL" at /SQL.pm line 19. I'm pretty new to OO so I
    can't figure out what I'm doing wrong. I understand that its trying to call
    on SQL::prepare but I don't know how I can make it not do that. I have a
    feeling its got something to do with me re-blessing $dbh which has already
    been blessed but would like someone with more experience to confirm that if
    possible. If I'm wrong could someone please point me in the right
    direction? Thanks for your time.

    =test.pl=
    #!/usr/bin/perl

    use lib './';
    use SQL;
    use strict;

    my $dbh = SQL->new();
    if ($dbh->checkpass( "username", "password" ))
    {
    print "authed";
    }
    else
    {
    print "not authed";
    }

    =SQL.pm=
    Package SQL;

    use DBI;
    use strict;

    sub new
    {
    my $dbh = DBI->connect("DBI:mysql:database", "username", "password")
    unless ($dbh) { die($DBI::errstr); }

    bless $dbh, 'SQL';
    return $dbh;
    }

    sub checkpass
    {
    my ($dbh, $username, $password);

    my $sql = "SELECT id FROM users WHERE username=? AND PASSWORD=?";
    my $sth = $dbh->prepare($sql);
    $sth->execute( $username, $password ) || die($sth->errstr));
    my $rows = $sth->rows;

    return $rows;
    }

    1;
    --
    Jon
     
    Jon, Jul 25, 2005
    #1
    1. Advertising

  2. Also sprach Jon:

    > I'm trying to tidy up my code a bit by creating an 'SQL' package. At the
    > moment to interface with my db I'm doing something like..
    >
    > sub checkpass
    > {
    > my ($username, $password) = @_;
    >
    > my $dbh = DBI->connect("DBI:mysql:database", "username", "password")
    > unless ($dbh) { die($DBI::errstr); }
    >
    > my $sql = "SELECT id FROM users WHERE username=? AND password=?";
    > my $sth = $dbh->prepare($sql);
    > $sth->execute( $username, $password) || die($sth->errstr());
    >
    > my $rows = $sth->rows;
    >
    > $sth->finish();
    > $dbh->disconnect();
    >
    > return $rows;
    > }
    >
    > I'd like to be able to create a package so I only need to connect the
    > database once and I can disconnect when the script has finished. eg:
    >
    > my $dbh = SQL->new();
    >
    > if ($dbh->checkpass()) { #authed } else { #notauthed }
    >
    > I've tried the code below but get it dies with "Can't locate object method
    > "prepare" via package "SQL" at /SQL.pm line 19. I'm pretty new to OO so I
    > can't figure out what I'm doing wrong. I understand that its trying to call
    > on SQL::prepare but I don't know how I can make it not do that. I have a
    > feeling its got something to do with me re-blessing $dbh which has already
    > been blessed but would like someone with more experience to confirm that if
    > possible. If I'm wrong could someone please point me in the right
    > direction? Thanks for your time.


    After re-blessing, the thing returned by DBI->connect is no longer an
    instance of DBI::db. That's ok as long as your SQL package inherits
    from DBI::db. See "Subclassing the DBI" in DBI's documentation.

    So make SQL a subclass of 'DBI::db':

    >=test.pl=
    > #!/usr/bin/perl
    >
    > use lib './';
    > use SQL;
    > use strict;
    >
    > my $dbh = SQL->new();
    > if ($dbh->checkpass( "username", "password" ))
    > {
    > print "authed";
    > }
    > else
    > {
    > print "not authed";
    > }
    >
    >=SQL.pm=
    > Package SQL;
    >
    > use DBI;
    > use strict;

    use Carp; # better use Carp::croak() instead of die()

    @SQL::ISA = qw/DBI::db/; # make SQL a subclass of DBI::db

    > sub new
    > {
    > my $dbh = DBI->connect("DBI:mysql:database", "username", "password")


    Don't retype code: This statement is missing a semicolon.

    > unless ($dbh) { die($DBI::errstr); }
    >
    > bless $dbh, 'SQL';
    > return $dbh;
    > }


    The way 'new' is written forbids further subclassing of SQL. You might
    not want to do that anyway, but it can't hurt to do it properly:

    sub new {
    my $class = shift;
    my $dbh = DBI->connect("DBI:mysql:database", "username", "password")
    or croak $DBI::errstr;
    bless $dbh => $class;
    }

    > sub checkpass
    > {
    > my ($dbh, $username, $password);


    Don't retype code: This statement is missing the assignment of @_.

    > my $sql = "SELECT id FROM users WHERE username=? AND PASSWORD=?";
    > my $sth = $dbh->prepare($sql);
    > $sth->execute( $username, $password ) || die($sth->errstr));
    > my $rows = $sth->rows;
    >
    > return $rows;
    > }
    >
    > 1;


    Tassilo
    --
    use bigint;
    $n=71423350343770280161397026330337371139054411854220053437565440;
    $m=-8,;;$_=$n&(0xff)<<$m,,$_>>=$m,,print+chr,,while(($m+=8)<=200);
     
    Tassilo v. Parseval, Jul 25, 2005
    #2
    1. Advertising

  3. Jon

    Jon Guest

    Tassilo v. Parseval wrote:

    > Also sprach Jon:

    [ snip ]
    > After re-blessing, the thing returned by DBI->connect is no longer an
    > instance of DBI::db. That's ok as long as your SQL package inherits
    > from DBI::db. See "Subclassing the DBI" in DBI's documentation.
    >
    > So make SQL a subclass of 'DBI::db':

    [ snip ]
    >> sub new
    >> {
    >> my $dbh = DBI->connect("DBI:mysql:database", "username",
    >> "password")

    >
    > Don't retype code: This statement is missing a semicolon.
    >
    >> unless ($dbh) { die($DBI::errstr); }
    >>
    >> bless $dbh, 'SQL';
    >> return $dbh;
    >> }

    >
    > The way 'new' is written forbids further subclassing of SQL. You might
    > not want to do that anyway, but it can't hurt to do it properly:
    >
    > sub new {
    > my $class = shift;
    > my $dbh = DBI->connect("DBI:mysql:database", "username", "password")
    > or croak $DBI::errstr;
    > bless $dbh => $class;
    > }
    >


    Thanks for your suggestions Tasillo, I'll look into them. My apologies for
    retyping code, it seemed easier at the time but in hindsight probably
    wasn't.
    --
    Jon
     
    Jon, Jul 25, 2005
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Nick Marden
    Replies:
    0
    Views:
    1,082
    Nick Marden
    Jan 17, 2004
  2. Nick Marden
    Replies:
    1
    Views:
    150
    Ben Morrow
    Jan 20, 2004
  3. Vetle Roeim

    Threads and shared blessed references

    Vetle Roeim, Jun 9, 2004, in forum: Perl Misc
    Replies:
    0
    Views:
    177
    Vetle Roeim
    Jun 9, 2004
  4. sbk

    pulling apart a blessed hash

    sbk, Jan 26, 2005, in forum: Perl Misc
    Replies:
    3
    Views:
    119
    Gary E. Ansok
    Jan 26, 2005
  5. A. Farber
    Replies:
    9
    Views:
    137
Loading...

Share This Page