Skip to content

Commit

Permalink
Fix power bi connection (#22)
Browse files Browse the repository at this point in the history
* Fix bug with SQLGetData incorrect set strLen and add exception for login timeout attribute.

Signed-off-by: Forest Vey <[email protected]>

* Adding test case for empty response.

Signed-off-by: Forest Vey <[email protected]>

* Add SQLGetData test and update to not set SQL_NO_TOTAL for empty responses.

Signed-off-by: Forest Vey <[email protected]>

* Cleaning up test comments.

Signed-off-by: Forest Vey <[email protected]>

* Removing not needed empty fetch test.

Signed-off-by: Forest Vey <[email protected]>

* re-work putStrToBuffer function.

Signed-off-by: Forest Vey <[email protected]>

* Indentation fix.

Signed-off-by: Forest Vey <[email protected]>

* Update PutStrToStrBuffer to note use SQL_NO_TOTAL.

Signed-off-by: Forest Vey <[email protected]>

* Revising setting cell offset.

Signed-off-by: Forest Vey <[email protected]>

* Cleaning up code for meaningless variables and conversions.

Signed-off-by: Forest Vey <[email protected]>

* Fixing off by one error when setting truncated cell offset.

Signed-off-by: Forest Vey <[email protected]>

* Updating wstring_convert to fix compilation error.

Signed-off-by: Forest Vey <[email protected]>

* Removing wstring_convert dependency to application_data_buffer_test.

Signed-off-by: Forest Vey <[email protected]>

* Moving to older version of cmake to fix windows build CI.

Signed-off-by: Forest Vey <[email protected]>

* Testing ignoring warnings compilation to fix windows build.

Signed-off-by: Forest Vey <[email protected]>

* Adding noerr flag for msbuild commands with aws-sdk-cpp.

Signed-off-by: Forest Vey <[email protected]>

* Upgrading cmake min req version.

Signed-off-by: Forest Vey <[email protected]>

* Reverting cmake version change.

Signed-off-by: Forest Vey <[email protected]>

* Revising test for reslen comparison in bytes.

Signed-off-by: Forest Vey <[email protected]>

* adding warnaserror flag for msbuild with aws-sdk-cpp.

Signed-off-by: Forest Vey <[email protected]>

* Adding noerr for C2220

Signed-off-by: Forest Vey <[email protected]>

* Fixing noerr flag for msbuild command.

Signed-off-by: Forest Vey <[email protected]>

* Testing DAWS_SDK_WARNING_ARE_ERRORS

Signed-off-by: Forest Vey <[email protected]>

* re-organizing aws-sdk-cpp build script to ignore warnings.

Signed-off-by: Forest Vey <[email protected]>

* Re-testing DAWS_SDK_WARNINGS_ARE_ERRORS

Signed-off-by: Forest Vey <[email protected]>

* Testing deprecated-declarations

Signed-off-by: Forest Vey <[email protected]>

* Removing noerr portions to msbuild config.

Signed-off-by: Forest Vey <[email protected]>

* Adding MSVC specific error ignore.

Signed-off-by: Forest Vey <[email protected]>

* Disabling WX for aws-sdk-cpp compilation.

Signed-off-by: Forest Vey <[email protected]>

* Reverting aws-sdk-cpp fixes to use upstream instead.

Signed-off-by: Forest Vey <[email protected]>

* Removing aws-sdk-cpp build script for windows.

Signed-off-by: Forest Vey <[email protected]>

* Fixing invalid version updates for workflows during rebase.

Signed-off-by: Forest Vey <[email protected]>

---------

Signed-off-by: Forest Vey <[email protected]>
  • Loading branch information
forestmvey authored Sep 19, 2024
1 parent a702de5 commit 9af2284
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 13 deletions.
23 changes: 10 additions & 13 deletions src/odbc/src/app/application_data_buffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -277,27 +277,25 @@ ConversionResult::Type ApplicationDataBuffer::PutStrToStrBuffer(
return ConversionResult::Type::AI_SUCCESS;
}

// If cellOffset is not -1, we are on a continuation
SqlUlen currentCellOffset = cellOffset >= 0 ? cellOffset : 0;
// Since cellOffset is in bytes, an index needs to be calculated.
SqlUlen inCharIndex = currentCellOffset / inCharSize;

if (inCharIndex >= value.length()) {
if (resLenPtr) {
*resLenPtr = SQL_NO_TOTAL;
}
// If all data has already been read, return AI_NO_DATA
if ((currentCellOffset * outCharSize) >= bytesRequired) {
return ConversionResult::Type::AI_NO_DATA;
}


size_t bytesWritten = 0;
bool isTruncated = false;
if (inCharSize == 1) {
if (outCharSize == 2 || outCharSize == 4) {
bytesWritten = utility::CopyUtf8StringToSqlWcharString(
reinterpret_cast< const char* >(value.c_str() + inCharIndex),
reinterpret_cast< const char* >(value.c_str() + currentCellOffset),
reinterpret_cast< SQLWCHAR* >(dataPtr), buflen, isTruncated);
} else if (sizeof(OutCharT) == 1) {
bytesWritten = utility::CopyUtf8StringToSqlCharString(
reinterpret_cast< const char* >(value.c_str() + inCharIndex),
reinterpret_cast< const char* >(value.c_str() + currentCellOffset),
reinterpret_cast< SQLCHAR* >(dataPtr), buflen, isTruncated);
} else {
LOG_ERROR_MSG("Unexpected conversion from UTF8 string.");
Expand Down Expand Up @@ -326,14 +324,13 @@ ConversionResult::Type ApplicationDataBuffer::PutStrToStrBuffer(
*resLenPtr = remainingBytesRequired;
}

if (cellOffset >= 0) {
size_t numCharsWritten = bytesWritten / outCharSize;
SetCellOffset(cellOffset + numCharsWritten * inCharSize);
}

if (isTruncated) {
SetCellOffset(currentCellOffset + ((buflen / outCharSize) - 1));
return ConversionResult::Type::AI_VARLEN_DATA_TRUNCATED;
} else {
if (cellOffset >= 0) {
SetCellOffset(totalBytesWritten);
}
return ConversionResult::Type::AI_SUCCESS;
}
}
Expand Down
5 changes: 5 additions & 0 deletions src/odbc/src/connection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,11 @@ SqlResult::Type Connection::InternalSetAttribute(int attr, void* value,
LOG_INFO_MSG("log level is set to " << static_cast< int >(type));
break;
}

case SQL_LOGIN_TIMEOUT: {
LOG_INFO_MSG("login timeout is not implemented yet and this value is ignored.");
break;
}
default: {
AddStatusRecord(SqlState::SHYC00_OPTIONAL_FEATURE_NOT_IMPLEMENTED,
"Specified attribute is not supported.");
Expand Down
26 changes: 26 additions & 0 deletions src/tests/integration-test/src/api_robustness_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -856,6 +856,32 @@ BOOST_AUTO_TEST_CASE(TestSQLGetData) {
SQLFetch(stmt);
}

BOOST_AUTO_TEST_CASE(TestSQLGetDataEmpty) {
ConnectToTS();

std::vector< SQLWCHAR > sql =
MakeSqlBuffer("select ''");

SQLRETURN ret = SQLExecDirect(stmt, sql.data(), SQL_NTS);

ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);

ret = SQLFetch(stmt);

ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);

SQLWCHAR buffer[ODBC_BUFFER_SIZE];
SQLLEN resLen = 0;

ret = SQLGetData(stmt, 1, SQL_C_WCHAR, buffer, sizeof(buffer), &resLen);
// Empty response should set resLen to 0
BOOST_CHECK(resLen == 0);

ret = SQLGetData(stmt, 1, SQL_C_WCHAR, buffer, sizeof(buffer), &resLen);
// Follow up calls to SQLGetData should return SQL_NO_DATA
BOOST_CHECK_EQUAL(ret, SQL_NO_DATA);
}

BOOST_AUTO_TEST_CASE(TestSQLGetDataVarcharAsciiZeroBufferLength) {
// Ensures that calling SQLGetData with a buffer length of zero
// returns the required amount of data in the indicator pointer.
Expand Down
86 changes: 86 additions & 0 deletions src/tests/integration-test/src/application_data_buffer_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1549,6 +1549,92 @@ BOOST_AUTO_TEST_CASE(TestSetStringWithOffset) {
BOOST_CHECK(buf[1].reslen == strlen("Hello with offset!"));
}


BOOST_AUTO_TEST_CASE(TestSetLongString) {
char buffer[1024];
SqlLen reslen = 0;

ApplicationDataBuffer appBuf(OdbcNativeType::AI_CHAR, buffer, sizeof(buffer),
&reslen);

std::string longString("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus cursus urna in nibh congue, at semper sapien efficitur. \
Cras eget velit at eros pharetra tempus. Sed laoreet lorem nunc, a congue orci euismod vel. Cras molestie tellus vitae nisl pretium, a tristique magna \
tristique. In feugiat leo ac augue elementum facilisis. Pellentesque sollicitudin fringilla felis, id ornare mi lobortis a. Cras id eros vel nisi \
condimentum elementum sed eget tellus. Pellentesque commodo augue vitae diam suscipit dictum. Quisque vulputate a nulla dignissim semper. Cras rhoncus \
tortor sed ante maximus bibendum. Vivamus accumsan eros sem, vitae accumsan purus ornare quis. Cras eget quam at ipsum vestibulum laoreet. Nullam ut \
massa rhoncus, elementum velit nec, dignissim eros. Suspendisse potenti. Vivamus feugiat urna arcu, ut blandit dui molestie porttitor. Suspendisse mi \
risus, luctus vitae bibendum quis, ornare eget lacus. Maecenas rutrum sapien at interdum sagittis. Donec consectetur rutrum leo at ornare. Duis molestie \
diam ac diam imperdiet gravida. Ut sed tempus lorem. Vestibulum mattis quam mauris, non iaculis risus faucibus nec. Nullam congue volutpat gravida. \
Nullam vestibulum metus ultricies, consequat sem id, viverra velit. Sed eu diam eget purus rhoncus viverra ac et magna. Maecenas quis dignissim tortor, \
eu sodales ante. Maecenas rhoncus et massa eu suscipit. Sed pulvinar, sem vel viverra semper, dui risus ornare libero, vitae lacinia leo metus pharetra \
massa. Phasellus elementum efficitur nibh at blandit. Phasellus et auctor augue. Praesent quis facilisis orci. Orci varius natoque penatibus et magnis dis \
parturient montes, nascetur ridiculus mus. Nullam maximus ac mauris vel semper. Integer hendrerit bibendum nulla vitae blandit. Suspendisse in eleifend \
libero, ac semper est. Fusce non mattis lorem. Sed finibus leo egestas finibus euismod. Maecenas quis mauris vitae lacus efficitur mollis. Fusce faucibus \
fermentum mauris, vitae vestibulum ligula aliquam in. Proin ut eu.");

ConversionResult::Type ret = appBuf.PutString(longString);
BOOST_CHECK(!longString.substr(0, 1023).compare(buffer));
BOOST_CHECK_EQUAL(reslen, longString.size() - 1023);
BOOST_CHECK(ConversionResult::Type::AI_VARLEN_DATA_TRUNCATED == ret);

ret = appBuf.PutString(longString);
BOOST_CHECK_EQUAL(reslen, longString.size() - 2046);
BOOST_CHECK(!longString.substr(1023, 1023).compare(buffer));
BOOST_CHECK(ConversionResult::Type::AI_VARLEN_DATA_TRUNCATED == ret);

ret = appBuf.PutString(longString);
BOOST_CHECK(ConversionResult::Type::AI_SUCCESS == ret);
BOOST_CHECK(!longString.substr(2046).compare(buffer));
BOOST_CHECK_EQUAL(reslen, 2080);

ret = appBuf.PutString(longString);
BOOST_CHECK(ConversionResult::Type::AI_NO_DATA == ret);
}

BOOST_AUTO_TEST_CASE(TestSetLongStringWchar) {
SQLWCHAR buffer[1024];
SqlLen reslen = 0;

ApplicationDataBuffer appBuf(OdbcNativeType::AI_WCHAR, buffer, sizeof(buffer),
&reslen);

std::string longString("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus cursus urna in nibh congue, at semper sapien efficitur. \
Cras eget velit at eros pharetra tempus. Sed laoreet lorem nunc, a congue orci euismod vel. Cras molestie tellus vitae nisl pretium, a tristique magna \
tristique. In feugiat leo ac augue elementum facilisis. Pellentesque sollicitudin fringilla felis, id ornare mi lobortis a. Cras id eros vel nisi \
condimentum elementum sed eget tellus. Pellentesque commodo augue vitae diam suscipit dictum. Quisque vulputate a nulla dignissim semper. Cras rhoncus \
tortor sed ante maximus bibendum. Vivamus accumsan eros sem, vitae accumsan purus ornare quis. Cras eget quam at ipsum vestibulum laoreet. Nullam ut \
massa rhoncus, elementum velit nec, dignissim eros. Suspendisse potenti. Vivamus feugiat urna arcu, ut blandit dui molestie porttitor. Suspendisse mi \
risus, luctus vitae bibendum quis, ornare eget lacus. Maecenas rutrum sapien at interdum sagittis. Donec consectetur rutrum leo at ornare. Duis molestie \
diam ac diam imperdiet gravida. Ut sed tempus lorem. Vestibulum mattis quam mauris, non iaculis risus faucibus nec. Nullam congue volutpat gravida. \
Nullam vestibulum metus ultricies, consequat sem id, viverra velit. Sed eu diam eget purus rhoncus viverra ac et magna. Maecenas quis dignissim tortor, \
eu sodales ante. Maecenas rhoncus et massa eu suscipit. Sed pulvinar, sem vel viverra semper, dui risus ornare libero, vitae lacinia leo metus pharetra \
massa. Phasellus elementum efficitur nibh at blandit. Phasellus et auctor augue. Praesent quis facilisis orci. Orci varius natoque penatibus et magnis dis \
parturient montes, nascetur ridiculus mus. Nullam maximus ac mauris vel semper. Integer hendrerit bibendum nulla vitae blandit. Suspendisse in eleifend \
libero, ac semper est. Fusce non mattis lorem. Sed finibus leo egestas finibus euismod. Maecenas quis mauris vitae lacus efficitur mollis. Fusce faucibus \
fermentum mauris, vitae vestibulum ligula aliquam in. Proin ut eu.");

ConversionResult::Type ret = appBuf.PutString(longString);

BOOST_CHECK(!longString.substr(0, 1023).compare(timestream::odbc::utility::SqlWcharToString(buffer, SQL_NTS)));
BOOST_CHECK_EQUAL(reslen, (longString.size() - 1023) * sizeof(SQLWCHAR));
BOOST_CHECK(ConversionResult::Type::AI_VARLEN_DATA_TRUNCATED == ret);

ret = appBuf.PutString(longString);

BOOST_CHECK(!longString.substr(1023, 1023).compare(timestream::odbc::utility::SqlWcharToString(buffer, SQL_NTS)));
BOOST_CHECK_EQUAL(reslen, (longString.size() - 2046) * sizeof(SQLWCHAR));
BOOST_CHECK(ConversionResult::Type::AI_VARLEN_DATA_TRUNCATED == ret);

ret = appBuf.PutString(longString);

BOOST_CHECK(!longString.substr(2046).compare(timestream::odbc::utility::SqlWcharToString(buffer, SQL_NTS)));
BOOST_CHECK(ConversionResult::Type::AI_SUCCESS == ret);
BOOST_CHECK_EQUAL(reslen, longString.size() * sizeof(SQLWCHAR));

ret = appBuf.PutString(longString);
BOOST_CHECK(ConversionResult::Type::AI_NO_DATA == ret);
}

BOOST_AUTO_TEST_CASE(TestGetDateFromString) {
char buf[] = "1999-02-22";
SqlLen reslen = sizeof(buf);
Expand Down

0 comments on commit 9af2284

Please sign in to comment.