internal static extern OdbcReturn SQLGetData( IntPtr StatementHandle, ushort ColumnNumber, SQL_C_TYPE TargetType, ref OdbcTimestamp TargetPtr, int BufferLen, ref int Len);
internal static extern OdbcReturn SQLGetData ( IntPtr StatementHandle, ushort ColumnNumber, SQL_C_TYPE TargetType, ref OdbcTimestamp TargetPtr, int BufferLen, ref int Len);
object GetValue (int i) { if (IsClosed) throw new InvalidOperationException ("The reader is closed."); if (currentRow == -1) throw new InvalidOperationException ("No data available."); if (i > cols.Length-1 || i < 0) throw new IndexOutOfRangeException (); OdbcReturn ret; int outsize = 0, bufsize; byte[] buffer; OdbcColumn col = GetColumn (i); object DataValue = null; ushort ColIndex = Convert.ToUInt16 (i + 1); // Check cached values 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); 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. // FIXME : use Numeric. ret = libodbc.SQLGetData (hstmt, ColIndex, SQL_C_TYPE.CHAR, buffer, bufsize, ref outsize); if (outsize!=-1) { byte [] temp = new byte [outsize]; for (int j = 0; j < outsize; j++) temp [j] = buffer [j]; DataValue = Decimal.Parse (Encoding.Default.GetString (temp), CultureInfo.InvariantCulture); } break; case OdbcType.TinyInt: short short_data = 0; ret = libodbc.SQLGetData (hstmt, ColIndex, col.SqlCType, ref short_data, 0, ref outsize); DataValue = 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; break; case OdbcType.SmallInt: 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; 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 (); char[] charBuffer = new char[bufsize]; Decoder unicodeDecoder = Encoding.Unicode.GetDecoder (); 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.Success || ret == OdbcReturn.SuccessWithInfo) { if (outsize >= bufsize || outsize == (int)OdbcLengthIndicator.NoTotal) outsize = bufsize; int charCount = unicodeDecoder.GetChars (buffer, 0, outsize, charBuffer, 0); string strValue = new String (charBuffer, 0, charCount); sb.Append (RemoveTrailingNullChar (strValue)); } } while (ret != OdbcReturn.NoData); DataValue = sb.ToString (); charBuffer = null; 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 StringBuilder sb1 = new StringBuilder (); charBuffer = new char[bufsize]; Decoder defaultDecoder = Encoding.Default.GetDecoder(); 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.Success || ret == OdbcReturn.SuccessWithInfo) { if (outsize >= bufsize || outsize == (int)OdbcLengthIndicator.NoTotal) outsize = bufsize - 1; int charCount = defaultDecoder.GetChars(buffer, 0, outsize, charBuffer, 0); sb1.Append(charBuffer, 0, charCount); } } 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; break; case OdbcType.Double: 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 if (col.OdbcType == OdbcType.Time) { // libodbc returns value in first three fields for OdbcType.Time DataValue = new System.TimeSpan (ts_data.year, ts_data.month, ts_data.day); } else { 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 > 0 ? col.MaxLength : 255); buffer= new byte [bufsize]; ArrayList al = new ArrayList (); //get the size of data to be returned. ret = libodbc.SQLGetData (hstmt, ColIndex, SQL_C_TYPE.BINARY, buffer, 0, ref outsize); if (outsize != (int) OdbcLengthIndicator.NullData) { do { ret = libodbc.SQLGetData (hstmt, ColIndex, SQL_C_TYPE.BINARY, buffer, bufsize, ref outsize); if (ret == OdbcReturn.Error) break; if (ret != OdbcReturn.NoData && outsize != -1) { if (outsize < bufsize) { byte [] tmparr = new byte [outsize]; Array.Copy (buffer, 0, tmparr, 0, outsize); al.AddRange (tmparr); } else al.AddRange (buffer); } else { break; } } while (ret != OdbcReturn.NoData); } DataValue = al.ToArray (typeof (byte)); break; case OdbcType.Binary : bufsize = col.MaxLength; buffer = new byte [bufsize]; GetBytes (i, 0, buffer, 0, bufsize); ret = OdbcReturn.Success; DataValue = buffer; break; default: 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 = Encoding.Default.GetString (buffer, 0, outsize); break; } if ((ret!=OdbcReturn.Success) && (ret!=OdbcReturn.SuccessWithInfo) && (ret!=OdbcReturn.NoData)) throw Connection.CreateOdbcException (OdbcHandleType.Stmt, hstmt); if (outsize == -1) // This means SQL_NULL_DATA col.Value = DBNull.Value; else col.Value = DataValue; } return col.Value; }
object GetValue(int i) { if (IsClosed) { throw new InvalidOperationException("The reader is closed."); } if (currentRow == -1) { throw new InvalidOperationException("No data available."); } if (i > cols.Length - 1 || i < 0) { throw new IndexOutOfRangeException(); } OdbcReturn ret; int outsize = 0, bufsize; byte[] buffer; OdbcColumn col = GetColumn(i); object DataValue = null; ushort ColIndex = Convert.ToUInt16(i + 1); // Check cached values 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); 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. // FIXME : use Numeric. ret = libodbc.SQLGetData(hstmt, ColIndex, SQL_C_TYPE.CHAR, buffer, bufsize, ref outsize); if (outsize != -1) { byte [] temp = new byte [outsize]; for (int j = 0; j < outsize; j++) { temp [j] = buffer [j]; } DataValue = Decimal.Parse(Encoding.Default.GetString(temp), CultureInfo.InvariantCulture); } break; case OdbcType.TinyInt: short short_data = 0; ret = libodbc.SQLGetData(hstmt, ColIndex, col.SqlCType, ref short_data, 0, ref outsize); DataValue = 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; break; case OdbcType.SmallInt: 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; 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(); char[] charBuffer = new char[bufsize]; Decoder unicodeDecoder = Encoding.Unicode.GetDecoder(); 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.Success || ret == OdbcReturn.SuccessWithInfo) { if (outsize >= bufsize || outsize == (int)OdbcLengthIndicator.NoTotal) { outsize = bufsize; } int charCount = unicodeDecoder.GetChars(buffer, 0, outsize, charBuffer, 0); string strValue = new String(charBuffer, 0, charCount); sb.Append(RemoveTrailingNullChar(strValue)); } } while (ret != OdbcReturn.NoData); DataValue = sb.ToString(); charBuffer = null; 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 StringBuilder sb1 = new StringBuilder(); charBuffer = new char[bufsize]; Decoder defaultDecoder = Encoding.Default.GetDecoder(); 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.Success || ret == OdbcReturn.SuccessWithInfo) { if (outsize >= bufsize || outsize == (int)OdbcLengthIndicator.NoTotal) { outsize = bufsize - 1; } int charCount = defaultDecoder.GetChars(buffer, 0, outsize, charBuffer, 0); sb1.Append(charBuffer, 0, charCount); } } 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; break; case OdbcType.Double: 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 { if (col.OdbcType == OdbcType.Time) { // libodbc returns value in first three fields for OdbcType.Time DataValue = new System.TimeSpan(ts_data.year, ts_data.month, ts_data.day); } else { 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 > 0 ? col.MaxLength : 255); buffer = new byte [bufsize]; ArrayList al = new ArrayList(); //get the size of data to be returned. ret = libodbc.SQLGetData(hstmt, ColIndex, SQL_C_TYPE.BINARY, buffer, 0, ref outsize); if (outsize != (int)OdbcLengthIndicator.NullData) { do { ret = libodbc.SQLGetData(hstmt, ColIndex, SQL_C_TYPE.BINARY, buffer, bufsize, ref outsize); if (ret == OdbcReturn.Error) { break; } if (ret != OdbcReturn.NoData && outsize != -1) { if (outsize < bufsize) { byte [] tmparr = new byte [outsize]; Array.Copy(buffer, 0, tmparr, 0, outsize); al.AddRange(tmparr); } else { al.AddRange(buffer); } } else { break; } } while (ret != OdbcReturn.NoData); } DataValue = al.ToArray(typeof(byte)); break; case OdbcType.Binary: bufsize = col.MaxLength; buffer = new byte [bufsize]; GetBytes(i, 0, buffer, 0, bufsize); ret = OdbcReturn.Success; DataValue = buffer; break; default: 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 = Encoding.Default.GetString(buffer, 0, outsize); } } break; } if ((ret != OdbcReturn.Success) && (ret != OdbcReturn.SuccessWithInfo) && (ret != OdbcReturn.NoData)) { throw Connection.CreateOdbcException(OdbcHandleType.Stmt, hstmt); } if (outsize == -1) // This means SQL_NULL_DATA { col.Value = DBNull.Value; } else { col.Value = DataValue; } } return(col.Value); }
object GetValue (int ordinal) { if (currentRow == -1) throw new IndexOutOfRangeException (); if (ordinal>cols.Length-1 || ordinal<0) throw new IndexOutOfRangeException (); OdbcReturn ret; int outsize=0, bufsize; byte[] buffer; OdbcColumn col=GetColumn(ordinal); object DataValue=null; ushort ColIndex=Convert.ToUInt16(ordinal+1); // Check cached values 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.Numeric: case OdbcType.Decimal: bufsize=50; buffer=new byte[bufsize]; // According to sqlext.h, use SQL_CHAR for decimal. ret=libodbc.SQLGetData(hstmt, ColIndex, col.SqlCType, 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)); } 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); break; case OdbcType.Int: 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; break; case OdbcType.BigInt: long long_data=0; ret=libodbc.SQLGetData(hstmt, ColIndex, col.SqlCType, ref long_data, 0, ref outsize); DataValue=long_data; break; case OdbcType.NVarChar: bufsize=col.MaxLength*2+1; // Unicode is double byte buffer=new byte[bufsize]; ret=libodbc.SQLGetData(hstmt, ColIndex, col.SqlCType, buffer, bufsize, ref outsize); if (outsize!=-1) DataValue=System.Text.Encoding.Unicode.GetString(buffer,0,outsize); break; case OdbcType.VarChar: bufsize=col.MaxLength+1; buffer=new byte[bufsize]; // According to sqlext.h, use SQL_CHAR for both char and varchar ret=libodbc.SQLGetData(hstmt, ColIndex, col.SqlCType, buffer, bufsize, ref outsize); if (outsize!=-1) DataValue=System.Text.Encoding.Default.GetString(buffer,0,outsize); break; case OdbcType.Real: 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; 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)); break; case OdbcType.Binary : case OdbcType.Image : bufsize = col.MaxLength + 1; buffer = new byte [bufsize]; long read = GetBytes (ordinal, 0, buffer, 0, bufsize); ret = OdbcReturn.Success; DataValue = buffer; break; default: 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); break; } if ((ret!=OdbcReturn.Success) && (ret!=OdbcReturn.SuccessWithInfo)) throw new OdbcException(new OdbcError("SQLGetData",OdbcHandleType.Stmt,hstmt)); if (outsize==-1) // This means SQL_NULL_DATA col.Value=DBNull.Value; else col.Value=DataValue; } return col.Value; }