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

I know I'm probably the last person on earth using dbmopen() to tie hashes, but here's a question -- if I do this:
dbmopen(%my_hash,'my_data',0777) || die "$!";
and the file has not yet been created, it will automagically be created. The only error I'm likely to get is if I don't have permission to create files in that directory or something.

Is there a way to find out if a database file already exists before I open it and start (possibly) clobbering its values?

I know on the particular system I'm using right now, that implies the creation of a file called 'my_data.db', but on another system, it implies the creation of two files, 'my_data.pag' and 'my_data.dir' -- because it uses NDBM, or something.

In my case, I know the system so I can just do an "if file exists 'my_data.db'", but if I can't be sure what the filename is every time, can I in some other way logically test whether there's already a database file before I do this:

dbmopen(%my_hash,'my_data',0777) || die "$!"; $my_hash{'something_really_important'} = '';

?
--

“Every bit of code is either naturally related to the problem at hand, or else it's an accidental side effect of the fact that you happened to solve the problem using a digital computer.”
M-J D

Replies are listed 'Best First'.
Re: dbmopen() test if file exists already?
by broquaint (Abbot) on May 28, 2003 at 09:42 UTC
    Since I don't think there's a function to test for the existence of a dbm file you could either try a test dbmopen or a glob e.g
    warn "dbm exists" if dbmopen(my %hash, "your_data"); warn "dbm_exists" if glob('your_data.{pag,db,dir}');
    But since dbmopen doesn't clobber the data this test seems rather frivolous.
    HTH

    _________
    broquaint

      warn "dbm_exists" if glob('your_data.{pag,db,dir}');
      There's no promise that this syntax is portable, even to all Unix systems. On versions of Perl prior to 5.6, where glob was a callout to a separate shell process, and a csh-like shell was not available, the Bourne Shell was used, and this would definitely get a Bourne Shell upset.

      Of course, now that glob is internal, it's a lot more portable.

      -- Randal L. Schwartz, Perl hacker
      Be sure to read my standard disclaimer if this is a reply.

      >since dbmopen doesn't clobber the data >this test seems rather frivolous.

      Didn't say it did.

      I was thinking about some data structure where, for example, user details could be stored in that kind of tied hash, and so you might want to check if you already had a "codypendant.db" or a "broquaint.db" when a new user came along, in case of duplication.

      I really should learn Tie::Hash shouldn't I? --

      “Every bit of code is either naturally related to the problem at hand, or else it's an accidental side effect of the fact that you happened to solve the problem using a digital computer.”
      M-J D
        I was thinking about some data structure where, for example, user details could be stored in that kind of tied hash, and so you might want to check if you already had a "codypendant.db" or a "broquaint.db" when a new user came along, in case of duplication.
        This sounds like a case for creating a single hash, where each user is a key, then it would just be a matter testing the existence of a user with exists %user_db. If however, you've decided to do it on a per file basis for whatever reason then it would just be a matter of testing the return status of dbmopen e.g
        dbmopen(my %hash, "codypendant") and warn "codypendant already exists";

        HTH

        _________
        broquaint

Re: dbmopen() test if file exists already?
by Skeeve (Parson) on May 28, 2003 at 09:36 UTC
    Try
    dbmopen(%my_hash,'my_data',undef) || die "$!";