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 } |