Thanks for such a quick RE.
Unfortunately in my opinion it can’t be done that easy.
Not only types defined in CLI headers were used but also some funcions mantainig tasks like allocating so called handles, connecting to or disconnectng from DB, etc. Moreover I don’t exactly understand how hiding IBMs headers and creating dummy structs so as to maintain proper mem allocation can prevent rootcint from converting them to classes while creating dictionary.
I’ll paste some real code so it’ll be easier to pointout the problem.
here goes my header:
class Tdb2: public TObject
{
private:
SQLRETURN cliRC; /*CLI return code*/
int rc; /*return code*/
SQLHANDLE henv; /*CLI environment handle*/
SQLHANDLE hdbc; /*CLI connection handle*/
char dbAlias[SQL_MAX_DSN_LENGTH + 1];
char user[MAX_UID_LENGTH + 1];
char pswd[MAX_PWD_LENGTH + 1];
int DbDriverConnect(SQLHANDLE, char *, char*, char*); /*assume additional connection parameters*/
public:
Tdb2(); /*default constructor for test purpose only*/
Tdb2(char * /*dbAlias*/, char * /*user*/, char * /*pswd*/);
~Tdb2(); /*destructor mainly for freing CLI handles*/
};
and now some defs:
#include <string>
#include <stdio>
#include "Tdb2.h"
#include "/home/db2inst1/sqllib/include/sqlcli1.h" //<-MUST REMAIN AS IS
Tdb2::Tdb2() /*default constructor definition; for test purpose only*/
{
dbAlias = "SAMPLE"; /*set db info*/
user = "";
pswd = "";
/*allocate a CLI environment handle*/
cliRC = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
if(cliRC != SQL_SUCCESS) /*whether alloc is successful*/
{
std::cout<<"\n CLI error in SQLAllocHandle()! Unable to alloc environment handle!\n";
exit(-1);
}
/*set env handle attribute to run as ODBC 3.0 compliant application*/
cliRC = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (void *)SQL_OV_ODBC3, 0);
SQLCHAR connStr[255];
/* allocate a database connection handle */
cliRC = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
if(cliRC != SQL_SUCCESS) /*whether alloc is successful*/
{
std::cout<<"\n CLI error in SQLAllocHandle()! Unable to alloc connection handle!\n";
exit(-1);
}
/*prepare connection string*/
sprintf((char *)connStr, "DSN=%s; UID=%s; PWD=%s; AUTOCOMMIT=0; CONNECTTYPE=1;", dbAlias, user, pswd);
/*connect to database*/
cliRC = SQLDriverConnect(hdbc, (SQLHWND)NULL, connStr, SQL_NTS, NULL, 0, NULL, SQL_DRIVER_NOPROMPT);
if(cliRC != SQL_SUCCESS) /*whether connect is successful*/
{
std::cout<<"\n CLI error in SQLDriverConnect()! Unable to connect to database " << dbAlias << std::cout;
exit(-1);
}
std::cout << "\n Connected to database " << dbAlias << std::endl;
/*disconnect from database*/
cliRC = SQLDisconnect(hdbc);
if(cliRC != SQL_SUCCESS) /*whether disconnect is successful*/
{
std::cout<<"\n CLI error in SQLDisconnect()! Unable to disconnect from database " << dbAlias << std::cout;
exit(-1);
}
std::cout << "\nDisconnected form database " << dbAlias << std::endl;
}
Tdb2::Tdb2(char dbAlias[], char user[], char pswd[])
{
}
Tdb2::~Tdb2()
{
/*free the connection handle*/
cliRC = SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
/* free the environment handle */
cliRC = SQLFreeHandle(SQL_HANDLE_ENV, henv);
}
As you can see #include “/home/db2inst1/sqllib/include/sqlcli1.h” provides types for members and funcs used in methods/constructors. sqlcli1.h includes other .h files (sql.h, sqlutil.h and about four more) and MUST remain as is.
Functions declared in sqlcli1.h and other are defined in (already built) libdb2.so provided by IBM, so there is no way to modify anything.
IMHO there is not a chance to get CLI rewritten in C++ (no deal for IBM )
The goal is to force CINT understand this C/C++ mixture and then call Tdb2 *blahblah = new Tdb2() in ROOT and be happy(=to get positive grade)