Guildencrantz has asked for the wisdom of the Perl Monks concerning the following question:

Monks,

I have linked a DB file with a hash and have tried to apply the exists function to it. For some reason I am getting the error: "AnyDBM_File doesn't define an EXISTS method at /var/www/cgi-bin/ds/deactivate.pl line 18". I even checked the Perl Cookbook and it reports that this is a valid function. What am I doing wrong?

~~Guildencrantz
#!/usr/bin/perl -wT # # Script: Dynamic Dungeon Siege IP Database Deactivate IP Script # Author: Guildencrantz # Version: 4-13-02 # use strict; use CGI::Carp 'fatalsToBrowser'; my $userIP = $ENV{REMOTE_ADDR}; my $activeIPsPath = "/var/www/cgi-bin/ds/database/activeIPs"; dbmopen(my %activeIPs, $activeIPsPath, 0666) or die "Cannot open activeIPs database: $!"; if(exists $activeIPs{$userIP}) { delete($activeIPs{$userIP}); ...

Replies are listed 'Best First'.
Re: Exists with DBM
by grep (Monsignor) on Apr 13, 2002 at 21:36 UTC

    As Juerd pointed out tie is the preferred function.

    You may also force your program to the DB_File instead of AnyDBM_File. You can just throw a use DB_File; on the top of each of your programs. DB_File supports exists and is a bit richer in functionality

    You should redo the db file for the change



    grep
    Unix - where you can thrown the manual on the keyboard and get a command
Re: Exists with DBM
by Juerd (Abbot) on Apr 13, 2002 at 21:19 UTC
Re: Exists with DBM
by Guildencrantz (Sexton) on Apr 13, 2002 at 22:50 UTC
    Thank you Monks.

    I have made the suggested changes, but I haven't fixed all the problems. Now I get everything open, but on the server I get a software error with no information as to what the error is. On the CLI I get no error, but the output stops as soon as the script gets into the "if(exists ($allIPs{$userIP}))" loop, it prints the first line, and nothing else. The nested loop just doesn't seem to be activated at all. Any suggestions?

    ~~Guildencrantz
    #!/usr/bin/perl -wT # # Script: Dynamic Dungeon Siege IP Database Activate IP Script # Author: Guildencrantz # Version: 4-13-02 # use strict; use DB_File; use CGI; use CGI::Carp 'fatalsToBrowser'; my $q = new CGI; my $userIP = $q->remote_host; my $allIPsPath = "/var/www/cgi-bin/ds/database/allIPs.db"; my $activeIPsPath = "/var/www/cgi-bin/ds/database/activeIPs.db"; tie my %allIPs, "DB_File", $allIPsPath or die "Cannot open allIPs database: $!"; tie my %activeIPs, "DB_File", $activeIPsPath or die "Cannot open activeIPs database: $!"; print "userIP = $userIP\n"; print "userdata = $allIPs{$userIP}\n"; if( exists $allIPs{$userIP} ) { print "exists in allIPs\n"; if( exists $activeIPs{$userIP} ) { print "exists in activeIPs\n"; print "Content-type: html/text"; print <<END_OF_BLOCK; <HTML> <HEAD> <META HTTP-EQUIV="Refresh" CONTENT="5; URL=/ds +-cgi/viewActive.pl"> <TITLE>ACTIVE</TITLE> </HEAD> <BODY> <H1>Your IP is already marked as active!</H1> <P> <A HREF="/ds-cgi/viewActive.pl"> You will be forwarded in 5 seconds </A> </P> </BODY> </HTML> END_OF_BLOCK } else { print "does not exist in activeIPs\n"; $activeIPs{$userIP} = $allIPs{$userIP}; print "active IPs= $activeIPs{$userIP}\n"; print "Content-type: html/text"; print <<END_OF_BLOCK; <HTML> <HEAD> <META HTTP-EQUIV="Refresh" CONTENT="5; URL=/ds +-cgi/viewActive.pl"> <TITLE>Added!</TITLE> </HEAD> <BODY> <H1>Your IP has been activated!</H1> <P> <A HREF="/ds-cgi/viewActive.pl"> You will be forwarded in 5 seconds </A> </P> </BODY> </HTML> END_OF_BLOCK } } else { print "Content-type: text/html\n\n"; print <<END_OF_BLOCK; <HEAD> <META HTTP-EQUIV="Refresh" CONTENT="5; URL=/ds/submit. +html"> <TITLE>IP Not Registered</TITLE> </HEAD> <BODY> <H1>There is no entry in the database for this IP. You must regis +ter this IP and the associated server attributes</H1> <P> <A HREF="/ds/submit.html"> You will be forwarded in 5 seconds </A> </P> </BODY> </HTML> END_OF_BLOCK } untie %activeIPs; untie %allIPs;

      Good, you have identitfied a case that works and one that doesn't (i.e. CLI and browser). Now just narrow down the problems.
      Ask yourself:

    • What am I doing to get it to display on the browser?
    • What does a '500 Server Error' mean (that was your error? wasn't it?).
    • Then you should search your resources for those answers

      I see a couple of problems:

    • You're doing your headers in a manner that could be incorrect or at least inconsistiant.
      print "Content-type: html/text"; print <<END_OF_BLOCK; <HTML>
      This is highly dependant on how your editor does line endings. use  print "Content-type: html/text\n\n"; even better use that CGI module that you loaded  print $q->header();
    • You are printing several things before you print your headers
    • Both of these things will cause a '500 Server Error'. Whenever you see a 500 error, you should check your log file. The log file will generally point you in the right direction

      2 excellent resources for your CGI programming quests:
      tachyon's CGI Help Guide
      Ovid's Ovid's Web Programming with Perl

      grep
      Unix - where you can thrown the manual on the keyboard and get a command

(crazyinsomniac) Re: Exists with DBM
by crazyinsomniac (Prior) on Apr 14, 2002 at 10:36 UTC
    I even checked the Perl Cookbook and it reports that this is a valid function.
    Did the author of the book write the AnyDBM_File module?

    What version of the module is used in the book?

    I would greatly question any claims made in some book about some module.

    I would sugguest you take the advice of tilly (a rather knowledgable monk, who advises wisely often) and rely on your local documentation for definitive information.

    Open up AnyDBM_File.pm in your favorite editor or pod viewer and read to see what the module actually does.

    Which database module are you actually using? (NDBM_File, DB_File, GDBM_File, SDBM_File, ODBM_File ...)

    The Perl Cookbook is probably speaking about the existence of the perl built-in function exists, in any case, rely on your local documentation, and be as explicit and specific as possible when asking questions, and provide sample data.

    Does your database key your are looking for actually exist in the database?

     
    ______crazyinsomniac_____________________________
    Of all the things I've lost, I miss my mind the most.
    perl -e "$q=$_;map({chr unpack qq;H*;,$_}split(q;;,q*H*));print;$q/$q;"