http://qs321.pair.com?node_id=599541

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

Magnanomous Monks,

Consider a typical database and a db management system written in Perl. Table "Users" has fields Name, Join_Date, and "User_Type". On the "Create New User" screen, the Name field that accepts free-text input, the Join_Date input is a date drop-down menu with year, month day, and the User-Type input is a drop-down with the three possible user types.

This arrangement means that part of the database specification - the allowable values of fields - is encoded into the html input page. That is, the database spec is disjoited, partly held in the definitions of the columns, and partly held remotely in other files.

I'd like to "correct" this by including all database specs in the database. I imagine a Perl-cgi generated input page instead of the static-html one. It will draw the necessary allowable-values information right from the database and dynamically generate the input form based on that.

The most likely place to store such information that I've come up with so far is in the COMMENTS field for columns (MYSQL). Then they can be retrieved with a SHOW FULL.

Then, in my Perl script, I'll have to have a CASE-type construct. If this field is defined as a free-text input, then output a text-box input. If it's defined as a limited-value drop down, get the values and generate a SELECT.

But, before I embark on this, I'm wondering what others have done with this.

Thanks.




Forget that fear of gravity,
Get a little savagery in your life.
  • Comment on Migrating database field values rules from Perl code to DB

Replies are listed 'Best First'.
Re: Migrating database field values rules from Perl code to DB
by dragonchild (Archbishop) on Feb 12, 2007 at 15:29 UTC
    Hookay! Let's start this answer with an explanation of APIs. You have two (maybe three) completely different and (mostly) unrelated applications working together. You have:
    • The database
    • The CGI script
    • The browser (if you're using JS validation)

    Just because the browser says it's an acceptable value DOES NOT MEAN that the CGI script believes it. Your data will NOT always come through the CGI script. And, likewise for your database! Your database is the be-all-end-all master arbiter of all things. If it doesn't safeguard its data, who will?!

    So, what you do is code up the restrictions EVERYWHERE. You replicate restrictions. This is defense-in-depth. The goal is to guarantee that you refuse a bad value, even if you accidentally refuse a good value every once in a while. Recovering from a refused good value is easy. Recovering from an accepted bad value can be impossible.


    My criteria for good software:
    1. Does it work?
    2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
Re: Migrating database field values rules from Perl code to DB
by talexb (Chancellor) on Feb 12, 2007 at 16:07 UTC

    If you're asking whether a form CGI can take its format from the structure of a database table, the answer is Yes.

    If you're asking if that's a good plan, the answer is Probably Not. :)

    The short answer to that is you'll probably end up in a situation where you don't want each column to be represented by a form field, so you'll start to make exceptions. And that way madness lies.

    Instead, I use Template::Toolkit to lay out the form, and I may use an array of field names in the CGI to collect information and put it into the database. That way, the CGI form field names are the same as the database field names. And I use CGI::Application as the application framework .. it works well.

    Alex / talexb / Toronto

    "Groklaw is the open-source mentality applied to legal research" ~ Linus Torvalds

    Update at 9am, February 13, 2007: I approved this post under Meditations because it doesn't ask a specific question, but rather a general, conceptual question. The anticipated answer would be general thoughts on the topic, and not Here's three lines of code that would solve your problem.

Re: Migrating database field values rules from Perl code to DB
by perrin (Chancellor) on Feb 12, 2007 at 15:18 UTC
    The right place to store allowable values for a field is in a separate lookup table, with a foreign key constraint that forces the value to be one of the keys from the lookup table. MySQL supports this just fine as long as you use InnoDB tables.
Re: Migrating database field values rules from Perl code to DB
by punch_card_don (Curate) on Feb 12, 2007 at 17:03 UTC
    Well, maybe there's more to it than I wrote originally.

    I imagine a Perl script with some generic form generation routines that take their directions from some specs held within the database.

    For example, for field_1:

    • at creation is to be displayed as a drop-down on the creation screen, with possible values a-to-z,
    • not be editable on a record-update screen
    • in a listing of records from the table, not be displayed if the user is of user_type=X.
    These parts of the database specification are going to be littered here and there throughout the system, in conditionals and template layouts. What I imagine is having these specs centralized within the database somewhere and then a generic screen form element generator script that takes its direction from those specs.

    Mmmmmm....I'm beginning to imagine a table of table column specs.....

    Table: specs table_name, field_name, creation_form_type, editable, view_types,....
    Something like that....but I fear a great deal of querying for every page generation.




    Forget that fear of gravity,
    Get a little savagery in your life.
      Any time you want to start putting application constraints into a database, you should stop thinking and just do the simplest thing possible. That will, most likely, not involve a database.

      My criteria for good software:
      1. Does it work?
      2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?

        I respectfully disagree with this assessment. While it is certainly true that you can overcomplicate your application for the next poor guy who has to maintain it by storing all kinds of application logic in a database, there are a couple of good reasons for storing allowable field values and other application configuration data in a database table or tables.

        Such reasons may include:

        • The entry field in question may appear in multiple locations throughout the application -- storing (and retrieving) constraints like this may save you from some ugly (and difficult to maintain) duplication of code.
        • You expect the allowable values for some of the fields to frequently change over time, and you'd like to avoid multiple trivial releases of your code.
        • Updating your code in production is fraught with red tape; in some corporate environments, database changes can often sneak under the wire, avoiding onerous (but unsophisticated) bureaucratic constraints.
        • You have a very large number of entry fields with a large number of similar attributes, and you want to simplify your application code.
        • You need to be able to re-configure your application on the fly in a distributed environment.

        I'm sure there are more reasons than this, but these are a few which come to mind, suggesting that the advice dragonchild offered above is not universally true.

        if the discussion is about putting code in your DB that apps should SELECT out and then run arbitrarily, I'd agree with you on moral grounds -- but there are lots of situations where the "data" for one application is "constraints" for another application.

        CMSs are a great example of applications where the person writing the application doesn't know what kinds of constraints the end user needs for their data, because the "content" is different for each installation -- so the "adminstrators" of the system enter the constraint data, and the "users" of the system enter the content that conforms to those constraints.

        Surely you wouldn't suggest that everyone who wants to install/maintain a complex application needs to write code to define how they wnat to allow others to use that application? you might rgue "that's what configuration files are for." but how is puting that information in a configuration file really any different then putting it in a database?