LAMP - Program Design with Perl

D

Dieter

Hi,

here I'd like to ask for your advice how to
generally code a certain task, not for the details.

O.K.- I try to express myself clearly:

* There's a HTML-form from which the user can choose
many different options (about 15) simultanously in
all possible combinations for a variable number of items
(batch mode).

So e.g. lets say, she can enter "apple, peach, cherry"
and request "color, taste, shape, short description"
out of a set of many other options.

* The CGI-script constructs a statement, depending on the desired
information and queries the MySQL database.

* Depending on what kind of information was requested,
the output from the database is formatted differentially
(headers, linebreaks ... ) and sent to the user.


Now, the system already runs fine just for a few options.
But with a about 15 options in different combinations
I don't want to end up with endless numbers of "if"-clauses.

Do you know a elegant solution, how to manage all the
different optional parameters ?

The problem appears on three stages:

* Parsing the POST data (request)
* Constructing the query for the database
* Handling the output


Maybe there are Perl modules to faciliate this kind of task ?


Dieter
 
A

Anno Siegel

[...]
Now, the system already runs fine just for a few options.
But with a about 15 options in different combinations
I don't want to end up with endless numbers of "if"-clauses.

Time for a timeless quote: "I don't know what your problem is,
but I suggest using a hash"

Seriously, if a cascade of if/elsif spins out of control, a hash is
often the solution.
Do you know a elegant solution, how to manage all the
different optional parameters ?

Consider a hash along these lines:

my %options = (
apple => [ qw( size color taste) ],
car => [ qw( size color seats fuel) ],
# ...
);

Note that a hash can also contain code to deal with specific situations.
Such a thing is called a dispatch table, and it is a very powerful tool.

Instead of writing

if ( $thing eq 'apple' ) {
# code to deal with apple
} elsif ( $thing eq 'car' ) {
# code to deal with car
} elsif ( ... ) {

you can construct a hash

my %action = (
apple => sub {
# code to deal with apple
},
car => sub {
# code to deal with car
},
# ...
);

and replace the entire if/elsif construct with

$action{ $thing}->();

Using hashes along these lines is one of the standard techniques in Perl
to deal with complex branching based on string values. It is very
maintainable when options (possible string values) are added, removed
or changed.

Anno
 
D

Dieter

(e-mail address removed)-berlin.de (Anno Siegel) wrote in message
Yes, I think this is going to the right direction.
The whole thing could be wrapped by "foreach" (see below).

It's not so easy to explain, but my main problem is
that I have to dynamically generate Meta-Information.
Since I don't know what kind of Information the user requests,
it has to be stored somewhere that the e.g. second column returned
from the database is 'color' and not 'size' or 'shape' .

Maybe I do it that way: slurp all parameters from the user
into a hash and then go through all possible parameters
with "foreach" and "if defined".

Maybe the trick is to name the parameters in the HTML-form
exactly the same as they are named in the database and store
the database information in an hash of hashes.


Thanks, Dieter
 
A

Anno Siegel

Dieter said:
(e-mail address removed)-berlin.de (Anno Siegel) wrote in message

Yes, I think this is going to the right direction.

What is? Please provide context. I have moved the rest of your reply
to the bottom. Please follow the preferred posting style.
The whole thing could be wrapped by "foreach" (see below).

It's not so easy to explain, but my main problem is
that I have to dynamically generate Meta-Information.

If you find it hard to explain, you have not fully understood your
problem yet.
Since I don't know what kind of Information the user requests,
it has to be stored somewhere that the e.g. second column returned
from the database is 'color' and not 'size' or 'shape' .

Does that mean that the second column of the database stores all
three types of data, and you must know from somewhere else what
it is?

Or are we talking multiple databases, each a key-value mapping
as in tied hashes? It's hard to comment unless you define your
terms more clearly. Or something else?
Maybe I do it that way: slurp all parameters from the user
into a hash and then go through all possible parameters
with "foreach" and "if defined".

No comment on that either, unless you say what you mean by "parameter"
Maybe the trick is to name the parameters in the HTML-form
exactly the same as they are named in the database and store
the database information in an hash of hashes.

That sounds distinctly like a bad idea. Don't tie data together that
underlie independent constraints. (Column-) names in a data base have
one syntax, parameter names in HTML-forms have another. They have
independent life cycles and change for different reasons. Don't force
them together. If those names are user-visible (still not sure what
exactly we're talking about), that's a further no-no.

Instead, it would be a job for a hash to associate user-chooseable
strings with the info needed to access the data base. Another hash
(or the same one) could store the info needed to display the data.
It's hard to be more specific at this point.

Anno
 
D

Dieter

(e-mail address removed)-berlin.de (Anno Siegel) wrote in message
Dear Anno,

thanks for your patience.
It's true that I first have to become clear about the problem.
Maybe it's simpler as I thought. Why not doing this:


%info = cgi -> Vars # What infos about which fruits are needed

#some code for parsing

foreach $fruit (@fruits){
do_this if defined $info{taste};
do_that if defined $info(color)
.....
}

Such a loop could be used for constructing the statement for the
database and also for formatting the output.

As I already said, the problem remains that I have to keep track
what kind of information is returned by the database.
One time the third column could be '"taste", next time it could be
"shape"
or "color". By the way, I didn't mention that the info from the
database
is sucked into an hash of arrays. The fruits are the keys and the
infos
are the values of this HoA. Maybe there's a better way.

Wait a minute, maybe this works also:
Just get the whole row from the DB, and then select the desired
information with the loop described above. Well, that's brute force,
since the rows contain a lot of data.


Best Regards, Dieter

If you find it hard to explain, you have not fully understood your
problem yet.

That's true, I admit.
Does that mean that the second column of the database stores all
three types of data, and you must know from somewhere else what
it is?

No, each piece of information is stored in its own column.

+cherry+red+sweet+"Cherries are delicious bla+ ...
+lemon+yellow+sour+"Lemon trees bla"+ ...

Or are we talking multiple databases,

No, definitely not.
No comment on that either, unless you say what you mean by "parameter"

Well, the options chosen from the HTML-form to
be queried from the database.

That sounds distinctly like a bad idea. Don't tie data together that
underlie independent constraints. (Column-) names in a data base have
one syntax, parameter names in HTML-forms have another. They have
independent life cycles and change for different reasons. Don't force
them together. If those names are user-visible (still not sure what
exactly we're talking about), that's a further no-no.

That's true. Might be a security issue.
 
B

Bill

That's true. Might be a security issue.

To give an example, do not think that the values given in your form
are the only ones that any user may submit. If the allowable colors
for a widget are blue and red, what if the user alters the CGI form to
submit a request for a white widget, and the database generates an
order for one on the back end?

You probably need a database table of valid values (a metadata
database). The CGI should validate data against this prior to changing
the database itself.
 
D

Dieter

Anno,

what do you think about "Tie::DBI" ?
Seems to be an interesting module.
Though one has to take significant
decrease of performance into account.


Dieter
 
D

Dieter

Anno,

what do you think about "Tie::DBI" ?
Seems to be an interesting module.
Though one has to take significant
decrease of performance into account.


Dieter
 
T

Tad McClellan

To give an example, do not think that the values given in your form
are the only ones that any user may submit. If the allowable colors
for a widget are blue and red, what if the user alters the CGI form to ^^^^^^^^^^^^^^^^^^^
submit a request for a white widget, and the database generates an
order for one on the back end?


The user does not need to modify the form to submit a request
for a white widget.

The request may not come from a "browser" at all.

An HTTP request is an HTTP request without regard to what kind of
program it was that generated the request.
 
B

Bill

Tad McClellan said:
The user does not need to modify the form to submit a request
for a white widget.

The request may not come from a "browser" at all.

An HTTP request is an HTTP request without regard to what kind of
program it was that generated the request.

All true, and irrelevant to the discussion?
 
C

ChrisO

Dieter said:
Hi,

here I'd like to ask for your advice how to
generally code a certain task, not for the details.

O.K.- I try to express myself clearly:

* There's a HTML-form from which the user can choose
many different options (about 15) simultanously in
all possible combinations for a variable number of items
(batch mode).

So e.g. lets say, she can enter "apple, peach, cherry"
and request "color, taste, shape, short description"
out of a set of many other options.

* The CGI-script constructs a statement, depending on the desired
information and queries the MySQL database.

* Depending on what kind of information was requested,
the output from the database is formatted differentially
(headers, linebreaks ... ) and sent to the user.


Now, the system already runs fine just for a few options.
But with a about 15 options in different combinations
I don't want to end up with endless numbers of "if"-clauses.

Do you know a elegant solution, how to manage all the
different optional parameters ?

The problem appears on three stages:

* Parsing the POST data (request)
* Constructing the query for the database
* Handling the output


Maybe there are Perl modules to faciliate this kind of task ?

I have to second Anno's suggestion that you look very hard at a
"dispatch table" setup using a hash. Very powerful stuff. You agreed
somewhat, but then I saw you spit out some more nested "if" constructs,
so I think it worthwhile to second Anno's suggestion on this method (eg.
dispatching).

Secondly, at the risk of further complicating things for you, if you are
willing to take the time to thoroughly understand it, an recent article
by Randal Schwartz may be helpful to you (from _Linux Magazine_, Feb 2004):

http://www.linux-mag.com/2004-02/perl_01.html

Also consider in your "web application mix" not only Class::prototype
(mentioned in Randal's article), but maybe even CGI::Application, and I
can't even imagine doing a web application without HTML::Template. At
the very least, HTML::Template can help get your mind off the
presentation layer and it's "connection" to your logic and allow you to
just focus on your logic.

Aside from the hint about dispatch tables, the rest of my suggestions
require some familiarization with Perl beyond the beginning stages;
judge for yourself to what level of Perl prowess you would place
yourself. But the article above could be helpful to you. Certainly
your discussion reminded me of it.

-ceo
 

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

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,007
Latest member
obedient dusk

Latest Threads

Top