@@ -224,7 +224,27 @@ SQLRETURN BindParameters(SQLHANDLE hStmt, const py::list& params,
224224
225225 // TODO: Add more data types like money, guid, interval, TVPs etc.
226226 switch (paramInfo.paramCType ) {
227- case SQL_C_CHAR:
227+ case SQL_C_CHAR: {
228+ if (!py::isinstance<py::str>(param) && !py::isinstance<py::bytearray>(param) &&
229+ !py::isinstance<py::bytes>(param)) {
230+ ThrowStdException (MakeParamMismatchErrorStr (paramInfo.paramCType , paramIndex));
231+ }
232+ if (paramInfo.isDAE ) {
233+ LOG (" Parameter[{}] is marked for DAE streaming" , paramIndex);
234+ dataPtr = const_cast <void *>(reinterpret_cast <const void *>(¶mInfos[paramIndex]));
235+ strLenOrIndPtr = AllocateParamBuffer<SQLLEN>(paramBuffers);
236+ *strLenOrIndPtr = SQL_LEN_DATA_AT_EXEC (0 );
237+ bufferLength = 0 ;
238+ } else {
239+ std::string* strParam =
240+ AllocateParamBuffer<std::string>(paramBuffers, param.cast <std::string>());
241+ dataPtr = const_cast <void *>(static_cast <const void *>(strParam->c_str ()));
242+ bufferLength = strParam->size () + 1 ;
243+ strLenOrIndPtr = AllocateParamBuffer<SQLLEN>(paramBuffers);
244+ *strLenOrIndPtr = SQL_NTS;
245+ }
246+ break ;
247+ }
228248 case SQL_C_BINARY: {
229249 if (!py::isinstance<py::str>(param) && !py::isinstance<py::bytearray>(param) &&
230250 !py::isinstance<py::bytes>(param)) {
@@ -1004,23 +1024,40 @@ SQLRETURN SQLExecute_wrap(const SqlHandlePtr statementHandle,
10041024 continue ;
10051025 }
10061026 if (py::isinstance<py::str>(pyObj)) {
1007- std::wstring wstr = pyObj.cast <std::wstring>();
1008- #if defined(__APPLE__) || defined(__linux__)
1009- auto utf16Buf = WStringToSQLWCHAR (wstr);
1010- const char * dataPtr = reinterpret_cast <const char *>(utf16Buf.data ());
1011- size_t totalBytes = (utf16Buf.size () - 1 ) * sizeof (SQLWCHAR);
1012- #else
1013- const char * dataPtr = reinterpret_cast <const char *>(wstr.data ());
1014- size_t totalBytes = wstr.size () * sizeof (wchar_t );
1015- #endif
1016- const size_t chunkSize = DAE_CHUNK_SIZE;
1017- for (size_t offset = 0 ; offset < totalBytes; offset += chunkSize) {
1018- size_t len = std::min (chunkSize, totalBytes - offset);
1019- rc = SQLPutData_ptr (hStmt, (SQLPOINTER)(dataPtr + offset), static_cast <SQLLEN>(len));
1020- if (!SQL_SUCCEEDED (rc)) {
1021- LOG (" SQLPutData failed at offset {} of {}" , offset, totalBytes);
1022- return rc;
1027+ if (matchedInfo->paramCType == SQL_C_WCHAR) {
1028+ std::wstring wstr = pyObj.cast <std::wstring>();
1029+ #if defined(__APPLE__) || defined(__linux__)
1030+ auto utf16Buf = WStringToSQLWCHAR (wstr);
1031+ const char * dataPtr = reinterpret_cast <const char *>(utf16Buf.data ());
1032+ size_t totalBytes = (utf16Buf.size () - 1 ) * sizeof (SQLWCHAR);
1033+ #else
1034+ const char * dataPtr = reinterpret_cast <const char *>(wstr.data ());
1035+ size_t totalBytes = wstr.size () * sizeof (wchar_t );
1036+ #endif
1037+ const size_t chunkSize = DAE_CHUNK_SIZE;
1038+ for (size_t offset = 0 ; offset < totalBytes; offset += chunkSize) {
1039+ size_t len = std::min (chunkSize, totalBytes - offset);
1040+ rc = SQLPutData_ptr (hStmt, (SQLPOINTER)(dataPtr + offset), static_cast <SQLLEN>(len));
1041+ if (!SQL_SUCCEEDED (rc)) {
1042+ LOG (" SQLPutData failed at offset {} of {}" , offset, totalBytes);
1043+ return rc;
1044+ }
10231045 }
1046+ } else if (matchedInfo->paramCType == SQL_C_CHAR) {
1047+ std::string s = pyObj.cast <std::string>();
1048+ const char * dataPtr = s.data ();
1049+ size_t totalBytes = s.size ();
1050+ const size_t chunkSize = DAE_CHUNK_SIZE;
1051+ for (size_t offset = 0 ; offset < totalBytes; offset += chunkSize) {
1052+ size_t len = std::min (chunkSize, totalBytes - offset);
1053+ rc = SQLPutData_ptr (hStmt, (SQLPOINTER)(dataPtr + offset), static_cast <SQLLEN>(len));
1054+ if (!SQL_SUCCEEDED (rc)) {
1055+ LOG (" SQLPutData failed at offset {} of {}" , offset, totalBytes);
1056+ return rc;
1057+ }
1058+ }
1059+ } else {
1060+ ThrowStdException (" Unsupported C type for str in DAE" );
10241061 }
10251062 } else {
10261063 ThrowStdException (" DAE only supported for str or bytes" );
0 commit comments