Example #1
0
 // Dynamically load column descriptions as needed.
 private OdbcColumn GetColumn(int ordinal)
 {
     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 Connection.CreateOdbcException(OdbcHandleType.Stmt, hstmt);
         }
         colname = RemoveTrailingNullChar(Encoding.Unicode.GetString(colname_buffer));
         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;
     }
     return(cols [ordinal]);
 }
Example #2
0
 // Dynamically load column descriptions as needed.
 private OdbcColumn GetColumn(int ordinal)
 {
     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;
         if (c.IsVariableSizeType)
         {
             c.MaxLength = (int)ColSize;
         }
         cols [ordinal] = c;
     }
     return(cols [ordinal]);
 }
Example #3
0
		// Dynamically load column descriptions as needed.
		private OdbcColumn GetColumn (int ordinal)
		{
			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 Connection.CreateOdbcException (OdbcHandleType.Stmt, hstmt);
				colname = RemoveTrailingNullChar (Encoding.Unicode.GetString (colname_buffer));
				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;
			}
			return cols [ordinal];
		}
Example #4
0
        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);
        }
Example #5
0
        DataTable GetSchemaTable()
        {
            if (IsClosed)
            {
                throw new InvalidOperationException("The reader is closed.");
            }

            // FIXME :
            // * Map OdbcType to System.Type and assign to DataType.
            //   This will eliminate the need for IsStringType in
            //   OdbcColumn

            if (_dataTableSchema != null)
            {
                return(_dataTableSchema);
            }

            DataTable dataTableSchema = null;

            // Only Results from SQL SELECT Queries
            // get a DataTable for schema of the result
            // otherwise, DataTable is null reference
            if (cols.Length > 0)
            {
                dataTableSchema = new DataTable();

                dataTableSchema.Columns.Add("ColumnName", typeof(string));
                dataTableSchema.Columns.Add("ColumnOrdinal", typeof(int));
                dataTableSchema.Columns.Add("ColumnSize", typeof(int));
                dataTableSchema.Columns.Add("NumericPrecision", typeof(int));
                dataTableSchema.Columns.Add("NumericScale", typeof(int));
                dataTableSchema.Columns.Add("IsUnique", typeof(bool));
                dataTableSchema.Columns.Add("IsKey", typeof(bool));
                DataColumn dc = dataTableSchema.Columns["IsKey"];
                dc.AllowDBNull = true;                 // IsKey can have a DBNull
                dataTableSchema.Columns.Add("BaseCatalogName", typeof(string));
                dataTableSchema.Columns.Add("BaseColumnName", typeof(string));
                dataTableSchema.Columns.Add("BaseSchemaName", typeof(string));
                dataTableSchema.Columns.Add("BaseTableName", typeof(string));
                dataTableSchema.Columns.Add("DataType", typeof(Type));
                dataTableSchema.Columns.Add("AllowDBNull", typeof(bool));
                dataTableSchema.Columns.Add("ProviderType", typeof(int));
                dataTableSchema.Columns.Add("IsAliased", typeof(bool));
                dataTableSchema.Columns.Add("IsExpression", typeof(bool));
                dataTableSchema.Columns.Add("IsIdentity", typeof(bool));
                dataTableSchema.Columns.Add("IsAutoIncrement", typeof(bool));
                dataTableSchema.Columns.Add("IsRowVersion", typeof(bool));
                dataTableSchema.Columns.Add("IsHidden", typeof(bool));
                dataTableSchema.Columns.Add("IsLong", typeof(bool));
                dataTableSchema.Columns.Add("IsReadOnly", typeof(bool));

                DataRow schemaRow;

                for (int i = 0; i < cols.Length; i += 1)
                {
                    OdbcColumn col = GetColumn(i);

                    schemaRow = dataTableSchema.NewRow();
                    dataTableSchema.Rows.Add(schemaRow);

                    schemaRow ["ColumnName"]       = col.ColumnName;
                    schemaRow ["ColumnOrdinal"]    = i;
                    schemaRow ["ColumnSize"]       = col.MaxLength;
                    schemaRow ["NumericPrecision"] = GetColumnAttribute(i + 1, FieldIdentifier.Precision);
                    schemaRow ["NumericScale"]     = GetColumnAttribute(i + 1, FieldIdentifier.Scale);
                    schemaRow ["BaseTableName"]    = GetColumnAttributeStr(i + 1, FieldIdentifier.TableName);
                    schemaRow ["BaseSchemaName"]   = GetColumnAttributeStr(i + 1, FieldIdentifier.SchemaName);
                    schemaRow ["BaseCatalogName"]  = GetColumnAttributeStr(i + 1, FieldIdentifier.CatelogName);
                    schemaRow ["BaseColumnName"]   = GetColumnAttributeStr(i + 1, FieldIdentifier.BaseColumnName);
                    schemaRow ["DataType"]         = col.DataType;
                    schemaRow ["IsUnique"]         = false;
                    schemaRow ["IsKey"]            = DBNull.Value;
                    schemaRow ["AllowDBNull"]      = GetColumnAttribute(i + 1, FieldIdentifier.Nullable) != libodbc.SQL_NO_NULLS;
                    schemaRow ["ProviderType"]     = (int)col.OdbcType;
                    schemaRow ["IsAutoIncrement"]  = GetColumnAttribute(i + 1, FieldIdentifier.AutoUniqueValue) == libodbc.SQL_TRUE;
                    schemaRow ["IsExpression"]     = schemaRow.IsNull("BaseTableName") || (string)schemaRow ["BaseTableName"] == String.Empty;
                    schemaRow ["IsAliased"]        = (string)schemaRow ["BaseColumnName"] != (string)schemaRow ["ColumnName"];
                    schemaRow ["IsReadOnly"]       = ((bool)schemaRow ["IsExpression"] ||
                                                      GetColumnAttribute(i + 1, FieldIdentifier.Updatable) == libodbc.SQL_ATTR_READONLY);

                    // FIXME: all of these
                    schemaRow ["IsIdentity"]   = false;
                    schemaRow ["IsRowVersion"] = false;
                    schemaRow ["IsHidden"]     = false;
                    schemaRow ["IsLong"]       = false;

                    // FIXME: according to Brian,
                    // this does not work on MS .NET
                    // however, we need it for Mono
                    // for now
                    // schemaRow.AcceptChanges();
                }

                // set primary keys
                DataRow [] rows = dataTableSchema.Select("BaseTableName <> ''",
                                                         "BaseCatalogName, BaseSchemaName, BaseTableName ASC");

                string lastTableName   = String.Empty,
                       lastSchemaName  = String.Empty,
                       lastCatalogName = String.Empty;
                string [] keys         = null;         // assumed to be sorted.
                foreach (DataRow row in rows)
                {
                    string tableName   = (string)row ["BaseTableName"];
                    string schemaName  = (string)row ["BaseSchemaName"];
                    string catalogName = (string)row ["BaseCatalogName"];

                    if (tableName != lastTableName || schemaName != lastSchemaName ||
                        catalogName != lastCatalogName)
                    {
                        keys = GetPrimaryKeys(catalogName, schemaName, tableName);
                    }

                    if (keys != null &&
                        Array.BinarySearch(keys, (string)row ["BaseColumnName"]) >= 0)
                    {
                        row ["IsKey"]       = true;
                        row ["IsUnique"]    = true;
                        row ["AllowDBNull"] = false;
                        GetColumn(ColIndex((string)row ["ColumnName"])).AllowDBNull = false;
                    }
                    lastTableName   = tableName;
                    lastSchemaName  = schemaName;
                    lastCatalogName = catalogName;
                }
                dataTableSchema.AcceptChanges();
            }
            return(_dataTableSchema = dataTableSchema);
        }
		// Dynamically load column descriptions as needed.
		private OdbcColumn GetColumn(int ordinal)
		{
			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;
				if (c.IsStringType)
					c.MaxLength=(int)ColSize;
				cols[ordinal]=c;
			}
			return cols[ordinal];
		}