|
|
Question : File Update - Expert pitonyak please note.
|
|
Hi Experts, I have a flat file with records in 1000^email^platform^detail^status format. pitonyak and others helped me set up the script to generate the tracking number. now my requirement is: I have managed to get the data back into a form for update, now, when I click on update, I need a script which will scan my database, look for the track number, and update the changes, and if the status has changed, send a email. -Help , urgent requirement. PS: I am a newbee to perl.
|
Answer : File Update - Expert pitonyak please note.
|
|
OK, here is some code to perform the update. It aint quick and it aint robust. Shoot me a copy of what you finally use.
[email protected]
# # This is not a production safe routine. # Some issues it will not handle. # This will fail if the file does not exist. # File locking is not implemented. # This assumes that NO line is longer than $max_line_len # No check is made that the status is really the correct length. # I assume that you want a status longer than 10. # use IO::file; use StrFmt; use Fcntl ':flock'; # import LOCK_* constants
my $max_line_len = 100; my $status_len = 10;
sub add_record { # # You should probably add some error checking here # verify that that all of these have values # and see what happens when one of them is empty or something. # my ($file_name, $email, $platform, $detail, $status) = @_; my $fh = new IO::File;
if ($fh->open("+<$file_name")) { # # This allows things to run in a mult-user system. # but not implemented on my test system # #flock($fh, LOCK_EX); # LOCK_EX is probably 2 my $file_size = ($fh->stat())[7]; my $new_pos = $file_size - $max_line_len; print "File Size = $file_size\n"; my $next_num = 1;
if ($file_size > 0) { $fh->seek($new_pos, 0) if $new_pos > 0; while (<$fh>) { my ($tmp) = /^\s*(\d+)/; $next_num = $tmp if defined($tmp); } } ++$next_num; $fh->seek(0, 2); $status = StrFmt::right_fmt($status_len, $status); # padd on the left my $out_line = join('^', ($next_num, $email, $platform, $detail, $status)); print $fh "\n$out_line"; print "$out_line\n"; # but not implemented on my test system #flock($fh, LOCK_UN); # LOCK_UN is probably 8 $fh->close(); } else { print "Unable to open file $file_name because $!\n"; } undef $fh; }
sub update_record { # # You should probably add some error checking here # verify that that all of these have values # and see what happens when one of them is empty or something. # my ($file_name, $num, $new_status) = @_; my $fh = new IO::File;
if ($fh->open("+<$file_name")) { # # This allows things to run in a mult-user system. # # but not implemented on my test system #flock($fh, LOCK_EX); # LOCK_EX is probably 2 # # This is really ineffecient. I do a linear search # A better solution may be to perform a binary search # if the file becomes larger. # my $cur_pos = $fh->tell(); my $line = $fh->getline(); my $done = 0; my $this_num = $num - 1; while (defined($line) && !$fh->error() && !$done) { chomp($line); $this_num = (split /\^/ , $line)[0]; if ($this_num == $num) { print $line."\n"; $done = 1; } else { $cur_pos = $fh->tell(); $line = $fh->getline(); } } if ($this_num != $num) { print "WARNING, unable to find record $num\n"; } else { my $status_loc = $cur_pos + length($line) - $status_len; $fh->seek($status_loc, 0); if ($fh->tell() != $status_loc) { print "??Bad error, say something\n"; } else { # # A smarter person would verify the length of the satus first. # if (length((split /\^/ , $line)[4]) != $status_len) { # either print to this length or generate an error # } # my $status = StrFmt::right_fmt($status_len, $new_status); # padd on the left print $fh $status; } } # but not implemented on my test system #flock($fh, LOCK_UN); # LOCK_UN is probably 8 $fh->close(); } else { print "Unable to open file $file_name because $!\n"; } undef $fh; }
add_record('tst', 'email', 'OS/2', 'this is a test', 'status'); update_record('tst', 35, 'new status');
|
|
|
|
|