pyodbc: really fix endianess of SQL_WCHAR
authorDaniel Golle <daniel@makrotopia.org>
Sun, 16 Jul 2017 09:56:56 +0000 (11:56 +0200)
committerDaniel Golle <daniel@makrotopia.org>
Sun, 16 Jul 2017 09:58:31 +0000 (11:58 +0200)
auto-endian auf UTF-16 doesn't work with all drivers, some fail to
interpret the byte-order-marking. Hence explicitely use UTF16BE on
big-endian systems and UTF16LE otherwise.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
lang/python/pyodbc/Makefile
lang/python/pyodbc/patches/100-connection-assume-SQL_C_WCHAR-is-native-endian.patch

index e0c6d4058b64310aa650c518c8864eec3a8449d2..1c20e7a63504cf93e2cc58d85c924e24c2e7165e 100644 (file)
@@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=pyodbc
 PKG_VERSION:=4.0.17
-PKG_RELEASE:=3
+PKG_RELEASE:=4
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=https://pypi.python.org/packages/ce/57/6b92aa5b3497dde6be55fd6fcb76c7db215ed1d56fde45c613add4a43095/
index e03cd94869a3bce195d61f40e00b832335e1a477..4d03cb72a93cd160312c1af04d791ac5a48082f3 100644 (file)
@@ -1,34 +1,50 @@
 --- a/src/connection.cpp
 +++ b/src/connection.cpp
-@@ -90,7 +90,7 @@ static bool Connect(PyObject* pConnectSt
+@@ -18,6 +18,15 @@
+ #include "cnxninfo.h"
+ #include "sqlwchar.h"
++#include <endian.h>
++#if __BYTE_ORDER == __BIG_ENDIAN
++# define OPTENC_UTF16NE OPTENC_UTF16BE
++# define ENCSTR_UTF16NE "utf-16be"
++#else
++# define OPTENC_UTF16NE OPTENC_UTF16LE
++# define ENCSTR_UTF16NE "utf-16le"
++#endif
++
+ #if PY_MAJOR_VERSION < 3
+ static bool IsStringType(PyObject* t) { return (void*)t == (void*)&PyString_Type; }
+ static bool IsUnicodeType(PyObject* t) { return (void*)t == (void*)&PyUnicode_Type; }
+@@ -90,7 +99,7 @@ static bool Connect(PyObject* pConnectSt
          // indication that we can handle Unicode.  We are going to use the same unicode ending
          // as we do for binding parameters.
  
 -        SQLWChar wchar(pConnectString, SQL_C_WCHAR, encoding, "utf-16le");
-+        SQLWChar wchar(pConnectString, SQL_C_WCHAR, encoding, "utf-16");
++        SQLWChar wchar(pConnectString, SQL_C_WCHAR, encoding, ENCSTR_UTF16NE);
          if (!wchar)
              return false;
  
-@@ -216,24 +216,24 @@ PyObject* Connection_New(PyObject* pConn
+@@ -216,24 +225,24 @@ PyObject* Connection_New(PyObject* pConn
      // single-byte text we don't actually know what the encoding is.  For example, with SQL
      // Server the encoding is based on the database's collation.  We ask the driver / DB to
      // convert to SQL_C_WCHAR and use the ODBC default of UTF-16LE.
 -    cnxn->sqlchar_enc.optenc = OPTENC_UTF16LE;
 -    cnxn->sqlchar_enc.name   = _strdup("utf-16le");
-+    cnxn->sqlchar_enc.optenc = OPTENC_UTF16;
-+    cnxn->sqlchar_enc.name   = _strdup("utf-16");
++    cnxn->sqlchar_enc.optenc = OPTENC_UTF16NE;
++    cnxn->sqlchar_enc.name   = _strdup(ENCSTR_UTF16NE);
      cnxn->sqlchar_enc.ctype  = SQL_C_WCHAR;
  
 -    cnxn->sqlwchar_enc.optenc = OPTENC_UTF16LE;
 -    cnxn->sqlwchar_enc.name   = _strdup("utf-16le");
-+    cnxn->sqlwchar_enc.optenc = OPTENC_UTF16;
-+    cnxn->sqlwchar_enc.name   = _strdup("utf-16");
++    cnxn->sqlwchar_enc.optenc = OPTENC_UTF16NE;
++    cnxn->sqlwchar_enc.name   = _strdup(ENCSTR_UTF16NE);
      cnxn->sqlwchar_enc.ctype  = SQL_C_WCHAR;
  
 -    cnxn->metadata_enc.optenc = OPTENC_UTF16LE;
 -    cnxn->metadata_enc.name   = _strdup("utf-16le");
-+    cnxn->metadata_enc.optenc = OPTENC_UTF16;
-+    cnxn->metadata_enc.name   = _strdup("utf-16");
++    cnxn->metadata_enc.optenc = OPTENC_UTF16NE;
++    cnxn->metadata_enc.name   = _strdup(ENCSTR_UTF16NE);
      cnxn->metadata_enc.ctype  = SQL_C_WCHAR;
  
      // Note: I attempted to use UTF-8 here too since it can hold any type, but SQL Server fails
@@ -37,8 +53,8 @@
      // something, so we'll stay with the default ODBC conversions.
 -    cnxn->unicode_enc.optenc = OPTENC_UTF16LE;
 -    cnxn->unicode_enc.name   = _strdup("utf-16le");
-+    cnxn->unicode_enc.optenc = OPTENC_UTF16;
-+    cnxn->unicode_enc.name   = _strdup("utf-16");
++    cnxn->unicode_enc.optenc = OPTENC_UTF16NE;
++    cnxn->unicode_enc.name   = _strdup(ENCSTR_UTF16NE);
      cnxn->unicode_enc.ctype  = SQL_C_WCHAR;
  
  #if PY_MAJOR_VERSION < 3