vsDB.pm Tutorial

vsDB is a Perl module that provides Perl programmers with a simple object-oriented interface for text-delimited data files.  The object model is very similar to Microsoft's ADO RecordSet object, so if you've used that, vsDB will be a bit familiar to you.  The primary difference is that you don't use SQL commands to retrieve data.  Instead, all data is loaded from flat files.  You use a Filter method to find individual or groups of records, and the Sort method to order your results.

If you have experience with data driven applications you may be wondering why you would choose vsDB as opposed to the Perl DBI modules, which support a wide range of database back-ends?  vsDB fits a particular niche that I have discovered while writing small applications to distribute as freeware.  Most end-users of Perl scripts fit one of two profiles: 1) webmasters with an account on a virtual server, 2) webmasters with their own personal Windows server.  Although installing DBI and a database server is not terribly difficult, it is beyond what the average webmaster is willing to do (and/or has the server permissions to do),  especially for a small utility-type application.  Furthermore, a full-featured database system may be overkill for a script to store a small mailing list, product listing, etc. 

vsDB is perfect for small applications, but I've used it with files of over 20,000 records.  It is fairly fast and has all the features needed for single-table applications.  Relational databases can even be simulated with clever programming.  Also, with some Perl trickery on your part, the end-user of your script does not even need server permissions to install new Perl modules.  You can create a simple data-driven application in minutes that will run on just about any server with no complicated installation.

Example 1: Create a new database file and add two records

The following program will create a new database with two fields "Name" and "Age."  It will add two records to the database, set the values for each record's fields, and save it to C:\database.txt.  You can copy/paste this code to a Perl script, or even run it directly from the Perl command line.  (If you are using a UNIX server, you should change C:\database.txt to an appropriate file path)  We'll use this datafile for the other examples, so keep the datafile that it creates.  This program is meant to run from the command line - not through web browser.

use vsDB;

# first create the database object
my ($objDB) = new vsDB;

# specify the filepath for our new file 
$objDB->File("C:/database.txt");

#this is a new database - add two columns 
$objDB->AddNewField("Name"); 
$objDB->AddNewField("Age"); 

# now add a new record and set the field values 
$objDB->AddNew; 
$objDB->FieldValue("Name","Joe"); 
$objDB->FieldValue("Age",8); 

# let's add a second record
$objDB->AddNew; 
$objDB->FieldValue("Name","Jim"); 
$objDB->FieldValue("Age",9); 

# looks good - lets save it to disk and close the database 
$objDB->Commit;
$objDB->Close; 

Example 2: Retrieve information from your database

Now that you have created the database with the first program, we can retrieve some records and print them to the screen.  Make sure that you have a file called database.txt on your C:\ drive (or wherever you saved it) 

use vsDB;

# first create the database object
my ($objDB) = new vsDB; 

# specify the file path and open the file 
$objDB->File("C:/database.txt"); 
$objDB->Open; 

# now loop through all the records, printing them one per line 
until($objDB->EOF) { 
    print"Name: " . $objDB->FieldValue("Name") . " "; 
    print "Age:" . $objDB->FieldValue("Age") . "\n"; 
    $objDB->MoveNext; 
} 

# all done - close the database
$objDB->Close; 

What we have done is open the datafile, then loop through all of the records in the file.  If you were running this at the command line, you would have seen the two records that we added to the datafile in Example 1.  If you tried to run this in a browser, you probably got a cgi error, because we didn't print the "Content-type text/html\n\n" header.

The most interesting part of this script is where we are looping through the records.  Notice that the until command loops until $objDB->EOF.  What the heck does this mean??!!  Well, EOF is a property of the vsDB object that stands for End Of File.  This means that when $objDB->EOF returns a True value, we have reached the end of our datafile.

vsDB uses the database concept of a "curser."  You move your computer's curser up and down in a document using the up and down arrows on your keypad.  Well, you can move the database "curser" up and down from one record to the next.  To do this, you simple call the method $objDB->MoveNext to move down one line to the next record.  In case you're curious, there's another method not used in this example called $objDB->MovePrevious.  That, of course, moves the cursor up one line to the previous record.  If you know exacly what row you want, you can call the AbsolutePosition method.  For example, $objDB->AbsolutePosition(2) would move the cursor directly to record number 2.

So, using the cursor we are able to retrieve the entire datafile - one record at a time.  When we want to move to the next record, we call the MoveNext method.  Each time we check the EOF property.  When EOF is True, then we know we have reached the end of the datafile - there are no more records.

Example 3: Update a record

This third example will open our datafile and update one of the records.

use vsDB;

# first create the database object
my ($objDB) = new vsDB; 

# specify the file path for data file and open it 
$objDB->File("C:/database.txt"); 
$objDB->Open; 

# move the cursor to a specific record 
$objDB->AbsolutePosition(2); 

# update the field values
$objDB->FieldValue("Name","Jerry"); 
$objDB->FieldValue("Age",10); 

# save it to disk and close the database 
$objDB->Commit;
$objDB->Close; 

If you open the datafile, you'll see that the second record has been changed from Jim, Age 9 to Jerry, Age 10. We updated record number 2.

You might have noticed that the FieldValue method is used differently in Example 2. Example 2 has one parameter, which is our field name ("Name") and ("Age"). In Example 1 and 3, though, it has two parameters ("Name", "Jerry"). When you submit only 1 parameter, vsDB assumes that you want to see what the value is for that field. When you submit 2 parameters, vsDB assumes that you want to change the value of that field.

Notes:

The above examples show you the 3 main features that you would normally need from a datafile. Inserting data, retrieving data, and updating data. In addition, Example 1 showed us how to create a brand new datafile programmatically.

There are several features that you will probably need that are not explained here. This includes sorting records, searching for one or more records Included with this module are a few example scripts. They should provide you with further examples for normal database functions. You can also check the documentation for vsDB.

One particular thing to notice is that the row number is used for locating a particular record in Example 3. Basically, we are using the actual file row number as the primary key for the data. This works fine as however you have to be careful when deleting or re-ordering the datafile, as you can update the wrong record. This method is especially dangerous if you're writing an application that more than one person will be using simultaneously. A safer way to do this is to create an ID field to use as a primary key. You simply increment the ID for each new record. (The Max method is helpful for finding the current largest ID). Then you use the Filter method to locate the record with the specified ID. This technique is used in the included example scripts.

Perl trickery to allow the script to look in the current directory for modules:

One of the best things about using vsDB is that you can create a script that will run on just about any platform with no administrative access to the server necessary. Most people with a virtual host don't have permission to install Pel modules. Using the following code, you can tell your script to look in a specific directory for modules. This requires two steps.

a) Perl modules are generally installed in the Perl path somewhere.  Not all Perl programmers realize that the Perl path is available to your program in an array called @INC.  You can add the current directory to this array, thus adding the current directory to the Perl path!  The trick is that you have to put it in the BEGIN clause so that it will be compiled by the Perl interpreter before interpreting the rest of the script.  (Otherwise it would compile the whole script first and would give you an error saying that it couldn't find your module!)  You can copy/paste the following BEGIN clause into your script.  All this does is attempt to find the current directory and then add it to the Perl path (@INC array).  You may or may not know that . stands for the current directory on many servers.  However, Windows servers are more picky, requiring the full path.

BEGIN {
  my ($currentDirectory);
  if ($ENV{'PATH_TRANSLATED'}) {
    my ($scriptPath) = $ENV{'PATH_TRANSLATED'};
    my ($directorySeparator) = "\\";
    $currentDirectory =  substr($scriptPath,0,rindex($scriptPath,$directorySeparator)); 
  } else { 
    $currentDirectory = "."; 
  }  
  push(@INC,$currentDirectory);
}   

b) The next step is just a slight modification of the way you would normally include a module for use in your script.  Normally, you would include a module like so:

use vsDB;

However, this will execute at compile time and can cause an error when Perl doesn't find your module.  You can instead force the module to load at run-time instead like so:

eval 'use vsDB';

That's it!  Now you can just include a copy of vsDB.pm along with your script and your end-user only has to save it in the same directory as the script.


Copyright 2001, Jason M. Hinkle