Interacting with FileFlex

FileFlex is a relational database engine. It's functionality is designed to store, retrieve, search, and sort text-based information. Unlike most database engines, which are standalone applications containing other features including user-interface builders and report writers, FileFlex only manages data. Also, unlike most other database engines, FileFlex is designed to be embedded within your application, not reside as an external application called by your application or communicated with via interprocess communications.

This embedded nature of FileFlex provides a great deal of benefit to the developer of multimedia applications:

A principle design decision was that FileFlex uses each host application's "plug-in" architecture. This allows the host application to talk to FileFlex with no penalty for speed and allows FileFlex to be very tightly integrated into the programming environment of the host application. For example, in Director, the FileFlex engine exists as a Lingo Xtra. Just drop it into the Xtras folder and full relational database capability is available.

FileFlex Has Its Own Data Files

FileFlex data files (the database) are external to your project. This is in direct contrast to how Director stores data. When you build a Director movie the "normal" way, you defined various text cast members within the movie. The data itself is stored in the cast members, and as you add data, the movie size grows.

There are some amazing advantages to having the data stored separately from the controlling application.

The first, of course, is speed. Searches using FileFlex' ultra-high speed indexing technology allow you to go anywhere in the database virtually instantly. Because the data is structured specifically around this search mechanism, everything is optimized for speed.

The next key advantage to using your development environment as a front-end to data is how easy it is to change "views" or "layouts" on the data file. If you've used FileMaker, you know that you can have a bunch of different layouts for the same data fields. The layout is simply the way you look at the data. For example, you might have a purchase order system with fields such as P.O. number, vendor name and address, a list of items, expected date, and a total dollar amount. However, depending on the level of detail interest you have in the order, you might want to view the data different ways: with all the details, or just a summary of the information. FileFlex allows you to work the same way. Rather than having to switch your entire cast, FileFlex lets you instantly jump between databases and sort orders without incurring any overhead of disk access.

Lastly, it is far easier to deliver updates to users of your software if the program or application is separate from the data. There's no need to try to save off the old data and read it into the new, updated project (or update all the scripts of the old movie). You just delete the old movie and replace it with the new. The data file is untouched.

FileFlex Standard Data File Formats

In earlier versions of FileFlex, when you created a database, it was in the dBASE III format. In FileFlex 3, the native format is FoxPro.

When you create a FileFlex database, you're going to create one, two, or three different types of data files. They are:

The value of using these file formats is that they are extremely fast and extremely common. While they're the native format for FileFlex, virtually any database engine can read and write the FoxPro standard. Even products that aren't databases, like Word 6 and Excel, can both read and export into the FoxPro format.

In addition, Microsoft Access has the concept of an "external table". This is a database that is treated as part of the Access .MDB structure, but lives outside as a separate file. FileFlex 3 .DBF files can be external tables to Access and can be completely and freely manipulated by Acces.

One word of caution though: the standard to which FileFlex adheres religiously is the native, accellerated FoxPro file format. If you choose to export data from another application (say Access), be sure to specify the FoxPro format. If you select dBASE III or dBASE IV formats, FileFlex will refuse to recognize the file.

Since FileFlex 2 files were dBASE III format, you'll need to convert these files to FoxPro format so they can be understood by FileFlex. To do this, you'll need to use Access or FoxPro to read the data in, then export it back out in FoxPro format.

FileFlex Data Types

FileFlex supports the following native data types:

While FileFlex understands the FoxPro format, it does not yet save/restore the following field types: Currency, DateTime, Double, Integer, Binary Character, and Binary Memo. Data retrieved from/to these field types is likely to be corrupted (there's no error checking).

Managing Multimedia Data

Although the file format allows for it, FileFlex does not internally store "blob" data like graphics files, QuickTime movies, sounds, etc. This doesn't mean you can't or shouldn't use FileFlex to manage multimedia data. Far from it. Instead, you should store the images or video clips as individual files on disk, perhaps assigning them to specified folders or directories. Then, store the location, path, or some identifying characteristic inside a FileFlex text or memo field. When you want to access the image, do a search in FileFlex, grab the path from a character field, and just import the image into Director.

There are strong advantages to this approach. First, you're able to use your native image editing tools to modify the files. Second, you can replace images individually, rather than having to reinstall a complete database. And third, as you add images, you can span disk volumes or store certain images or multimedia components easily on different parts of your network.

Finally, by not storing multimedia data within the data file, the database files are substantially faster and smaller.

Wrapper Scripts

When you install FileFlex, your development environment talks with the FileFlex plug-in via "Wrapper Scripts". Wrapper scripts are very short handlers written in your host language's scripting language. Here's a sample wrapper script for Director, written in Lingo:

on DBSelect dbID
  return FileFlex("5",string(dbID))
end DBSelect

In the above example, the DBSelect function is defined. You'll learn later that DBSelect switches the current database from one open database file to another. The wrapper script calls the FileFlex engine plug-in with the function code "5" and with an ID number contained in the variable dbID.

The reason this is done is that the FileFlex engine is actually one solid code module. The FileFlex code knows which of it's sixty-some-odd functions to perform based on which code number is specified. So, if FileFlex is passed a code 3, then it performs a DBUse to open a database. If it's passed a code 30, it knows to write a record to the database.

But programming by remembering all those numerical codes is difficult and hard to debug. It's much easier to remember descriptively named commands. These are the commands in the wrapper scripts, such as DBSelect above.

There is one other reason why the wrapper scripts are so important: You can place a breakpoint inside the wrapper. In this way, you can tell exactly what data you're passing to the database engine through the function's parameters, prior to actually invoking the engine. This debugging tool can often be an invaluable way to make sure you know what you're telling FileFlex to do.

"Don't forget to copy the wrapper scripts from WRAPPERS.TXT into a cast member."

When you begin your Director production, one of the very first things you should do is open the WRAPPERS.TXT file and copy the wrapper scripts into one of the very first cast members. The wrapper scripts you'll use in your productions are stored in the WRAPPERS.TXT file. You need to make sure that the contents of this file are copied into the an early cast member of your production. When you call a FileFlex function (like DBSelect), Director will look for a handler of that name. The wrappers from WRAPPERS.TXT contain all of the handlers and pass those calls off to the FileFlex Xtra. So, if you don't move the contents of WRAPPERS.TXT into a cast member, Director won't be able to find the handlers, and you'll get "Handler not found" error messages.

Calling FileFlex Functions

Calling FileFlex is a simple matter of executing a function call. Here's an example that opens the database file "STARS.DBF":

put DBUse("STARS.DBF") into dbResult 

As described earlier, DBUse is a wrapper that tells the FileFlex engine to open a database file. Every FileFlex function returns a value, which should be placed into a variable and then tested. In the above example, the result of the DBUse command is placed into the variable dbResult. When you call most FileFlex functions, you should check the value returned by the program to be sure that no error occurred in the process. The mechanism by which FileFlex notifies you of an error is simple. If the value returned by the function call is less than zero, then an error occurred. The FileFlex Result Code Reference lists all the possible error codes.

To handle errors in your scripts, then, you must simply:

Here is a simple example of dealing with a potential FileFlex error condition:

on mouseUp
  put DBUse("VIDEO") into dbResult
  if dbResult < 0 then
  end if
  -- continues other normal processing
end mouseUp

This is a good general-purpose approach to the problem. However, you may wish to get more specific, as this expanded version of the above handler indicates:

on mouseUp
    put DBUse("VIDEO") into dbResult
    if dbResult = -120 then
      alert "Can't find VIDEO file"
    end if
    if dbResult = -200 then
      alert "Database file is bad"
    end if
    -- continue other processibng
  end mouseUp
If other errors could occur but you don't need to provide special handling for them, you can add another if-then clause to deal with those as well.

Some FileFlex functions (like DBBottom and DBSkip) can return positive results that indicate some special situation has arisen. When you use these functions, you should know that a return value of 1 means that the beginning of the file has been reached and a return value of 3 means the end of the file has been reached.

Here is an example of dealing with these conditions (the DBSkip call moves the pointer to the next record in the database):

on mouseUp
  put DBSkip(1) into dbResult
  if dbResult = 3 then
    alert "End of file reached"
  end if
  -- continues normal processing
end mouseUp

Initiating FileFlex Operations

FileFlex operates as a self-contained little world within Director. Each time you make a call to FileFlex, you're rapidly loading and unloading the FileFlex engine. But since FileFlex needs to maintain an awareness of all the database information between calls (when, normally, it would be completely out of the picture), FileFlex maintains it's own internal memory structures and data.

FileFlex also resides as an external code resource to your host environment. Before you can give FileFlex commands, you need to be able to establish communications with FileFlex. In most development environments, this is accomplished by opening a resource or opening an external library. In Director, this can be accomplished as easily as dropping the FileFlex Lingo Xtra into the Xtras folder.

Once FileFlex is available to Director, FileFlex must be initialized the first time it's used and "turned off" when you're finished. When you tell FileFlex to initialize itself, it allocates all the memory data structures it'll need for your database session.

In earlier versions of FileFlex, you'd have to call the DBOpenSession function to initialize FileFlex. FileFlex now does this automatically. It checks to see if certain global variables are in existence, and if not, calls the internal open session functions.

The key to this is the existence of globals in the host environment. Never clear globals while FileFlex is running.

"Never clear globals while FileFlex is running."

Terminating FileFlex Operations

After you are done using FileFlex, you should clean up your environment by releasing memory used for buffers. To do this, put the following call into the handler called when exiting your movie or project. (It may be placed elsewhere, but this is the most logical place for its use.)

put DBCloseSession() into dbResult

This will free all the data structures in use by the FileFlex engine.

Discuss this chapter on the FileFlex Boards.

Copyright © 1992-1998 by David Gewirtz, under license to Component Enterprises, Inc.

Casa de Bender