Automating Backup Procedures

By Tom Cone

Tom (tcone@ix.netcom.com) has a backup button in his Alpha Five application that zips up his data  files onto a floppy disk for transport from home to office and vice versa. Here's how he does it.

The natural law of entropy dictates that all systems in the physical world break down. This is true for computer systems, too. Important data can be lost, often at great expense, unless duplicate copies are not safely and frequently preserved. It's been my experience that the probability of having a recent backup on hand is inversely proportional to the complexity of the backup system. The greater the complexity, the less likely that your user will employ it. An elegant, comprehensive, backup routine does the user little good if it is run infrequently or not at all.

This article describes a simple system which works quickly and easily to create a duplicate copy of your database tables on diskette. The techniques used below can be extended to cover other types of files, including, if you wish, all the files in your database's folder. In addition, I will suggest ways to modify the code to permit the user to specify alternate backup locations.

The goal of this exercise is an Xbasic script which will be attached to an OnPush event for a button (called "Backup") on your main menu form. The user presses this button, inserts a diskette, and then picks Drive "A:" or "B:" from a screen which pops up automatically. The backup proceeds to identify and compress copies of the database tables, and then zips them into a "zip" file on the diskette.

In doing this I have assumed the following conditions will exist:

  1. First, I assume that all the database tables will be found in a single folder (directory) along with your database itself. This is the design recommended by Alpha Software.
  2. Next, I assume that you own, or can obtain, a copy of PKZip (Command Line for Windows, Version 2.5). This is available for $29 from PKWare, Inc., (www.pkware.com) and I highly recommend it to you. It's fast, accurate, and produces tightly compressed copies of your tables. This is important because the fixed length DBF format used by Alpha Five lends itself to good data compression ratios. In my case the uncompressed size of my data tables totals 4,757 kilobytes (about 4.7 megabytes). After compression, they exist inside a single zip file which is only 643 kilobytes in size (about 0.6 megabytes). Instead of a handful of floppy disks, I can easily get by with a single one, and have plenty of room left over since each floppy can hold up to 1.44 Mb. This version will also automatically span diskettes for you if your compressed files won't fit entirely on a single disk.
    (Caution: Do not use earlier versions of PKZip without verifying that they handle the new long filenames which you may have used when you named your data tables within Alpha Five. Several of my tables and forms have lengthy filenames. Windows 9x is quite happy with them. But DOS is not, insisting on truncating long filenames to the old 8.3 standard. Well, I'm sad to report that I was unaware of this wrinkle, and zipped up my entire database using the DOS version (2.04g). I then took it to the office, and, without checking to see what would happen, confidently "unzipped" all the files into my database folder there. Oops! All the long filenames had been changed, and my application was broken. Not a pretty picture!)
  3. Lastly, I assume that "PKZip25.Exe" is located in the same folder as your data. This is probably not the best choice, since you would need to store extra copies of the program in each data directory if you run more than one database with Alpha Five. I'd recommend you consider storing it in the folder with your Alpha Five program files, instead. This would necessitate small changes in the code shown below. In the meantime, I've put my copy of "PKZip25.Exe" in the data folder to simplify the discussion which follows.

So much for the hors d'oeuvres. Now for the meat and potatoes

In pseudo code this is what our script needs to accomplish:

  1. First, we have to find where the data tables are located. This may be on the local workstation, in the case of a stand alone system, or it may be out there somewhere on the network.
  2. Next we quiz the user to find out whether he or she wants to backup to Drive "A:" or "B:" While most new systems only have a Drive A:, plenty of older units are still out there with both. The technique illustrated below relies on a simple Radio Button Object. This could be easily modified to permit the user to specify alternate destinations and filenames for the backup files, using the ui_get_file() function.

    Figure 1. Choose A: or B: Drive

  3. Then we build a custom batch file and save it. This contains the DOS commands necessary to invoke PKZip, in such a way that it knows what name to give to the resulting zip file. Importantly, this batch file also tells PKZip which files to include in the zip file. The batch file is a simple DOS text file, and can be assembled, line by line, using the <file_pointer>.write_line() functions in Alpha Five. This may seem like extra work, especially if you feel certain that the user will never want to change the destination for the resulting backup files. However, doing it this way is necessary if you ever want to permit the user to use the ui_get_file() function to find and specify a different filename or location for the zip file PKZip will build. Building the batch file in real time will give the user greater flexibility and control.
  4. Then we shove Alpha Five into the background, and run the batch file we just built.

Figure 2. The batch file has just finished...

Here's the actual code:

'xbasic
'by tom cone, 5-15-99
'backup data files to A: or B: drives
'Note: on startup PKZip25 is already stored in data directory
'Save path to database to a variable
alb_directory=:a5.get_master_path()
'find path to actual tables in 'shadowed environment
 'this function requires vers. 4.01 or higher
 'and will return empty string if system is
 'not shadowed.
if len(trim(alb_directory))=0 then
' not shadowed, so find local path to database
 alb_directory=:a5.get_path() 
end if
'now find out where the user wants to put the backup
'ask A: or B: 
response=ui_get_radio("Choose Destination for Backup\ 
	File",1,"A:","B:")
'The backwards slash in the preceding statement is
'Alpha Five's line continuation character...
'bailout if user cancels
if len(trim(response))=0 then
 end 
end if
'At this point, user has selected destination, and it's stored in 
'a variable called response
'so now we build the batch file in the data directory
'Concatenate the path to the database with a name for the batch file.
' Lets call it mbrsbak.bat
filename=alb_directory + "\mbrsbak.bat"
'Note: this code will create a new batch file and will overwrite
'any file with same name
'Now create the text file which will become our batch file.
p_file=file.create(filename,file_rw_shared)
'now build the batch file, one line at a time
p_file.write_line("PKZip25 -add "+response+"\mbrsbak *.dbf")
p_file.write_line("pause")
p_file.write_line("exit") 
'now flush buffer and close file
p_file.flush() 'this forces the buffer to be written to disk
p_file.close() 'this closes the file and releases the pointer
'ok, the necessary batch file is in place and, in my case, results in
'a batch file that looks like this:
 'PKZip25 -add A:\mbrsbak *.dbf (Line 1 of batch file)
 'pause (Line 2 of batch file)
 'exit (Line 3 of batch file)
 'Line 1 will tell PKZip to compress all files that have a DBF
 'extension and store 
 'them in a single zip file called MBRSBAK.ZIP on Drive A:\ 
 'Line 2 will tell the DOS session to pause, so the user can 
 'see which files were 
 'included as PKZip works its way through all the data tables.
 'This causes the 'prompt "Press any key to continue..." which is
 'visible in the screen shot, above.
 'Line 3 will end the DOS session and return the display to your
 'opening main 'menu.
 'However, the batch file still hasn't been run yet. 
 'It's just been created. 
'First, we change the current working directory to the location 
'of the batch file.
dir_put(alb_directory)
'Note: this will not change where Alpha Five looks
' for its program files or data tables.
'now we can run the batch file to create the backup file.
' (It would be smart to prompt the user to stick in the diskette 
' about now!)
' (Also, it would be smart to include some error trapping in case 
' the user's disk drive or diskette has trouble.)
sys_shell("mbrsbak.bat",1)
'this line starts a DOS session and runs the batch file
end 'That's all folks.

Conclusion

You may think that Tom has gone to a lot of trouble to produce a script from Alpha Five when he could easily have placed a batch file on his Windows desktop. That's true, but remember that Tom is moving his data from machine to machine, and the path to the data, required by PKZip, changes each time. With his present script he allows Alpha Five to construct the path to the data each time the backup button is pressed.
The same techniques could be applied to any sequence of batch commands that Windows can run. You can let Alpha Five write the commands with its file-writing methods and run the commands with sys_shell().

The techniques used in this short script can easily be modified to create and run other batch files. For example you may want a batch file to run a tape drive, or to run network update or utility programs. You are not limited to running PkZip, so use your imagination. Think about those time consuming, error prone, sequences with which your users are struggling. Maybe they can be streamlined and automated with a script like this.

As for this particular backup project, to some this approach may seem like a "quick and dirty" solution. It is true that it overlooks other aspects which could be polished up or improved. (For example, you might want to backup other files, or even your entire application. In my case I have a separate backup of the data dictionary, the forms, the reports, and so on.) What I find compelling, is that it's easy to use, and fast. These characteristics are prerequisites to a high probability of it's being used!

To those of you who noticed PKZip's warning message in Figure 2, I salute your good vision! (Personally, my arms aren't long enough to see it!) Actually, this message is PKZip's way of telling us that it couldn't compress and copy the MBRSTART.DBF table because it was in use by another process under Windows 9x. Which process? Well, you might have guessed, it's my Main Menu Form in my application. This is the form which contains my "backup" button. As recommended by Alpha Software it is attached to an empty table. So, for my purposes, leaving it out of the backup set is no big deal. On the other hand, if you run this code on a network, and other users are working with the database, you may see similar warnings for other tables. This should signal to you that the backup was not complete, and that you should try again when the other users have logged off.

5/16/99

Don't forget, we need your feedback to make this site better!

Return to home