| 830 | } |
| 831 | |
| 832 | SQLRETURN SQLDriverConnect(SQLHDBC conn, SQLHWND window_handle, |
| 833 | SQLWCHAR* in_connection_string, |
| 834 | SQLSMALLINT in_connection_string_len, |
| 835 | SQLWCHAR* out_connection_string, |
| 836 | SQLSMALLINT out_connection_string_buffer_len, |
| 837 | SQLSMALLINT* out_connection_string_len, |
| 838 | SQLUSMALLINT driver_completion) { |
| 839 | ARROW_LOG(DEBUG) << "SQLDriverConnectW called with conn: " << conn |
| 840 | << ", window_handle: " << static_cast<const void*>(window_handle) |
| 841 | << ", in_connection_string: " |
| 842 | << static_cast<const void*>(in_connection_string) |
| 843 | << ", in_connection_string_len: " << in_connection_string_len |
| 844 | << ", out_connection_string: " |
| 845 | << static_cast<const void*>(out_connection_string) |
| 846 | << ", out_connection_string_buffer_len: " |
| 847 | << out_connection_string_buffer_len << ", out_connection_string_len: " |
| 848 | << static_cast<const void*>(out_connection_string_len) |
| 849 | << ", driver_completion: " << driver_completion; |
| 850 | |
| 851 | // GH-46449 TODO: Implement FILEDSN and SAVEFILE keywords according to the spec |
| 852 | |
| 853 | // GH-46560 TODO: Copy connection string properly in SQLDriverConnect according to the |
| 854 | // spec |
| 855 | |
| 856 | using ODBC::ODBCConnection; |
| 857 | |
| 858 | return ODBCConnection::ExecuteWithDiagnostics(conn, SQL_ERROR, [=]() { |
| 859 | ODBCConnection* connection = reinterpret_cast<ODBCConnection*>(conn); |
| 860 | std::string connection_string = |
| 861 | ODBC::SqlWcharToString(in_connection_string, in_connection_string_len); |
| 862 | Connection::ConnPropertyMap properties; |
| 863 | std::string dsn_value = ""; |
| 864 | std::optional<std::string> dsn = ODBCConnection::GetDsnIfExists(connection_string); |
| 865 | if (dsn.has_value()) { |
| 866 | dsn_value = dsn.value(); |
| 867 | LoadPropertiesFromDSN(dsn_value, properties); |
| 868 | } |
| 869 | ODBCConnection::GetPropertiesFromConnString(connection_string, properties); |
| 870 | |
| 871 | std::vector<std::string_view> missing_properties; |
| 872 | |
| 873 | // GH-46448 TODO: Implement SQL_DRIVER_COMPLETE_REQUIRED in SQLDriverConnect according |
| 874 | // to the spec |
| 875 | #if defined _WIN32 |
| 876 | // Load the DSN window according to driver_completion |
| 877 | if (driver_completion == SQL_DRIVER_PROMPT) { |
| 878 | // Load DSN window before first attempt to connect |
| 879 | config::Configuration config; |
| 880 | if (!DisplayConnectionWindow(window_handle, config, properties)) { |
| 881 | return static_cast<SQLRETURN>(SQL_NO_DATA); |
| 882 | } |
| 883 | connection->Connect(dsn_value, properties, missing_properties); |
| 884 | } else if (driver_completion == SQL_DRIVER_COMPLETE || |
| 885 | driver_completion == SQL_DRIVER_COMPLETE_REQUIRED) { |
| 886 | try { |
| 887 | connection->Connect(dsn_value, properties, missing_properties); |
| 888 | } catch (const DriverException&) { |
| 889 | // If first connection fails due to missing attributes, load |