Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions cpp/src/arrow/flight/sql/odbc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ else()
set(ODBCINST odbcinst)
endif()

add_definitions(-DUNICODE=1)

add_subdirectory(flight_sql)
add_subdirectory(odbcabstraction)
add_subdirectory(tests)
Expand Down
155 changes: 77 additions & 78 deletions cpp/src/arrow/flight/sql/odbc/entry_points.cc

Large diffs are not rendered by default.

48 changes: 33 additions & 15 deletions cpp/src/arrow/flight/sql/odbc/flight_sql/config/configuration.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

#include "arrow/flight/sql/odbc/flight_sql/include/flight_sql/config/configuration.h"
#include "arrow/flight/sql/odbc/flight_sql/flight_sql_connection.h"
#include "arrow/result.h"
#include "arrow/util/utf8.h"

#include <odbcinst.h>
#include <boost/range/adaptor/map.hpp>
Expand All @@ -27,7 +29,6 @@
namespace driver {
namespace flight_sql {
namespace config {

static const char DEFAULT_DSN[] = "Apache Arrow Flight SQL";
static const char DEFAULT_ENABLE_ENCRYPTION[] = TRUE_STR;
static const char DEFAULT_USE_CERT_STORE[] = TRUE_STR;
Expand All @@ -36,19 +37,27 @@ static const char DEFAULT_DISABLE_CERT_VERIFICATION[] = FALSE_STR;
namespace {
std::string ReadDsnString(const std::string& dsn, const std::string_view& key,
const std::string& dflt = "") {
std::wstring wDsn = arrow::util::UTF8ToWideString(dsn).ValueOr(L"");
std::wstring wKey = arrow::util::UTF8ToWideString(key).ValueOr(L"");
std::wstring wDflt = arrow::util::UTF8ToWideString(dflt).ValueOr(L"");

#define BUFFER_SIZE (1024)
std::vector<char> buf(BUFFER_SIZE);
int ret = SQLGetPrivateProfileString(dsn.c_str(), key.data(), dflt.c_str(), buf.data(),
static_cast<int>(buf.size()), "ODBC.INI");
std::vector<wchar_t> buf(BUFFER_SIZE);
int ret =
SQLGetPrivateProfileString(wDsn.c_str(), wKey.c_str(), wDflt.c_str(), buf.data(),
static_cast<int>(buf.size()), L"ODBC.INI");

if (ret > BUFFER_SIZE) {
// If there wasn't enough space, try again with the right size buffer.
buf.resize(ret + 1);
ret = SQLGetPrivateProfileString(dsn.c_str(), key.data(), dflt.c_str(), buf.data(),
static_cast<int>(buf.size()), "ODBC.INI");
ret =
SQLGetPrivateProfileString(wDsn.c_str(), wKey.c_str(), wDflt.c_str(), buf.data(),
static_cast<int>(buf.size()), L"ODBC.INI");
}

return std::string(buf.data(), ret);
std::wstring wResult = std::wstring(buf.data(), ret);
std::string result = arrow::util::WideStringToUTF8(wResult).ValueOr("");
return result;
}

void RemoveAllKnownKeys(std::vector<std::string>& keys) {
Expand All @@ -65,28 +74,32 @@ void RemoveAllKnownKeys(std::vector<std::string>& keys) {
}

std::vector<std::string> ReadAllKeys(const std::string& dsn) {
std::vector<char> buf(BUFFER_SIZE);
std::wstring wDsn = arrow::util::UTF8ToWideString(dsn).ValueOr(L"");

std::vector<wchar_t> buf(BUFFER_SIZE);

int ret = SQLGetPrivateProfileString(dsn.c_str(), NULL, "", buf.data(),
static_cast<int>(buf.size()), "ODBC.INI");
int ret = SQLGetPrivateProfileString(wDsn.c_str(), NULL, L"", buf.data(),
static_cast<int>(buf.size()), L"ODBC.INI");

if (ret > BUFFER_SIZE) {
// If there wasn't enough space, try again with the right size buffer.
buf.resize(ret + 1);
ret = SQLGetPrivateProfileString(dsn.c_str(), NULL, "", buf.data(),
static_cast<int>(buf.size()), "ODBC.INI");
ret = SQLGetPrivateProfileString(wDsn.c_str(), NULL, L"", buf.data(),
static_cast<int>(buf.size()), L"ODBC.INI");
}

// When you pass NULL to SQLGetPrivateProfileString it gives back a \0 delimited list of
// all the keys. The below loop simply tokenizes all the keys and places them into a
// vector.
std::vector<std::string> keys;
char* begin = buf.data();
wchar_t* begin = buf.data();
while (begin && *begin != '\0') {
char* cur;
wchar_t* cur;
for (cur = begin; *cur != '\0'; ++cur) {
}
keys.emplace_back(begin, cur);

std::string key = arrow::util::WideStringToUTF8(std::wstring(begin, cur)).ValueOr("");
keys.emplace_back(key);
begin = ++cur;
}
return keys;
Expand Down Expand Up @@ -150,6 +163,11 @@ const std::string& Configuration::Get(const std::string_view& key) const {
return itr->second;
}

void Configuration::Set(const std::string_view& key, const std::wstring& wValue) {
std::string value = arrow::util::WideStringToUTF8(wValue).ValueOr("");
Set(key, value);
}

void Configuration::Set(const std::string_view& key, const std::string& value) {
const std::string copy = boost::trim_copy(value);
if (!copy.empty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class Configuration {
void Clear();
bool IsSet(const std::string_view& key) const;
const std::string& Get(const std::string_view& key) const;
void Set(const std::string_view& key, const std::wstring& wValue);
void Set(const std::string_view& key, const std::string& value);
Comment thread
rscales marked this conversation as resolved.
Outdated
void Emplace(const std::string_view& key, std::string&& value);
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class AddPropertyWindow : public CustomWindow {
*
* @return true if the dialog was OK'd, false otherwise.
*/
bool GetProperty(std::string& key, std::string& value);
bool GetProperty(std::wstring& key, std::wstring& value);

private:
/**
Expand All @@ -97,9 +97,9 @@ class AddPropertyWindow : public CustomWindow {

std::unique_ptr<Window> valueEdit;

std::string key;
std::wstring key;

std::string value;
std::wstring value;

/** Window width. */
int width;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class CustomWindow : public Window {
* @param className Window class name.
* @param title Window title.
*/
CustomWindow(Window* parent, const char* className, const char* title);
CustomWindow(Window* parent, const wchar_t* className, const wchar_t* title);

/**
* Destructor.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class Window {
* @param className Window class name.
* @param title Window title.
*/
Window(Window* parent, const char* className, const char* title);
Window(Window* parent, const wchar_t* className, const wchar_t* title);

/**
* Constructor for the existing window.
Expand Down Expand Up @@ -102,7 +102,7 @@ class Window {
* @return Auto pointer containing new window.
*/
std::unique_ptr<Window> CreateGroupBox(int posX, int posY, int sizeX, int sizeY,
const char* title, int id);
const wchar_t* title, int id);

/**
* Create child label window.
Expand All @@ -116,7 +116,7 @@ class Window {
* @return Auto pointer containing new window.
*/
std::unique_ptr<Window> CreateLabel(int posX, int posY, int sizeX, int sizeY,
const char* title, int id);
const wchar_t* title, int id);

/**
* Create child Edit window.
Expand All @@ -131,7 +131,7 @@ class Window {
* @return Auto pointer containing new window.
*/
std::unique_ptr<Window> CreateEdit(int posX, int posY, int sizeX, int sizeY,
const char* title, int id, int style = 0);
const wchar_t* title, int id, int style = 0);

/**
* Create child button window.
Expand All @@ -146,7 +146,7 @@ class Window {
* @return Auto pointer containing new window.
*/
std::unique_ptr<Window> CreateButton(int posX, int posY, int sizeX, int sizeY,
const char* title, int id, int style = 0);
const wchar_t* title, int id, int style = 0);

/**
* Create child CheckBox window.
Expand All @@ -161,7 +161,7 @@ class Window {
* @return Auto pointer containing new window.
*/
std::unique_ptr<Window> CreateCheckBox(int posX, int posY, int sizeX, int sizeY,
const char* title, int id, bool state);
const wchar_t* title, int id, bool state);

/**
* Create child ComboBox window.
Expand All @@ -175,7 +175,7 @@ class Window {
* @return Auto pointer containing new window.
*/
std::unique_ptr<Window> CreateComboBox(int posX, int posY, int sizeX, int sizeY,
const char* title, int id);
const wchar_t* title, int id);

/**
* Show window.
Expand All @@ -201,15 +201,15 @@ class Window {

void SetVisible(bool isVisible);

void ListAddColumn(const std::string& name, int index, int width);
void ListAddColumn(const std::wstring& name, int index, int width);

void ListAddItem(const std::vector<std::string>& items);
void ListAddItem(const std::vector<std::wstring>& items);

void ListDeleteSelectedItem();

std::vector<std::vector<std::string> > ListGetAll();
std::vector<std::vector<std::wstring> > ListGetAll();

void AddTab(const std::string& name, int index);
void AddTab(const std::wstring& name, int index);

bool IsTextEmpty() const;

Expand All @@ -218,14 +218,14 @@ class Window {
*
* @param text Text.
*/
void GetText(std::string& text) const;
void GetText(std::wstring& text) const;

/**
* Set window text.
*
* @param text Text.
*/
void SetText(const std::string& text) const;
void SetText(const std::wstring& text) const;

/**
* Get CheckBox state.
Expand All @@ -246,7 +246,7 @@ class Window {
*
* @param str String.
*/
void AddString(const std::string& str);
void AddString(const std::wstring& str);

/**
* Set current ComboBox selection.
Expand Down Expand Up @@ -285,10 +285,10 @@ class Window {
void SetHandle(HWND value) { handle = value; }

/** Window class name. */
std::string className;
std::wstring className;

/** Window title. */
std::string title;
std::wstring title;

/** Window handle. */
HWND handle;
Expand Down
25 changes: 15 additions & 10 deletions cpp/src/arrow/flight/sql/odbc/flight_sql/system_dsn.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

#include "arrow/flight/sql/odbc/flight_sql/flight_sql_connection.h"
#include "arrow/flight/sql/odbc/flight_sql/include/flight_sql/config/configuration.h"
#include "arrow/result.h"
#include "arrow/util/utf8.h"

#include <odbcinst.h>
#include <sstream>
Expand All @@ -29,14 +31,14 @@ using driver::flight_sql::config::Configuration;
void PostLastInstallerError() {
#define BUFFER_SIZE (1024)
DWORD code;
char msg[BUFFER_SIZE];
wchar_t msg[BUFFER_SIZE];
SQLInstallerError(1, &code, msg, BUFFER_SIZE, NULL);

std::stringstream buf;
buf << "Message: \"" << msg << "\", Code: " << code;
std::string errorMsg = buf.str();
std::wstringstream buf;
buf << L"Message: \"" << msg << L"\", Code: " << code;
std::wstring errorMsg = buf.str();

MessageBox(NULL, errorMsg.c_str(), "Error!", MB_ICONEXCLAMATION | MB_OK);
MessageBox(NULL, errorMsg.c_str(), L"Error!", MB_ICONEXCLAMATION | MB_OK);
SQLPostInstallerError(code, errorMsg.c_str());
}

Expand All @@ -46,7 +48,7 @@ void PostLastInstallerError() {
* @param dsn DSN name.
* @return True on success and false on fail.
*/
bool UnregisterDsn(const std::string& dsn) {
bool UnregisterDsn(const std::wstring& dsn) {
if (SQLRemoveDSNFromIni(dsn.c_str())) {
return true;
}
Expand All @@ -62,10 +64,11 @@ bool UnregisterDsn(const std::string& dsn) {
* @param driver Driver.
* @return True on success and false on fail.
*/
bool RegisterDsn(const Configuration& config, LPCSTR driver) {
bool RegisterDsn(const Configuration& config, LPCWSTR driver) {
const std::string& dsn = config.Get(FlightSqlConnection::DSN);
std::wstring wDsn = arrow::util::UTF8ToWideString(dsn).ValueOr(L"");

if (!SQLWriteDSNToIni(dsn.c_str(), driver)) {
if (!SQLWriteDSNToIni(wDsn.c_str(), driver)) {
PostLastInstallerError();
return false;
}
Expand All @@ -78,8 +81,10 @@ bool RegisterDsn(const Configuration& config, LPCSTR driver) {
continue;
}

if (!SQLWritePrivateProfileString(dsn.c_str(), key.data(), it->second.c_str(),
"ODBC.INI")) {
std::wstring wKey = arrow::util::UTF8ToWideString(key).ValueOr(L"");
std::wstring wValue = arrow::util::UTF8ToWideString(it->second).ValueOr(L"");
if (!SQLWritePrivateProfileString(wDsn.c_str(), wKey.c_str(), wValue.c_str(),
L"ODBC.INI")) {
PostLastInstallerError();
return false;
}
Expand Down
4 changes: 2 additions & 2 deletions cpp/src/arrow/flight/sql/odbc/flight_sql/system_dsn.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,12 @@ bool DisplayConnectionWindow(void* windowParent, Configuration& config,
* @param driver Driver.
* @return True on success and false on fail.
*/
bool RegisterDsn(const Configuration& config, LPCSTR driver);
bool RegisterDsn(const Configuration& config, LPCWSTR driver);

/**
* Unregister specified DSN.
*
* @param dsn DSN name.
* @return True on success and false on fail.
*/
bool UnregisterDsn(const std::string& dsn);
bool UnregisterDsn(const std::wstring& dsn);
Loading
Loading