|GNADE User's Guide: GNADE, The GNat Ada Database Environment; Version 1.5.3; Document Revision $Revision: 1.45 $|
The ODBC interface provides an interface between applications and an underlying data base in such a way, that the application code does not depend on the underlying data base.
The ODBC interface consists of a so called driver manager and the ODBC driver it self. The driver manager (DM) is a library that on one site offers the specified ODBC API to applications. The DM therefore is what you essentially link to your application. But in large parts the DM routines are only stubs. At run time the DM decides which database to access and based on the type of the database which vendors database ODBC driver to load. So basically most DM implementations require that the OS supports dynamic linking and that the database vendors provide the database site of the ODBC drivers as dynamic loadable entity (aka DLL or shared libraries). But the DM does more than just to provide these stubs and the dynamic linking of the corresponding implementations. As ODBC evolves over time, the DM is also responsible to handle the situation that with a new version of ODBC new API entries are defined, but they are not available in a database driver because this driver was developed when an earlier version of ODBC was the rule (for example we now have ODBC 3.52 and the MySQL ODBC driver is written for ODBC 2.5x). So an application might link against an ODBC 3.52 DM and use all the new and hot ODBC entries, although the database used doesn't have them in its ODBC driver. The DM usually reacts in one of two ways:
it raises an error indicating an unsupported call.
it emulates the new call by translating it to a previous (maybe deprecated) call or series of calls. Funny enough this happens quite often and the way how to emulate a new call by existing ones is in most cases exactly described in the ODBC spec.
The mechanism how to select the right driver is system dependent, but the principal idea is that you have some kind of repository where you associate logical names with configuration information telling the DM the specifics which driver to load. On Win32 this repository can be the registry or so called DSN-files, on UNIX this is mostly an ODBC.INI file containing the information in some structured fashion. The application opens the database by specifying such a logical name and its the task of the DM to consult the repository and to dynamically load the right database driver. In this way, a carefully written application can not only be written in a database independent fashion (using the ODBC API), but also the resulting binary can be dynamically configured to use different databases. This is what makes ODBC so successful on Win32 and will make it more and more important also on UNICes. You can write very generic data aware code ranging from applications like MS Access that can operate on any database that supports ODBC, to GUI widgets like data grids that you can incorporate into your GUI application and that binds "magically" to nearly any database you want.
The database ODBC driver is typically a sharable object that implements the ODBC interface on the database site and is loaded by the DM. In theory - although quite uncommon - you may link such a driver directly to your application. This will work if your application makes only ODBC calls that are implemented by the ODBC version used when writing the database driver. Your application then is written in a database independent fashion, but the binary is bound to a specific database.