2007-09-11 AMC <amc1999@gmail.com>
[mono.git] / mcs / class / System.Data / System.Data.Odbc / OdbcDataReader.cs
index d06950c0bb743a9ad41ecd14f2c806be570cd438..1359cfe681db013b8a32248ea137588f88d2efec 100644 (file)
@@ -37,15 +37,12 @@ using System.Collections;
 using System.ComponentModel;
 using System.Data;
 using System.Data.Common;
-#if NET_2_0
-using System.Data.ProviderBase;
-#endif // NET_2_0
 using System.Text;
 
 namespace System.Data.Odbc
 {
 #if NET_2_0
-        public sealed class OdbcDataReader : DbDataReaderBase
+        public sealed class OdbcDataReader : DbDataReader
 #else
        public sealed class OdbcDataReader : MarshalByRefObject, IDataReader, IDisposable, IDataRecord, IEnumerable
 #endif
@@ -60,30 +57,23 @@ namespace System.Data.Odbc
                private int _recordsAffected = -1;
                bool disposed = false;
                private DataTable _dataTableSchema;
-#if ONLY_1_1
                private CommandBehavior behavior;
-#endif // ONLY_1_1
 
                #endregion
 
                #region Constructors
 
                internal OdbcDataReader (OdbcCommand command, CommandBehavior behavior)
-#if NET_2_0
-                        : base (behavior)
-#endif // NET_2_0
                {
                        this.command = command;
-#if ONLY_1_1
-                       this.CommandBehavior=behavior;
-#endif // ONLY_1_1
+                       this.CommandBehavior = behavior;
                        open = true;
                        currentRow = -1;
-                       hstmt=command.hStmt;
+                       hstmt = command.hStmt;
                        // Init columns array;
-                       short colcount=0;
-                       libodbc.SQLNumResultCols(hstmt, ref colcount);
-                       cols=new OdbcColumn[colcount];
+                       short colcount = 0;
+                       libodbc.SQLNumResultCols (hstmt, ref colcount);
+                       cols = new OdbcColumn [colcount];
                        GetSchemaTable ();
                }
 
@@ -98,22 +88,12 @@ namespace System.Data.Odbc
 
                #region Properties
 
-#if ONLY_1_1
                 private CommandBehavior CommandBehavior 
                 {
                         get { return behavior; }
                         set { value = behavior; }
                 }
-#endif // ONLY_1_1
                 
-#if NET_2_0
-                [MonoTODO]
-                protected override bool IsValidRow 
-                {
-                        get { throw new NotImplementedException (); }
-                }
-#endif // NET_2_0
-
                public
 #if NET_2_0
                 override
@@ -168,13 +148,12 @@ namespace System.Data.Odbc
 #if NET_2_0
                 override
 #endif // NET_2_0
-                object this[int index] {
+                object this [int index] {
                        get {
                                return (object) GetValue (index);
                        }
                }
 
-                [MonoTODO]
                public
 #if NET_2_0
                 override
@@ -198,9 +177,9 @@ namespace System.Data.Odbc
 
                #region Methods
                
-               private int ColIndex(string colname)
+               private int ColIndex (string colname)
                {
-                       int i=0;
+                       int i = 0;
                        foreach (OdbcColumn col in cols)
                        {
                                if (col != null) {
@@ -216,31 +195,30 @@ namespace System.Data.Odbc
                }
 
                // Dynamically load column descriptions as needed.
-               private OdbcColumn GetColumn(int ordinal)
+               private OdbcColumn GetColumn (int ordinal)
                {
-                       if (cols[ordinal]==null)
-                       {
-                               short bufsize=255;
-                               byte[] colname_buffer=new byte[bufsize];
+                       if (cols [ordinal] == null) {
+                               short bufsize = 255;
+                               byte [] colname_buffer = new byte [bufsize];
                                string colname;
-                               short colname_size=0;
-                               uint ColSize=0;
-                               short DecDigits=0, Nullable=0, dt=0;
-                               OdbcReturn ret=libodbc.SQLDescribeCol(hstmt, Convert.ToUInt16(ordinal+1), 
-                                                                     colname_buffer, bufsize, ref colname_size, ref dt, ref ColSize, 
-                                                                     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();
-                               OdbcColumn c=new OdbcColumn(colname, (SQL_TYPE) dt);
-                               c.AllowDBNull=(Nullable!=0);
-                               c.Digits=DecDigits;
+                               short colname_size = 0;
+                               uint ColSize = 0;
+                               short DecDigits = 0, Nullable = 0, dt = 0;
+                               OdbcReturn ret = libodbc.SQLDescribeCol (hstmt, Convert.ToUInt16 (ordinal + 1), 
+                                                                        colname_buffer, bufsize, ref colname_size, ref dt, ref ColSize, 
+                                                                        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 ();
+                               OdbcColumn c = new OdbcColumn (colname, (SQL_TYPE) dt);
+                               c.AllowDBNull = (Nullable != 0);
+                               c.Digits = DecDigits;
                                if (c.IsVariableSizeType)
-                                       c.MaxLength=(int)ColSize;
-                               cols[ordinal]=c;
+                                       c.MaxLength = (int) ColSize;
+                               cols [ordinal] = c;
                        }
-                       return cols[ordinal];
+                       return cols [ordinal];
                }
 
                public
@@ -255,8 +233,8 @@ namespace System.Data.Odbc
 
                        this.command.FreeIfNotPrepared ();
 
-                       if ((this.CommandBehavior & CommandBehavior.CloseConnection)==CommandBehavior.CloseConnection) {
-                               this.command.Connection.Close();
+                       if ((this.CommandBehavior & CommandBehavior.CloseConnection) == CommandBehavior.CloseConnection) {
+                               this.command.Connection.Close ();
                        }
                }
 
@@ -362,10 +340,12 @@ namespace System.Data.Odbc
 
                [MonoTODO]
                [EditorBrowsableAttribute (EditorBrowsableState.Never)]
-               public 
+#if ONLY_1_1
+               public
+#endif
 #if NET_2_0
                new
-#endif // NET_2_0
+#endif
                IDataReader GetData (int ordinal)
                {
                        throw new NotImplementedException ();
@@ -377,11 +357,11 @@ namespace System.Data.Odbc
 #endif // NET_2_0
                string GetDataTypeName (int index)
                {
-                       return GetColumn(index).OdbcType.ToString();
+                       return GetColumn (index).OdbcType.ToString ();
                }
 
-               public DateTime GetDate(int ordinal) {
-                       return GetDateTime(ordinal);
+               public DateTime GetDate (int ordinal) {
+                       return GetDateTime (ordinal);
                }
 
                public 
@@ -390,17 +370,16 @@ namespace System.Data.Odbc
 #endif // NET_2_0
                DateTime GetDateTime (int ordinal)
                {
-                       return (DateTime) GetValue(ordinal);
+                       return (DateTime) GetValue (ordinal);
                }
 
-               [MonoTODO]
                public 
 #if NET_2_0
                override
 #endif // NET_2_0
                decimal GetDecimal (int ordinal)
                {
-                       throw new NotImplementedException ();
+                       return (decimal) GetValue (ordinal);
                }
 
                public 
@@ -409,7 +388,7 @@ namespace System.Data.Odbc
 #endif // NET_2_0
                double GetDouble (int ordinal)
                {
-                       return (double) GetValue(ordinal);
+                       return (double) GetValue (ordinal);
                }
 
                public 
@@ -427,7 +406,7 @@ namespace System.Data.Odbc
 #endif // NET_2_0
                float GetFloat (int ordinal)
                {
-                       return (float) GetValue(ordinal);
+                       return (float) GetValue (ordinal);
                }
 
                [MonoTODO]
@@ -446,7 +425,7 @@ namespace System.Data.Odbc
 #endif // NET_2_0
                short GetInt16 (int ordinal)
                {
-                       return (short) GetValue(ordinal);
+                       return (short) GetValue (ordinal);
                }
 
                public 
@@ -455,7 +434,7 @@ namespace System.Data.Odbc
 #endif // NET_2_0
                int GetInt32 (int ordinal)
                {
-                       return (int) GetValue(ordinal);
+                       return (int) GetValue (ordinal);
                }
 
                public 
@@ -464,7 +443,7 @@ namespace System.Data.Odbc
 #endif // NET_2_0
                long GetInt64 (int ordinal)
                {
-                       return (long) GetValue(ordinal);
+                       return (long) GetValue (ordinal);
                }
 
                public 
@@ -623,7 +602,7 @@ namespace System.Data.Odbc
 #endif // NET_2_0
                string GetString (int ordinal)
                {
-                       return (string) GetValue(ordinal);
+                       return (string) GetValue (ordinal);
                }
 
                [MonoTODO]
@@ -641,69 +620,69 @@ namespace System.Data.Odbc
                        if (currentRow == -1)
                                throw new IndexOutOfRangeException ();
 
-                       if (ordinal>cols.Length-1 || ordinal<0)
+                       if (ordinal > cols.Length-1 || ordinal < 0)
                                throw new IndexOutOfRangeException ();
 
                        OdbcReturn ret;
-                       int outsize=0, bufsize;
+                       int outsize = 0, bufsize;
                        byte[] buffer;
-                       OdbcColumn col=GetColumn(ordinal);
-                       object DataValue=null;
-                       ushort ColIndex=Convert.ToUInt16(ordinal+1);
+                       OdbcColumn col = GetColumn (ordinal);
+                       object DataValue = null;
+                       ushort ColIndex = Convert.ToUInt16 (ordinal+1);
 
                        // Check cached values
-                       if (col.Value==null) {
+                       if (col.Value == null) {
                                 // odbc help file
                                // mk:@MSITStore:C:\program%20files\Microsoft%20Data%20Access%20SDK\Docs\odbc.chm::/htm/odbcc_data_types.htm
                                switch (col.OdbcType) {
                                case OdbcType.Bit:
                                        short bit_data = 0;
-                                       ret=libodbc.SQLGetData(hstmt, ColIndex, col.SqlCType, ref bit_data, 0, ref outsize);
+                                       ret = libodbc.SQLGetData (hstmt, ColIndex, col.SqlCType, ref bit_data, 0, ref outsize);
                                        if (outsize != (int) OdbcLengthIndicator.NullData)
                                                DataValue = bit_data == 0 ? "False" : "True";
                                        break;
                                case OdbcType.Numeric:
                                case OdbcType.Decimal:
-                                       bufsize=50;
-                                       buffer=new byte[bufsize];  // According to sqlext.h, use SQL_CHAR for decimal.
+                                       bufsize = 50;
+                                       buffer = new byte [bufsize];  // According to sqlext.h, use SQL_CHAR for decimal.
                                        // FIXME : use Numeric.
-                                       ret=libodbc.SQLGetData(hstmt, ColIndex, SQL_C_TYPE.CHAR, buffer, bufsize, ref outsize);
+                                       ret = libodbc.SQLGetData (hstmt, ColIndex, SQL_C_TYPE.CHAR, buffer, bufsize, ref outsize);
                                        if (outsize!=-1) {
-                                               byte[] temp = new byte[outsize];
-                                               for (int i=0;i<outsize;i++)
-                                                       temp[i]=buffer[i];
-                                               DataValue=Decimal.Parse(System.Text.Encoding.Default.GetString(temp));
+                                               byte [] temp = new byte [outsize];
+                                               for (int i = 0;i<outsize;i++)
+                                                       temp[i] = buffer[i];
+                                               DataValue = Decimal.Parse(System.Text.Encoding.Default.GetString(temp));
                                        }
                                        break;
                                case OdbcType.TinyInt:
-                                       short short_data=0;
-                                       ret=libodbc.SQLGetData(hstmt, ColIndex, col.SqlCType, ref short_data, 0, ref outsize);
-                                       DataValue=System.Convert.ToByte(short_data);
+                                       short short_data = 0;
+                                       ret = libodbc.SQLGetData (hstmt, ColIndex, col.SqlCType, ref short_data, 0, ref outsize);
+                                       DataValue = System.Convert.ToByte(short_data);
                                        break;
                                case OdbcType.Int:
-                                       int int_data=0;
-                                       ret=libodbc.SQLGetData(hstmt, ColIndex, col.SqlCType, ref int_data, 0, ref outsize);
-                                       DataValue=int_data;
+                                       int int_data = 0;
+                                       ret = libodbc.SQLGetData (hstmt, ColIndex, col.SqlCType, ref int_data, 0, ref outsize);
+                                       DataValue = int_data;
                                        break;
 
                                case OdbcType.SmallInt:
-                                       short sint_data=0;
-                                       ret=libodbc.SQLGetData(hstmt, ColIndex, col.SqlCType, ref sint_data, 0, ref outsize);
-                                       DataValue=sint_data;
+                                       short sint_data = 0;
+                                       ret = libodbc.SQLGetData (hstmt, ColIndex, col.SqlCType, ref sint_data, 0, ref outsize);
+                                       DataValue = sint_data;
                                        break;
 
                                case OdbcType.BigInt:
-                                       long long_data=0;
-                                       ret=libodbc.SQLGetData(hstmt, ColIndex, col.SqlCType, ref long_data, 0, ref outsize);
-                                       DataValue=long_data;
+                                       long long_data = 0;
+                                       ret = libodbc.SQLGetData (hstmt, ColIndex, col.SqlCType, ref long_data, 0, ref outsize);
+                                       DataValue = long_data;
                                        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
+                                       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 { 
-                                               ret=libodbc.SQLGetData(hstmt, ColIndex, col.SqlCType, buffer, bufsize, ref outsize);
+                                               ret = libodbc.SQLGetData (hstmt, ColIndex, col.SqlCType, buffer, bufsize, ref outsize);
                                                if (ret == OdbcReturn.Error)
                                                        break;
                                                if (ret != OdbcReturn.NoData && outsize!=-1) {
@@ -717,49 +696,52 @@ namespace System.Data.Odbc
                                        break;
                                case OdbcType.Text:
                                case OdbcType.VarChar:
-                                       bufsize=(col.MaxLength < 255 ? (col.MaxLength+1) : 255);
-                                       buffer=new byte[bufsize];  // According to sqlext.h, use SQL_CHAR for both char and varchar
+                                       bufsize = (col.MaxLength < 255 ? (col.MaxLength+1) : 255);
+                                       buffer = new byte[bufsize];  // According to sqlext.h, use SQL_CHAR for both char and varchar
                                        StringBuilder sb1 = new StringBuilder ();
                                        do { 
-                                               ret=libodbc.SQLGetData(hstmt, ColIndex, col.SqlCType, buffer, bufsize, ref outsize);
+                                               ret = libodbc.SQLGetData (hstmt, ColIndex, col.SqlCType, buffer, bufsize, ref outsize);
                                                if (ret == OdbcReturn.Error)
                                                        break;
                                                if (ret != OdbcReturn.NoData && outsize!=-1) {
                                                        if (outsize < bufsize)
                                                                sb1.Append (System.Text.Encoding.Default.GetString(buffer,0,outsize));
                                                        else
-                                                               sb1.Append (System.Text.Encoding.Default.GetString(buffer,0,bufsize));
+                                                               sb1.Append (System.Text.Encoding.Default.GetString (buffer, 0, bufsize - 1));
                                                }
                                        } while (ret != OdbcReturn.NoData);
                                        DataValue = sb1.ToString ();
                                        break;
                                case OdbcType.Real:
-                                       float float_data=0;
-                                       ret=libodbc.SQLGetData(hstmt, ColIndex, col.SqlCType, ref float_data, 0, ref outsize);
-                                       DataValue=float_data;
+                                       float float_data = 0;
+                                       ret = libodbc.SQLGetData (hstmt, ColIndex, col.SqlCType, ref float_data, 0, ref outsize);
+                                       DataValue = float_data;
                                        break;
                                case OdbcType.Double:
-                                       double double_data=0;
-                                       ret=libodbc.SQLGetData(hstmt, ColIndex, col.SqlCType, ref double_data, 0, ref outsize);
-                                       DataValue=double_data;
+                                       double double_data = 0;
+                                       ret = libodbc.SQLGetData (hstmt, ColIndex, col.SqlCType, ref double_data, 0, ref outsize);
+                                       DataValue = double_data;
                                        break;
                                case OdbcType.Timestamp:
                                case OdbcType.DateTime:
                                case OdbcType.Date:
                                case OdbcType.Time:
-                                       OdbcTimestamp ts_data=new OdbcTimestamp();
-                                       ret=libodbc.SQLGetData(hstmt, ColIndex, col.SqlCType, ref ts_data, 0, ref outsize);
-                                       if (outsize!=-1) // This means SQL_NULL_DATA 
-                                               DataValue=new DateTime(ts_data.year,ts_data.month,ts_data.day,ts_data.hour,
-                                                                      ts_data.minute,ts_data.second,Convert.ToInt32(ts_data.fraction));
+                                       OdbcTimestamp ts_data = new OdbcTimestamp();
+                                       ret = libodbc.SQLGetData (hstmt, ColIndex, col.SqlCType, ref ts_data, 0, ref outsize);
+                                       if (outsize!=-1) {// This means SQL_NULL_DATA
+                                               DataValue = new DateTime(ts_data.year,ts_data.month,ts_data.day,ts_data.hour,
+                                                                      ts_data.minute,ts_data.second);
+                                               if (ts_data.fraction != 0)
+                                                       DataValue = ((DateTime) DataValue).AddTicks ((long)ts_data.fraction / 100);
+                                       }
                                        break;
                                case OdbcType.VarBinary :
                                case OdbcType.Image :
-                                       bufsize= (col.MaxLength < 255 ? col.MaxLength : 255);
+                                       bufsize =  (col.MaxLength < 255 ? col.MaxLength : 255);
                                        buffer= new byte [bufsize];
                                        ArrayList al = new ArrayList ();
                                        do { 
-                                               ret=libodbc.SQLGetData (hstmt, ColIndex, SQL_C_TYPE.BINARY, buffer, bufsize, ref outsize);
+                                               ret = libodbc.SQLGetData (hstmt, ColIndex, SQL_C_TYPE.BINARY, buffer, bufsize, ref outsize);
                                                if (ret == OdbcReturn.Error)
                                                        break;
                                                if (ret != OdbcReturn.NoData && outsize!=-1) {
@@ -781,13 +763,13 @@ namespace System.Data.Odbc
                                        DataValue = buffer;
                                        break;
                                default:
-                                       bufsize=255;
-                                       buffer=new byte[bufsize];
-                                       ret=libodbc.SQLGetData(hstmt, ColIndex, SQL_C_TYPE.CHAR, buffer, bufsize, ref outsize);
+                                       bufsize = 255;
+                                       buffer = new byte[bufsize];
+                                       ret = libodbc.SQLGetData (hstmt, ColIndex, SQL_C_TYPE.CHAR, buffer, bufsize, ref outsize);
                                        if (outsize != (int) OdbcLengthIndicator.NullData)
                                                if (! (ret == OdbcReturn.SuccessWithInfo
                                                       && outsize == (int) OdbcLengthIndicator.NoTotal))
-                                                       DataValue=System.Text.Encoding.Default.GetString(buffer, 0, outsize);
+                                                       DataValue = System.Text.Encoding.Default.GetString(buffer, 0, outsize);
                                        break;
                                }
 
@@ -795,9 +777,9 @@ namespace System.Data.Odbc
                                        throw new OdbcException(new OdbcError("SQLGetData",OdbcHandleType.Stmt,hstmt));
 
                                if (outsize==-1) // This means SQL_NULL_DATA 
-                                       col.Value=DBNull.Value;
+                                       col.Value = DBNull.Value;
                                else
-                                       col.Value=DataValue;
+                                       col.Value = DataValue;
                        }
                        return col.Value;
                }
@@ -813,7 +795,7 @@ namespace System.Data.Odbc
                        // copy values
                        for (int i = 0; i < values.Length; i++) {
                                if (i < FieldCount) {
-                                       values[i] = GetValue(i);
+                                       values[i] = GetValue (i);
                                }
                                else {
                                        values[i] = null;
@@ -833,24 +815,26 @@ namespace System.Data.Odbc
 
 #if ONLY_1_1
 
-                [MonoTODO]
-               IDataReader IDataRecord.GetData (int ordinal)
-               {
-                       throw new NotImplementedException ();
-               }
-
                void IDisposable.Dispose ()
                {
                        Dispose (true);
                        GC.SuppressFinalize (this);
                }
 
-                IEnumerator IEnumerable.GetEnumerator ()
+               IEnumerator IEnumerable.GetEnumerator ()
                {
                        return new DbEnumerator (this);
                }
 #endif // ONLY_1_1
 
+               
+#if NET_2_0
+                public override IEnumerator GetEnumerator ()
+               {
+                       return new DbEnumerator (this);
+               }
+#endif
+
 #if NET_2_0
                protected override
 #endif
@@ -876,7 +860,7 @@ namespace System.Data.Odbc
 #endif // NET_2_0
                 bool IsDBNull (int ordinal)
                {
-                       return (GetValue(ordinal) is DBNull);
+                       return (GetValue (ordinal) is DBNull);
                }
 
                /// <remarks>
@@ -925,10 +909,10 @@ namespace System.Data.Odbc
                 {
                         OdbcReturn ret = OdbcReturn.Error;
                         byte [] buffer = new byte [255];
-                        int outsize = 0;
+                        short outsize = 0;
                         int val = 0;
-                        ret = libodbc.SQLColAttribute (hstmt, column, fieldId, 
-                                                       buffer, buffer.Length, 
+                        ret = libodbc.SQLColAttribute (hstmt, (short)column, fieldId, 
+                                                       buffer, (short)buffer.Length, 
                                                        ref outsize, ref val);
                         if (ret != OdbcReturn.Success && ret != OdbcReturn.SuccessWithInfo)
                                 throw new OdbcException (new OdbcError ("SQLColAttribute",
@@ -943,10 +927,10 @@ namespace System.Data.Odbc
                 {
                         OdbcReturn ret = OdbcReturn.Error;
                         byte [] buffer = new byte [255];
-                        int outsize = 0;
+                        short outsize = 0;
                         int val = 0;
-                        ret = libodbc.SQLColAttribute (hstmt, column, fieldId, 
-                                                       buffer, buffer.Length, 
+                        ret = libodbc.SQLColAttribute (hstmt, (short)column, fieldId, 
+                                                       buffer, (short)buffer.Length, 
                                                        ref outsize, ref val);
                         if (ret != OdbcReturn.Success && ret != OdbcReturn.SuccessWithInfo)
                                 throw new OdbcException (new OdbcError ("SQLColAttribute",
@@ -973,6 +957,8 @@ namespace System.Data.Odbc
                                } catch (OdbcException) {
                                }
                         }
+                       if (keys == null)
+                               return null;
                        keys.Sort ();
                        return (string []) keys.ToArray (typeof (string));
                 }
@@ -1094,28 +1080,6 @@ namespace System.Data.Odbc
                        return NextRow ();
                }
 
-#if NET_2_0
-                [MonoTODO]
-               public override object GetProviderSpecificValue (int i)
-                {
-                       throw new NotImplementedException ();
-                }
-                
-                [MonoTODO]
-               public override int GetProviderSpecificValues (object[] values)
-                {
-                       throw new NotImplementedException ();
-                }
-
-                [MonoTODO]
-               public override Type GetProviderSpecificFieldType (int i)
-                {
-                       throw new NotImplementedException ();
-                }
-                
-#endif // NET_2_0
-
-
                #endregion
        }
 }