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

Hello to all monks,

I am trying to do something which I am not sure is possible or not. (Can't even think if it's a good practice or not as this moment). I have created a dynamic webpage (perl v5.8) using cgi (Testing.pl) which when opened from browser pulls data from a MySQL table and show user in form of editable text fields.

User can modify any of those fields and when submit button is clicked, the changes are updated in the same table.

As of now I am checking each of the value that is displayed on webpage and can be changed by users and applying business rules on all those. But as these are 139 rows, after submit button is clicked, the page is taking 11 seconds to do all processing, update the DB and show the page with the changes.

In an attempt to reduce this time, I am trying to check if I can create an array (@compare_1) with values stored when user fetches the page and compare this array with a second array (@compare_2) which is created with the values sent over when submit button is clicked. Then I want to run all the business logic only on these changed vales.

I am trying with the code below and though the values are getting stored in arrays, but I can't save @compare_1 when the script is run for first time (when Testing.pl is fetched) and then use it for comparison when script is run for second time (when submit button is clicked on Testing.pl)

Is it possible to do what I am trying here? I have no knowledge of JavaScript and already facing hard time to maintain whatever JavaScript I have already used to display pop up messages etc.

Thank you for the time to read such lengthy post. Following is not running code but just snipet of my actual code related to this operation.

my $formStatus = $query->param('submitButton'); my $sql13 = "SELECT name, sub_name, good_high, critical_low, warning_l +ow, warning_high FROM comm_desk_thresholds WHERE user = ? "; my $sth13 = $dbh->prepare($sql13); $sth13->execute($userName); my @compare_1; while (my @row_13 = $sth13->fetchrow_array) {#Storing list of values w +hen page is loaded before submit button is clicked push @compare_1, @row_13; } if ( $formStatus eq "Submit" ) { # This code will run only when Submit + button is clicked my $sql14 = "SELECT name, sub_name, good_high, critical_low, warni +ng_low, warning_high FROM comm_desk_thresholds WHERE user = ? "; my $sth14 = $dbh->prepare($sql14); $sth14->execute($userName); print $fh "After $sql14 executed (Performance_2): ". localtime()." +\n"; my @compare_2; while (my @row_14 = $sth14->fetchrow_array) {#Storing list of valu +es after submit button is clicked push @compare_2, @row_14; } my @diff; for ( my $i=0; $i <($#compare_1+1); $i++) { if ( $compare_1[$i] ne $compare_2[$i] ) { push @diff, $compare_2[$i]; } } #Run business logic for only those elements in @diff. }
UPDATE: Changed subject line to mark Solved as NetWallah's suggestion worked for me.
  • Comment on [Solved]: Is it possible to save an array and use when then script is called second time?
  • Download Code

Replies are listed 'Best First'.
Re: Is it possible to save an array and use when then script is called second time?
by NetWallah (Canon) on Sep 21, 2015 at 20:06 UTC
    If you are avoiding JavaScript, you will need to save the values in @array1 as a HIDDEN field on the form.

    That way, when the SUBMIT is clicked, @array1 is returned via the param name of the hidden field.
    You can use that to compare with what you receive with the form fields.

    This method does have a potential security issue if the user tampers with the hidden fields.
    To avoid that, you may add an additional hidden "checksum" type field, or, preferably, persist the checksum somewhere in the database, or local temp file, or even a session variable.

            Software efficiency halves every 18 months, thus compensating for Moore's Law.

Re: Is it possible to save an array and use when then script is called second time?
by GotToBTru (Prior) on Sep 21, 2015 at 20:36 UTC

    Data::Dumper or Storable would work for the storage part of this; for help with an efficient comparison afterwards, I think Super Search here or search on cpan should provide a solution or at least ideas.

    Dum Spiro Spero
Re: Is it possible to save an array and use when then script is called second time?
by Perl300 (Friar) on Sep 23, 2015 at 16:38 UTC
    Thank you NetWallah, Anonymous Monk and GotToBTru.

    I am using NetWallah's suggestion for it's simplicity and seems like it'll work for me. I'll post update here once I get it working as I want it to.

Re: Is it possible to save an array and use when then script is called second time?
by locked_user sundialsvc4 (Abbot) on Sep 21, 2015 at 22:57 UTC

    Certainly, you could do this entirely on the server side ... and you might well prefer to do so.   Here, generally, is how it would work:

    (1) When the user selects a set of records to process, store the complete set of records in the Session data ... which, of course, is a standard feature of any web framework, and able to store any sort of hash/array structure for you.   Save a copy as the “changed record.”

    (2) As you build the HTML forms to be filled-out, include a record-ID in a hidden field.   This will identify, say, the ID of the first record that you included in the form.   Give each set of input-fields on the form a unique but arbitrary name.   Use the “changed record” as the data source.

    (3) When POST data is returned, decode the names and so-forth to update the “changed record,” noting also that changes have indeed been made.

    (4) When the user clicks the button that indicates he wishes to commit the changes (and, mind you, he might never) ... and, having also already processed all other POST variables ... compare the two to see what changed.   Consider presenting this information in a confirmation form.   Update the database accordingly.

    Since you have retained both a “before” and an “after” version of the record, taken at the same moment in time, you can also conveniently test to see if anyone else changed the data in the meantime.   Within an SQL Transaction, query the same set of records to see if any values changed.   If not, Update and Commit.   If so, roll-back and display an error message.