Database CGI

Overview
Objectives
Installing Apache
Installing Perl
Lesson 1
Hello World
Anatomy of a CGI Program
Hello World with CGI.pm
Lesson 2
HTML Forms and DOM
POST and GET
A Form Example
Lesson 3
Cookie Tutorial
Database Tutorial

Software Links
FAQ / Terminology
Contact the Author

 

There is nothing magical about database programming with CGI -- it is just as easy as any other CGI program, but different tools are added into the mix. After saying that, though, it must be noted that all web input must be thoroughly scoured to prevent security problems (do not trust anything you receive from a form submission!).

Let's take a look at a more elaborate CGI script:

      #!/usr/bin/perl
      use strict;
      use DBI;
      use CGI;

      # setup database connection variables
      my $user = "some username goes here";
      my $password = "some password goes here";
      my $host = "the host you want to connect to";
      my $driver = "mysql";
      
      # connect to database
      my $dsn = "DBI:$driver:database=cis430;host=$host";
      my $dbh = DBI->connect($dsn, $user, $password);

      # setup CGI handle
      my $cgi = new CGI;

      # start HTML
      print $cgi->header . $cgi->start_html('Some Tunes');

      # handle any queries that have been sent our way
      my $artist = validate($cgi->param('Artist'));
      my $song = validate($cgi->param('Song'));
      my $album = validate($cgi->param('Album'));
      if ($cgi->param('Query')) {
        my $sql = "select filename, artist, album, track, song from mp3s ";
        $sql .= "where artist like '$artist' "
          if (length $artist > 1);
        $sql .= "where song like '$song' "
          if (length $song > 1);
        $sql .= "where album like '$album' "
          if (length $album > 1);
        $sql .= "order by artist, album, track";
        my $rows = $dbh->selectall_arrayref($sql) || die $dbh->errstr;
        if (@$rows) {
          print "<table border=1 cellspacing=0 cellpadding=3><tr>" .
                "<th>Filename</th><th>Artist</th><th>Album</th><th>Track</th><th>Song</th></tr>";
          foreach my $row (@$rows) {
            print "<tr><td>" . join ("</td><td>", @$row) . "</td></tr>\n";
          }
          print "</table>\n";
        }
        else {
          print "<p><i>No matches found</i></p>\n";
        }
      }
 
      # display form
      print <<HTML;
      <form method="get" action="database.pl">
      <h3>Search for songs</h3>
      <blockquote>
        You can use a percent (%) for wild cards, and you can
        fill in as many or as few categories as you like.
        Search criteria must be larger than 2 characters,
        otherwise it is ignored.
        </blockquote>
      <h4>Artist</h4>
      <p><input type="text" name="Artist" value="$artist"></p>
      <h4>Song</h4>
      <p><input type="text" name="Song" value="$song"></p>
      <h4>Album</h4>
      <p><input type="text" name="Album" value="$album"></p>
      <p><input type="submit" name="Query" value="Search Tunes"></p>
      HTML

      # end HTML
      print $cgi->end_html();

      # disconnect from database
      $dbh->disconnect();
      exit(0);

      # validate user input to clean out garbage and sneaky people
      sub validate {
        my $string = shift;
        # get rid of all non-letter, non-numerical characters and percents
        $string =~ s/[^A-Za-z0-9%]//g;
        return $string;
      }
		

You can try out the program here:

http://inconnu.isu.edu/cgi-bin/perl_tut/database.pl

Some notes about the program:

  • There is no HTML file for this program. All of the necessary document data is contained within the CGI program, and a default page is displayed when there is no form data to show directly from the program. Results are shown only when the submit button was pressed (the line

    if ($cgi->param('Query'))

    tests if the CGI variable 'Query' is present, which happens to be the name of the submit button.
  • It connects to a MySQL database, but it could connect to any number of other databases including (but not limited to): Oracle, Sybase, DB2, ODBC, Postgres, Excel Spreadsheet, or even a dotNET server. See CPAN for a complete list of databases that Perl's DBD module can connect to.
  • The database can be on another machine, providing for simple n-tier connectivity and load balancing. The web (application) server handles this CGI code, but leaves some processing for the client and the database (back end) to perform as well.
  • This code isn't much more complicated than what we've already done, it just has more lines so that communications with the database can be established.

The schema of the table used in this example looks like this:

+----------+--------------+
| Field | Type |
+----------+--------------+
| filename | varchar(255) |
| artist | varchar(64) |
| song | varchar(64) |
| album | varchar(64) |
| track | int(11) |
+----------+--------------+

And, incidentally, the table was generated using the MP3::Tag Perl module from CPAN and a 10-line Perl program that searched all my files.


All pages written by Craig Kelley unless otherwise specified. Please use the Contact link from the menu to submit changes or suggestions. Permission is given to use this tutorial in any way you wish including re-publishing or "mirroring". The most up-to-date version of this document currently resides at http://inconnu.isu.edu/~ink/perl_cgi.

This page updated: May 6, 2002 22:21