CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Intermediate:
pulling hair out trying to replace data in a flatfile!!

 



DSelver
Novice

Nov 7, 2000, 1:21 PM

Post #1 of 8 (795 views)
pulling hair out trying to replace data in a flatfile!! Can't Post

How does one replace ONE line in a flat file database with updated information!!!

I start with a comma delimitted text file with the following fields. ordernumber,price,description,id,emailaddr,name,address1,address2,city,st,zip,tracking,insurance.

The initial web page allows the user to enter in either the ordernumber, their ID, or their email addres. Once entered the cgi script will open the flatfile and pull the info and populate an HTML form with certain information.

The user then adds in their shipping info and checks whether they want tracking or insurance and submits it.

So, now that I have this data, how do I write it back to the file! HECK! I can't even write it back to the screen!!!

Can one read a file one line at a time and then replace it? or am I going to have to read in the entire file and write the ENTIRE file back out.

here is a snippet of how I'm trying to write the data back out to the database file. I've tried so many things that I don't even know where I've left off! I think I'm missing at least a '>' when I do a print OUTF... HELP!

<BLOCKQUOTE><font size="1" face="Arial,Helvetica,sans serif">code:</font><HR>


# Assign the variable $wid to equal the value of the
# web $form(id) key
$wid = $FORM{'id'};

#open the file or terminate if error
open(INF,"test.txt") or dienice("Couldn't open auctions database for reading: $! \n");

#put the file into an array
@data = <INF>;

#close the file
close(INF);

#break the data into lines and begin loop
foreach $line(@data) {
chomp $line;
($itemnum,$price,$desc,$id,$emailaddr,$name,$addr1,$addr2,$city,$st,$zip,$tracking,$insurance) = split(/\,/,$line);

#compare the web form ID with the id field in the database to locate a match
if ($wid eq $id) {


open(INF,"test.txt") or dienice("Couldn't open auctions database for reading: $! \n");
while (<INF> ) {
chomp;
($itemnum,$price,$desc,$id,$emailaddr,$name,$addr1,$addr2,$city,$st,$zip,$tracking,$insurance) = split(/\,/,$line);

#got sick of failing! attempting to PRINT the current database line to the browser
# to see if it's even working
print "$itemnum,$price,$desc,$id,$emailaddr,$name,$addr1,$addr2,$city,$st,$zip,$tracking,$insurance";
}
close(INF);
# open(OUTF,"> test.txt") or dienice( "Can't open database for writing!");

#lock the database file.
# flock(OUTF,2);
#send the output back to the file.
#print the UPDATED line to the browser to see if the updates are even there!
print "$itemnum,$price,$desc,$ebayid,$emailaddr,FORM{'$name'},FORM{'$addr1'},FORM{'$addr2'},FORM{'$city'},FORM{'$st'},FORM{'$zip'},FORM{'$tracking'},FORM{'$insurance'}\n";

#write the file out to disk
# print OUT "$itemnum,$price,$desc,$ebayid,$emailaddr,FORM{'$name'},FORM{'$addr1'},FORM{'$addr2'},FORM{'$city'},FORM{'$st'},FORM{'$zip'},FORM{'$tracking'},FORM{'$insurance'}\n";
# close(OUT);
#end of sending output to the file.
</pre><HR></BLOCKQUOTE>


sleuth
Enthusiast / Moderator

Nov 7, 2000, 2:10 PM

Post #2 of 8 (795 views)
Re: pulling hair out trying to replace data in a flatfile!! [In reply to] Can't Post

 
Ok, what you need to do is this. Take one field that is uniqe to that person. For instance their ID. Now, if you have their id you can do exactly what you want. just like this.

First of all, you are going to have to write All of the data back to the file. But the good news is you won't have to work hard for it and the line posistions won't change. Now since you look like you know perl pretty well, I'm going to write out the code and it should explain it self.

I'm going to assume that the very first field is the id and that the id is passed to the program via hidden value through the form. I take it the id is stored in "$wid".

<BLOCKQUOTE><font size="1" face="Arial,Helvetica,sans serif">code:</font><HR>


$data = "data_file.db";
open(data, "<$data");
while(<data> ){
(@res)=split(/,/, $_);
if ($res[0] eq "$wid"){
push(@new "$wid,$form{'field2'},$form{'field3'}\n");
}else{
push(@new,$_);
}
}
close(data);
open(new_data, ">$data");
print new_data @new;
close(new_data);
</pre><HR></BLOCKQUOTE>

The only thing you should have to change is

push(@new "$wid,$form{'field2'},$form{'field3'}\n");

And the $data variable.

The Line above using push, you'll have to take all of the values from the form and recreate the line. The line's posision will not change in the file.

Do you understand how I did that?

If not than just post again :)

Sleuth


DSelver
Novice

Nov 11, 2000, 11:32 AM

Post #3 of 8 (795 views)
Re: pulling hair out trying to replace data in a flatfile!! [In reply to] Can't Post

ok..I see what you are doing, but I must be having some other problem.. Let me go through your code and explain it back to you...that way you can make sure I understand it.

----------

#assign a string value to equal the data file
$data = "data_file.db";

#open filehandle DATA for reading using string value $data (from above)

open(data, "<$data");


#begin parsing the fields of the data file..

while(<data> ){

#..into the array @res and separate the fields of each line ($_) on the comma.

(@res)=split(/,/, $_);

#if the first field[0] of the array '$res' equals the "widget id" then
if ($res[0] eq "$wid"){

#push onto a NEW array stack any new values desired.
push(@new "$wid,$form{'field2'},$form{'field3'}\n");

#otherwise
}else{
#push the current line ($_) as is into the new array

push(@new,$_);
}
}

#quit reading the input file
close(data);

#open a new file handle for output using the previously assigned $data string

open(new_data, ">$data");

#Print the @new array into the new_data file handle
print new_data @new;

#and close the new data file handle
close(new_data);

---------------------
ok...well now that that's over, I couldn't get it to work. I have two possible issues going on here...and a question

1) I made a basic cgi script to test my new line ( \n ) function in perl! it's NOT working. check this out..

<BLOCKQUOTE><font size="1" face="Arial,Helvetica,sans serif">code:</font><HR>


#!/usr/bin/perl
print "Content-type: text/html\n\n";
print "this is the first line.\n\n";
print "this is the second line.\n\n";
die;
</pre><HR></BLOCKQUOTE>
my results were...

this is the first line. this is the second line.

all on one line! UG!


2. I think I am screwing up the passing of variables from one script to another. I added this line at the bottom of my split routine...
print "($name - $value)\n\n";
... This shows me that the fields ARE being passed and split properly, but When I try to use one in a print statement...
print "Widget id = *$FORM{'wid'}*";
...all I get is...
Widget id = **

sooOOoOOooOOooo. I'm going to keep working on this and see if I can get it working....

I suppose the routine is not writing to the file because I can't properly get the information TO write.

Still working at it!

3. Should I have to worry about issuing a flock command??


sleuth
Enthusiast / Moderator

Nov 11, 2000, 1:25 PM

Post #4 of 8 (795 views)
Re: pulling hair out trying to replace data in a flatfile!! [In reply to] Can't Post

 
Naa, Flock is only good for when your getting a lot of usage on one script. If it's just you then don't worry about it, but if you're getting more than say .... 100 hits on that script a day then yes.

To flock do this.

use Fcntl;
open(data, ">$data");
flock(data, 1);
close(data);

I learned that most programmers don't close there flocks. Because when they close the file perl takes care of the file lock.

Instead of 1 in the flock(); statement, you can use 2, 2 is to use the file exclusivly, and 1 is to share it.

You understand the code very well.

When you print "test\n\n";

It will show as one line if in your browser. When you do that. View the source, and see that it does print the newlines.

About the FORM{'wid'}, this will only print something if you have it being passed through the form, Say you pull up a line in a file for editing. You want to use some piece of information to grab the right line right? So you can use most likely a name & password, or an email address, whatever, as long as it's a unique element. Another wards, you can't have two lines for the same user name because it's usually one per user. As long as one field doesn't exists more than once, that's the one you want to use. I'll write as if you pull up a line by user name.

<BLOCKQUOTE><font size="1" face="Arial,Helvetica,sans serif">code:</font><HR>


open(file, "<$data");
while(<file> ){
($user_name, $password, $id, $tmp)=split(/,/, $_);
if ($user_name eq "$FORM{'user_name'}"){
print qq~
<form>
content
</form>
~;
last;
}
}
close(file);
</pre><HR></BLOCKQUOTE>

You see, that way the use can pull up the user's information for editing. Of course you are already doing this, but my point is that when you do this procedure you must add one thing in the form. And that is a hidden value,

<input type="HIDDEN" name="id" value="$id">

That way when you go to edit the line using the code I wrote in the previous code, you can grab the line again by using their id. $FORM{'id'} will now work.

If you still are having problems, send me your code & data base, then I'll find what was wrong and let you know what to do to fix it.

Slueth


DSelver
Novice

Nov 11, 2000, 5:25 PM

Post #5 of 8 (795 views)
Re: pulling hair out trying to replace data in a flatfile!! [In reply to] Can't Post

SUCCESS! Thanks.

Flock WILL be necessary. I will add it after my celebratory 'adult beveridge' though. It's break time!

I had SOME of the 'hidden' fields being passed through. Once I got the script working, and corrected the file rights on the database I noticed that there were two more missing.

Now comes the clean up and the beautify-ing of the whole mess.

If someone puts a comma (,) in a field it obviously screws things up. Would this be the correct split format?
split(/\",\"/, $_)

this should split on the ","

So many rules to remember!!but I think the \ must preface a quote (") mark...at least in a print command it does...
Any other gotchas?? what if a user puts a quote mark in a field?! ug! Can anything be made idiot proof??

Hey, THANKS for your help!

[This message has been edited by DSelver (edited 11-11-2000).]


sleuth
Enthusiast / Moderator

Nov 11, 2000, 11:57 PM

Post #6 of 8 (795 views)
Re: pulling hair out trying to replace data in a flatfile!! [In reply to] Can't Post

 
Your welcome DSelver,

Not many more gotchas, just look into regular expressions some more. Then you will find em all out, regex is the best thing to know in perl in my opinion. It's helped me out soo much. I don't think you have to escpe a quote in split, because it doesn't mean to do anything when in split. Things that you would have to escape are, a period, a backslash, & * ^ $ @ ! ( ) and maybe a few others I'm missing.

But you always know when you forget to do it when you try and read a field or something, so don't stress about it. Time will teach you, he he.

My favorit way to split a field is by using |^|, not a comma or : or "," |^| seems to never come up in a form field.

Plus, unless someone types in exactly what your using to split the fields, it won't screw with your script. Plus, it depends what your doing with their input. You should always check ahead and make sure that if they type in a comma and your using that to split your fields. Like so,

$FORM{'bla'} =~ s/,//g;

I also just got back in from the Theaters, Men Of Honor, was the best movie I've seen in a while, and I was not looking forward to seeing it either, I was killin time until Red Planet started, then I saw Red Planet, and it was terrible. Don't pay to see it! Men of Honor: A++, Red Planet: F--

Just a little note.

Have a good one,

Sleuth


DSelver
Novice

Nov 12, 2000, 4:04 PM

Post #7 of 8 (795 views)
Re: pulling hair out trying to replace data in a flatfile!! [In reply to] Can't Post

What's REGEX?

oh, and the reason I'm using "," is because I have another program that will need to READ in the data.

So how/where/when did you get so good at PERL?! I've been working off an on with PERL for about two years. I've mostly done output to file, or append to file. This is my first update procedure. There is so much more one has to know what with the reading, sorting, parsing, arrays -- PHEW! I'm sure glad there are gurus around like you.

Thanks for the heads up on Red Planet.


sleuth
Enthusiast / Moderator

Nov 12, 2000, 5:43 PM

Post #8 of 8 (795 views)
Re: pulling hair out trying to replace data in a flatfile!! [In reply to] Can't Post

 
He he, yea, Red Planet was a big disapointment :(, heh

I started perl almost exactly 1 year ago. About 11 months really. I started learning so much about it because I just, well, it was required of me to push on and learn every ounce that I could get a hold of. Parsing is my favorite. I caught a big break working for a search engine and we write all of our own scripts. That's why I learned a bunch here & there because of the large variety of scripts that were needed. I'm just glad I didn't make the mistake of jumping into C++ b4 perl :). Still havn't started c++ too. Perl is just to cool to stop using.

Regex is short for Regular Expressions. it's mostly data manipulation by finding patterns in the data. like so:

$text = "This is a piece of text";
$text =~ s/^\w+/That/g;

That would take This & turn it into That. If you get a book on perl, you will better understand regex. It's really simple when you learn what all the operators mean. Like ^, $, *, . they all mean to do something & when you know that you just start putting them together and making up cool stuff. :)

I recommend "Perl Little Black Book, Core Language", it's a fine book. Great regex chapter, I read it like 5 times and then I understood a lot more.

Guru's here would be Kanji, Japhy, rGeoffrey, Cure, And Jasmine (Admin). They just probably get a little busy to make it around here at times so that's why I said I could help with what I can. I'm a novice to them.

I took the name Sleuth because I wanted people to know I would do the digging for them. I learn a lot from helping others in any way I can.

Sleuth

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives