Database driver is an instance of a Driver subclass. Each driver is identified by a unique name. Implementation of a new database driver begins by creating a subclass of the Driver class. The subclass requires the following to be implemented:
Driver
Driver initialisation and termination code if needed (Driver::doInit() and Driver::doShutdown() methods). Usually the initialisation routine registers features the driver supports:
Driver::doInit()
Driver::doShutdown()
void Oracle10gDriver::doInit() { // typeMappingFeature is defined as an attribute in the Oracle10gDriver class: // Oracle10gTypeMappingFeature typeMappingFeature; registerFeautre<TypeMappingFeature>(typeMappingFeature); }
getDatabaseImpl() and returnDatabaseImpl() methods which should create, repspectively free the driver-specific instance of the DatabaseImpl subclass.
getDatabaseImpl()
returnDatabaseImpl()
DatabaseImpl
A constructor implemented in the following way:
Oracle10gDriver::Oracle10gDriver(const std::string& driverName) : Driver(driverName) {}
Driver registration code. A single static driver instance which is initialized as soon as the driver is loaded. Run-time calls the driver constructor that in turn registers the driver at the DriverManager.
DriverManager
static Oracle10gDriver oracle10gDriverInstance("IopcOracle10g");
As you can see, the Driver class is only an entry point to the driver. Most of its code can be found in its DatabaseImpl, ConnectionImpl and CursorImpl implementations.
ConnectionImpl
CursorImpl
Driver extensions are usually sets of additional driver features which are appended to the features the drivers provide. Driver extension is a DriverExtension subclass instance which is created and registered in a similar way to driver:
DriverExtension
The DriverExtension::doInit() initialisation method takes one parameter which is a reference to the associated driver. In the IopcOracle10gORExtension, additional driver features are registered:
DriverExtension::doInit()
void Oracle10gExtension::doInit(Driver& driver) { driver.registerFeature<ORStatementsFeature>(orStatementsFeature); ... }
Driver extension constructor has two parameters. One parameter is a name of a driver the extension extends, second is a name of the extension. Again, its implementation should call the parent constructor as in the following example:
Oracle10gORExtension::Oracle10gORExtension(const std::string& driverName, const std::string& name) : DriverExtension(driverName, name) {}
Driver extension registration code:
static Oracle10gORExtension Oracle10gORExtensionInstance("IopcOracle10g", "IopcOracle10gORExtension");