Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 9 of 9
  1. #1
    New Coder
    Join Date
    Jan 2010
    Posts
    79
    Thanks
    1
    Thanked 0 Times in 0 Posts

    Can't call method "prepare" without a package or object reference

    I have the following code in the TCP server:
    while (my $from_who = accept(CLIENT_SOCK, TCP_SOCK)) {

    my $data = '';
    #my $previous = select CLIENT_SOCK;
    #$| = 1;
    #select $previous;

    my $data = <CLIENT_SOCK>;
    my @params = split('#', $data);
    @params = split('#', $data);
    my $dAccess = new DataAccess;
    $dbh = $dAccess->connection('dbname', 'root', 'mypassword') or die "Cannot connect to database: $dbh->errstr\n";
    my @info = $dAccess->get_info($dbh, $params[0], $params[1]) or die "Cannot lanch query: $!";
    my $rvalues = '';
    foreach (@info) {
    $rvalues = $rvalues.'#'.$_;
    }
    print $rvalues;
    print CLIENT_SOCK $rvalues;
    close CLIENT_SOCK or warn "close failed: $!\n";
    }

    close TCP_SOCK;
    DataAccess object is:
    package DataAccess;

    sub new {
    my $self = {};
    bless \$self, "DataAccess";
    }

    sub connection {
    my $class = shift;
    my ($db, $userdb, $pw) = @_;
    DBI->connect("DBI:mysql:$db",$userdb,$pw,{RaiseError => 1}) or die "Cannot connect to $db: $DBI::errstr\n" unless (defined $dbh);
    }

    sub get_info {
    my $class = shift;
    ($dbh, $email, $password) = @_;
    my $query = qq{SELECT Type, Profile, Email FROM clients WHERE Email=? and Password=?;};
    my $sth = $dbh->prepare($query) or die "$dbh->errstr\n"; #LINE 96
    my $rc = $sth->execute($email, $password) or die "$dbh->errstr\n";
    $sth->fetchrow_array();
    }

    1;
    and TCP client is:
    my $email = 'myemail@email.it';
    my $password = 'mypassword';
    my $data = "$email#$password";

    my $remote = REMOTE_HOST;
    my $remote_port = SIMPLE_TCP_PORT;
    my $trans_serv = getprotobyname('tcp');
    my $remote_host = gethostbyname($remote) or die "name lookup failed: $remote\n";
    my $destination = sockaddr_in($remote_port, $remote_host);
    socket(TCP_SOCK, PF_INET, SOCK_STREAM, $trans_serv) or die "socket creation failed: $!\n";
    connect(TCP_SOCK, $destination) or die "connect to remote system failed: $!\n";

    my $previous = select TCP_SOCK;
    $| = 1;
    select $previous;

    print TCP_SOCK $data;
    shutdown(TCP_SOCK, 1);

    my $rvalues = '';
    while (my $chunk = <TCP_SOCK>) {
    $rvalues = $rvalues.$chunk;
    }
    close TCP_SOCK or warn "close failed: $!\n";
    my @info = split('#', $rvalues);
    print "INFO = @info\n";
    If I call client two times server crash with following output:
    Can't call method "prepare" without a package or object reference at /home/savio/myperlprograms/DataAccess.pm line 96, <CLIENT_SOCK> line 1.

    I read this page http://search.cpan.org/~timb/DBI-1.1...m#Fatal_Errors but I don't find solution.

    I'm crazying!

  • #2
    New Coder
    Join Date
    Jan 2010
    Posts
    79
    Thanks
    1
    Thanked 0 Times in 0 Posts
    I've add use warnings and use strict and now output is:

    Global symbol "$dbh" requires explicit package name at DataAccessServer.pl line 35.
    Execution of DataAccessServer.pl aborted due to compilation errors.


    The code is:
    Code:
    #!/usr/bin/perl
    
    use strict;
    use warnings;
    
    use lib qw(/home/savio/myperlprograms);
    use DataAccess;
    use DBI;
    use Socket;
    use Data::Dumper;
    
    .......
    .......
    .......
    .......
    
    while (my $from_who = accept(CLIENT_SOCK, TCP_SOCK)) {
      
      my $data = '';
      my $previous = select CLIENT_SOCK;
      $| = 1;
      select $previous;
      
      $data = <CLIENT_SOCK>;
      my @params = split('#', $data);
      @params = split('#', $data);
      my $dAccess = new DataAccess;
      my $dbh = $dAccess->connection('dbname', 'root', 'mypassword') or die "Cannot connect to database: $dbh->errstr\n"; # LINE 35
      my @info = $dAccess->get_info($dbh, $params[0], $params[1]) or die "Cannot lanch query: $dbh->errstr\n";
      my $rvalues = '';
      foreach (@info) {
        $rvalues = $rvalues.'#'.$_;
      }
      print $rvalues;
      print CLIENT_SOCK $rvalues;
      close CLIENT_SOCK or warn "close failed: $!\n";
    }

  • #3
    New Coder
    Join Date
    Jan 2010
    Posts
    79
    Thanks
    1
    Thanked 0 Times in 0 Posts
    I've declared $dbh as global variable.
    The server code is:
    Code:
    my $dbh;
    
    while (my $from_who = accept(CLIENT_SOCK, TCP_SOCK)) {
      
      my $data = '';
      my $previous = select CLIENT_SOCK;
      $| = 1;
      select $previous;
      
      $data = <CLIENT_SOCK>;
      my @params = split('#', $data);
      my $dAccess = new DataAccess;
      $dbh = $dAccess->connection('dbname', 'root', 'mypassword') or die "Cannot connect to database: $dbh->errstr\n";
      my @info = $dAccess->get_info($dbh, $params[0], $params[1]) or die "Cannot lanch query: $dbh->errstr\n";
      my $rvalues = '';
      foreach (@info) {
        $rvalues = $rvalues.'#'.$_;
      }
      $dbh->disconnect;
      print $rvalues;
      print CLIENT_SOCK $rvalues;
      close CLIENT_SOCK or warn "close failed: $!\n";
    }
    
    close TCP_SOCK;
    The message now is yet Can't call method "prepare" without a package or object reference at /home/savio/myperlprograms/DataAccess.pm line 96, <CLIENT_SOCK> line 1.

    Where is the problem?

  • #4
    Super Moderator
    Join Date
    May 2005
    Location
    Southern tip of Silicon Valley
    Posts
    2,871
    Thanks
    2
    Thanked 164 Times in 159 Posts
    Try changing your connection sub to this:
    Code:
    sub connection {
        my $class = shift;
        my ($db, $userdb, $pw) = @_;
        my $dbh = DBI->connect("DBI:mysql:$db", $userdb, $pw, { RaiseError => 1} )
                    or die "Cannot connect to $db: $DBI::errstr\n";
        return $dbh;
    }

  • #5
    Super Moderator
    Join Date
    May 2005
    Location
    Southern tip of Silicon Valley
    Posts
    2,871
    Thanks
    2
    Thanked 164 Times in 159 Posts
    Why write DataAccess.pm as an OO module when, based on the posted code, it appears that you're not using any of the OO advantages. As is it's just a more verbose method of calling a subroutine.

  • #6
    New Coder
    Join Date
    Jan 2010
    Posts
    79
    Thanks
    1
    Thanked 0 Times in 0 Posts
    I writed
    Code:
    sub connection {
        my $class = shift;
        my ($db, $userdb, $pw) = @_;
        my $dbh = DBI->connect("DBI:mysql:$db", $userdb, $pw, { RaiseError => 1} ) or die "Cannot connect to $db: $DBI::errstr\n";
        return $dbh;
    }
    but the output is Can't call method "prepare" without a package or object reference at /home/savio/myperlprograms/DataAccess.pm line 96, <CLIENT_SOCK> line 1.

    How can I write DataAccess module in OO manner?
    Last edited by dark0s; 10-04-2010 at 08:01 PM.

  • #7
    Super Moderator
    Join Date
    May 2005
    Location
    Southern tip of Silicon Valley
    Posts
    2,871
    Thanks
    2
    Thanked 164 Times in 159 Posts
    As a starting point, I need to question your choice of using your DataAccess module. Unless it's doing a lot more that what you've posted, it only serves to make your code a little more complex and slightly obfuscated.

    When I first looked at your module code, I assumed that you left out the portions of it that wasn't related to your question. If that's not correct, then you're missing some very important code. You're missing the use statements, 3 of which are:
    Code:
    use strict;
    use warnings;
    use DBI;
    Here's a possible modified version which still has lots of room for improvement. Of course it will also require modifying your script that uses this module.
    Code:
    package DataAccess;
    
    use strict;
    use warnings;
    use DBI;
    
    sub new {
        my $class = shift;
        my $self = {};
        if ( @_ != 3 ) {
            die "missing some or all db connection parameters";
        }
        my ($db, $userdb, $pw) = @_;
        $self->{dbh} = connection($db, $userdb, $pw);
        bless $self, $class;
        return $self;
    }
    
    sub connection {
        my $self = shift;
        my ($db, $userdb, $pw) = @_;
        my $dbh = DBI->connect("DBI:mysql:$db", $userdb, $pw, { RaiseError => 1 } )
                    or die "Cannot connect to $db: $DBI::errstr\n";
        return $dbh;
    }
    
    sub get_info {
        my $self = shift;
        my ($email, $password) = @_;
        my $query = qq{SELECT Type, Profile, Email FROM clients WHERE Email=? and Password=?;};
        my $sth = $self->{dbh}->prepare($query) or die "$self->{dbh}->errstr\n";
        $sth->execute($email, $password) or die "$self->{dbh}->errstr\n";
        $sth->fetchrow_array();
    }
    
    1;

  • #8
    New Coder
    Join Date
    Jan 2010
    Posts
    79
    Thanks
    1
    Thanked 0 Times in 0 Posts
    I have some questions:
    Code:
    sub new {
        my $class = shift;
        my $self = {};
        if ( @_ != 3 ) {
            die "missing some or all db connection parameters";
        }
        my ($db, $userdb, $pw) = @_;
        $self->{dbh} = connection($db, $userdb, $pw);
        bless $self, $class;
        return $self;
    }
    1) Why you make connection into constructor method?
    2) my $self={} in perl is anonymous hash declaration?
    3) $self->{dbh} = connection($db, $userdb, $pw); add dbh key with connection(...) value into $self anonymous hash?
    It's right?

  • #9
    Super Moderator
    Join Date
    May 2005
    Location
    Southern tip of Silicon Valley
    Posts
    2,871
    Thanks
    2
    Thanked 164 Times in 159 Posts
    Sorry, I'm on my way to the airport so I don't have time right now to answer your questions. When I get back from my trip tomorrow night, I'll check back in.


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •