Writing dupliactes to database file

T

Testor

Hi all,

I posted this message in comp.lang.perl, but someone suggested I post
to this group instead. I wish I could delete the other one I hope
admins will note this.

Anyway, here goes:

I am writing a simple perl script to learn in the process. The script
is supposed to grab a receipt number from the query-string and write
it into a file.

To do that, here's what I did:

$query = new CGI;

$myreceipt = $query->param('bnkreceipt');

open(DATABASE, ">>bnkrecpts.db") or die "Can't write open file.
Reason: $!";
seek(DATABASE,0,2);
print DATABASE "$myreceipt\n";
close(DATABASE);

This works OK though not sure if it's the best way because I'm writing
duplicate receipt numbers. I tried to use an if statement to make sure
is the number exists in the file before writing it but I'm afraid I
wasn't successful I did something like:

open (THERECEIPT, "bnkrecpts.db") or die "Can't open file. Because:
$!";
flock(THERECEIPT,2);
$receiptnum = <THERECEIPT>;
close (THERECEIPT);

if ($receiptnum eq $myreceipt) {
stop and redirect or print something to the page etc..

}

As you can see since I'm still learning, my logic is out of no where
here :)

Comments on the above code will be appreciated.
 
T

Tad McClellan

Testor said:
I posted this message in comp.lang.perl, but someone suggested I post
to this group instead. I wish I could delete the other one I hope
admins will note this.


Admins that carry comp.lang.perl have already demonstrated
a low level of conscientiousness, so I wouldn't count on
them noticing. :-(

open(DATABASE, ">>bnkrecpts.db") or die "Can't write open file.
Reason: $!";
seek(DATABASE,0,2);


Why the seek() ?

This works OK though not sure if it's the best way because I'm writing
duplicate receipt numbers.


The Perl FAQ should be checked *before* posting to the Perl newsgroup:

perldoc -q duplicate

How can I remove duplicate elements from a list or array?

Adapt the answer given there to your situation.
 
T

Tore Aursand

open(DATABASE, ">>bnkrecpts.db") or die "Can't write open file.
Reason: $!";
seek(DATABASE,0,2);
print DATABASE "$myreceipt\n";
close(DATABASE);

This works OK though not sure if it's the best way because I'm writing
duplicate receipt numbers. I tried to use an if statement to make sure
is the number exists in the file before writing it but I'm afraid I
wasn't successful I did something like:

open (THERECEIPT, "bnkrecpts.db") or die "Can't open file. Because:
$!";
flock(THERECEIPT,2);
$receiptnum = <THERECEIPT>;
close (THERECEIPT);

if ($receiptnum eq $myreceipt) {
stop and redirect or print something to the page etc..

}

This is partly answered in the Perl FAQ;

perldoc -q duplicate

Anyway. You could take a look at the following code which might help you
get a clue;

my $filename = 'bnkrecpts.db';
my $receipt = $query->param('receipt') || '';

if ( $receipt ) {
my $receipt_exists = 0;

open( THERECEIPT, '<', $filename ) or die "$!\n";
while ( <THERECEIPT> ) {
chomp;
if ( $_ eq $receipt ) {
$receipt_exists++;
last;
}
}
close( THERECEIPT );

unless ( $receipt_exists ) {
open( THERECEIPT, '>>', $filename ) or die "$!\n";
print THERECEIPT "$receipt\n";
close( THERECEIPT );
}
}

Fill in with file locking etc. as it suits you. The code above is a
simple example and has not been tested or anything.

Hope it helps, though.
 
M

Malcolm Dew-Jones

Testor ([email protected]) wrote:
: Hi all,

: I posted this message in comp.lang.perl, but someone suggested I post
: to this group instead. I wish I could delete the other one I hope
: admins will note this.

: Anyway, here goes:

: I am writing a simple perl script to learn in the process. The script
: is supposed to grab a receipt number from the query-string and write
: it into a file.

: To do that, here's what I did:

: $query = new CGI;

: $myreceipt = $query->param('bnkreceipt');

: open(DATABASE, ">>bnkrecpts.db") or die "Can't write open file.
: Reason: $!";
: seek(DATABASE,0,2);
: print DATABASE "$myreceipt\n";
: close(DATABASE);

: This works OK though not sure if it's the best way because I'm writing
: duplicate receipt numbers. I tried to use an if statement to make sure
: is the number exists in the file before writing it but I'm afraid I
: wasn't successful I did something like:

: open (THERECEIPT, "bnkrecpts.db") or die "Can't open file. Because:
: $!";
: flock(THERECEIPT,2);
: $receiptnum = <THERECEIPT>;
: close (THERECEIPT);

I just wanted to say one thing.

Once you close the file then the lock goes away. You have to check the
contents and write the new number _while the file is still open_.
(Assuming you use this technique at all.)

open read write
flock
read file to see what's in it
write any new values into the right place in the file
(if file should be shorter then truncate to the right length)
close (flock goes away)
 
T

Testor

Tore Aursand said:
This is partly answered in the Perl FAQ;

perldoc -q duplicate

Anyway. You could take a look at the following code which might help you
get a clue;

my $filename = 'bnkrecpts.db';
my $receipt = $query->param('receipt') || '';

if ( $receipt ) {
my $receipt_exists = 0;

open( THERECEIPT, '<', $filename ) or die "$!\n";
while ( <THERECEIPT> ) {
chomp;
if ( $_ eq $receipt ) {
$receipt_exists++;
last;
}
}
close( THERECEIPT );

unless ( $receipt_exists ) {
open( THERECEIPT, '>>', $filename ) or die "$!\n";
print THERECEIPT "$receipt\n";
close( THERECEIPT );
}
}

Fill in with file locking etc. as it suits you. The code above is a
simple example and has not been tested or anything.

Hope it helps, though.

Tore,

Thanks much for the reply, yes "partly" answered, what you gave is
much better than the stu...FAQ which I keep refering to always before
posting, but honestly the info is scarce.

I shall try your code, certainly it looks like I can learn from it and
make it work if it doesn't.

Malcolm,

I got your tip, thanks.
 
T

Testor

Tore Aursand said:
This is partly answered in the Perl FAQ;

perldoc -q duplicate

Anyway. You could take a look at the following code which might help you
get a clue;

my $filename = 'bnkrecpts.db';
my $receipt = $query->param('receipt') || '';

if ( $receipt ) {
my $receipt_exists = 0;

open( THERECEIPT, '<', $filename ) or die "$!\n";
while ( <THERECEIPT> ) {
chomp;
if ( $_ eq $receipt ) {
$receipt_exists++;
last;
}
}
close( THERECEIPT );

unless ( $receipt_exists ) {
open( THERECEIPT, '>>', $filename ) or die "$!\n";
print THERECEIPT "$receipt\n";
close( THERECEIPT );
}
}

Fill in with file locking etc. as it suits you. The code above is a
simple example and has not been tested or anything.

Hope it helps, though.

Tore,

It worked just fine the first time. I was hoping it fails so I spend
sometime trying to make it work, that way, I will learn more.

Of course, couple of questions came to mind:

1- Do I have to do any flocking if it's only one script that's opening
and writing to the file?

2- What about seek? don't I have to rewind? or it's not needed in this
case?

3- I inserted a print location like so:

if ( $_ eq $receipt ) {
$receipt_exists++;
print "Location: test.html\n\n";
last;

That worked too, any problem in doing so?

Thanks,
 
T

Tore Aursand

1- Do I have to do any flocking if it's only one script that's opening
and writing to the file?

It doesn't matter how many scripts. What matters is if the script(s) will
try to access the file simulatenously.

If you are _absolutely_ sure that there will be only one script at a time,
and only one instance of that script, you don't need file-locking.
2- What about seek? don't I have to rewind? or it's not needed in this
case?

Not in this case, as I see it; Whenever you open a file, the "file
cursor" will position itself at the very beginning of the file. If you
are opening a file in "append mode" (ie. '>>'), whatever written to the
file will be appended to the file.
3- I inserted a print location like so:

if ( $_ eq $receipt ) {
$receipt_exists++;
print "Location: test.html\n\n";
last;

That worked too, any problem in doing so?

Not really, but the code above won't work if you're not local; 'test.html'
only exists on the server (ie. where the script is running), right?

Anyway. You should consider letting the CGI.pm module take care of any
redirects, so that you're sure that you'll get it 100% correct. Read the
documentation for the CGI.pm module for more information.
 
T

Testor

Tore Aursand said:
It doesn't matter how many scripts. What matters is if the script(s) will
try to access the file simulatenously.

If you are _absolutely_ sure that there will be only one script at a time,
and only one instance of that script, you don't need file-locking.


Not in this case, as I see it; Whenever you open a file, the "file
cursor" will position itself at the very beginning of the file. If you
are opening a file in "append mode" (ie. '>>'), whatever written to the
file will be appended to the file.


Not really, but the code above won't work if you're not local; 'test.html'
only exists on the server (ie. where the script is running), right?

Anyway. You should consider letting the CGI.pm module take care of any
redirects, so that you're sure that you'll get it 100% correct. Read the
documentation for the CGI.pm module for more information.

Tore,

Thanks once again for the reply and answers. Yes, the html file is on
the same server as the script :)

In the beginning, I was going to grab the query string, do splitting
and so on, but someone said CGI.pm will do all that for ya. So I read
what was on some site and came up with the command to use CGI and the
$query->param...much easier and cleaner so definitly I'd like CGI.pm
to handle the redirect. I will search up on that and read and play
with it.

Thanks so much I learned alot.

regards,
 
J

Juha Laiho

(e-mail address removed) (Testor) said:
I am writing a simple perl script to learn in the process. The script
is supposed to grab a receipt number from the query-string and write
it into a file. ....
This works OK though not sure if it's the best way because I'm writing
duplicate receipt numbers.

Depending on what you're going to do with the file later (i.e. whether
you need that actual file to be in some certain format, or whether you
can utilise another program to extract the file contents for you), it
might not be a bad idea to look at "tied hashes". There the regular
properties of a hash would make sure you don't have duplicates, and
storing the hash contents into the file would be transparent for you.
 

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

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,158
Latest member
Vinay_Kumar Nevatia
Top