Skip to content

Commit 2b39bca

Browse files
committed
DSN window implementation
1 parent c98f368 commit 2b39bca

File tree

3 files changed

+59
-9
lines changed

3 files changed

+59
-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: 30 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,37 @@ 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+
// Attempt connection once, if connection failed due to missing properties,
374+
// load the DSN window according to driverCompletion
375+
376+
driver::flight_sql::config::Configuration config;
377+
if (driverCompletion == SQL_DRIVER_PROMPT) {
378+
DisplayConnectionWindow(windowHandle, config, properties);
379+
connection->connect(dsn, properties, missing_properties);
380+
} else if (driverCompletion == SQL_DRIVER_COMPLETE ||
381+
driverCompletion == SQL_DRIVER_COMPLETE_REQUIRED) {
382+
try {
383+
connection->connect(dsn, properties, missing_properties);
384+
} catch (DriverException& ex) {
385+
// If first connection fails due to missing attributes, load
386+
// the DSN window and try to connect again
387+
if (!missing_properties.empty()) {
388+
missing_properties.clear();
389+
390+
DisplayConnectionWindow(windowHandle, config, properties);
391+
connection->connect(dsn, properties, missing_properties);
392+
} else {
393+
throw ex;
394+
}
395+
}
396+
} else {
397+
// Default case: attempt connection without showing DSN window
398+
connection->connect(dsn, properties, missing_properties);
377399
}
378-
#endif
379-
400+
#else
401+
// Attempt connection without loading DSN window on macOS/Linux
380402
connection->connect(dsn, properties, missing_properties);
381-
403+
#endif
382404
// Copy connection string to outConnectionString after connection attempt
383405
return ODBC::GetStringAttribute(true, connection_string, true, outConnectionString,
384406
outConnectionStringBufferLen, outConnectionStringLen,

0 commit comments

Comments
 (0)