tie() with DB_File not tie()ing ?

B

botfood

weird problem.... my web host melted down saturday, backups were
corrupt. So, I am moving to a different host. Not a perl issue yet...
let me continue. This is one of those perl-webserver-apache... I dont
know where the problem could be questions.

I have a couple websites that use a fairly simple implementation of
DB_File and tie() to pack up fields of data tie()ed to a file, and fake
it as a database table. I have restored a couple of the websites to the
new host... and in the process of testing found that one site is
working properly, but the other is failing to tie() . No errors are
generated, but the hash is mysteriously empty.

any ideas on how this can happen?

Initially, it did not appear that DB_File was loaded on the server. It
was not listed from the cPanel, so I requested it to be loaded, and
they report they did... although it still doesnt show in the list.

The site that works was uploaded after thet report installing DB_File,
the one that doesnt was uploaded first.

I have checked permissions, re-uploaded scripts, re-uploaded the
database files (binary)... I'm stumped how the same scripts in two
different sites on the same host could behave differently. Could this
possibly be anything to do with apache caching? mod_perl? or some
server side that needs to be flushed or restarted?
 
A

Anno Siegel

[...]
I have a couple websites that use a fairly simple implementation of
DB_File and tie() to pack up fields of data tie()ed to a file, and fake
it as a database table. I have restored a couple of the websites to the
new host... and in the process of testing found that one site is
working properly, but the other is failing to tie() . No errors are
generated, but the hash is mysteriously empty.

any ideas on how this can happen?

No.

Show the code that does the tie. Unless they are absolutely identical,
show both versions. If variables are involved, document their values
(not what you think they contain but what they actually contain at that
point).

Could the databases involved have been generated with different versions
of DB_File and/or Berkeley DB?

Anno
 
B

botfood

the code is the same on both sites, which are on the same server...
databases which were created on old host were also on the same server;
so must have had same version of DB_File and Berkley.

use DB_File;
tie ( %tempHash , 'DB_File' , "./databases/DB_PatientInfo" ) ;

....and %tempHash has no records when used, and reports no errors at
runtime. above this snippet I check and make sure the file exists, and
it does. It has about 10k records in it. I can open it with Wordpad,
but of course it comes out garbled because it is not plain text... just
verifying that the file can be opened and does have data .
 
A

Anno Siegel

[please quote some context when you reply]
the code is the same on both sites, which are on the same server...
databases which were created on old host were also on the same server;
so must have had same version of DB_File and Berkley.

use DB_File;
tie ( %tempHash , 'DB_File' , "./databases/DB_PatientInfo" ) ;

...and %tempHash has no records when used, and reports no errors at
runtime. above this snippet I check and make sure the file exists, and
it does. It has about 10k records in it. I can open it with Wordpad,
but of course it comes out garbled because it is not plain text... just
verifying that the file can be opened and does have data .

You are not checking tie() for success. Is the current directory
what you assume it is? Arm your code with debugging aids:

use DB_File;
my $db = "./databases/DB_PatientInfo";
die "no database" unless -f $db;
die "empty database" unless -s $db;
# add more tests if needed
# verify the current directory
tie ( my %temphash, 'DB_File', $db) or die "tie failed: $!";

Check the server's error log for die() messages, or use other methods
to see them. Add more checks or run other tests, depending on results.

You're not a helpless victim of what your code does. It's your code,
you can change it. Use the ability to clear up what's going wrong.

Anno
 
B

botfood

like I said I do test for existance and readability above the
snippet... -f and -r . both pass. I added a debug statements afterward
that verify the tie(0 is not tie()ing by checking the number of keys
like...

use DB_File;
tie ( %tempHash , 'DB_File' , "./databases/DB_PatientInfo" ) ;

@tempList = keys(%tempHash);
print STDERR " db has $#tempList keys \n";

and what I find is that $#tempList is -1, which means that the hash was
undefined... but the file exists, and is readable, which gets me back
to the question of how can tie() fail to understand it? especially when
the same code works in a different site hosted on the same server.
 
D

David Squire

botfood said:
like I said I do test for existance and readability above the
snippet... -f and -r . both pass. I added a debug statements afterward
that verify the tie(0 is not tie()ing by checking the number of keys
like...

[snip]

Please include context when replying to a post. See the posting
guidelines for this newsgroup.

DS
 
B

botfood

....just trying to keep it short. There are a number of subs that write
to the borwser and stuff like that that are irrelant to the issue I
snipped out. In the meantine I added more checks to test the success of
the tie(), and now have a perplexing issue where -f and -r tests above
the tie succeed, but when i add a test of the tie() itself it says the
file is not found... but its there and readable.

appropriate snippet now reads:

unless (-f "${cfgRelPath_cgi2DB}/DB_OrderInfo" ) {
$cDEBUG=0;
&ExitToBrowser('warn', "could not find
${cfgRelPath_cgi2DB}/DB_OrderInfo" );
}
unless (-r "${cfgRelPath_cgi2DB}/DB_OrderInfo" ) {
$cDEBUG=0;
&ExitToBrowser('warn', " ${cfgRelPath_cgi2DB}/DB_OrderInfo is not
readable" );
}
use DB_File;
unless ( tie( %OrderInfoHash , 'DB_File' ,
"${cfgRelPath_cgi2DB}/DB_OrderInfo" ) ){
$cDEBUG=0;
$tempString = $!;
untie %OrderInfoHash ;
&ExitToBrowser('warn', "could not tie to
${cfgRelPath_cgi2DB}/DB_OrderInfo ".
"because $tempString \n" );
}


....what I get is the error that the tie failed, even though the -f and
-r tests passed. What more context do you want?
 
D

David Squire

botfood said:
...just trying to keep it short.

You have misunderstood the meaning of "context" in the previous post. It
refers to the quoting of the relevant part of post to which you are
replying. Remember, you are posting to a Usenet group. Many (most?)
participants read this in a newsreader, not via the Google Groups interface.

Did you read the posting guidelines? They are available at
http://augustmail.com/~tadmc/clpmisc/clpmisc_guidelines.html

You have now provided more details of your script, which is good, but
more people will be inclined to help you if you adhere to the guidelines.

[snip]
use DB_File;
unless ( tie( %OrderInfoHash , 'DB_File' ,
"${cfgRelPath_cgi2DB}/DB_OrderInfo" ) ){
$cDEBUG=0;
$tempString = $!;
untie %OrderInfoHash ;
&ExitToBrowser('warn', "could not tie to
${cfgRelPath_cgi2DB}/DB_OrderInfo ".
"because $tempString \n" );
}


...what I get is the error that the tie failed, even though the -f and
-r tests passed. What more context do you want?

Could you tell us exactly what error message ends up in $tempString above?

DS
 
B

botfood

David said:
You have misunderstood the meaning of "context" in the previous post. It
refers to the quoting of the relevant part of post to which you are
replying.
------------
I get it now, and also notice that the reply at the bottom of the posts
does not automatically quote like it used to.... so, lets try again. I
am removing the now duplicate code snippet, and sticking to your new
question. ;)

the -f and -r tests pass as stated in previous posts, but this test:
Could you tell us exactly what error message ends up in $tempString above?
--------------------------
it fails with the error message:

could not tie to ./databases/DB_OrderInfo because No such file or
directory

even though it IS there, does pass the previous test, and the same sort
of relative path is used in the other website that is up and
running.... the question becomes how can a file pass -r and -f, and not
be found by tie() .

d
 
D

David Squire

botfood said:
the -f and -r tests pass as stated in previous posts, but this test:


it fails with the error message:

could not tie to ./databases/DB_OrderInfo because No such file or
directory

even though it IS there, does pass the previous test, and the same sort
of relative path is used in the other website that is up and
running.... the question becomes how can a file pass -r and -f, and not
be found by tie() .

OK. Really just guessing now, but are there any environment variables
floating around that could influence where DB_File is trying to do its
thing, e.g. $ENV{DB_HOME}?

Also, you do not appear to have:

use strict;
use warnings;

at the top of your script.

DS
 
A

A. Sinan Unur

------------
I get it now, and also notice that the reply at the bottom of the
posts does not automatically quote like it used to.... so, lets try
again. I am removing the now duplicate code snippet, and sticking to
your new question. ;)

the -f and -r tests pass as stated in previous posts, but this test:

What is your objection to using an absolute path?

What happens if you do use an absolute path?
could not tie to ./databases/DB_OrderInfo because No such file or
directory

even though it IS there, does pass the previous test,

The proof is in the pudding. If the file cannot be found in a relative
path, the fact must be that the current directory, by the time the
appropriate point is reached, is not the same as the current directory
in the -r -f tests.

Sinan
--
A. Sinan Unur <[email protected]>
(remove .invalid and reverse each component for email address)

comp.lang.perl.misc guidelines on the WWW:
http://augustmail.com/~tadmc/clpmisc/clpmisc_guidelines.html
 
B

botfood

David said:
OK. Really just guessing now, but are there any environment variables
floating around that could influence where DB_File is trying to do its
thing, e.g. $ENV{DB_HOME}?
-----------
no, the pathnames are set to global variables in a config file that is
'required' at the top of the script. for testing purposes I have
replaced the vars with a hardcoded string, with the same results. The
mindboggling thing is that the -f and -r tests just above the tie()
pass, and when I look via ftp the file sure enough exists, has correct
privs rw-r--r--, and has data in it...
but the tie() fails with the $! error message that no such file exists
????

only thing I can come up with at this point is that the file is somehow
corrupted such that DB_File can figure it out, but still looks like a
readable file to -r. I guess my next question would be if it is
possible to 'rebuild' a file, when I cant open it with tie()

Also, you do not appear to have:
use strict;
use warnings;
---------------------
they are way up out of sight in a config file that this particular
script pulls in via 'require'

d
 
B

botfood

A. Sinan Unur said:
What is your objection to using an absolute path?
-----------
well, this particular script is a utility script that is used for a
couple different DBs that are in different place, AND its the easiest
way to get the same code working on my PC test environment as well as
the linux webhost without modifying code. Never had a problem with it
before, and dont have a problem with it in similar use in a different
website on the same server.

What happens if you do use an absolute path?
----------
I tried this... hardcoded in the path for testing. same results. leads
me to believe that either the file is in some way corrupted just enough
that DB_File cant figure it out and tie() to it.
The proof is in the pudding. If the file cannot be found in a relative
path, the fact must be that the current directory, by the time the
appropriate point is reached, is not the same as the current directory
in the -r -f tests.
-----------------------
I sure dont see how the current directory could change between one line
and the next. Also, the error message gives the correct path to where
the file actually is relative to the script that is running.

d
 
A

A. Sinan Unur

-----------
well, this particular script is a utility script that is used for a
couple different DBs that are in different place, AND its the easiest
way to get the same code working on my PC test environment as well as
the linux webhost without modifying code. Never had a problem with it
before, and dont have a problem with it in similar use in a different
website on the same server.

None of that is relevant. You can add another config variable for the
root directory of you installation, and concatenate that and the
relative path to the DB file.

I would like to see a short, uncluttered example, and its output where
you attempt to tie using an absolute path.
I sure dont see how the current directory could change between one

I don't know because I did not step through everything that happens when
you make the tie call.
Also, the error message gives the correct path to
where the file actually is relative to the script that is running.

It just reports the string you passed.

Sinan
--
A. Sinan Unur <[email protected]>
(remove .invalid and
reverse each component for email address)

comp.lang.perl.misc
guidelines on the WWW:
http://augustmail.com/~tadmc/clpmisc/clpmisc_guidelines.html
 
B

botfood

A. Sinan Unur said:
I would like to see a short, uncluttered example, and its output where
you attempt to tie using an absolute path.
----------------------
ok, I wrote a simple hardcoded test, and installed it in the same dir
as the data file. I get the same results in that this test fails in one
website, and works on another one the same server!

the one that works runs and give me a count of the records, the one
that fails prints out $! which outputs to browser:
running test to open DB_OrderInfo
could not tie to DB_OrderInfo because No such file or directory


the code of the test script is:

#! /usr/bin/perl -w

use strict;
use CGI::Carp 'fatalsToBrowser';

# hardcoded test script for existing DB file
# installed to same directory as DB file
# prints output to browser when run via webserver

my $db_filename = 'DB_OrderInfo' ;

print "Content-type: text/plain\n\n" ;
print "running test to open $db_filename \n";

unless (-f "$db_filename" ) {

print "could not find $db_filename \n" ;
exit;
}
unless (-r "$db_filename" ) {

print "could not read $db_filename \n" ;
exit;
}

use DB_File;
my %OrderInfoHash = ();

if ( tie( %OrderInfoHash , 'DB_File' , "$db_filename" ) ){

my @tempList = keys(%OrderInfoHash);
print "DB was tied... and has $#tempList records in it. \n";
}else{
print "could not tie to $db_filename because $! \n" ;
}

untie %OrderInfoHash ;
exit;
 
B

botfood

botfood said:
ok, I wrote a simple hardcoded test, and installed it in the same dir
as the data file. I get the same results in that this test fails in one
website, and works on another one the same server!

the one that works runs and give me a count of the records, the one
that fails prints out $! which outputs to browser:
running test to open DB_OrderInfo
could not tie to DB_OrderInfo because No such file or directory
------------------------------

further tests reveal that when I copy a working database file from the
website that has been working to the one that is not, the test runs...
aaarrrgh which leaves me to conclude that the database file itself is
somehow corrupted just enough that the tie() fails.

The question NOW becomes, how can i tell what is wrong with the file,
and how can I attempt to repair it?

This whole problem occurred because the host the sites were on had
massive corruption and their whole filesystem and all the RAID disks
went down leaving no backups except what i had grabbed the night before
via ftp... which now apparently has been proven 'slightly corrupted'.

any ideas now?
 
A

A. Sinan Unur

----------------------
ok, I wrote a simple hardcoded test,
....

my $db_filename = 'DB_OrderInfo' ;

That is *not* an absolute path. An absolute path looks like:

/var/www/home/myhost/public_html/db/DB_OrderInfo
print "Content-type: text/plain\n\n" ;
print "running test to open $db_filename \n";

unless (-f "$db_filename" ) {

D:\Dload> perldoc -q vars
Found in C:\opt\Perl\lib\pod\perlfaq4.pod
What's wrong with always quoting "$vars"?
if ( tie( %OrderInfoHash , 'DB_File' , "$db_filename" ) ){

Do not quote $db_filename (although it has no effect here), and use an
absolute path to the db file.

Sinan
--
A. Sinan Unur <[email protected]>
(remove .invalid and reverse each component for email address)

comp.lang.perl.misc guidelines on the WWW:
http://augustmail.com/~tadmc/clpmisc/clpmisc_guidelines.html
 
B

botfood

A. Sinan Unur said:
That is *not* an absolute path. An absolute path looks like:
------------
irrelevant at this point... by copying a db file from the website that
is working, and running the same test program on it, with the same
local path, it was able to tie() without error and tell me the number
of records in the file. Pretty much sells me that the file I restored
from the host that melted down is 'slightly corrupted', or at least the
file descriptors are messed up somehow such that tie(0 cant figure the
file out even though it exists and is readable as far as the -f and -r
tests went.

so... the question now becomes whether anyone can hazard a guess how
a file can exist and be readable to -f and -r, but returns an error 'No
such file or directory' from tie() using DB_File.

followed by, can it be 'fixed?"

d
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top