Connection Handling through IldDbms Objects

With DB Link, an application connects to an RDBMS through an object of the class IldDbms. In fact, the first thing that DB Link must do before an interactive session can be initiated with a database server is to create such an IldDbms object.

This section explains how to create, manipulate, and delete IldDbms objects. It is divided as follows:

Initiating a Session or a Connection

The only way to initiate a session or a connection is to create an IldDbms object. To do this, use the inline function IldNewDbms. (This entry point is defined as an inline global function in the header file dblink.h.) As a consequence, a connection is activated. It can be closed by calling the function IldDbms::disconnect and reopened later by calling the function IldDbms::connect.

Note: Several connections can be active at the same time. Their number is limited only by the server configuration (not by DB Link itself).

When the IldDbms object is deleted, the connection is automatically closed and all dependent objects are deleted.

If the driver fails to establish the initial connection, an object from the class IldErrorDbms is returned.

Caution: The class IldErrorDbms is not documented.

There are five cases where an error of type IldErrorDbms can be returned and only one where an instance of IldErrorRequest is returned. All cases where an IldErrorDbms error is returned are handled by the driver manager in the function IldAllocConnect. Only the member function IldDbms::getFreeRequest may return an IldErrorRequest error, when the connection is not established and the
error handler fails to fix it.

Error-Raising Conditions

  • Null or empty strings as arguments

The arguments passed to the function IldNewDbms must not be null or empty strings. Otherwise, an IldErrorDbms error is returned.

See Connection Arguments for details about these two arguments.

  • Driver not linked or not found

    • When the drivers are linked statically, the driver whose name is passed as first argument to the function IldNewDbms must be found. Otherwise, an instance of IldErrorDbms is created, initialized in an error state—that is, the function IldIldBase::isErrorRaised returns IlTrue—and returned. (This function is inherited from the common base class IldIldBase.)

    • When the drivers are loaded dynamically and an entry with the proper name is missing in the dblink.ini file, the same behavior occurs.

  • Memory allocation failure

When the driver entry point is called and fails to return a valid address, the driver manager creates and returns an IldErrorDbms error.

  • Unknown driver

When using the dynamic load feature, if the RDBMS name is not found in the [dblink] section of the configuration file, the driver manager returns an IldErrorDbms error.

  • Improper driver found

When using the dynamic load feature, if the driver library is loaded properly but the entry point cannot be found, the driver manager allocates and returns an IldErrorDbms error.

  • Unconnected

When the connection is not established or has been closed, and the error handler did not attempt to re-establish it or this attempt failed, the IldDbms::getFreeRequest function allocates and returns an IldErrorRequest object.

The only time that the function IldNewDbms can return a null value is when no object can be allocated because the application ran out of memory.

Creating IldDbms Objects

There is no public constructor for objects of the class IldDbms. To create IldDbms objects, use the inline function IldNewDbms. This function is defined in your application as soon as the file dblink.h is included. Its code is modified by the compile-time flags you define.

If your application is linked in dynamic load mode, no RDBMS-specific compile-time flag is needed.

Throughout this manual, multiple examples show you how to use the function IldNewDbms.

{

cout << "Connecting to: " << IldDbmsName << endl;

IldDbms* dbms = IldNewDbms(IldDbmsName, IldConString);

if (!dbms) cout << "Out of memory" << endl;

if (dbms->isErrorRaised()) {

IldDisplayError("Creating Dbms: ", dbms);

delete [] queryBuffer;

delete dbms;

return 1;

}

}

Caution: Even though the allocation may be successful, the creation of the IldDbms object may still fail. To make sure the connection is successful, you must a) Check that IldNewDbms returns a non-null pointer; b) Use the member function IldIldBase::isErrorRaised to check whether the IldDbms object was successfully allocated.

Automatic Connection

Creating an IldDbms object connects you to the RDBMS using the values passed to the function IldNewDbms. This initial connection is required to test whether the server can be reached and is ready for communication.

Connection Arguments

The function IldNewDbms takes two arguments, which are the DB Link name of the database system and the connection string.

  • The first argument is the name of the database system as known by DB Link. It must have one of the following values:

    • db2

    • db29x

    • informix9

    • mssql

    • odbc

    • oledb

    • oracle9

    • oracle10

    • oracle11

    • sybase

      These names are all lowercase and must be entered exactly as shown. Any other names are illegal when using DB Link-supported drivers.

      If the name you pass does not match one from the above list, DB Link raises either the error ILD_UNKNOWN_RDBMS, indicating that it does not recognize the RDBMS, or ILD_LIB_NLNKD if the application did not link the driver statically.

  • The second argument is the connection string. It must comply with a format that depends on the target RDBMS.

Connection String Format

The format and contents of a connection string depend on the target RDBMS:

  • DB2: [<user>]/[<password>]/<database name>

  • Informix: [<user>]/[<password>]/<database name>[@<server>]

  • MS SQL Server: <user>/<password>/<database name>/<server name>

  • ODBC: <data source name>/[<user>]/[<password>]

  • Oracle: [<user>]/[<password>][@<service>]

  • Sybase: <user>/<password>/<database name>/<server name>

Values enclosed in square brackets are optional.

Note: With ODBC, you cannot pass the database name in the connection string. It can be set through the odbc.ini file. Also, the slash marks ('/') are mandatory. The ODBC driver also supports a connection string following the format: "DRIVER= ...; DBQ=..."

If the second argument passed to the function IldNewDbms does not comply with the appropriate format, DB Link raises the error ILD_BAD_DB_SPEC indicating that the connection string is not valid for this RBDMS. Nothing can be done using that IldDbms object until a valid connection is established.

Session Configuration

Default Error Reporter

When you create an IldDbms object, it is associated with a new IldErrorReporter object. The default reporter is not accessible to the application. As a consequence, the function IldDbms::getErrorReporter returns a null pointer if no user-derived error reporter has been set.

To customize error handling, you can create your own error reporter class and instantiate it for the IldDbms object reporter using the function IldDbms::setErrorReporter.

Default Configuration

The default settings for a session configuration are the following:

  • The date as string feature is turned on.

  • The numeric as string feature is turned off.

  • The numeric as object feature is turned off.

  • The array size for the array bind and array fetch modes is set to 1.

Checking the Default Configuration of a Connection

Once you have created the first object of the class IldDbms, you can access the following configuration settings:

  • To get the versions of the currently accessed RDBMS against which DB Link was tested, use the function IldDbms::getDbmsVersions.

None of these values can be changed, so they remain valid for all IldDbms objects your application creates.

Checking the Current Configuration of a Connection

In the current IldDbms object, several session-wide parameters are set. Checking the Current Configuration of a Connection shows what IldDbms member function you can use to check their values.

Checking the Current Configuration of a Connection

Use this member function...

...to get this setting.

Default Value

IldDbms::getName

DB Link name of the currently accessed RDBMS

 

IldDbms::getUser

Name of the user who established the connection

 

IldDbms::getDatabase

Name of the database used to establish the connection

 

IldDbms::getDefaultColArraySize

Default size of the array used to fetch rows when the SQL statement executed is a select query

11

IldDbms::getDefaultParamArraySize

Default size of the array used to send rows of parameter values

12

IldIldBase::useStringDate

Date as string feature

IlTrue

IldIldBase::useStringNumeric

Numeric as string feature

IlFalse

IldIldBase::useNumeric

Numeric as object feature

IlFalse

Changing the Configuration of a Connection

You can change the settings in your current connection configuration, as shown in Changing the Settings of the Current Connection Configuration:

Changing the Settings of the Current Connection Configuration

Use

To

IldDbms::setDefaultColArraySize

Change the default fetch array size3

IldDbms::setDefaultParamArraySize

Change the default parameter array size

IldIldBase::setStringDateUse

Turn off the date as string feature

IldIldBase::setStringNumericUse

Turn on the numeric as string feature

IldIldBase::setNumericUse

Turn on the numeric as object feature

Disconnecting and Reconnecting

To disconnect from an RDBMS, you must call the function IldDbms::disconnect as follows:

{

cout << "Disconnecting from: " << argv[1] << endl;

if (!dbms->disconnect())

IldDisplayError("Disconnection failed: ", dbms);
}

Note: The error reporter of the IldDbms object is inherited by all subsequently created IldRequest objects.

This function:

  • deletes all its attached IldRequest objects;

  • deletes all its attached schema entity description objects;

  • closes the connection to the RDBMS.

Once you have disconnected, you cannot create an IldRequest object from that same IldDbms object. Any such attempt raises the error ILD_DBMS_NOT_CONNECTED and an IldErrorRequest object is returned to the calling application.

With a disconnected IldDbms object, you can reconnect to any database from the same database system by calling the member function connect. Its argument is a connection string of the same format as the second argument passed to the function IldNewDbms. If the IldDbms object was not properly disconnected prior to your call to connect, the error ILD_ALREADY_CONNECTED is raised, indicating that the current object is still in use or has not been properly disconnected yet.

{

cout << "New connection to: " << argv[1] << endl;

if (!dbms->connect(argv[2]))

IldDisplayError("Reconnection failed: ", dbms);

}

The member function IldDbms::disconnect is used in the example testerr where an attempt to connect twice is made deliberately. The user-defined error reporter forces a disconnection to enable the new connection to be made:

{

case ILD_ALREADY_CONNECTED:

cout << endl

<< "USER WARNING: already connected to: "

<< dbms->getDatabase()

<< endl;

dbms->disconnect();

// The connection will be performed by DB Link itself.

break;

}

Number of Connections

DB Link has no built-in limitation to the number of connections an application can create. The RDBMS itself raises an error when its maximum number of connections is reached. This maximum may be configured.

The member function IldDbms::getNumberOfActiveConnections returns the number of IldDbms objects created.

Destroying IldDbms Objects

All IldDbms objects created by an application must be destroyed before the application exits to avoid memory leaks and possible dangling connections to the RDBMS.

The IldDbms destructor has the same effect on attached IldRequest objects and schema entity description objects as a call to the function IldDbms::disconnect. All these objects are destroyed, hence, there is no need to delete them. DB Link takes care of deleting them before deleting the IldDbms object itself.

Important: Objects of classes derived from IldDbmsModel DO NOT behave in this way: IldRequestModel derived objects MUST be explicitly separately deleted.