Skip to content

Commit d23e867

Browse files
committed
DSN window implementation
1 parent ce4a14e commit d23e867

File tree

3 files changed

+58
-9
lines changed

3 files changed

+58
-9
lines changed

cpp/src/arrow/flight/sql/odbc/flight_sql/system_dsn.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "arrow/flight/sql/odbc/flight_sql/include/flight_sql/config/configuration.h"
2222

2323
using driver::flight_sql::config::Configuration;
24+
using driver::odbcabstraction::Connection;
2425

2526
#if defined _WIN32 || defined _WIN64
2627
/**
@@ -31,6 +32,19 @@ using driver::flight_sql::config::Configuration;
3132
* @return True on success and false on fail.
3233
*/
3334
bool DisplayConnectionWindow(void* windowParent, Configuration& config);
35+
36+
/**
37+
* For SQLDriverConnect.
38+
* Display connection window for user to configure connection parameters.
39+
*
40+
* @param windowParent Parent window handle.
41+
* @param config Output configuration, presumed to be empty, it will be using values from
42+
* properties.
43+
* @param config Output properties.
44+
* @return True on success and false on fail.
45+
*/
46+
void DisplayConnectionWindow(void* windowParent, Configuration& config,
47+
Connection::ConnPropertyMap& properties);
3448
#endif
3549

3650
/**

cpp/src/arrow/flight/sql/odbc/flight_sql/win_system_dsn.cc

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ using driver::flight_sql::config::ConnectionStringParser;
4141
using driver::flight_sql::config::DsnConfigurationWindow;
4242
using driver::flight_sql::config::Result;
4343
using driver::flight_sql::config::Window;
44+
using driver::odbcabstraction::DriverException;
4445

4546
BOOL CALLBACK ConfigDriver(HWND hwndParent, WORD fRequest, LPCSTR lpszDriver,
4647
LPCSTR lpszArgs, LPSTR lpszMsg, WORD cbMsgMax,
@@ -63,7 +64,7 @@ bool DisplayConnectionWindow(void* windowParent, Configuration& config) {
6364
window.Update();
6465

6566
return ProcessMessages(window) == Result::OK;
66-
} catch (const driver::odbcabstraction::DriverException& err) {
67+
} catch (const DriverException& err) {
6768
std::stringstream buf;
6869
buf << "SQL State: " << err.GetSqlState() << ", Message: " << err.GetMessageText()
6970
<< ", Code: " << err.GetNativeError();
@@ -76,6 +77,19 @@ bool DisplayConnectionWindow(void* windowParent, Configuration& config) {
7677
return false;
7778
}
7879

80+
void DisplayConnectionWindow(void* windowParent, Configuration& config,
81+
Connection::ConnPropertyMap& properties) {
82+
for (const auto& [key, value] : properties) {
83+
config.Set(key, value);
84+
}
85+
86+
if (DisplayConnectionWindow(windowParent, config)) {
87+
properties = config.GetProperties();
88+
} else {
89+
throw DriverException("Connection canceled by user", "HY008");
90+
}
91+
}
92+
7993
BOOL INSTAPI ConfigDSN(HWND hwndParent, WORD req, LPCSTR driver, LPCSTR attributes) {
8094
Configuration config;
8195
ConnectionStringParser parser(config);

cpp/src/arrow/flight/sql/odbc/odbc_api.cc

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,7 @@ SQLRETURN SQLDriverConnectW(SQLHDBC conn, SQLHWND windowHandle,
354354
// spec https://github.com/apache/arrow/issues/46560
355355

356356
using driver::odbcabstraction::Connection;
357+
using driver::odbcabstraction::DriverException;
357358
using ODBC::ODBCConnection;
358359

359360
return ODBCConnection::ExecuteWithDiagnostics(conn, SQL_ERROR, [=]() {
@@ -369,16 +370,36 @@ SQLRETURN SQLDriverConnectW(SQLHDBC conn, SQLHWND windowHandle,
369370
// TODO: Implement SQL_DRIVER_COMPLETE_REQUIRED in SQLDriverConnectW according to the
370371
// spec https://github.com/apache/arrow/issues/46448
371372
#if defined _WIN32 || defined _WIN64
372-
if (driverCompletion == SQL_DRIVER_PROMPT ||
373-
((driverCompletion == SQL_DRIVER_COMPLETE ||
374-
driverCompletion == SQL_DRIVER_COMPLETE_REQUIRED) &&
375-
!missing_properties.empty())) {
376-
// TODO: implement driverCompletion behavior to display connection window.
373+
// Load the DSN window according to driverCompletion
374+
375+
driver::flight_sql::config::Configuration config;
376+
if (driverCompletion == SQL_DRIVER_PROMPT) {
377+
DisplayConnectionWindow(windowHandle, config, properties);
378+
connection->connect(dsn, properties, missing_properties);
379+
} else if (driverCompletion == SQL_DRIVER_COMPLETE ||
380+
driverCompletion == SQL_DRIVER_COMPLETE_REQUIRED) {
381+
try {
382+
connection->connect(dsn, properties, missing_properties);
383+
} catch (DriverException& ex) {
384+
// If first connection fails due to missing attributes, load
385+
// the DSN window and try to connect again
386+
if (!missing_properties.empty()) {
387+
missing_properties.clear();
388+
389+
DisplayConnectionWindow(windowHandle, config, properties);
390+
connection->connect(dsn, properties, missing_properties);
391+
} else {
392+
throw ex;
393+
}
394+
}
395+
} else {
396+
// Default case: attempt connection without showing DSN window
397+
connection->connect(dsn, properties, missing_properties);
377398
}
378-
#endif
379-
399+
#else
400+
// Attempt connection without loading DSN window on macOS/Linux
380401
connection->connect(dsn, properties, missing_properties);
381-
402+
#endif
382403
// Copy connection string to outConnectionString after connection attempt
383404
return ODBC::GetStringAttribute(true, connection_string, true, outConnectionString,
384405
outConnectionStringBufferLen, outConnectionStringLen,

0 commit comments

Comments
 (0)