Learning RACE

RACE and Database Access

RACE was primarily created to make database access easy, and here's a short example of it in action. We'll walk through an easy, single-page "guestbook" style application.

This tutorial assumes you have RACE configured with MySQL support. Refer to the respective installation documentation or your host's support/admin center for details.

Now, we need to create a database. In your favorite MySQL client, create a new database called "race_examples" and execute this statement in it:

To avoid making this a SQL how-to, we'll keep everything in one table for simplicity. If the above CREATE statement doesn't make sense, a little SQL primer may be in order - www.mysql.com/doc will get you into shape.

Now that we have our db table, we're ready to dive in. Open up a new file in your text editor and save it as defs.race - it'll be a central location for a couple tags we'll define. Since this is pretty much a one-page app it's not really necessary, but once you take this to a "real" site environment and merge it with other code, you'll see how indispensable it can be.


An explanation is in order. We're defining two tags here (rather, one tag and one macro). The <db> tag is just a "wrapper" for the standard <database> tag. It does exactly what <database> does, but with a lot less typing. It also catches & displays any error messages the database server returns. And by storing it in an includeable file, we can store our database name and username/password info safely in one spot.

Make sure to replace the "USERNAME" and "PASSWORD" attributes with your proper MySQL username and password. For this application, you'll need at least SELECT and INSERT permissions on the table.

The .quote() macro we've created is a mess of <translate> tags to convert certain characters (semicolon, single- and double-quotes, and backslashes) to make them safe for running in SQL queries. Because the definition doesn't have the "balanced" attribute, it's safe to use as a macro (i.e., <$variable.quote()>) instead of a balanced tag (<quote><$variable></quote>). It's a little easier to type and your queries will be a little easier to read.

Our base is complete, and we can move on to some real coding. Create another new text file in your editor and save it as guestbook.race. Let's assume we are putting this in an existing site and have a common header and footer, stored in files called header.race and footer.race respectively. All we need to worry about is what gets put in the main area.


That will list the 20 most recent messages. What we're doing here using a query that will select every record from the guestbook db table ordered newest first and limiting it to only 20 records. We pass that to our <db> tag, and everything in the tag will run on each record returned. Similar to looping a Recordset object in ASP, or PHP's mysql_fetch_row() function, if you're familiar with those.

Inside the <database> tag (and therefore our <db> tag), all of the fields will be accessible by special variables. Given our database structure and SELECT query, we'll have: <#ID>, <#date_posted>, <#author>, <#subject>, and <#message>. They only exist within the body of the <database> (<db>) tag, so we would need to define new variables with their values if we wanted to use them outside of it.

Another special variable, <$database.rows>, gives us the number of rows the query returns (and it continues to exist outside of the loop, like <$database.error>). We added a little <if> test to make sure that a message is returned in case nobody's posted anything yet.

Also, note the use of the <date> tag. We pass <#date_posted> to it because MySQL's standard "2003-06-30 11:43:28" format isn't too pretty. Consult the RACE documentation to format the date to your taste.

Now we need to let our visitors post messages. Add this form under the current code:


<$system.document_name> is a special variable that will return the name of the current document. This makes it easier for us - we can rename guestbook.race to whatever we want, and the form will automatically post to that name.

Finally, we need to add the new messages to the database when people post them. We aren't going to do any error-checking or require any fields, we'll just assume everyone's nice and accept whatever comes in. We should process it before the posts are displayed, so it'll be shown as the newest post. See the "[This space reserved]" comment in the code above? Replace it with this code:

Easy enough, if the hidden "action" field exists, then the posting form was submitted. All we need to process it is a simple SQL INSERT. It uses MySQL's NOW() function to insert the current date, and the .quote() macro to escape any apostrophes, semi-colons, and other SQL-breaking characters. The <db> tag won't return anything when inserting or updating unless there's an error, so we'll just close it off.

Save the files and upload them to your server, and you've got a simple guestbook, ready for you to tweak. Try using RACE to make certain fields required (<if test="<$author> == ''"></if>), add a couple fields to the database and form (email address, age, etc.), or even an administrative interface where you can moderate the posts and remove any inappropriate messages using a SQL DELETE on the ID number. Good luck!

(Note: if you tweak this enough to make a good guestbook app and would like to share your code for others to learn from, we'd love to host it here! Contact support@racekit.net for details.)

Previous Learning RACE Features
Creating a RACE Mail Form

Current Version

Current Stable Build

Previous Stable Build

Log In

not logged in. (who's online? )
log in or register free!

Feature RACE Site

US Grand Prix
The US Grand Prix has used RACE for the past 2 years for their volunteer registration.

RACE Survey

We want to hear from you!
If you have a minute, take a look at our RACE survey.

Copyright 2003 Riverwatcher, Inc.