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

Fellow Monks, I've got a flat file database that I need to be able to edit. Right now, I have a system that works as follows: Each line in the database is numbered. A cgi spits out a HTML page with the entire contents of the database. Beside each line is a link containing a parameter to be passed to the cgi. That parameter is the line number of the database. When passed to the cgi, the cgi works something like this (example code only, not actual code from site):
my $number = $cgi->param('number'); open(DATABASE, "database.dat") || die "Couldn't open the database for +reading: $!"; @database=<DATABASE>; close(DATABASE); my @data = split(/\|/, $database[$number]); # Do all my manipulations here $database[$number] = join('|', @data); open(DATABASE, ">database.dat") || die "Couldn't open the database for + writing: $!"; foreach (@database) { chomp; print DATABASE "$_\n" if ($_ ne ""); } close(DATABASE);

It seems to me that this is a bit error/bug prone. Is there a better way to do this? There is also the remote possibility that I may get multiple users on this system in which I am sure this system would fail. Could anyone tell me a more secure way to do this?

I'm a self-taught programmer. I have no formal training what-so-ever. Any suggestions as to how I could improve both my system and my code would be greatly appreciated! Thanks!

Stamp_Guy
Computers aren't intelligent, they just think they are.

Replies are listed 'Best First'.
Re: Flat File Editing Question
by jorg (Friar) on May 24, 2001 at 04:10 UTC
    The issue you have with concurrent updates is one you'll always have : last update overwrites previous one. This is true whether you're using a flat file or a database.
    So for data integrity you would need to feedback to the user if the file was updated between him viewing it on the webpage and updating it.

    As far as system integrity concerns : you're opening the file twice, the read will get screwed up if another thread is writing to it. There are ways of editing a file in place so you wouldn't need to open it twice.

    Note : I removed the rest of my rant after a supersearch, this topic has been reviewed extensively already in editing/deleting record in flat file database and turnstep even added a nice code snippet that handles concurrent updates.



    Jorg

    "Do or do not, there is no try" -- Yoda

Re: Flat File Editing Question
by no_slogan (Deacon) on May 24, 2001 at 04:03 UTC
    Storing your data in a tied-hash database file (e.g. GDBM_File) is easy, efficient, and reliable.

    You need some form of locking on the database, since two people might happen to hit "submit" at almost exactly the same time. It would be bad if two different cgi processes tried to modify the file at once. Locking can be a pain to get working right, but GDBM_File does it for you by default (in UNIX, at least. Anyone have suggestions for Windows?).

Re: Flat File Editing Question
by Banky (Acolyte) on May 24, 2001 at 07:24 UTC
    One way to prevent the multiple update is to have a tag alone md5 checksum for each field you might be updating. Then before you update it in the database you check to see whether the md5_sum of the current database state matches when you started by comparing checksums;

    To get a md5 checksum for a piece of data all you need to do is: You can take a look at Digest:MD5 on CPAN.

    use Digest::MD5 qw(md5_base64); my $checksum=md5_sum($data);