Skip to content

Commit a913e66

Browse files
committed
In-progress implement unicode support conversion
1 parent 7ff034a commit a913e66

4 files changed

Lines changed: 62 additions & 23 deletions

File tree

cpp/src/arrow/flight/sql/odbc/odbc_impl/config/configuration.cc

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -60,18 +60,20 @@ std::string ReadDsnString(const std::string& dsn, std::string_view key,
6060

6161
#define BUFFER_SIZE (1024)
6262
std::vector<SQLWCHAR> buf(BUFFER_SIZE);
63-
int ret = SQLGetPrivateProfileString(
64-
reinterpret_cast<LPCWSTR>(wdsn.c_str()), reinterpret_cast<LPCWSTR>(wkey.c_str()),
65-
reinterpret_cast<LPCWSTR>(wdflt.c_str()), buf.data(), static_cast<int>(buf.size()),
66-
reinterpret_cast<LPCWSTR>(L"ODBC.INI"));
63+
int ret = SQLGetPrivateProfileString(reinterpret_cast<LPCWSTR>(GET_SQWCHAR_PTR(wdsn)),
64+
reinterpret_cast<LPCWSTR>(GET_SQWCHAR_PTR(wkey)),
65+
reinterpret_cast<LPCWSTR>(GET_SQWCHAR_PTR(wdflt)),
66+
buf.data(), static_cast<int>(buf.size()),
67+
reinterpret_cast<LPCWSTR>(L"ODBC.INI"));
6768

6869
if (ret > BUFFER_SIZE) {
6970
// If there wasn't enough space, try again with the right size buffer.
7071
buf.resize(ret + 1);
71-
ret = SQLGetPrivateProfileString(
72-
reinterpret_cast<LPCWSTR>(wdsn.c_str()), reinterpret_cast<LPCWSTR>(wkey.c_str()),
73-
reinterpret_cast<LPCWSTR>(wdflt.c_str()), buf.data(),
74-
static_cast<int>(buf.size()), reinterpret_cast<LPCWSTR>(L"ODBC.INI"));
72+
ret = SQLGetPrivateProfileString(reinterpret_cast<LPCWSTR>(GET_SQWCHAR_PTR(wdsn)),
73+
reinterpret_cast<LPCWSTR>(GET_SQWCHAR_PTR(wkey)),
74+
reinterpret_cast<LPCWSTR>(GET_SQWCHAR_PTR(wdflt)),
75+
buf.data(), static_cast<int>(buf.size()),
76+
reinterpret_cast<LPCWSTR>(L"ODBC.INI"));
7577
}
7678

7779
std::string result("");
@@ -101,16 +103,18 @@ std::vector<std::string> ReadAllKeys(const std::string& dsn) {
101103

102104
std::vector<SQLWCHAR> buf(BUFFER_SIZE);
103105

104-
int ret = SQLGetPrivateProfileString(
105-
reinterpret_cast<LPCWSTR>(wdsn.c_str()), NULL, reinterpret_cast<LPCWSTR>(L""),
106-
buf.data(), static_cast<int>(buf.size()), reinterpret_cast<LPCWSTR>(L"ODBC.INI"));
106+
int ret = SQLGetPrivateProfileString(reinterpret_cast<LPCWSTR>(GET_SQWCHAR_PTR(wdsn)),
107+
NULL, reinterpret_cast<LPCWSTR>(L""), buf.data(),
108+
static_cast<int>(buf.size()),
109+
reinterpret_cast<LPCWSTR>(L"ODBC.INI"));
107110

108111
if (ret > BUFFER_SIZE) {
109112
// If there wasn't enough space, try again with the right size buffer.
110113
buf.resize(ret + 1);
111-
ret = SQLGetPrivateProfileString(
112-
reinterpret_cast<LPCWSTR>(wdsn.c_str()), NULL, reinterpret_cast<LPCWSTR>(L""),
113-
buf.data(), static_cast<int>(buf.size()), reinterpret_cast<LPCWSTR>(L"ODBC.INI"));
114+
ret = SQLGetPrivateProfileString(reinterpret_cast<LPCWSTR>(GET_SQWCHAR_PTR(wdsn)),
115+
NULL, reinterpret_cast<LPCWSTR>(L""), buf.data(),
116+
static_cast<int>(buf.size()),
117+
reinterpret_cast<LPCWSTR>(L"ODBC.INI"));
114118
}
115119

116120
// When you pass NULL to SQLGetPrivateProfileString it gives back a \0 delimited list of

cpp/src/arrow/flight/sql/odbc/odbc_impl/encoding_utils.h

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,26 @@
2828
#include <memory>
2929
#include <string>
3030

31+
// Workaround for ODBC `BOOL` def conflict on Linux
32+
#ifdef __linux__
33+
# ifdef BOOL
34+
# undef BOOL
35+
# endif // BOOL
36+
#endif // __linux__
37+
// Include fwd.h headers after ODBC headers
38+
#include "arrow/flight/sql/odbc/odbc_impl/util.h"
39+
40+
#include "arrow/util/logging.h" // -AL- TEMP
41+
3142
#define _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING
3243

44+
#ifdef __linux__
45+
# define GET_SQWCHAR_PTR(wstring_var) (ODBC::ToSqlWCharVector(wstring_var).data())
46+
#else
47+
// Windows and macOS
48+
# define GET_SQWCHAR_PTR(wstring_var) (wstring_var.c_str())
49+
#endif
50+
3351
namespace ODBC {
3452
using arrow::flight::sql::odbc::DriverException;
3553
using arrow::flight::sql::odbc::GetSqlWCharSize;
@@ -118,11 +136,28 @@ inline std::string SqlStringToString(const unsigned char* sql_str,
118136
return res;
119137
}
120138

139+
// On Linux, unixodbc defines SQLWCHAR as `unsigned short`
121140
inline std::vector<SQLWCHAR> ToSqlWCharVector(const std::wstring& ws) {
122141
std::vector<SQLWCHAR> buf;
123142
// buf.assign(ws.begin(), ws.end());
124-
// TODO implement in separate PR
125-
return buf;
143+
// -AL- TODO implement
144+
ARROW_LOG(DEBUG) << "-AL- sizeof(SQLWCHAR):" << sizeof(SQLWCHAR)
145+
<< ", sizeof(wchar_t):" << sizeof(wchar_t);
146+
147+
ARROW_LOG(DEBUG) << "-AL- sizeof(char16_t):" << sizeof(char16_t)
148+
<< ", sizeof(char32_t):" << sizeof(char32_t);
149+
if (sizeof(SQLWCHAR) == sizeof(wchar_t)) {
150+
ARROW_LOG(DEBUG) << "-AL- sizeof(SQLWCHAR) equals sizeof(wchar_t) ";
151+
return std::vector<SQLWCHAR>(ws.begin(), ws.end());
152+
} else {
153+
ARROW_LOG(DEBUG) << "-AL- sizeof(SQLWCHAR) != doesn't equal sizeof(wchar_t) ";
154+
CONVERT_UTF8_STR(const std::string utf8s, ws);
155+
CONVERT_UTF16_STR(const std::u16string utf16s, utf8s);
156+
// std::string WideStringToUTF8(input);
157+
// std::u16string u16s = UTF8StringToUTF16();
158+
159+
return std::vector<SQLWCHAR>(utf16s.begin(), utf16s.end());
160+
}
126161
}
127162

128163
} // namespace ODBC

cpp/src/arrow/flight/sql/odbc/odbc_impl/system_dsn.cc

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,6 @@
2525

2626
#include "arrow/flight/sql/odbc/odbc_impl/encoding_utils.h"
2727

28-
#ifdef __linux__
29-
# define GET_SQWCHAR_PTR(wstring_var) (ODBC::ToSqlWCharVector(wstring_var).data())
30-
#else
31-
// Windows and macOS
32-
# define GET_SQWCHAR_PTR(wstring_var) (wstring_var.c_str())
33-
#endif
34-
3528
namespace arrow::flight::sql::odbc {
3629

3730
using config::Configuration;

cpp/src/arrow/flight/sql/odbc/odbc_impl/util.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,13 @@
4242
return res.ValueOrDie(); \
4343
}()
4444

45+
#define CONVERT_UTF16_STR(utf16string_var, utf8_target) \
46+
utf16string_var = [&] { \
47+
arrow::Result<std::u16string> res = arrow::util::UTF8StringToUTF16(utf8_target); \
48+
arrow::flight::sql::odbc::util::ThrowIfNotOK(res.status()); \
49+
return res.ValueOrDie(); \
50+
}()
51+
4552
namespace arrow::flight::sql::odbc {
4653
namespace util {
4754

0 commit comments

Comments
 (0)