|
Basic Connection Example
The following source code is an example of how stale connections are automatically re-connected.
The code demonstrates the the use of the connection ping parameter.
Note that an automatic reconnect will occur once the ping timeout has lapsed if the connection is stale.
/* * basic_connection application showing the basic generic usage of the dbConnect API * Copyright (C) 2002 Johnathan Ingram, jingram@rogueware.org * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 US * */
#include <iostream> #include <map> #include <string>
#include <time.h> #include <stdio.h>
#include "dbconn/dbconnect.h" #include "dbconn/simpleThreads.h"
using namespace std;
char *tf[] = {"false", "true"};
void showTableData( DbQueryVar &conn) throw( BaseException) { // Execute the same query on both connections string sqlQuery = "SELECT " " id, description " "FROM " " TypeTest "; conn->command(sqlQuery); conn->execute();
// List the contents of the table cout << "TypeTest table data: " << endl; cout << "----------------------------------------- " << endl; cout << "id\tdescription" << endl; cout << "--\t-----------" << endl; if (conn->eof()) cout << "No rows in result set for this query" << endl; else { while (!conn->eof()) { conn->fetchNext(); cout << conn->getFieldByName("id")->asString() << "\t" << conn->getFieldByName("description")->asString() << endl; } } cout << endl; }
int main( int argc, char** argv) { char sql[2048]; map<string, DbConnection::Driver> drivers;
drivers["MYSQL"] = DbConnection::MYSQL; drivers["MSQL"] = DbConnection::MSQL; drivers["POSTGRESQL"] = DbConnection::POSTGRESQL; drivers["DB2"] = DbConnection::DB2;
if (argc == 2) { // Use smart pointers. Must be declared outside of the try // as if an exception is caught it will loose scope and free. DbConnectionVar driver; DbQueryVar conn;
try { driver = new DbConnection(drivers[argv[1]]); // Print out the driver information. DbConnectionDriverInfo* info = driver->getDriverInformation(); cout << "Author : " << info->author << endl; cout << "Vendor : " << info->vendor << endl; cout << "Copyright : " << info->copyright << endl; cout << "Driver Type : " << info->driverType << endl; cout << "Driver Name : " << info->driverName << endl; cout << "Description : " << info->driverDescription << endl; cout << "DbConnect Ver : " << info->dbConnectVersion << endl; cout << endl;
// Connect to the database. (DB2 takes different conn string) if (drivers[argv[1]] == DbConnection::DB2) driver->connect("dbconn", "letmein", "dbConnDB", "", 5, 2); else driver->connect("dbconnect", "letmein", "dbConnectDB", "localhost", 5, 2);
// Get a query connection object conn = driver->requestQueryConnection();
// Set the ping interval on the connection to 1 hour // Note: This is defaulted to 5 min. So in the event that a connection // becomes stale, you will receeve errors on the connection for 5 min // until it is pinged and a new connection to the server established. // If 5 min is too long, then set it to an acceptable ping interval. // The more the connection is pinged, the more overhead is introduced. // The minimum is can be set to is 10 seconds driver->setPingInterval(1 * 60 * 60);
// Test 1: Connection by doing a query on the TypeTest table cout << "Test 1: Querying on connection. " << endl; showTableData(conn); cout << endl << endl;
// Test 2: Stop the database to make the existing connection stale cout << "Test 2: Stop and start the database this application is connected to. " << endl; // Sleep for 10 seconds to make sure the ping interval is exceeded SimpleThread::sleep(10000);
cout << "Press any key to continue..." << endl; getchar(); cout << endl << endl;
// Test 3: Do the query again but with the ping interval at one hour forcing an error cout << "Test 3: Doing query on 'stale' connection. Ping Interval 1 hour" << endl; cout << " This will generate an error as the ping interval has not been exceeded" << endl; try { showTableData(conn); cout << "You did not stop / start the database or took more that 1 hour to do so ????" << endl; exit(1); } catch(BaseException &ex) { cout << "Expected Error trapped: " << ex.name << " " << ex.code << " : " << ex.description << endl; } cout << endl << endl;
// Test 4: Do the query again to make sure the ping establishes a new connection cout << "Test 4: Doing query on 'stale' connection. Ping interval 10 seconds" << endl; cout << " This will automatically connect as the ping interval has exceeded..." << endl;
// Set the ping interval on the connection to 10 seconds driver->setPingInterval(10);
showTableData(conn); cout << "The reconnection test completed OK" << endl; cout << endl << endl; } catch(BaseException &ex) { // Only need to catch a single exception. Can use name etc to determine the actual exception cout << "DbConnect Exception: " << ex.name << endl << " " << ex.code << " : " << ex.description << endl; } catch(...) { cout << "An Unknown exception has been trapped!\n" << endl; } cout << endl;
// The 'conn' and 'driver' objects are smart pointers and will cleanup as soon as they go out of scope } else { cout << "Syntax: basic_connection DRIVER" << endl; cout << "Drivers: MYSQL" << endl; cout << " : MSQL" << endl; cout << " : POSTGRESQL" << endl; cout << " : DB2" << endl; return 1; }
return 0; }
|