src/DriverManager.cpp
branchv_0
changeset 37 3de41719d7eb
parent 36 91cb012d779a
child 38 a871779a4e3c
equal deleted inserted replaced
36:91cb012d779a 37:3de41719d7eb
    28 namespace relpipe {
    28 namespace relpipe {
    29 namespace tr {
    29 namespace tr {
    30 namespace sql {
    30 namespace sql {
    31 
    31 
    32 DriverManager::DriverManager() {
    32 DriverManager::DriverManager() {
    33 	env = OdbcCommon::allocateHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE);
    33 	environment = OdbcCommon::allocateHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE);
    34 	SQLRETURN result = SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void*) SQL_OV_ODBC3, 0);
    34 	SQLRETURN result = SQLSetEnvAttr(environment, SQL_ATTR_ODBC_VERSION, (void*) SQL_OV_ODBC3, 0);
    35 	if (OdbcCommon::isNotSuccessful(result)) throw SqlException(L"Unable to set ODBC version", result, SQL_HANDLE_ENV, env);
    35 	if (OdbcCommon::isNotSuccessful(result)) throw SqlException(L"Unable to set ODBC version", result, SQL_HANDLE_ENV, environment);
    36 }
    36 }
    37 
    37 
    38 DriverManager::~DriverManager() {
    38 DriverManager::~DriverManager() {
    39 	OdbcCommon::freeHandle(SQL_HANDLE_ENV, env);
    39 	OdbcCommon::freeHandle(SQL_HANDLE_ENV, environment);
    40 }
    40 }
    41 
    41 
    42 std::vector<DriverManager::DataSource> DriverManager::getDataSources() {
    42 std::vector<DriverManager::DataSource> DriverManager::getDataSources() {
    43 	std::vector<DriverManager::DataSource> list;
    43 	std::vector<DriverManager::DataSource> list;
    44 	SQLCHAR name[SQL_MAX_DSN_LENGTH + 1];
    44 	SQLCHAR name[SQL_MAX_DSN_LENGTH + 1];
    46 	memset(name, 0, sizeof (name));
    46 	memset(name, 0, sizeof (name));
    47 	memset(description, 0, sizeof (description));
    47 	memset(description, 0, sizeof (description));
    48 	SQLSMALLINT nameLength;
    48 	SQLSMALLINT nameLength;
    49 	SQLSMALLINT descriptionLength;
    49 	SQLSMALLINT descriptionLength;
    50 	while (true) {
    50 	while (true) {
    51 		SQLRETURN result = SQLDataSources(env, SQL_FETCH_NEXT, name, sizeof (name), &nameLength, description, sizeof (description), &descriptionLength);
    51 		SQLRETURN result = SQLDataSources(environment, SQL_FETCH_NEXT, name, sizeof (name), &nameLength, description, sizeof (description), &descriptionLength);
    52 		// TODO: check nameLength and descriptionLength whether values were truncated?
    52 		// TODO: check nameLength and descriptionLength whether values were truncated?
    53 		if (OdbcCommon::isSuccessful(result)) list.push_back({convertor.from_bytes((char*) name), convertor.from_bytes((char*) description)});
    53 		if (OdbcCommon::isSuccessful(result)) list.push_back({convertor.from_bytes((char*) name), convertor.from_bytes((char*) description)});
    54 		else if (result == SQL_NO_DATA_FOUND) break;
    54 		else if (result == SQL_NO_DATA_FOUND) break;
    55 		else throw SqlException(L"Unable to list data sources: " + std::to_wstring(result), result, SQL_HANDLE_ENV, env);
    55 		else throw SqlException(L"Unable to list data sources: " + std::to_wstring(result), result, SQL_HANDLE_ENV, environment);
    56 	}
    56 	}
    57 	return list;
    57 	return list;
    58 }
    58 }
    59 
    59 
    60 Connection* DriverManager::getConnectionByDSN(relpipe::reader::string_t dataSourceName, relpipe::reader::string_t userName, relpipe::reader::string_t password) {
    60 Connection* DriverManager::getConnectionByDSN(relpipe::reader::string_t dataSourceName, relpipe::reader::string_t userName, relpipe::reader::string_t password) {
    61 	SQLHDBC connection = OdbcCommon::allocateHandle(SQL_HANDLE_DBC, env);
    61 	SQLHDBC connection = OdbcCommon::allocateHandle(SQL_HANDLE_DBC, environment);
    62 	std::string dataSourceNameBytes = convertor.to_bytes(dataSourceName);
    62 	std::string dataSourceNameBytes = convertor.to_bytes(dataSourceName);
    63 	std::string userNameBytes = convertor.to_bytes(userName);
    63 	std::string userNameBytes = convertor.to_bytes(userName);
    64 	std::string passwordBytes = convertor.to_bytes(password);
    64 	std::string passwordBytes = convertor.to_bytes(password);
    65 	SQLRETURN result = SQLConnect(connection,
    65 	SQLRETURN result = SQLConnect(connection,
    66 			(SQLCHAR*) dataSourceNameBytes.c_str(), SQL_NTS,
    66 			(SQLCHAR*) dataSourceNameBytes.c_str(), SQL_NTS,
    67 			(SQLCHAR*) userNameBytes.c_str(), SQL_NTS,
    67 			(SQLCHAR*) userNameBytes.c_str(), SQL_NTS,
    68 			(SQLCHAR*) password.c_str(), SQL_NTS);
    68 			(SQLCHAR*) passwordBytes.c_str(), SQL_NTS);
    69 	if (OdbcCommon::isNotSuccessful(result)) {
    69 	if (OdbcCommon::isNotSuccessful(result)) {
    70 		OdbcCommon::freeHandle(SQL_HANDLE_DBC, connection);
    70 		OdbcCommon::freeHandle(SQL_HANDLE_DBC, connection);
    71 		throw SqlException(L"Unable to connect to " + dataSourceName, result, SQL_HANDLE_ENV, env);
    71 		throw SqlException(L"Unable to connect to " + dataSourceName, result, SQL_HANDLE_ENV, environment);
    72 	}
    72 	}
    73 	return new Connection(connection);
    73 	return new Connection(connection);
    74 }
    74 }
    75 
    75 
    76 Connection* DriverManager::getConnectionByString(relpipe::reader::string_t connectionString) {
    76 Connection* DriverManager::getConnectionByURL(relpipe::reader::string_t connectionString) {
    77 	SQLHDBC connection = OdbcCommon::allocateHandle(SQL_HANDLE_DBC, env);
    77 	SQLHDBC connection = OdbcCommon::allocateHandle(SQL_HANDLE_DBC, environment);
    78 	char completeConnectionString[SQL_MAX_OPTION_STRING_LENGTH];
    78 	char completeConnectionString[SQL_MAX_OPTION_STRING_LENGTH];
    79 	memset(completeConnectionString, 0, sizeof (completeConnectionString));
    79 	memset(completeConnectionString, 0, sizeof (completeConnectionString));
    80 	SQLSMALLINT completeConnectionStringLength = -1;
    80 	SQLSMALLINT completeConnectionStringLength = -1;
    81 	SQLRETURN result = SQLDriverConnect(connection, nullptr,
    81 	SQLRETURN result = SQLDriverConnect(connection, nullptr,
    82 			(SQLCHAR*) convertor.to_bytes(connectionString).c_str(), SQL_NTS,
    82 			(SQLCHAR*) convertor.to_bytes(connectionString).c_str(), SQL_NTS,
    83 			(SQLCHAR*) completeConnectionString, sizeof (completeConnectionString), &completeConnectionStringLength,
    83 			(SQLCHAR*) completeConnectionString, sizeof (completeConnectionString), &completeConnectionStringLength,
    84 			SQL_DRIVER_NOPROMPT);
    84 			SQL_DRIVER_NOPROMPT);
    85 	if (OdbcCommon::isNotSuccessful(result)) throw SqlException(L"Unable to connect to " + connectionString, result, SQL_HANDLE_ENV, env);
    85 	if (OdbcCommon::isNotSuccessful(result)) throw SqlException(L"Unable to connect to " + connectionString, result, SQL_HANDLE_ENV, environment);
    86 	std::wcerr << "ODBC connected to: " << convertor.from_bytes(completeConnectionString) << std::endl; // FIXME: remove
       
    87 	return new Connection(connection);
    86 	return new Connection(connection);
    88 }
    87 }
    89 
       
    90 relpipe::reader::string_t DriverManager::buildDSN(const std::map<relpipe::reader::string_t, relpipe::reader::string_t>& parameters) {
       
    91 	throw SqlException(L"not yet implemented: buildDSN()"); // FIXME: implement buildDSN()
       
    92 }
       
    93 
       
    94 
    88 
    95 }
    89 }
    96 }
    90 }
    97 }
    91 }