Skip to content

Commit 56b3ad0

Browse files
committed
DSN window implementation
1 parent 573581b commit 56b3ad0

File tree

3 files changed

+65
-9
lines changed

3 files changed

+65
-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+
bool 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: 17 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,21 @@ bool DisplayConnectionWindow(void* windowParent, Configuration& config) {
7677
return false;
7778
}
7879

80+
bool 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+
return true;
89+
} else {
90+
// TODO: log cancelled dialog after logging is enabled.
91+
return false;
92+
}
93+
}
94+
7995
BOOL INSTAPI ConfigDSN(HWND hwndParent, WORD req, LPCSTR driver, LPCSTR attributes) {
8096
Configuration config;
8197
ConnectionStringParser parser(config);

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

Lines changed: 34 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,41 @@ 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+
if (driverCompletion == SQL_DRIVER_PROMPT) {
375+
// Load DSN window before first attempt to connect
376+
driver::flight_sql::config::Configuration config;
377+
if (!DisplayConnectionWindow(windowHandle, config, properties)) {
378+
return static_cast<SQLRETURN>(SQL_NO_DATA);
379+
}
380+
connection->connect(dsn, properties, missing_properties);
381+
} else if (driverCompletion == SQL_DRIVER_COMPLETE ||
382+
driverCompletion == SQL_DRIVER_COMPLETE_REQUIRED) {
383+
try {
384+
connection->connect(dsn, properties, missing_properties);
385+
} catch (const DriverException&) {
386+
// If first connection fails due to missing attributes, load
387+
// the DSN window and try to connect again
388+
if (!missing_properties.empty()) {
389+
driver::flight_sql::config::Configuration config;
390+
missing_properties.clear();
391+
392+
if (!DisplayConnectionWindow(windowHandle, config, properties)) {
393+
return static_cast<SQLRETURN>(SQL_NO_DATA);
394+
}
395+
connection->connect(dsn, properties, missing_properties);
396+
} else {
397+
throw;
398+
}
399+
}
400+
} else {
401+
// Default case: attempt connection without showing DSN window
402+
connection->connect(dsn, properties, missing_properties);
377403
}
378-
#endif
379-
404+
#else
405+
// Attempt connection without loading DSN window on macOS/Linux
380406
connection->connect(dsn, properties, missing_properties);
381-
407+
#endif
382408
// Copy connection string to outConnectionString after connection attempt
383409
return ODBC::GetStringAttribute(true, connection_string, true, outConnectionString,
384410
outConnectionStringBufferLen, outConnectionStringLen,

0 commit comments

Comments
 (0)