postgresql_session_backend::postgresql_session_backend( connection_parameters const& parameters) : statementCount_(0) { PGconn* conn = PQconnectdb(parameters.get_connect_string().c_str()); if (0 == conn || CONNECTION_OK != PQstatus(conn)) { std::string msg = "Cannot establish connection to the database."; if (0 != conn) { msg += '\n'; msg += PQerrorMessage(conn); PQfinish(conn); } throw soci_error(msg); } // Increase the number of digits used for floating point values to ensure // that the conversions to/from text round trip correctly, which is not the // case with the default value of 0. Use the maximal supported value, which // was 2 until 9.x and is 3 since it. int const version = PQserverVersion(conn); hard_exec(conn, version >= 90000 ? "SET extra_float_digits = 3" : "SET extra_float_digits = 2", "Cannot set extra_float_digits parameter"); conn_ = conn; }
sqlite3_session_backend::sqlite3_session_backend( connection_parameters const & parameters) { int timeout = 0; int connection_flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; std::string synchronous; std::string const & connectString = parameters.get_connect_string(); std::string dbname(connectString); std::stringstream ssconn(connectString); while (!ssconn.eof() && ssconn.str().find('=') != std::string::npos) { std::string key, val; std::getline(ssconn, key, '='); std::getline(ssconn, val, ' '); if (val.size()>0 && val[0]=='\"') { std::string quotedVal = val.erase(0, 1); if (quotedVal[quotedVal.size()-1] == '\"') { quotedVal.erase(val.size()-1); } else // space inside value string { std::getline(ssconn, val, '\"'); quotedVal = quotedVal + " " + val; std::string keepspace; std::getline(ssconn, keepspace, ' '); } val = quotedVal; } if ("dbname" == key || "db" == key) { dbname = val; } else if ("timeout" == key) { std::istringstream converter(val); converter >> timeout; } else if ("synchronous" == key)
postgresql_session_backend::postgresql_session_backend( connection_parameters const& parameters) : statementCount_(0) { PGconn* conn = PQconnectdb(parameters.get_connect_string().c_str()); if (0 == conn || CONNECTION_OK != PQstatus(conn)) { std::string msg = "Cannot establish connection to the database."; if (0 != conn) { msg += '\n'; msg += PQerrorMessage(conn); PQfinish(conn); } throw soci_error(msg); } conn_ = conn; }
void session::open(connection_parameters const & parameters) { if (isFromPool_) { pool_->at(poolPosition_).open(parameters); } else { if (backEnd_ != NULL) { throw soci_error("Cannot open already connected session."); } backend_factory const * const factory = parameters.get_factory(); if (factory == NULL) { throw soci_error("Cannot connect without a valid backend."); } backEnd_ = factory->make_session(parameters); lastConnectParameters_ = parameters; } }
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); }