Strategies for converting BDE applications to dbExpress through InstantBDExpress

(C) 2005-2023 Ethea

This article summarizes the various techniques you can use to port an existing BDE application to dbX through InstantBDExpress. These techniques are distilled from our experience in porting applications for our customers, but they are only the tip of the iceberg. Feel free to ask for further details as needed.

Keeping the code changes to a minimum: the interposer unit technique

With this approach you try to convert your application without changing the code, that is without changing the component names and the uses clauses of the application's units. This restyling operation can be done almost automatically, as we'll see in the next sections, but avoiding it altogether gives you the chance to start testing the converted application very early in the process. The trick here is to have components with the exact same interface (meaning public properties and methods) of the BDE components, and the exact same names. The first requirement is satisfied by the IBDX components, and for the second part you will need an interposer unit. This unit will define descendant classes of all IBDX components, giving them the same names as the equivalent BDE components. When your application, at run time, uses this unit, it will use IBDX without changes.

So how do you create this interposer unit? Basically you don't, as we provide one out-of-the-box with IBDX. Use the IBDXInterposer.pas unit, which you can find in the samples folder of IBDX, as an example for your customization. Typically, you will make a copy of it for your project and optionally customize it as needed. You will need more customization if your application is complex, or if you're changing the database type as well as the data access technology (much harder, and not recommended, to do both at the same time, but still possible).

You can make your project use the interposer unit in several ways:

  1. Call the unit DBTables, and add it to the project (or store it in the projects' folder). The project must not be compiled with run-time packages enabled for this to work. This will be enough in simple projects.
  2. Give the unit a name of your choice and add a suitable unit alias to the project's configuration. Adding a unit alias means that the compiler will transparently translate references to a given unit in the source files to references to a different unit. The alias, which you can set through Delphi's Project Options dialog box, needs to match DBTables to your interposer unit. For example, DBTables=MyDBTablesInterposer.
  3. Give the unit a name of your choice and make sure it is listed in all uses clauses in which DBTables appears, and that it is listed after DBTables there. This is risky and requires care.

If your project uses the DbiProcs, DbiTypes, DbiErrs or BDE units, it means that it is employing the low-level BDE API directly. InstantBDExpress makes no attempts to emulate this API, so you'll have to analyze and rework those parts of the code.

If, after setting up the interposer unit, your application still compiles, then this is excellent news, as you can start testing. Otherwise, you'll need to examine problems and apply customizations case by case.

In order to start testing, you need to define an IBDX alias matching your BDE alias. Use the IBDX Administrator for this (see the example described in Converting MastApp for details).

What if my application uses custom TTable/TQuery descendants?

If you are using your own descendants of the BDE dataset and field classes in your application, your best option is to change them so that they are inherited from the IBDX classes instead. IBDX doesn't mimic the BDE's protected interface as much as it does with the public interface, but you shouldn't have problems unless your components are doing particularly complex things. You could add a layer between IBDX and your components if you want. That layer will be the home for your customizations.

In this scenario, your application starts using IBDX but keeps referring to your custom components.

Jumping the gun: change all class names

If the interposer approach sounds hackish to you, that's because it is, to some extent. The main advantage of the interposer unit is that it allows you to start testing very soon, so that you can build yourself a clearer idea about the feasibility of the conversion project.

An alternative approach is to develop a unit similar to the interposer unit, but with different class names. This means that your application code will have to be modified to fix all references to the BDE class names and the DBTables unit. Don't worry, you can do that almost automatically through global search & replace operations on the sources (for which we suggest you use the excellent and free  GReplace tool). This is also the best option if your application uses custom components inherited from the BDE ones, as explained in the previous section.

You could also change your references to the BDE components to references to IBDX components. This is very simple to do, and allows you to work with IBDX at design time. Yet, we usually prefer one of the other approaches, because they leave you more room for customization.

Testing the application

Once you have verified that your application compiles and runs with IBDX, you begin testing it to see what still works and what doesn't anymore. Here begins the real conversion process. Depending on the techniques used by the application, you might find that you need to make significant changes to make it work acceptably in a Client/Server environment. Among the most frequent problem areas:

These problems are solved on a case-by-case basis, with the help of experience, peer support, and support from Ethea.

Getting more help and reporting misbehaviours

Since the goal of the IBDX components is to faithfully reproduce the interface and behaviour of the BDE components, you should refer to the BDE documentation provided with Delphi for help. If you find any discrepancy in interface or behaviour between the BDE and IBDX, please let us know so we can fix it if possible, or suggest you a workaround.