odbc_session_backend::odbc_session_backend( connection_parameters const & parameters) : henv_(0), hdbc_(0), product_(prod_uninitialized) { SQLRETURN rc; // Allocate environment handle rc = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv_); if (is_odbc_error(rc)) { throw soci_error("Unable to get environment handle"); } // Set the ODBC version environment attribute rc = SQLSetEnvAttr(henv_, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0); if (is_odbc_error(rc)) { throw odbc_soci_error(SQL_HANDLE_ENV, henv_, "setting ODBC version 3"); } // Allocate connection handle rc = SQLAllocHandle(SQL_HANDLE_DBC, henv_, &hdbc_); if (is_odbc_error(rc)) { throw odbc_soci_error(SQL_HANDLE_DBC, hdbc_, "allocating connection handle"); } SQLCHAR outConnString[1024]; SQLSMALLINT strLength; // Prompt the user for any missing information (typically UID/PWD) in the // connection string by default but allow overriding this using "prompt" // option. SQLHWND hwnd_for_prompt = NULL; unsigned completion = SQL_DRIVER_COMPLETE; std::string completionString; if (parameters.get_option(odbc_option_driver_complete, completionString)) { // The value of the option is supposed to be just the integer value of // one of SQL_DRIVER_XXX constants but don't check for the exact value in // case more of them are added in the future, the ODBC driver will return // an error if we pass it an invalid value anyhow. if (std::sscanf(completionString.c_str(), "%u", &completion) != 1) { throw soci_error("Invalid non-numeric driver completion option value \"" + completionString + "\"."); } } #ifdef _WIN32 if (completion != SQL_DRIVER_NOPROMPT) hwnd_for_prompt = ::GetDesktopWindow(); #endif // _WIN32 std::string const & connectString = parameters.get_connect_string(); rc = SQLDriverConnect(hdbc_, hwnd_for_prompt, sqlchar_cast(connectString), (SQLSMALLINT)connectString.size(), outConnString, 1024, &strLength, static_cast<SQLUSMALLINT>(completion)); if (is_odbc_error(rc)) { throw odbc_soci_error(SQL_HANDLE_DBC, hdbc_, "connecting to database"); } connection_string_.assign((const char*)outConnString, strLength); reset_transaction(); configure_connection(); }
db2_session_backend::db2_session_backend( connection_parameters const & parameters) : in_transaction(false) { std::string const& connectString = parameters.get_connect_string(); parseConnectString(connectString); SQLRETURN cliRC = SQL_ERROR; /* Prepare handles */ cliRC = SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&hEnv); if (cliRC != SQL_SUCCESS) { throw db2_soci_error("Error while allocating the enironment handle",cliRC); } cliRC = SQLAllocHandle(SQL_HANDLE_DBC, hEnv, &hDbc); if (cliRC != SQL_SUCCESS) { std::string msg=db2_soci_error::sqlState("Error while allocating the connection handle",SQL_HANDLE_ENV,hEnv); SQLFreeHandle(SQL_HANDLE_ENV,hEnv); throw db2_soci_error(msg,cliRC); } /* Set autocommit */ if(this->autocommit) { cliRC = SQLSetConnectAttr(hDbc,SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_ON, SQL_NTS); } else { cliRC = SQLSetConnectAttr(hDbc,SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_OFF, SQL_NTS); } if (cliRC != SQL_SUCCESS) { std::string msg=db2_soci_error::sqlState("Error while setting autocommit attribute",SQL_HANDLE_DBC,hDbc); SQLFreeHandle(SQL_HANDLE_DBC,hDbc); SQLFreeHandle(SQL_HANDLE_ENV,hEnv); throw db2_soci_error(msg,cliRC); } /* Connect to database */ // NOTE: SQLDriverConnect preparation steps below copied from ODBC backend. SQLCHAR outConnString[1024]; SQLSMALLINT strLength; // Prompt the user for any missing information (typically UID/PWD) in the // connection string by default but allow overriding this using "prompt" // option. SQLHWND hwnd_for_prompt = NULL; unsigned completion = SQL_DRIVER_COMPLETE; std::string completionString; if (parameters.get_option(db2_option_driver_complete, completionString)) { // The value of the option is supposed to be just the integer value of // one of SQL_DRIVER_XXX constants but don't check for the exact value in // case more of them are added in the future, the ODBC driver will return // an error if we pass it an invalid value anyhow. if (std::sscanf(completionString.c_str(), "%u", &completion) != 1) { throw soci_error("Invalid non-numeric driver completion option value \"" + completionString + "\"."); } } #ifdef _WIN32 if (completion != SQL_DRIVER_NOPROMPT) hwnd_for_prompt = ::GetDesktopWindow(); #endif // _WIN32 cliRC = SQLDriverConnect(hDbc, hwnd_for_prompt, reinterpret_cast<SQLCHAR*>(const_cast<char*>(connectString.c_str())), (SQLSMALLINT)connectString.size(), outConnString, 1024, &strLength, static_cast<SQLUSMALLINT>(completion)); if (cliRC != SQL_SUCCESS) { std::string msg=db2_soci_error::sqlState("Error connecting to database",SQL_HANDLE_DBC,hDbc); SQLFreeHandle(SQL_HANDLE_DBC,hDbc); SQLFreeHandle(SQL_HANDLE_ENV,hEnv); throw db2_soci_error(msg,cliRC); } connection_string_.assign((const char*)outConnString, strLength); }