Part VII. Databases providers for developers

Table of Contents

Providers' support API
GdaServerProvider — Base class for all the DBMS providers
Subclassing GdaDataSelect — Base class for all the data models returned by DBMS providers when a SELECT statement is executed
GdaPStmt — Prepared statement's base class
Quark lists — Manages lists of KEY=VALUE pairs
SQL rendering API — Adapting the SQL to the database's own SQL dialect
Misc API — Methods dedicated to implementing providers
Virtual methods for providers
Synchronous / asynchronous mode
Multi threaded environment
Methods - provider's information
get_name() - mandatory
get_version() - mandatory
get_server_version() - mandatory
supports_feature()
Methods - connection management
open_connection() - mandatory
close_connection() - mandatory
get_database()
Methods - DDL queries
supports_operation()
create_operation()
render_operation()
perform_operation()
Methods - transactions management
begin_transaction()
commit_transaction()
rollback_transaction()
add_savepoint()
rollback_savepoint()
delete_savepoint()
Methods - DML queries
create_parser()
statement_to_sql()
statement_prepare()
statement_execute() - mandatory
handle_async()
Methods - data representation
get_data_handler()
get_def_dbms_type()
escape_string()
unescape_string()
Methods - metadata
Important note about SQL identifiers
Reserved SQL keywords
_info()
_btypes()
schemata() and _schemata()
tables_views() and _tables_views()
columns() and _columns()
constraints_tab() and _constraints_tab()
constraints_ref() and _constraints_ref()
key_columns() and _key_columns()
Methods - misc.
cancel()
create_connection()
is_busy()
Virtual methods for recordsets
Virtual methods for Blob operations
SQL parser
Implementation overview
Generic SQL parser
Provider specific SQL parser
Tips to write a custom parser
GdaSqlStatement — Structure which decomposes an SQL statement
Assembling all the parts
libmain.c
plugin_init()
plugin_get_name()
plugin_get_description()
plugin_get_dsn_spec()
plugin_get_auth_spec()
plugin_create_provider()

For each database engine, Libgda requires an object which maps Libgda's API to the native API offered by that database engine. That object, a database provider needs to inherit GdaServerProvider and implement its virtual methods.

Database provider objects are generally instantiated once by the Libgda framework and can be used several times to open and work on connections to several databases of the same type.

Since Libgda itself is developed in the C language, and that most providers are also implemented in that language, the Libgda library itself contains a set of helper classes and functions to guide you in the addition of a new provider to the GDA framework. Two reference implementations are provided in the providers/skel-implementation directory of Libgda's sources:

The helper objects and functions to write database providers are documented in the Providers' support API section.

Getting started

Libgda's sources contain templates to get started in creating a new database provider. The following templates are available:

  • the template in the providers/skel-implementation/capi directory which can be used when writing a provider using the database's C or C++ API (for example the PostgreSQL or MySQL providers)

  • the template in the providers/skel-implementation/models directory which can be used when writing a provider for a system which is not a relational database (or does offer a very limited API, such as for the MS Access or Berkeley DB systems).

In any case, for example to create a DummyDb provider, follow these steps:

  • copy one of the template's directory into a new directory named dummydb

  • From inside that new directory, run the providers/prepare_provider_sources.sh script with the name of the provider as sole argument ("dummydb" here), which replaces all the class and object names with the name of the provider and renames the files correctly. These new sources should be compilable without any modification.

  • Edit the Makefile.am to add provider specific compilation and link flags

  • Integrate the provider's new code into a compilation unit: either Libgda's sources in the providersdirectory or in your own application (this step usually involves modifying the configure.ac or configure.in files).

  • Implement the missing parts (it is usually a good idea to look how other provider's implementations are done to get ideas).