Table of Contents

IBPP Version 3

overview30.jpg

This is preliminary documentation regarding the unreleased version 3.0.

Let's have a look to IBPP 3.0 structure. You can compare it with previous versions.

Well, nothing big changed. The only real structural change is the addition of the Driver interface (in red in this 3.0 overview graph). Now, all the other interfaces have a runtime dependency to such a Driver instance. Think of it as older versions having an implicit single Driver hidden instance, while version 3.0 can have multiple, hence the explicit dependency.

This change has implications on the Factories though and this makes IBPP 3.0 source code incompatible with previous versions. But wait, the changes are limited and are easy to apply to existing applications source code. Version 3.0 was designed to allow a fairly easy upgrade path.

The new Factories

The major changes at the hosting application source code level are with Factories. Those were functions in previous versions and now they are all (but one) methods of the Driver interface. An existing application must obtain one Driver before being able to do anything else. To get this Driver instance, the application calls the DriverFactory as in:

// IBPP 3.0
IBPP::Driver driver = IBPP::DriverFactory();
driver->Load();

From that point on, this driver will be used as the factory for all other objects.

As an example, to get a Database interface, with previous versions, the code could have been written this way:

// IBPP 2.x
IBPP::Database db = IBPP::DatabaseFactory("", "/tmp/database.fdb", "SYSDBA", "password");
db->Connect();
...
db->Disconnect();

Now, assuming you previously obtained an application wide driver instance as shown above, the same code looks this way with version 3.0:

// IBPP 3.0
IBPP::Database db = driver->DatabaseFactory("", "/tmp/database.fdb", "SYSDBA", "password");
db->Connect();
...
db->Disconnect();

Clearly, if you don't look after more advanced usages, the upgrade path to version 3.0 is an easy text editing job, that can be handled with some replace all (or regex replace all) actions: allocate an application wide IBPP::Driver instance, initialize it and Load() it as shown above at the start of the application and replace all calls to IBPP::DatabaseFactory(…), IBPP::StatementFactory(…), IBPP::TransactionFactory(…), and so on with calls to driver→DatabaseFactory(…), driver→StatementFactory(…), and so on. It is that annoying once, yes, but it is that simple too.

Why this new Driver interface?

The new Driver interface has been added to achieve more flexibility in controlling what exact Firebird client interface is used at runtime by IBPP, and obviously too, to allow one host program to actually load multiple different versions of the client libraries, dynamically.

Some programs might need to load one specific version to access some server, then load another to work against another server. Some programs might even need to load two of them simultaneously. For sure, this last case is certainly not a common case. Especially since Firebird client libraries are designed to be as compatible as possible, to some extent, with previous versions. There is a limit to that compatibility and this is were IBPP 3.0 comes to help.

As a side note, this new architecture might help adding other engines support (than Firebird / Interbase) to IBPP, but this is absolutely not a goal for now.