Embperl and Databases

This month, Mr. Lerner returns to the subject of Embperl, showing us how it can be used to edit database records.
Creating our Table

This month, we will create a database consisting of a single table, a list of clients for a consulting practice. One of the central tables in this system is the Clients table, which contains basic information about each client.

Here is the SQL necessary to create this table:

        name VARCHAR(40) NOT NULL,
        address1 VARCHAR(40) NOT NULL,
        address2 VARCHAR(40) NULL,
        city VARCHAR(40) NOT NULL,
        state VARCHAR(40) NULL,
        country VARCHAR(40) NOT NULL,
        zip VARCHAR(40) NULL,
        contact_name VARCHAR(40) NOT NULL,
        contact_phone1 VARCHAR(40) NOT NULL,
        contact_phone2 VARCHAR(40) NULL,
        contact_fax VARCHAR(40) NULL,
        initial_contact_date DATE NULL,
        dollars_per_hour TINYINT NOT NULL,
        UNIQUE (name)

Again, we cannot enter this SQL directly into a relational database server; we must use a program that has been compiled with the correct client libraries. MySQL comes with a program (mysql) that allows interactive communication with the database; alternatively, we can use DBI to send the above SQL.

Each column in Clients is defined as a VARCHAR, that is, a variable-length text field. The length of the field is determined by the number in parentheses, which I set to 40 mostly to make other elements of the programming easier. (Over time, I expect to make most of these fields quite a bit shorter.)

The id field is special, not only because we define it as an unsigned integer (giving us the option of including up to 16 million different clients), but because it is set to be the “primary key”. As far as the database is concerned, each row can be identified uniquely with the primary key alone. We set id to AUTO_INCREMENT, meaning that MySQL will give the first client an ID of 1 in the archive file, the second an ID of 2 and so forth. Each client will receive an automatically generated, unique ID number.

We also declare the name column to be unique, since having more than one client with a given name could be confusing for the people involved. The database would accept several identically named columns, as long as the ID numbers were different. However, we will avoid the possibility of having two clients named “IBM” by checking for this in the database.

You may wonder why we didn't use name as the primary key, since it is guaranteed to be unique. We could have done so, and everything would work fine (perhaps a bit slower, since text strings are larger than integers). But consider what will happen if a client changes its name—we would have to update all of the references to that client, since old ones will no longer point to the right place. By making our primary key independent of any information the client changes, we can continue to keep track of the client regardless of what information changes.

Inserting Records into the Table

Now that we have defined our table, we will create an Embperl document that will let us insert new records. (Right now, our table is empty.) An Embperl document is largely the same as an HTML document, so you can use the <H1>, <P> and <Blink> tags as well as regular text, and it will work just fine.

However, you can insert Perl code within the Embperl document by putting it within special square brackets. Here are the four types of square brackets that Embperl understands:

  • [- CODE -]: Evaluate CODE.

  • [+ CODE +]: Evaluate CODE, inserting the final value into the HTML document.

  • [! CODE !]: Evaluate CODE as [- CODE -], but only once.

  • [$ Meta-code $]: Evaluate Embperl meta-commands.

Thus, we can include this statement:

[- $foo = 5; -]
and $foo will be set to 5—a value that persists over multiple invocations, since mod_perl and Embperl cache such values. If instead we include:
[+ $foo = 5; +]
then a “5” will appear in the document where the brackets were. If you are unfamiliar with the idea of a “final value from an expression”, you might want to end every Embperl block with the name of a variable. Variables return their values, so if you type:
[+ @reverse_list = reverse @list; $foo +]
then a “5” will be inserted into the HTML document at that point.

Listing 1, add-client.html, is a simple Embperl document that adds a client to the database. It does not check the data we hand it—since MySQL will do much of that for us—although it will show the user any database errors that might occur.