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

Happy Holidays Everyone. I have a question re editing entries in a flat database. I'm still relatively new at PERL and am learning new things every day :) . I know how to add and remove entries from a flat database, but would like to know how to edit entries. Here's the removal section of the program that I'm playing with:
if ($command eq 'Remove') { &header('<title>Remove Unwanted Postings</title>'); print " $head $pageadmin $mid<center>\n"; print " <table border=0 width=100% cellspacing=0 cellpadding=1><tr>< +td bgcolor=#CCCCCC><b>&nbsp;Remove Outdated Entries</b></td></tr></ta +ble>\n"; print " Select entries you wish to remove an then click the <B>Proc +ess Information</B> button below.<br>\n"; print " </center>\n"; print " <form method=post action=\"$cgiUrl\">\n"; print " <input type=hidden name=action value=Remove>\n"; print " <input type=hidden name=USER value=\"$USER\">\n"; print " <input type=hidden name=PWD value=\"$PWD\">\n"; open(MESG,"$mesgFile") || &error(mesgFile); @lines = <MESG>; $size = @lines; close(MESG); @lines = sort(@lines); #This should sort the lines by alpha order #Number,IP,Name,URL,URL,Date,Comments $totalPage = int(($size-3)/10 + .95); $totalPage = 1 unless ($totalPage > 0); if ($page > $totalPage) { $page = 1; } $pageEntryMin = ($page-1)*10; $pageEntryMax = ($page*10)+1; $entry = -3; # Init to -3, since 3 starter lines print " <table width=\"100%\"><tr>\n"; print " <td width=\"25%\" align=center><hr noshade size=4></td>\n" +; $entryPlural = "Entr" . ($size-3 != 1 ? "ies" : "y"); $pagePlural = "Page" . ($totalPage != 1 ? "s" : ""); print " <td width=\"50%\" align=center>Info: ",$size-3," $entryPlu +ral on $totalPage $pagePlural &#183; Current Page: $page</td>\n"; print " <td width=\"25%\" align=center><hr noshade size=4></td>\n" +; print " </tr></table><p>\n"; print " <table width=\"100%\">\n"; foreach $line (@lines) { $entry++; next if ($line =~ m/<!--Name\/Pwd: (.*):(.*)-->/); next if ($line =~ m/<!--Restrict IP: (.*)-->/); next if ($line =~ m/<!--Add Here: (\d+)-->/); next if (($entry<=$pageEntryMin) || ($entry>=$pageEntryMax)); @entry = split(/\cR/, $line); $EntryNumber{$line} = $entry[0]; $IP{$line} = $entry[1]; $Event_Date{$line} = $entry[2]; $Seminar_Topic{$line} = $entry[3]; $Seminar_Location{$line} = $entry[4]; print " <tr>\n"; print " <td align=center valign=top><input type=checkbox name=r +emove$EntryNumber{$line} value=$EntryNumber{$line}><br></td>\n"; print " <td> <font size=-1>\n"; print " <b>Event #:</b> $EntryNumber{$line}<br>\n"; print " <b>Event Date:</b> $Event_Date{$line}<br>\n"; print " <b>Seminar Topic:</b> $Seminar_Topic{$line} <br>\n"; print " <b>Seminar Location:</b> $Seminar_Location{$line} <br> +\n"; print " </blockquote><p><br><br>\n"; print " </td>\n"; print " </tr>\n"; push(@usedValues,$EntryNumber{$line}); } print " </table>\n"; print " <input type=hidden name=usedValues value=\"@usedValues\">\n +"; print " <center>\n"; print " <table width=\"100%\"><tr>\n"; if (($totalPage<=1) || ($page==1)) { print " <td>Previous Page</td>\n"; } else { print " <td>Previous Page<input type=radio name=prevNext value= +",$page-1,"></td>\n"; } print " <td align=center>\n"; print " <input type=submit value=\"Process Information\">\n"; print " <input type=reset value=\"Clear Form\">\n"; print " </td>\n"; if (($totalPage<=1) || ($page==$totalPage)) { print " <td align=right>Next Page</td>\n"; } else { print " <td align=right><input type=radio name=prevNext value=" +,$page+1,">Next Page</td>\n"; } print " </tr></table>\n"; print " </center>\n"; print " </form> $footer\n"; print "</body>\n"; print "</html>\n"; exit; }
Thanks for any help! Happy New Year All!

Replies are listed 'Best First'.
Re: Editing Entries In A Flat Database
by dmmiller2k (Chaplain) on Dec 28, 2001 at 02:49 UTC

    Some comments:

    • Use CGI.pm. It turns this:
      print " <td align=center>\n"; print " <input type=submit value=\"Process Information\">\n"; print " <input type=reset value=\"Clear Form\">\n"; print " </td>\n";
      into this:
      print td( {-align=>'center'}, submit( -value=>'Process Information'), reset( -value=>'Clear Form') ), "\n";
    • Instead of print statements on every line, try using a HERE document. You no longer have to explicitly insert \n characters or escape the embedded quotes, among other readability advantages:
      print <<"END_HTML"; <HTML> <HEAD> <TITLE>Document Title</TITLE> </HEAD> <BODY> Hello, World! </BODY> </HTML> END_HTML
      Once you get used to it, it's a much cleaner (and more efficient -- one call to print() rather than fifty -- way to express large amounts of literal text.
    • Try to separate your presentation code (HTML output) from your business logic (database code). It's more than a little difficult to see what's actually going on here, much less what you are trying to do.

        dmm

        You can give a man a fish and feed him for a day ...
        Or, you can
        teach him to fish and feed him for a lifetime
      It seems to me that everytime someone advocates using CGI.pm for HTML generation, they give examples that show (IMHO) no advantage over printing HTML in a 'heredoc'.

      I have found many cases where CGI.pm HTML functions are very useful (such as generating checkbox groups from data), but in cases like this, I find the HTML more readable.

      Impossible Robot
        IMHO there should be no HTML in Perl code at all. Neither in form of heredocs nor in form of CGI.pm method calls. Use templates!

        --
        Ilya Martynov (http://martynov.org/)

        Perhaps you're right. That was a bad example. One way CGI.pm shows its usefulness which seems to been obscured here is with deeply nested constructs (table within a table within a form, etc.).

        By replacing the BEGIN/END (tag) paradigm with a nested function call paradigm, CGI all but eliminates the kind of unbalanced tag nuisances one frequently encounters when generating HTML dynamically.

        IMHO, I find looking at naked HTML (in a HEREDOC or otherwise) annoying for its waste of space (I suppose XML rubs me much the same way) and its near-redundancy; I dislike typing it even more.

        I suppose the advantage is better illustrated with this comparison:

        <FORM METHOD='POST> <INPUT TYPE="hidden" NAME="mode" VALUE="confirm"> <TABLE BORDER=0> <TR> <TD> <TABLE WIDTH='100%'> <TR> <TH>ColA</TH> <TH>ColB</TH> <TH>ColC</TH> </TR> <TR> <TD>Value A</TD> <TD>Value B</TD> <TD>Value C</TD> </TR> <TR> <TD><INPUT TYPE="submit"></TD> <TD><INPUT TYPE="reset"</TD> <TD>&nbsp;</TD> </TR> </TABLE> </TD> </TR> </TABLE> </FORM>

        Compared with:

        form( { -method => 'POST' }, hidden( -name => 'mode', -value => 'confirm' ), table( { -border => 0 }, Tr( td( table( { -width => '100%' }, Tr( th( [ 'ColA','ColB','ColC' ] ), td( [ 'Value A','Value B','Value C' +] ) td( [ submit, reset, '&nbsp;' ] )) ))) ) )

        Oh, you want to write all that to the browser?

        print form( { -method => 'POST' }, hidden( -name => 'mode', -value => 'confirm' ), table( { -border => 0 }, Tr( td( table( { -width => '100%' }, Tr( th( [ 'ColA','ColB','ColC' ] ), td( [ 'Value A','Value B','Value C' +] ) td( [ submit, reset, '&nbsp;' ] )) ))) ) )

        dmm

        You can give a man a fish and feed him for a day ...
        Or, you can
        teach him to fish and feed him for a lifetime
Re: Editing Entries In A Flat Database
by chip (Curate) on Dec 28, 2001 at 01:01 UTC
    It's not clear to me what you are trying to do. Could you try separating the CGI code from the rest of it? Databases and HTML need not go hand in hand, you know.

        -- Chip Salzenberg, Free-Floating Agent of Chaos

Re: Editing Entries In A Flat Database
by chromatic (Archbishop) on Dec 28, 2001 at 05:54 UTC
Re: Editing Entries In A Flat Database
by simon.proctor (Vicar) on Dec 28, 2001 at 08:36 UTC
    Another solution to this is to use splice and insert/remove lines from your file. This involves you reading the whole file into an array (or into a scalar and calling split) and then writing the whole array back out again.

    I notice that you skip on certain lines whilst moving about the array and printing it out. As long as you keep a track of the line index - the above method should work regardless.

    I have used this method on a basic .htaccess file manager in the past with success. However, I would argue that it is only viable for a low usage system. I would also recommend that you consider making regular backups (you do do that? :P)
Re: Editing Entries In A Flat Database
by Ryszard (Priest) on Dec 28, 2001 at 17:31 UTC
    A slight aside comment on your code style, why not use an 'anti match' rather than a massive 'if'. something like exit unless ($command eq 'Remove')

    On the other hand if there are multiple conditions, you could use a if..then..else type of construct, and branch away to different subbies

    Like everyone else, i would recommend using CGI.pm, and if you're doing a structured site (rather than a one off script) check out CGI::Application. It will rock your world.

    Geeze i'm easily rocked..