in reply to Re^3: Database problem
in thread Database problem

I made a Perl script to create the databases. And now their isn't a cant find the file or directory error. But now theirs this error.

AnyDBM_File doesn't define an EXISTS method at /home/k0rn/public_html/register.pl line 75

this is line 74

tie(%DBAPACHE, "AnyDBM_File", $dbapache, 0644, O_RDWR|O_CREAT) or die "Can't open $dbapache : $!\n";

And this is line 75 were the error is from.

unless(exists($DBAPACHE{$name})) { # Check if exists in database

Im pretty new to Perl but i don't think that is incorrect.

Replies are listed 'Best First'.
Re^5: Database problem
by tachyon-II (Chaplain) on Apr 21, 2008 at 00:19 UTC

    No it's not your fault.

    AnyDBM_File is a thin wrapper over any of NDBM_File, DB_File, GDBM_File, SDBM_File and ODBM_File which are a series of different flavours. What AnyDBM_File does is try to load each one (in the order stated) and uses the first working version. My Perl (5.8.8 on Win 32) uses SDBM_File which does define an EXISTS method so does not choke. It looks like dbmmanage insists on SDBM_File (at least on the Apache 2 Win32 port).

    Tied hashes require that a number of methods get defined. If they are not things default back to the code in Tie::Hash which in the case of exists is to choke with the error you note. The only way to fix this properly is to patch the source of whatever *DB_File your system is using and add the missing method. As noted it works fine for me so it has quite probably already been fixed and you just have an old version of *DB_File.

    Anyway the quick fix answer is don't use exists. Use defined instead.

    unless(defined $DBAPACHE{$name}) {
    Presumably the DB_File version you are using does not autovivify (create the hash entry) so it will work fine. If not I'm sure someone will patch it by adding the missing EXISTS tie method to the XS.

    To find out which version of *DB_File you are actually using try this simple test code (adjust the file path as required and the test username):

    use strict; use Fcntl; use AnyDBM_File (); my $file = "C:/dbase"; # no file extension as dbmmanage chops this of +f our @ISA; my %DB; tie (%DB, "AnyDBM_File", $file, 0666, O_RDWR|O_CREAT ) or die "Can't tie $file: $!"; print "ISA @AnyDBM_File::ISA\n"; #my $user = 'test'; #if (exists $DB{$user}) { # print "$user:$DB{$user} found!\n"; #} untie %DB; __DATA__ SDBM_File test:password found!
      Using Defined worked. Thanks. I though that was weird when it kept giving me that funky error.

      Now I have a whole new error its when im trying to store data the to the db file.

      Could not open /home/k0rn/data/dbapache: Resource temporarily unavailable at /home/k0rn/public_html/register.pl line 129.,

      And i did do untie(%DBAPACHE); when i opened the db's in the beginning of the script. Now i get that error twoards the end of the script.Line 129 and 130 is as follows.

      tie(%DBAPACHE, 'AnyDBM_File', $dbapache, 0644, O_RDWR) or die "Could not open $dbapache: $!";

      $DBAPACHE{$name} = "$cryptpass:$groups:$key";

      I don't see why i get that error for that code unless the 0644 needs to be something else but i don't think so.

        You may need 0666 as the permissions. I presume you have shell access? It is much simpler to debug things on the command line. Try the simplified script I posted and then add a line to do what you want. I need to know which flavour of DB you are running (an the script will tell you). Run it off the command line. Once you get it to work off the command line add this to the test script

        BEGIN { $|=1; print "Content-type: text/html\n\n"; use CGI::Carp('fatalsToBrowser'); }

        and try to run it as a CGI. It should still work. If it does not it is a permissions issue. The resource temporarily unavailable makes me think something ?apache is locking the DBM file. Anyway try off the command line first, then as a CGI