* libodbc.cs: Always use unicode version of ODBC functions. Fixes part
authorGert Driesen <drieseng@users.sourceforge.net>
Fri, 21 Mar 2008 21:00:55 +0000 (21:00 -0000)
committerGert Driesen <drieseng@users.sourceforge.net>
Fri, 21 Mar 2008 21:00:55 +0000 (21:00 -0000)
of bug #372823.
* OdbcTypeMap.cs: Fixed mapping for NChar, NText and NVarChar.
* OdbcDataReader.cs (GetColumn): Use Unicode encoding to decode
column name buffer.
(GetDataTypeName): Use SQLColAttribute to determine type name of
column.
(GetValue): Fixed retrieving value of nchar column. When retrieving
variable length unicode value, use Unicode encoding to decode buffer
and remove trailing null characters. Fixes bug #364430.

svn path=/trunk/mcs/; revision=98771

mcs/class/System.Data/System.Data.Odbc/ChangeLog
mcs/class/System.Data/System.Data.Odbc/OdbcDataReader.cs
mcs/class/System.Data/System.Data.Odbc/OdbcTypeMap.cs
mcs/class/System.Data/System.Data.Odbc/libodbc.cs

index 47ae0d64ce502de303a17c4858dec1373a9f529b..991e9af9d3c14de2593bf0b21e11db49f5105628 100644 (file)
@@ -1,3 +1,16 @@
+2008-03-21  Gert Driesen  <drieseng@users.sourceforge.net>
+
+       * libodbc.cs: Always use unicode version of ODBC functions. Fixes part
+       of bug #372823.
+       * OdbcTypeMap.cs: Fixed mapping for NChar, NText and NVarChar.
+       * OdbcDataReader.cs (GetColumn): Use Unicode encoding to decode
+       column name buffer.
+       (GetDataTypeName): Use SQLColAttribute to determine type name of
+       column.
+       (GetValue): Fixed retrieving value of nchar column. When retrieving
+       variable length unicode value, use Unicode encoding to decode buffer
+       and remove trailing null characters. Fixes bug #364430.
+
 2008-03-03  Veerapuram Varadhan  <vvaradhan@novell.com>
 
        ** Fixes Bug#324025
index d64d507a731edfa242305a66fe644503819c8b97..f28b80d9b2c11ee31e489de0aab4d197e65f1aed 100644 (file)
@@ -207,8 +207,7 @@ namespace System.Data.Odbc
                                                                         ref DecDigits, ref Nullable);
                                if ((ret != OdbcReturn.Success) && (ret != OdbcReturn.SuccessWithInfo))
                                        throw new OdbcException (new OdbcError ("SQLDescribeCol", OdbcHandleType.Stmt, hstmt));
-                               colname = System.Text.Encoding.Default.GetString (colname_buffer);
-                               colname = colname.Replace ((char) 0, ' ').Trim ();
+                               colname = RemoveTrailingNullChar (Encoding.Unicode.GetString (colname_buffer));
                                OdbcColumn c = new OdbcColumn (colname, (SQL_TYPE) dt);
                                c.AllowDBNull = (Nullable != 0);
                                c.Digits = DecDigits;
@@ -357,7 +356,7 @@ namespace System.Data.Odbc
 #endif // NET_2_0
                string GetDataTypeName (int index)
                {
-                       return GetColumn (index).OdbcType.ToString ();
+                       return GetColumnAttributeStr (index + 1, FieldIdentifier.TypeName);
                }
 
                public DateTime GetDate (int ordinal) {
@@ -678,23 +677,37 @@ namespace System.Data.Odbc
                                        ret = libodbc.SQLGetData (hstmt, ColIndex, col.SqlCType, ref long_data, 0, ref outsize);
                                        DataValue = long_data;
                                        break;
+                               case OdbcType.NChar:
+                                       bufsize = 255;
+                                       buffer = new byte [bufsize];
+                                       ret = libodbc.SQLGetData (hstmt, ColIndex, SQL_C_TYPE.WCHAR, buffer, bufsize, ref outsize);
+                                       if (outsize != (int) OdbcLengthIndicator.NullData)
+                                               if (!(ret == OdbcReturn.SuccessWithInfo
+                                                      && outsize == (int) OdbcLengthIndicator.NoTotal))
+                                                       DataValue = Encoding.Unicode.GetString (buffer, 0, outsize);
+                                       break;
                                case OdbcType.NText:
                                case OdbcType.NVarChar:
                                        bufsize = (col.MaxLength < 127 ? (col.MaxLength*2+1) : 255);
                                        buffer = new byte[bufsize];  // According to sqlext.h, use SQL_CHAR for both char and varchar
                                        StringBuilder sb = new StringBuilder ();
-                                       do { 
+                                       do {
                                                ret = libodbc.SQLGetData (hstmt, ColIndex, col.SqlCType, buffer, bufsize, ref outsize);
                                                if (ret == OdbcReturn.Error)
                                                        break;
                                                // Fix for strance ODBC drivers (like psqlODBC)
                                                if (ret == OdbcReturn.Success && outsize==-1)
                                                        ret = OdbcReturn.NoData;
+
                                                if (ret != OdbcReturn.NoData && outsize > 0) {
+                                                       string value = null;
+
                                                        if (outsize < bufsize)
-                                                               sb.Append (System.Text.Encoding.Unicode.GetString(buffer,0,outsize));
+                                                               value = Encoding.Unicode.GetString (buffer, 0, outsize);
                                                        else
-                                                               sb.Append (System.Text.Encoding.Unicode.GetString(buffer,0,bufsize));
+                                                               value = Encoding.Unicode.GetString (buffer, 0, bufsize);
+
+                                                       sb.Append (RemoveTrailingNullChar (value));
                                                }
                                        } while (ret != OdbcReturn.NoData);
                                        DataValue = sb.ToString ();
@@ -946,7 +959,7 @@ namespace System.Data.Odbc
                                                                        hstmt));
                        string value = string.Empty;
                        if (outsize > 0)
-                               value = Encoding.Default.GetString (buffer, 0, outsize);
+                               value = Encoding.Unicode.GetString (buffer, 0, outsize);
                        return value;
                }
 
@@ -1086,6 +1099,11 @@ namespace System.Data.Odbc
                        return NextRow ();
                }
 
+               static string RemoveTrailingNullChar (string value)
+               {
+                       return value.TrimEnd ('\0');
+               }
+
                #endregion
        }
 }
index cd273f9af6a3d045ff7f7ec96d931e72c0b041a8..daaa48bad444877adf2addd478d04bbf599b72fd 100644 (file)
@@ -147,12 +147,12 @@ namespace System.Data.Odbc
                                                                 SQL_TYPE.INTEGER);
                        maps [OdbcType.NChar]     = new OdbcTypeMap (DbType.String, 
                                                                 OdbcType.NChar,
-                                                                    SQL_C_TYPE.CHAR, //change
-                                                                    SQL_TYPE.CHAR); //change
+                                                                    SQL_C_TYPE.WCHAR,
+                                                                    SQL_TYPE.WCHAR);
                        maps [OdbcType.NText]     = new OdbcTypeMap (DbType.String, 
                                                                 OdbcType.NText,
-                                                                    SQL_C_TYPE.CHAR, // change
-                                                                    SQL_TYPE.LONGVARCHAR); //change
+                                                                    SQL_C_TYPE.WCHAR, // change
+                                                                    SQL_TYPE.WLONGVARCHAR); //change
                        // Currently, NUMERIC types works only with NUMERIC SQL Type to CHAR C Type mapping (pgsql). Other databases return 
                        // SQL_TYPE.DECIMAL in place of numeric types.
                        maps [OdbcType.Numeric]   = new OdbcTypeMap (DbType.Decimal, 
@@ -161,8 +161,8 @@ namespace System.Data.Odbc
                                                                 SQL_TYPE.NUMERIC);
                        maps [OdbcType.NVarChar]  = new OdbcTypeMap (DbType.String, 
                                                                 OdbcType.NVarChar,
-                                                                    SQL_C_TYPE.CHAR, // change
-                                                                    SQL_TYPE.VARCHAR); //change
+                                                                    SQL_C_TYPE.WCHAR,
+                                                                    SQL_TYPE.WVARCHAR);
                        maps [OdbcType.Real]      = new OdbcTypeMap (DbType.Single, 
                                                                 OdbcType.Real,
                                                                 SQL_C_TYPE.FLOAT,
index c339d43a3c60a35e7ad73d144b8ebfe8b0f478fd..b8d8bd54c8dfd79a1d9b9f9e8b1e2681585b16ab 100644 (file)
@@ -194,20 +194,20 @@ namespace System.Data.Odbc
                        }
                }
 
-               [DllImport("odbc32.dll")]
+               [DllImport ("odbc32.dll", CharSet = CharSet.Unicode)]
                internal static extern OdbcReturn SQLAllocHandle (
                        OdbcHandleType HandleType,
                        IntPtr InputHandle,
                        ref IntPtr OutputHandlePtr);
 
-               [DllImport("odbc32.dll")]
+               [DllImport ("odbc32.dll", CharSet = CharSet.Unicode)]
                internal static extern OdbcReturn SQLSetEnvAttr (
                        IntPtr EnvHandle,
                        OdbcEnv Attribute,
                        IntPtr Value,
                        int StringLength);
 
-               [DllImport("odbc32.dll")]
+               [DllImport ("odbc32.dll", CharSet = CharSet.Unicode)]
                internal static extern OdbcReturn SQLConnect (
                        IntPtr ConnectionHandle,
                        string ServerName,
@@ -217,7 +217,7 @@ namespace System.Data.Odbc
                        string Authentication,
                        short NameLength3);
 
-               [DllImport("odbc32.dll")]
+               [DllImport ("odbc32.dll", CharSet = CharSet.Unicode)]
                internal static extern OdbcReturn SQLDriverConnect (
                        IntPtr ConnectionHandle,
                        IntPtr WindowHandle,
@@ -228,27 +228,27 @@ namespace System.Data.Odbc
                        ref short StringLength2Ptr,
                        ushort DriverCompletion);
 
-               [DllImport("odbc32.dll")]
+               [DllImport ("odbc32.dll", CharSet = CharSet.Unicode)]
                internal static extern OdbcReturn SQLExecDirect (
                        IntPtr StatementHandle,
                        string StatementText,
                        int TextLength);
 
-               [DllImport("odbc32.dll")]
+               [DllImport ("odbc32.dll", CharSet = CharSet.Unicode)]
                internal static extern OdbcReturn SQLRowCount (
                        IntPtr StatementHandle,
                        ref int RowCount);
 
-               [DllImport("odbc32.dll")]
+               [DllImport ("odbc32.dll", CharSet = CharSet.Unicode)]
                internal static extern OdbcReturn SQLNumResultCols (
                        IntPtr StatementHandle,
                        ref short ColumnCount);
 
-               [DllImport("odbc32.dll")]
+               [DllImport ("odbc32.dll", CharSet = CharSet.Unicode)]
                internal static extern OdbcReturn SQLFetch (
                        IntPtr StatementHandle);
 
-               [DllImport("odbc32.dll")]
+               [DllImport ("odbc32.dll", CharSet = CharSet.Unicode)]
                internal static extern OdbcReturn SQLGetData (
                        IntPtr StatementHandle,
                        ushort ColumnNumber,
@@ -257,7 +257,7 @@ namespace System.Data.Odbc
                        int BufferLen,
                        ref int Len);
 
-               [DllImport("odbc32.dll")]
+               [DllImport ("odbc32.dll", CharSet = CharSet.Unicode)]
                internal static extern OdbcReturn SQLGetData (
                        IntPtr StatementHandle,
                        ushort ColumnNumber,
@@ -266,7 +266,7 @@ namespace System.Data.Odbc
                        int BufferLen,
                        ref int Len);
 
-               [DllImport("odbc32.dll")]
+               [DllImport ("odbc32.dll", CharSet = CharSet.Unicode)]
                internal static extern OdbcReturn SQLGetData (
                        IntPtr StatementHandle,
                        ushort ColumnNumber,
@@ -275,7 +275,7 @@ namespace System.Data.Odbc
                        int BufferLen,
                        ref int Len);
 
-               [DllImport("odbc32.dll")]
+               [DllImport ("odbc32.dll", CharSet = CharSet.Unicode)]
                internal static extern OdbcReturn SQLGetData (
                        IntPtr StatementHandle,
                        ushort ColumnNumber,
@@ -284,7 +284,7 @@ namespace System.Data.Odbc
                        int BufferLen,
                        ref int Len);
 
-               [DllImport("odbc32.dll")]
+               [DllImport ("odbc32.dll", CharSet = CharSet.Unicode)]
                internal static extern OdbcReturn SQLGetData (
                        IntPtr StatementHandle,
                        ushort ColumnNumber,
@@ -292,8 +292,8 @@ namespace System.Data.Odbc
                        ref float TargetPtr,
                        int BufferLen,
                        ref int Len);
-       
-               [DllImport("odbc32.dll")]
+
+               [DllImport ("odbc32.dll", CharSet = CharSet.Unicode)]
                internal static extern OdbcReturn SQLGetData (
                        IntPtr StatementHandle,
                        ushort ColumnNumber,
@@ -302,7 +302,7 @@ namespace System.Data.Odbc
                        int BufferLen,
                        ref int Len);
 
-               [DllImport("odbc32.dll")]
+               [DllImport ("odbc32.dll", CharSet = CharSet.Unicode)]
                internal static extern OdbcReturn SQLGetData (
                        IntPtr StatementHandle,
                        ushort ColumnNumber,
@@ -310,8 +310,8 @@ namespace System.Data.Odbc
                        ref int TargetPtr,
                        int BufferLen,
                        ref int Len);
-       
-               [DllImport("odbc32.dll")]
+
+               [DllImport ("odbc32.dll", CharSet = CharSet.Unicode)]
                internal static extern OdbcReturn SQLGetData (
                        IntPtr StatementHandle,
                        ushort ColumnNumber,
@@ -320,7 +320,7 @@ namespace System.Data.Odbc
                        int BufferLen,
                        ref int Len);
 
-               [DllImport("odbc32.dll")]
+               [DllImport ("odbc32.dll", CharSet = CharSet.Unicode)]
                internal static extern OdbcReturn SQLDescribeCol (
                        IntPtr StatementHandle,
                        ushort ColumnNumber,
@@ -332,26 +332,26 @@ namespace System.Data.Odbc
                        ref short DecimalDigits,
                        ref short Nullable);
 
-               [DllImport("odbc32.dll")]
+               [DllImport ("odbc32.dll", CharSet = CharSet.Unicode)]
                internal static extern OdbcReturn SQLFreeHandle (
                        ushort HandleType,
                        IntPtr SqlHandle);
 
-               [DllImport("odbc32.dll")]
+               [DllImport ("odbc32.dll", CharSet = CharSet.Unicode)]
                internal static extern OdbcReturn SQLDisconnect (
                        IntPtr ConnectionHandle);
 
-               [DllImport("odbc32.dll")]
+               [DllImport ("odbc32.dll", CharSet = CharSet.Unicode)]
                internal static extern OdbcReturn SQLPrepare (
                        IntPtr StatementHandle,
                        string Statement,
                        int TextLength);
 
-               [DllImport("odbc32.dll")]
+               [DllImport ("odbc32.dll", CharSet = CharSet.Unicode)]
                internal static extern OdbcReturn SQLExecute (
                        IntPtr StatementHandle);
 
-               [DllImport ("odbc32.dll")]
+               [DllImport ("odbc32.dll", CharSet = CharSet.Unicode)]
                internal static extern OdbcReturn SQLGetConnectAttr (
                        IntPtr ConnectionHandle,
                        OdbcConnectionAttribute Attribute,
@@ -359,20 +359,20 @@ namespace System.Data.Odbc
                        int BufferLength,
                        out int StringLength);
 
-               [DllImport("odbc32.dll")]
+               [DllImport ("odbc32.dll", CharSet = CharSet.Unicode)]
                internal static extern OdbcReturn SQLSetConnectAttr (
                        IntPtr ConnectionHandle,
                        OdbcConnectionAttribute Attribute,
                        IntPtr Value,
                        int Length);
 
-               [DllImport("odbc32.dll")]
+               [DllImport ("odbc32.dll", CharSet = CharSet.Unicode)]
                internal static extern OdbcReturn SQLEndTran (
                        int HandleType,
                        IntPtr Handle,
                        short CompletionType);
 
-               [DllImport("odbc32.dll")]
+               [DllImport ("odbc32.dll", CharSet = CharSet.Unicode)]
                internal static extern OdbcReturn SQLBindParameter (
                        IntPtr StatementHandle,
                        ushort ParamNum,
@@ -385,15 +385,15 @@ namespace System.Data.Odbc
                        int BufLen,
                        IntPtr StrLen);
 
-               [DllImport("odbc32.dll")]
+               [DllImport ("odbc32.dll", CharSet = CharSet.Unicode)]
                internal static extern OdbcReturn SQLCancel (
                        IntPtr StatementHandle);
-               
-               [DllImport("odbc32.dll")]
+
+               [DllImport ("odbc32.dll", CharSet = CharSet.Unicode)]
                internal static extern OdbcReturn SQLCloseCursor (
                        IntPtr StatementHandle);
 
-               [DllImport("odbc32.dll")]
+               [DllImport ("odbc32.dll", CharSet = CharSet.Unicode)]
                internal static extern OdbcReturn SQLError (
                        IntPtr EnvironmentHandle,
                        IntPtr ConnectionHandle,
@@ -404,7 +404,7 @@ namespace System.Data.Odbc
                        short BufferLength,
                        ref short TextLength);
 
-               [DllImport("odbc32.dll")]
+               [DllImport ("odbc32.dll", CharSet = CharSet.Unicode)]
                internal static extern OdbcReturn SQLGetStmtAttr (
                        IntPtr StatementHandle,
                        int Attribute,
@@ -412,7 +412,7 @@ namespace System.Data.Odbc
                        int BufLen,
                        int StrLen);
 
-               [DllImport("odbc32.dll")]
+               [DllImport ("odbc32.dll", CharSet = CharSet.Unicode)]
                internal static extern OdbcReturn SQLSetDescField (
                        IntPtr DescriptorHandle,
                        short RecNumber,
@@ -420,7 +420,7 @@ namespace System.Data.Odbc
                        byte[] Value,
                        int BufLen);
 
-               [DllImport("odbc32.dll")]
+               [DllImport ("odbc32.dll", CharSet = CharSet.Unicode)]
                internal static extern OdbcReturn SQLGetDiagRec (
                        OdbcHandleType HandleType,
                        IntPtr Handle,
@@ -431,7 +431,7 @@ namespace System.Data.Odbc
                        short BufferLength,
                        ref short TextLength);
 
-               [DllImport ("odbc32.dll")]
+               [DllImport ("odbc32.dll", CharSet = CharSet.Unicode)]
                internal static extern OdbcReturn SQLMoreResults (
                        IntPtr Handle);
 
@@ -443,12 +443,12 @@ namespace System.Data.Odbc
                        ResetParams
                }
 
-               [DllImport ("odbc32.dll")]
+               [DllImport ("odbc32.dll", CharSet = CharSet.Unicode)]
                internal static extern OdbcReturn SQLFreeStmt (
                        IntPtr Handle,
                        SQLFreeStmtOptions option);
 
-               [DllImport ("odbc32.dll")]
+               [DllImport ("odbc32.dll", CharSet = CharSet.Unicode)]
                internal static extern OdbcReturn SQLGetInfo (
                        IntPtr connHandle,
                        OdbcInfo info,
@@ -456,7 +456,7 @@ namespace System.Data.Odbc
                        short buffLength,
                        ref short remainingStrLen);
 
-               [DllImport ("odbc32.dll")]
+               [DllImport ("odbc32.dll", CharSet = CharSet.Unicode)]
                internal static extern OdbcReturn SQLColAttribute (
                        IntPtr StmtHandle,
                        short column,
@@ -466,7 +466,7 @@ namespace System.Data.Odbc
                        ref short strLengthPtr,
                        ref int numericAttributePtr);
 
-               [DllImport ("odbc32.dll")]
+               [DllImport ("odbc32.dll", CharSet = CharSet.Unicode)]
                internal static extern OdbcReturn SQLPrimaryKeys (
                        IntPtr StmtHandle,
                        string catalog,
@@ -476,7 +476,7 @@ namespace System.Data.Odbc
                        string tableName,
                        short tableLength);
 
-               [DllImport ("odbc32.dll")]
+               [DllImport ("odbc32.dll", CharSet = CharSet.Unicode)]
                internal static extern OdbcReturn SQLStatistics (
                        IntPtr StmtHandle,
                        string catalog,
@@ -488,7 +488,7 @@ namespace System.Data.Odbc
                        short unique,
                        short Reserved);
 
-               [DllImport ("odbc32.dll")]
+               [DllImport ("odbc32.dll", CharSet = CharSet.Unicode)]
                internal static extern OdbcReturn SQLBindCol (
                        IntPtr StmtHandle,
                        short column,
@@ -497,7 +497,7 @@ namespace System.Data.Odbc
                        int bufferLength,
                        ref int indicator);
 
-               [DllImport ("odbc32.dll")]
+               [DllImport ("odbc32.dll", CharSet = CharSet.Unicode)]
                internal static extern OdbcReturn SQLBindCol (
                        IntPtr StmtHandle,
                        short column,