Skip to content

Commit c0a91a2

Browse files
committed
cleanup
1 parent a510c54 commit c0a91a2

File tree

2 files changed

+11
-25
lines changed

2 files changed

+11
-25
lines changed

mssql_python/cursor.py

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -399,16 +399,6 @@ def _map_sql_type(self, param, parameters_list, i):
399399
0,
400400
False,
401401
)
402-
403-
# if isinstance(param, (bytes, bytearray)):
404-
# is_large = len(param) > 8000
405-
# return (
406-
# ddbc_sql_const.SQL_VARBINARY.value if is_large else ddbc_sql_const.SQL_BINARY.value,
407-
# ddbc_sql_const.SQL_C_BINARY.value,
408-
# len(param),
409-
# 0,
410-
# is_large,
411-
# )
412402

413403
if isinstance(param, datetime.datetime):
414404
return (

mssql_python/pybind/ddbc_bindings.cpp

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
#ifndef ARCHITECTURE
3131
#define ARCHITECTURE "win64" // Default to win64 if not defined during compilation
3232
#endif
33-
33+
#define DAE_CHUNK_SIZE 8192
3434
//-------------------------------------------------------------------------------------------------
3535
// Class definitions
3636
//-------------------------------------------------------------------------------------------------
@@ -43,11 +43,8 @@ struct ParamInfo {
4343
SQLSMALLINT paramSQLType;
4444
SQLULEN columnSize;
4545
SQLSMALLINT decimalDigits;
46-
// TODO: Reuse python buffer for large data using Python buffer protocol
47-
// Stores pointer to the python object that holds parameter value
48-
4946
SQLLEN strLenOrInd = 0; // Required for DAE
50-
bool isDAE = false; // Indicates if we need to stream via SQLPutData
47+
bool isDAE = false; // Indicates if we need to stream
5148
py::object dataPtr;
5249
};
5350

@@ -251,14 +248,13 @@ SQLRETURN BindParameters(SQLHANDLE hStmt, const py::list& params,
251248
!py::isinstance<py::bytes>(param)) {
252249
ThrowStdException(MakeParamMismatchErrorStr(paramInfo.paramCType, paramIndex));
253250
}
254-
255251
if (paramInfo.isDAE) {
256252
// deferred execution
257253
LOG("Parameter[{}] is marked for DAE streaming", paramIndex);
258254
dataPtr = const_cast<void*>(reinterpret_cast<const void*>(&paramInfos[paramIndex]));
259255
strLenOrIndPtr = AllocateParamBuffer<SQLLEN>(paramBuffers);
260256
*strLenOrIndPtr = SQL_LEN_DATA_AT_EXEC(0);
261-
bufferLength = 0; // Not used
257+
bufferLength = 0;
262258
} else {
263259
// Normal small-string case
264260
std::wstring* strParam =
@@ -784,7 +780,6 @@ DriverHandle LoadDriverOrThrowException() {
784780

785781
SQLParamData_ptr = GetFunctionPointer<SQLParamDataFunc>(handle, "SQLParamData");
786782
SQLPutData_ptr = GetFunctionPointer<SQLPutDataFunc>(handle, "SQLPutData");
787-
788783
bool success =
789784
SQLAllocHandle_ptr && SQLSetEnvAttr_ptr && SQLSetConnectAttr_ptr &&
790785
SQLSetStmtAttr_ptr && SQLGetConnectAttr_ptr && SQLDriverConnect_ptr &&
@@ -998,7 +993,7 @@ SQLRETURN SQLExecute_wrap(const SqlHandlePtr statementHandle,
998993
LOG("Beginning SQLParamData/SQLPutData loop for DAE.");
999994
SQLPOINTER paramToken = nullptr;
1000995
while ((rc = SQLParamData_ptr(hStmt, &paramToken)) == SQL_NEED_DATA) {
1001-
// Find the paramInfo that matches the returned token
996+
// Finding the paramInfo that matches the returned token
1002997
const ParamInfo* matchedInfo = nullptr;
1003998
for (auto& info : paramInfos) {
1004999
if (reinterpret_cast<SQLPOINTER>(const_cast<ParamInfo*>(&info)) == paramToken) {
@@ -1009,18 +1004,21 @@ SQLRETURN SQLExecute_wrap(const SqlHandlePtr statementHandle,
10091004
if (!matchedInfo) {
10101005
ThrowStdException("Unrecognized paramToken returned by SQLParamData");
10111006
}
1012-
10131007
const py::object& pyObj = matchedInfo->dataPtr;
10141008
if (pyObj.is_none()) {
10151009
SQLPutData_ptr(hStmt, nullptr, 0);
10161010
continue;
10171011
}
10181012
if (py::isinstance<py::str>(pyObj)) {
1019-
std::string utf16_str = pyObj.attr("encode")("utf-16-le").cast<py::bytes>();
1013+
std::string utf16_str;
1014+
try {
1015+
utf16_str = pyObj.attr("encode")("utf-16-le").cast<py::bytes>();
1016+
} catch (const std::exception& e) {
1017+
ThrowStdException("Error encoding string to UTF-16: " + std::string(e.what()));
1018+
}
10201019
const char* dataPtr = utf16_str.data();
10211020
SQLLEN totalBytes = static_cast<SQLLEN>(utf16_str.size());
1022-
1023-
const size_t chunkSize = 8192;
1021+
const size_t chunkSize = DAE_CHUNK_SIZE;
10241022
for (size_t offset = 0; offset < totalBytes; offset += chunkSize) {
10251023
size_t len = std::min(chunkSize, totalBytes - offset);
10261024
rc = SQLPutData_ptr(hStmt, (SQLPOINTER)(dataPtr + offset), static_cast<SQLLEN>(len));
@@ -1033,14 +1031,12 @@ SQLRETURN SQLExecute_wrap(const SqlHandlePtr statementHandle,
10331031
ThrowStdException("DAE only supported for str or bytes");
10341032
}
10351033
}
1036-
10371034
if (!SQL_SUCCEEDED(rc)) {
10381035
LOG("SQLParamData final rc: {}", rc);
10391036
return rc;
10401037
}
10411038
LOG("DAE complete, SQLExecute resumed internally.");
10421039
}
1043-
10441040
if (!SQL_SUCCEEDED(rc) && rc != SQL_NO_DATA) {
10451041
LOG("DDBCSQLExecute: Error during execution of the statement");
10461042
return rc;

0 commit comments

Comments
 (0)