/* * Copyright (C) 2007 Tildeslash Ltd. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation. * * There are special exceptions to the terms and conditions of the GPL * as it is applied to this software. View the full text of the exception * in the file EXCEPTIONS accompanying this software distribution. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef CONNECTIONPOOL_H #define CONNECTIONPOOL_H /** * A ConnectionPool class represent a database connection pool. * * A connection pool can be used to get a connection to a database and * execute statements. This class opens a number of database * connection and allow callers to obtain and use a database connection in * a reentrant manner. This ConnectionPool is thread-safe. * *

abort(3) upon encountering a fatal error.
* This callback method provides clients with means to close down execution
* gracefully. It is an unchecked runtime error to continue using the library
* after the callback method was called by the library.
*
* A connection pool is created default with 5 initial connections and
* with 20 maximum connections. These values can be changed by the property
* methods ConnectionPool_setInitialConnections() and
* ConnectionPool_setMaxConnections().
*
* Applications can instantiate as many ConnectionPool objects as needed
* and against as many different databases as needed.
*
*
* database://[user:password@][host][:port]/database[?propertyName1][=propertyValue1][&propertyName2][=propertyValue2]...
* user and password are always
* recognized and specify how to login to the database. Other properties
* depends on the database server in question. User name and password can
* alternatively be specified in the auth-part of the URL. If port number is
* omitted, the default port number for the database server is used.
*
* The caller is responsible for freeing the URL_T object given in
* ConnectionPool_new(), using the URL_free() method
*
* MySQL:
*
* Here is an example on how to connect to a
* mysql database server:
*
* \htmlonly
*
* mysql://localhost:3306/zild?user=root&password=swordfish
* root and password, swordfish
* are specified as properties to the URL. Another alternative is to
* use the auth-part of the URL to specify authentication information:
*
* \htmlonly
*
* mysql://root:swordfish@localhost:3306/zild
* name=value can be added as properties
* to the URL and will be set when the Connection is created. An URL for
* connecting to a SQLite database might look like:
*
* \htmlonly
*
* sqlite:///var/sqlite/my.database?synchronous=off&show_datatypes=off
* :memory: database name in the URL. (An in-memory database
* lives only as long as the program is running and use a small amount of
* memory before population). Notice that a preceding '/' path is required:
*
* \htmlonly
*
* sqlite:///:memory:
*
* postgresql://localhost:5432/zild?user=root&password=swordfish
*
* postgresql://root:swordfish@localhost/zild?use-ssl=true
*
*
* URL_T url = URL_new("mysql://localhost:3306/zild?user=root&password=swordfish");
* ConnectionPool_T pool = ConnectionPool_new(url);
* ConnectionPool_start(pool);
* [..]
* Connection_T con = ConnectionPool_getConnection(pool);
* ResultSet_T result = Connection_executeQuery(con, "select id, name, image from customer where salary>%d", salary);
* while (ResultSet_next(result))
* {
* int id = ResultSet_getIntByName(result, "id");
* const char *name = ResultSet_getString(result, 2);
* int blobSize;
* const void *image = ResultSet_getBlob(result, 3, &blobSize);
* [..]
* }
* Connection_close(con);
* [..]
* ConnectionPool_free(&pool);
* URL_free(&url);
*
* reaper
* thread can be activated at startup to sweep through Connections in the pool
* at a regular interval and close those Connections that have been inactive
* for a specified time or for some reason no longer respond. Only inactive
* Connections may be closed and no more than the initial number of Connections
* the pool was started with are closed. The method ConnectionPool_setReaper()
* is used to setup and activate the reaper thread. If this method was not
* called, the pool will not start with a reaper thread.
*
* Clients can also call the method, ConnectionPool_reapConnections(), to
* bonsai the pool directly if the reaper thread is not activated.
*
* It is recommended to start the pool with a reaper-thread, especially if
* the pool maintains TCP/IP Connections.
*
* connectionTimeout seconds. Default connectionTimeout is
* 30 seconds. The reaper thread if in use, see ConnectionPool_setReaper(),
* also use this value when closing inactive Connections. It is a
* checked runtime error for connectionTimeout to be less than,
* or equal to zero.
* @param P A ConnectionPool object
* @param connectionTimeout The number of seconds a Connection
* can be inactive, i.e. not in use, before the reaper close the Connection.
* (value > 0)
*/
void ConnectionPool_setConnectionTimeout(T P, int connectionTimeout);
/**
* Returns the connection timeout value in seconds.
* @param P A ConnectionPool object
* @return The time an inactive Connection may live before it is closed
*/
int ConnectionPool_getConnectionTimeout(T P);
/**
* Set the function to call if a fatal error occurs in the library.
* Clients may optionally provide this function. If not provided
* the library will call abort(3) upon encountering a
* fatal error. This method provide clients with means to close down
* execution gracefully. It is an unchecked runtime error to continue
* using the library after the abortHandler was called.
* @param P A ConnectionPool object
* @param abortHandler The handler function to call should a fatal
* error occur during processing. An explanatory error message is passed
* to the handler function in the string error
*/
void ConnectionPool_setAbortHandler(T P, void(*abortHandler)(const char *error));
/**
* Activate a reaper thread at startup. This thread will close all inactive
* Connections in the pool, down to initial connections. Inactive Connection
* are closed if and only if its connectionTimeout has expired
* or if the Connection failed the ping test. Active Connections are
* never closed by this thread. Note, that activating the
* reaper thread can have performance penalties if sweepInterval
* is set to low. Use minutes rather than seconds. It is a checked runtime
* error for sweepInterval to be less than, or equal to zero.
* @param P A ConnectionPool object
* @param sweepInterval number of seconds between sweeps of the
* reaper thread (value > 0)
*/
void ConnectionPool_setReaper(T P, int sweepInterval);
/**
* Prepare for the beginning of active use of this component. This method
* must be called before the pool is used and will connect to the database
* server and create the initial connections for the pool
* @param P A ConnectionPool object
*/
void ConnectionPool_start(T P);
/**
* Gracefully terminate the active use of the public methods of this
* component. This method should be the last one called on a given
* instance of this component. Calling this method close down all connections
* in the pool and disconnect the pool from the database server
* @param P A ConnectionPool object
*/
void ConnectionPool_stop(T P);
/**
* Get a connection from the pool
* @param P A ConnectionPool object
* @return A connection from the pool or NULL if maxConnection is reached
* @see Connection.h
*/
Connection_T ConnectionPool_getConnection(T P);
/**
* Returns a connection to the pool. The same as calling Connection_close()
* @param P A ConnectionPool object
* @param connection A Connection object
* @see Connection.h
*/
void ConnectionPool_returnConnection(T P, Connection_T connection);
/**
* Close all inactive Connections in the pool, down to initial connections.
* Inactive Connection are closed if and only if its
* connectionTimeout has expired or if the Connection
* failed the ping test against the database. Active Connections are
* not closed by this method.
* @param P A ConnectionPool object
* @return The number of Connections that was closed
*/
int ConnectionPool_reapConnections(T P);
/**
* Returns the current number of connections in the pool. The number of
* both active and inactive connections are returned.
* @param P A ConnectionPool object
* @return The number of connections in the pool
*/
int ConnectionPool_size(T P);
/**
* Returns the number of active connections in the pool. I.e. connections
* in use by clients.
* @param P A ConnectionPool object
* @return The number of active connections in the pool
*/
int ConnectionPool_active(T P);
#undef T
#endif