Quick Overview

Database Independent Abstraction Layer for C: libdbi Programmer's Guide
Prev | Chapter 2. libdbi in a Nutshell (Quickstart Guide) | Next

# 2.1. Quick Overview

libdbi uses a plugin system that allows various databases to be supported simultaneously, and can dynamically load or unload drivers that are supplied by libdbi or a third party. The library is initiallized by calling dbi_initialize and a connection instance is started by calling either dbi_conn_new or both dbi_driver_open and dbi_conn_open.

The connection's options (username, password, hostname, etc.) are set with dbi_conn_set_option and dbi_conn_set_option_numeric. Once all options are set, dbi_conn_connect will connect to the database, waiting to handle a dbi_conn_query. A query is a string containing a valid SQL statement. libdbi provides several functions to automatically quote any characters that might screw up the query string. The preferred functions are dbi_conn_quote_string and dbi_conn_quote_string_copy as they take into consideration the character encoding used by the current connection. The legacy functions dbi_driver_quote_string and dbi_driver_quote_string_copy are still supported but should be avoided in new code. After a successful query, you can retrieve rows with dbi_result_first_row, dbi_result_last_row, dbi_result_prev_row, dbi_result_next_row, and dbi_result_seek_row.

String data may be sent to and retrieved from a database using character encodings if they contain characters not covered by the ASCII character set. Most database engines support character encodings like ISO-8859-1, suitable for many European languages, or even the multibyte Unicode character sets like UTF-8. The character set used to store your data in your database is usually set by the CREATE DATABASE command, which you have to take care of yourself. libdbi uses the connection option "encoding" to select a particular character encoding for the current connection. If you set the value to "auto", libdbi will automatically use the database character encoding as the connection encoding. If you request a different character encoding, as defined by its IANA name, libdbi will convert the data on the fly.

There are two methods for fetching field data, and two ways to perform each method. You can either "pull" the data from DBI using the `dbi_result_get_*` family of functions, or have DBI automatically "push" the data into predefined variables with the `dbi_result_bind_*` family of functions. Both families of functions are as strongly typed as most SQL database engines are. That is, you must use the `dbi_result_get_*` or `dbi_result_bind_*` function that matches the type of the requested field. Table 2-1 shows an overview of these functions sorted by the field type they retrieve.

Pulling the data from the database can be done with one of the "get" functions such as dbi_result_get_long or dbi_result_get_string, which simply return the data in the field you asked for. You should run the function dbi_conn_error_flag immediately after each call to a "get" function to check for errors. You can also get more than one field at a time with dbi_result_get_fields, which uses a printf-like syntax.

If you want DBI to automatically fill your program's variables with field values whenever a new row is fetched, you can "bind" fields to your variables. Bindings are set up with dbi_result_bind_long, dbi_result_bind_string, and the rest of the bind family of functions. Like the associated "get" function, you can set up multiple bindings at once with the dbi_result_bind_fields function.

String data can be safely included into query strings by using the dbi_conn_quote_string and dbi_conn_quote_string_copy functions. Binary data can be included into query strings by using the dbi_conn_quote_binary_copy function. All of these functions return zero-terminated strings enclosed in the appropriate quoting characters. Binary strings are returned in their binary representation. That is, they may contain null bytes and other non-printable characters. It is mandatory to use the dbi_result_get_field_length or dbi_result_get_field_length_idx functions to determine the number of bytes contained in the binary string.

Caveats:

- For fields holding integers (not fractional numbers), DBI differentiates between signed and unsigned variables. By default, DBI returns signed values. If you want an unsigned value, prepend a "u" to the name of the target type. For example, dbi_result_bind_short becomes dbi_result_bind_ushort.

- You must set up any bindings after a successful query but before you fetch any rows. Even if you are using field bindings, you can still use the dbi_result_get_* functions as usual. (actually, I lied... setting up a binding should theoretically work at any time, but don't plan on this behavior in future versions)

- All string and binary data returned or bound from DBI is read-only. If you want your own local copy that can be modified at will, use dbi_result_get_string_copy, dbi_result_get_binary_copy, dbi_result_bind_string_copy, or dbi_result_bind_binary_copy. You will be responsible for freeing the memory allocated by these functions.

dbi_result_next_row and the other row-seeking functions will return zero when there are no more rows available. Before the next database operation is performed, you must call dbi_result_free. Before the program terminates, the connection must be disconnected and unloaded with dbi_conn_close and libdbi must be unloaded with dbi_shutdown.

Table 2-1. get* and bind* functions sorted by field type

field type | get by name | get by field index | bind
--- | --- | --- | ---
signed char | dbi_result_get_char | dbi_result_get_char_idx | dbi_result_bind_char
unsigned char | dbi_result_get_uchar | dbi_result_get_uchar_idx | dbi_result_bind_uchar
short | dbi_result_get_short | dbi_result_get_short_idx | dbi_result_bind_short
unsigned short | dbi_result_get_ushort | dbi_result_get_ushort_idx | dbi_result_bind_ushort
int | dbi_result_get_int | dbi_result_get_int_idx | dbi_result_bind_int
unsigned int | dbi_result_get_uint | dbi_result_get_uint_idx | dbi_result_bind_uint
long long | dbi_result_get_longlong | dbi_result_get_longlong_idx | dbi_result_bind_longlong
unsigned long long | dbi_result_get_ulonglong | dbi_result_get_ulonglong_idx | dbi_result_bind_ulonglong
float | dbi_result_get_float | dbi_result_get_float_idx | dbi_result_bind_float
double | dbi_result_get_double | dbi_result_get_double_idx | dbi_result_bind_double
character string | dbi_result_get_string, dbi_result_get_string_copy | dbi_result_get_string_idx, dbi_result_get_string_copy_idx | dbi_result_bind_string
binary string | dbi_result_get_binary, dbi_result_get_binary_copy | dbi_result_get_binary_idx, dbi_result_get_binary_copy_idx | dbi_result_bind_binary
date/time | dbi_result_get_datetime | dbi_result_get_datetime_idx | dbi_result_bind_datetime

Prev | Home | Next
libdbi in a Nutshell (Quickstart Guide) | Up | Generic Example Program