SqlEnums.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Data / System / Data / SqlClient / SqlEnums.cs / 1305376 / SqlEnums.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
// [....]
//----------------------------------------------------------------------------- 
 
namespace System.Data.SqlClient {
 

    using System;
    using System.Collections.Generic;
    using System.ComponentModel; 
    using System.Data.Common;
    using System.Data.OleDb; 
    using System.Data.SqlTypes; 
    using System.Diagnostics;
    using System.Globalization; 
    using System.Xml;
    using System.IO;
    using System.Data.Sql;
 
    using MSS=Microsoft.SqlServer.Server;
 
    internal sealed class MetaType { 
        internal readonly Type      ClassType;   // com+ type
        internal readonly Type      SqlType; 

        internal readonly int       FixedLength; // fixed length size in bytes (-1 for variable)
        internal readonly bool      IsFixed;     // true if fixed length, note that sqlchar and sqlbinary are not considered fixed length
        internal readonly bool      IsLong;      // true if long 
        internal readonly bool      IsPlp;       // Column is Partially Length Prefixed (MAX)
        internal readonly byte      Precision;   // maxium precision for numeric types // $ 
        internal readonly byte      Scale; 
        internal readonly byte      TDSType;
        internal readonly byte      NullableType; 

        internal readonly string    TypeName;    // string name of this type
        internal readonly SqlDbType SqlDbType;
        internal readonly DbType    DbType; 

        //  holds count of property bytes expected for a SQLVariant structure 
        internal readonly byte PropBytes; 

 
        // pre-computed fields
        internal readonly bool IsAnsiType;
        internal readonly bool IsBinType;
        internal readonly bool IsCharType; 
        internal readonly bool IsNCharType;
        internal readonly bool IsSizeInCharacters; 
 
        internal readonly bool Is70Supported;
        internal readonly bool Is80Supported; 
        internal readonly bool Is90Supported;
        internal readonly bool Is100Supported;

        public MetaType(byte precision, byte scale, int fixedLength, bool isFixed, bool isLong, bool isPlp, byte tdsType, byte nullableTdsType, string typeName, Type classType, Type sqlType, SqlDbType sqldbType, DbType dbType, byte propBytes) { 
            this.Precision    = precision;
            this.Scale        = scale; 
            this.FixedLength  = fixedLength; 
            this.IsFixed      = isFixed;
            this.IsLong       = isLong; 
            this.IsPlp        = isPlp;
            // can we get rid of this (?just have a mapping?)
            this.TDSType      = tdsType;
            this.NullableType = nullableTdsType; 
            this.TypeName     = typeName;
            this.SqlDbType    = sqldbType; 
            this.DbType       = dbType; 

            this.ClassType    = classType; 
            this.SqlType      = sqlType;
            this.PropBytes    = propBytes;

            IsAnsiType  = _IsAnsiType(sqldbType); 
            IsBinType   = _IsBinType(sqldbType);
            IsCharType  = _IsCharType(sqldbType); 
            IsNCharType = _IsNCharType(sqldbType); 
            IsSizeInCharacters = _IsSizeInCharacters(SqlDbType);
 
            Is70Supported = _Is70Supported(SqlDbType);
            Is80Supported = _Is80Supported(SqlDbType);
            Is90Supported = _Is90Supported(SqlDbType);
            Is100Supported = _Is100Supported(SqlDbType); 
        }
 
        // properties should be inlined so there should be no perf penalty for using these accessor functions 
        public int TypeId {             // partial length prefixed (xml, nvarchar(max),...)
            get { return 0;} 
        }

        private static bool _IsAnsiType(SqlDbType type) {
            return(type == SqlDbType.Char || 
                   type == SqlDbType.VarChar ||
                   type == SqlDbType.Text); 
        } 

        // is this type size expressed as count of characters or bytes? 
        private static bool _IsSizeInCharacters(SqlDbType type) {
            return(type == SqlDbType.NChar ||
                   type == SqlDbType.NVarChar ||
                   type == SqlDbType.Xml || 
                   type == SqlDbType.NText);
        } 
 
        private static bool _IsCharType(SqlDbType type) {
            return(type == SqlDbType.NChar || 
                   type == SqlDbType.NVarChar ||
                   type == SqlDbType.NText ||
                   type == SqlDbType.Char ||
                   type == SqlDbType.VarChar || 
                   type == SqlDbType.Text ||
                   type == SqlDbType.Xml); 
        } 

        private static bool _IsNCharType(SqlDbType type) { 
            return(type == SqlDbType.NChar ||
                   type == SqlDbType.NVarChar ||
                   type == SqlDbType.NText ||
                   type == SqlDbType.Xml); 
        }
 
        private static bool _IsBinType(SqlDbType type) { 
            return(type == SqlDbType.Image ||
                   type == SqlDbType.Binary || 
                   type == SqlDbType.VarBinary ||
                   type == SqlDbType.Timestamp ||
                   type == SqlDbType.Udt ||
                   (int) type == 24 /*SqlSmallVarBinary*/); 
        }
 
        private static bool _Is70Supported(SqlDbType type) { 
            return((type != SqlDbType.BigInt) && ((int)type > 0) &&
                   ((int)type <= (int) SqlDbType.VarChar)); 
        }

        private static bool _Is80Supported(SqlDbType type) {
            return((int)type >= 0 && 
                ((int)type <= (int) SqlDbType.Variant));
        } 
 
        private static bool _Is90Supported(SqlDbType type) {
            return _Is80Supported(type) || 
                    SqlDbType.Xml == type ||
                    SqlDbType.Udt == type;
        }
 
        private static bool _Is100Supported(SqlDbType type) {
            return _Is90Supported(type) || 
                    SqlDbType.Date == type || 
                    SqlDbType.Time == type ||
                    SqlDbType.DateTime2 == type || 
                    SqlDbType.DateTimeOffset == type;
        }

/*        private static bool _Is10Supported(SqlDbType type) { 
            return _Is90Supported(type) ||
                _IsNewKatmaiType(type); 
        } 
*/
        private static bool _IsNewKatmaiType(SqlDbType type) { 
            return SqlDbType.Structured == type;
        }

        internal bool IsNewKatmaiType { 
            get {
                return _IsNewKatmaiType(this.SqlDbType); 
            } 
        }
 
        internal static bool _IsVarTime(SqlDbType type) {
            return (type == SqlDbType.Time || type == SqlDbType.DateTime2 || type == SqlDbType.DateTimeOffset);
        }
 
        internal bool IsVarTime {
            get { 
                return _IsVarTime(this.SqlDbType); 
            }
        } 

        //
        // map SqlDbType to MetaType class
        // 
        internal static MetaType GetMetaTypeFromSqlDbType(SqlDbType target, bool isMultiValued) { // WebData 113289
            switch(target) { 
            case SqlDbType.BigInt:            return MetaBigInt; 
            case SqlDbType.Binary:            return MetaBinary;
            case SqlDbType.Bit:               return MetaBit; 
            case SqlDbType.Char:              return MetaChar;
            case SqlDbType.DateTime:          return MetaDateTime;
            case SqlDbType.Decimal:           return MetaDecimal;
            case SqlDbType.Float:             return MetaFloat; 
            case SqlDbType.Image:             return MetaImage;
            case SqlDbType.Int:               return MetaInt; 
            case SqlDbType.Money:             return MetaMoney; 
            case SqlDbType.NChar:             return MetaNChar;
            case SqlDbType.NText:             return MetaNText; 
            case SqlDbType.NVarChar:          return MetaNVarChar;
            case SqlDbType.Real:              return MetaReal;
            case SqlDbType.UniqueIdentifier:  return MetaUniqueId;
            case SqlDbType.SmallDateTime:     return MetaSmallDateTime; 
            case SqlDbType.SmallInt:          return MetaSmallInt;
            case SqlDbType.SmallMoney:        return MetaSmallMoney; 
            case SqlDbType.Text:              return MetaText; 
            case SqlDbType.Timestamp:         return MetaTimestamp;
            case SqlDbType.TinyInt:           return MetaTinyInt; 
            case SqlDbType.VarBinary:         return MetaVarBinary;
            case SqlDbType.VarChar:           return MetaVarChar;
            case SqlDbType.Variant:           return MetaVariant;
            case (SqlDbType)TdsEnums.SmallVarBinary: return MetaSmallVarBinary; 
            case SqlDbType.Xml:               return MetaXml;
            case SqlDbType.Udt:               return MetaUdt; 
            case SqlDbType.Structured: 
                if (isMultiValued) {
                    return MetaTable; 
                }
                else {
                    return MetaSUDT;
                } 
            case SqlDbType.Date:              return MetaDate;
            case SqlDbType.Time:              return MetaTime; 
            case SqlDbType.DateTime2:         return MetaDateTime2; 
            case SqlDbType.DateTimeOffset:    return MetaDateTimeOffset;
            default:                          throw SQL.InvalidSqlDbType(target); 
            }
        }

        // 
        // map DbType to MetaType class
        // 
        internal static MetaType GetMetaTypeFromDbType(DbType target) { 
            // if we can't map it, we need to throw
            switch (target) { 
            case DbType.AnsiString:             return MetaVarChar;
            case DbType.AnsiStringFixedLength:  return MetaChar;
            case DbType.Binary:                 return MetaVarBinary;
            case DbType.Byte:                   return MetaTinyInt; 
            case DbType.Boolean:                return MetaBit;
            case DbType.Currency:               return MetaMoney; 
            case DbType.Date: 
            case DbType.DateTime:               return MetaDateTime;
            case DbType.Decimal:                return MetaDecimal; 
            case DbType.Double:                 return MetaFloat;
            case DbType.Guid:                   return MetaUniqueId;
            case DbType.Int16:                  return MetaSmallInt;
            case DbType.Int32:                  return MetaInt; 
            case DbType.Int64:                  return MetaBigInt;
            case DbType.Object:                 return MetaVariant; 
            case DbType.Single:                 return MetaReal; 
            case DbType.String:                 return MetaNVarChar;
            case DbType.StringFixedLength:      return MetaNChar; 
            case DbType.Time:                   return MetaDateTime;
            case DbType.Xml:                    return MetaXml;
            case DbType.DateTime2:              return MetaDateTime2;
            case DbType.DateTimeOffset:         return MetaDateTimeOffset; 
            case DbType.SByte:                  // unsupported
            case DbType.UInt16: 
            case DbType.UInt32: 
            case DbType.UInt64:
            case DbType.VarNumeric: 
            default:                            throw ADP.DbTypeNotSupported(target, typeof(SqlDbType)); // no direct mapping, error out
            }
        }
 
        internal static MetaType GetMaxMetaTypeFromMetaType(MetaType mt) {
            // if we can't map it, we need to throw 
            switch (mt.SqlDbType) { 
            case SqlDbType.VarBinary:
            case SqlDbType.Binary: 
                return MetaMaxVarBinary;
            case SqlDbType.VarChar:
            case SqlDbType.Char:
                return MetaMaxVarChar; 
            case SqlDbType.NVarChar:
            case SqlDbType.NChar: 
                return MetaMaxNVarChar; 
            case SqlDbType.Udt:
                // 
                return MetaMaxUdt;
            default:
                return mt;
           } 
        }
 
#if WINFSFunctionality 
        internal static MetaType GetUdtMetaType(bool isLarge) {
            // if we can't map it, we need to throw 
            if (isLarge) {
                return MetaMaxUdt;
            }
            else { 
                return MetaUdt;
            } 
        } 
#endif
 
        //
        // map COM+ Type to MetaType class
        //
        static internal MetaType GetMetaTypeFromType(Type dataType) { 
            return GetMetaTypeFromValue(dataType, null, false);
        } 
        static internal MetaType GetMetaTypeFromValue(object value) { 
            return GetMetaTypeFromValue(value.GetType(), value, true);
        } 

        static private MetaType GetMetaTypeFromValue(Type dataType, object value, bool inferLen) {
            switch (Type.GetTypeCode(dataType)) {
                case TypeCode.Empty:     throw ADP.InvalidDataType(TypeCode.Empty); 
                case TypeCode.Object:
                    if (dataType == typeof(System.Byte[])) { 
                        // mdac 90455 must not default to image if inferLen is false ... 
                        //
                        if (!inferLen || ((byte[]) value).Length <= TdsEnums.TYPE_SIZE_LIMIT) { 
                            return MetaVarBinary;
                        }
                        else {
                            return MetaImage; 
                        }
                    } 
                    else if (dataType == typeof(System.Guid)) { 
                        return MetaUniqueId;
                    } 
                    else if (dataType == typeof(System.Object)) {
                        return MetaVariant;
                    } // check sql types now
                    else if (dataType == typeof(SqlBinary)) 
                        return MetaVarBinary;
                    else if (dataType == typeof(SqlBoolean)) 
                        return MetaBit; 
                    else if (dataType == typeof(SqlByte))
                        return MetaTinyInt; 
                    else if (dataType == typeof(SqlBytes))
                        return MetaVarBinary;
                    else if (dataType == typeof(SqlChars))
                        return  MetaNVarChar; // MDAC 87587 
                    else if (dataType == typeof(SqlDateTime))
                        return MetaDateTime; 
                    else if (dataType == typeof(SqlDouble)) 
                        return MetaFloat;
                    else if (dataType == typeof(SqlGuid)) 
                        return MetaUniqueId;
                    else if (dataType == typeof(SqlInt16))
                        return MetaSmallInt;
                    else if (dataType == typeof(SqlInt32)) 
                        return MetaInt;
                    else if (dataType == typeof(SqlInt64)) 
                        return MetaBigInt; 
                    else if (dataType == typeof(SqlMoney))
                        return MetaMoney; 
                    else if (dataType == typeof(SqlDecimal))
                        return MetaDecimal;
                    else if (dataType == typeof(SqlSingle))
                        return MetaReal; 
                    else if (dataType == typeof(SqlXml))
                        return MetaXml; 
                    else if (dataType == typeof(System.Xml.XmlReader)) 
                        return MetaXml;
                    else if (dataType == typeof(SqlString)) { 
                        return ((inferLen && !((SqlString)value).IsNull) ? PromoteStringType(((SqlString)value).Value) : MetaNVarChar); // MDAC 87587
                    }
                    else if (dataType == typeof(IEnumerable) || dataType == typeof(DataTable)) {
                        return MetaTable; 
                    } else if (dataType == typeof(TimeSpan)) {
                        return MetaTime; 
                    } 
                    else if (dataType == typeof(DateTimeOffset)) {
                        return MetaDateTimeOffset; 
                    }
                    else {
                        SqlUdtInfo attribs = SqlUdtInfo.TryGetFromType(dataType);
                        if (attribs != null) { 
                            return MetaUdt;
                        } 
                    } 
                    throw ADP.UnknownDataType(dataType);
 
                case TypeCode.DBNull:    throw ADP.InvalidDataType(TypeCode.DBNull);
                case TypeCode.Boolean:   return MetaBit;
                case TypeCode.Char:      throw ADP.InvalidDataType(TypeCode.Char);
                case TypeCode.SByte:     throw ADP.InvalidDataType(TypeCode.SByte); 
                case TypeCode.Byte:      return MetaTinyInt;
                case TypeCode.Int16:     return MetaSmallInt; 
                case TypeCode.UInt16:    throw ADP.InvalidDataType(TypeCode.UInt16); 
                case TypeCode.Int32:     return MetaInt;
                case TypeCode.UInt32:    throw ADP.InvalidDataType(TypeCode.UInt32); 
                case TypeCode.Int64:     return MetaBigInt;
                case TypeCode.UInt64:    throw ADP.InvalidDataType(TypeCode.UInt64);
                case TypeCode.Single:    return MetaReal;
                case TypeCode.Double:    return MetaFloat; 
                case TypeCode.Decimal:   return MetaDecimal;
                case TypeCode.DateTime:  return MetaDateTime; 
                case TypeCode.String:    return (inferLen ? PromoteStringType((string)value) : MetaNVarChar); 
                default:                 throw ADP.UnknownDataTypeCode(dataType, Type.GetTypeCode(dataType));
            } 
        }

        internal static object GetNullSqlValue(Type sqlType) {
            if      (sqlType == typeof(SqlSingle))   return SqlSingle.Null; 
            else if (sqlType == typeof(SqlString))   return SqlString.Null;
            else if (sqlType == typeof(SqlDouble))   return SqlDouble.Null; 
            else if (sqlType == typeof(SqlBinary))   return SqlBinary.Null; 
            else if (sqlType == typeof(SqlGuid))     return SqlGuid.Null;
            else if (sqlType == typeof(SqlBoolean))  return SqlBoolean.Null; 
            else if (sqlType == typeof(SqlByte))     return SqlByte.Null;
            else if (sqlType == typeof(SqlInt16))    return SqlInt16.Null;
            else if (sqlType == typeof(SqlInt32))    return SqlInt32.Null;
            else if (sqlType == typeof(SqlInt64))    return SqlInt64.Null; 
            else if (sqlType == typeof(SqlDecimal))  return SqlDecimal.Null;
            else if (sqlType == typeof(SqlDateTime)) return SqlDateTime.Null; 
            else if (sqlType == typeof(SqlMoney))    return SqlMoney.Null; 
            else if (sqlType == typeof(SqlXml))      return SqlXml.Null;
            else if (sqlType == typeof(object))      return DBNull.Value; 
            else if (sqlType == typeof(IEnumerable))  return DBNull.Value;
            else if (sqlType == typeof(DataTable))   return DBNull.Value;
            else if (sqlType == typeof(DateTime))    return DBNull.Value;
            else if (sqlType == typeof(TimeSpan))    return DBNull.Value; 
            else if (sqlType == typeof(DateTimeOffset))             return DBNull.Value;
            else { 
                Debug.Assert(false, "Unknown SqlType!"); 
                return DBNull.Value;
            } 
        }

        internal static MetaType PromoteStringType(string s) {
            int len = s.Length; 

            if ((len << 1) > TdsEnums.TYPE_SIZE_LIMIT) { 
                return MetaVarChar; // try as var char since we can send a 8K characters 
            }
            return MetaNVarChar; // send 4k chars, but send as unicode 
        }

        internal static object GetComValueFromSqlVariant(object sqlVal) {
            object comVal = null; 

            if (ADP.IsNull(sqlVal)) 
                return comVal; 

            if (sqlVal is SqlSingle) 
                comVal = ((SqlSingle)sqlVal).Value;
            else if (sqlVal is SqlString)
                comVal = ((SqlString)sqlVal).Value;
            else if (sqlVal is SqlDouble) 
                comVal = ((SqlDouble)sqlVal).Value;
            else if (sqlVal is SqlBinary) 
                comVal = ((SqlBinary)sqlVal).Value; 
            else if (sqlVal is SqlGuid)
                comVal = ((SqlGuid)sqlVal).Value; 
            else if (sqlVal is SqlBoolean)
                comVal = ((SqlBoolean)sqlVal).Value;
            else if (sqlVal is SqlByte)
                comVal = ((SqlByte)sqlVal).Value; 
            else if (sqlVal is SqlInt16)
                comVal = ((SqlInt16)sqlVal).Value; 
            else if (sqlVal is SqlInt32) 
                comVal = ((SqlInt32)sqlVal).Value;
            else if (sqlVal is SqlInt64) 
                comVal = ((SqlInt64)sqlVal).Value;
            else if (sqlVal is SqlDecimal)
                comVal = ((SqlDecimal)sqlVal).Value;
            else if (sqlVal is SqlDateTime) 
                comVal = ((SqlDateTime)sqlVal).Value;
            else if (sqlVal is SqlMoney) 
                comVal = ((SqlMoney)sqlVal).Value; 
            else if (sqlVal is SqlXml)
                comVal = ((SqlXml)sqlVal).Value; 
            else
                Debug.Assert(false, "unknown SqlType class stored in sqlVal");

            return comVal; 
        }
 
        // devnote: This method should not be used with SqlDbType.Date and SqlDbType.DateTime2. 
        //          With these types the values should be used directly as CLR types instead of being converted to a SqlValue
        internal static object GetSqlValueFromComVariant(object comVal) { 
            object sqlVal = null;
            if ((null != comVal) && (DBNull.Value != comVal)) {
                if (comVal is float)
                    sqlVal = new SqlSingle((float)comVal); 
                else if (comVal is string)
                    sqlVal = new SqlString((string)comVal); 
                else if (comVal is double) 
                    sqlVal = new SqlDouble((double)comVal);
                else if (comVal is System.Byte[]) 
                    sqlVal = new SqlBinary((byte[])comVal);
                else if (comVal is System.Char)
                    sqlVal = new SqlString(((char)comVal).ToString());
                else if (comVal is System.Char[]) 
                    sqlVal = new SqlChars((System.Char[])comVal);
                else if (comVal is System.Guid) 
                    sqlVal = new SqlGuid((Guid)comVal); 
                else if (comVal is bool)
                    sqlVal = new SqlBoolean((bool)comVal); 
                else if (comVal is byte)
                    sqlVal = new SqlByte((byte)comVal);
                else if (comVal is Int16)
                    sqlVal = new SqlInt16((Int16)comVal); 
                else if (comVal is Int32)
                    sqlVal = new SqlInt32((Int32)comVal); 
                else if (comVal is Int64) 
                    sqlVal = new SqlInt64((Int64)comVal);
                else if (comVal is Decimal) 
                    sqlVal = new SqlDecimal((Decimal)comVal);
                else if (comVal is DateTime) {
                    // devnote: Do not use with SqlDbType.Date and SqlDbType.DateTime2. See comment at top of method.
                    sqlVal = new SqlDateTime((DateTime)comVal); 
                } else if (comVal is XmlReader)
                    sqlVal = new SqlXml((XmlReader)comVal); 
                else if (comVal is TimeSpan || comVal is DateTimeOffset) 
                    sqlVal = comVal;
#if DEBUG 
                else
                    Debug.Assert(false, "unknown SqlType class stored in sqlVal");
#endif
            } 
            return sqlVal;
        } 
 
        internal static SqlDbType GetSqlDbTypeFromOleDbType(short dbType, string typeName) {
            SqlDbType sqlType = SqlDbType.Variant; 
            switch ((OleDbType)dbType) {
                case OleDbType.BigInt:
                    sqlType = SqlDbType.BigInt;
                    break; 
                case OleDbType.Boolean:
                    sqlType = SqlDbType.Bit; 
                    break; 
                case OleDbType.Char:
                case OleDbType.VarChar: 
                    // these guys are ambiguous - server sends over DBTYPE_STR in both cases
                    sqlType = (typeName == MetaTypeName.CHAR) ? SqlDbType.Char : SqlDbType.VarChar;
                    break;
                case OleDbType.Currency: 
                    sqlType = (typeName == MetaTypeName.SMALLMONEY) ? SqlDbType.SmallMoney : SqlDbType.Money;
                    break; 
                case OleDbType.Date: 
                case OleDbType.DBTimeStamp:
                case OleDbType.Filetime: 
                    switch (typeName) {
                       case MetaTypeName.SMALLDATETIME:
                            sqlType = SqlDbType.SmallDateTime;
                            break; 
                        case MetaTypeName.DATETIME2:
                            sqlType = SqlDbType.DateTime2; 
                            break; 
                       default:
                            sqlType = SqlDbType.DateTime; 
                            break;
                    }
                    break;
                case OleDbType.Decimal: 
                case OleDbType.Numeric:
                    sqlType = SqlDbType.Decimal; 
                    break; 
                case OleDbType.Double:
                    sqlType = SqlDbType.Float; 
                    break;
                case OleDbType.Guid:
                    sqlType = SqlDbType.UniqueIdentifier;
                    break; 
                case OleDbType.Integer:
                    sqlType = SqlDbType.Int; 
                    break; 
                case OleDbType.LongVarBinary:
                    sqlType = SqlDbType.Image; 
                    break;
                case OleDbType.LongVarChar:
                    sqlType = SqlDbType.Text;
                    break; 
                case OleDbType.LongVarWChar:
                    sqlType = SqlDbType.NText; 
                    break; 
                case OleDbType.Single:
                    sqlType = SqlDbType.Real; 
                    break;
                case OleDbType.SmallInt:
                case OleDbType.UnsignedSmallInt:
                    sqlType = SqlDbType.SmallInt; 
                    break;
                case OleDbType.TinyInt: 
                case OleDbType.UnsignedTinyInt: 
                    sqlType = SqlDbType.TinyInt;
                    break; 
                case OleDbType.VarBinary:
                case OleDbType.Binary:
                    sqlType = (typeName == MetaTypeName.BINARY) ? SqlDbType.Binary : SqlDbType.VarBinary;
                    break; 
                case OleDbType.Variant:
                    sqlType = SqlDbType.Variant; 
                    break; 
                case OleDbType.VarWChar:
                case OleDbType.WChar: 
                case OleDbType.BSTR:
                    // these guys are ambiguous - server sends over DBTYPE_WSTR in both cases
                    // BSTR is always assumed to be NVARCHAR
                    sqlType = (typeName == MetaTypeName.NCHAR) ? SqlDbType.NChar : SqlDbType.NVarChar; 
                    break;
                case OleDbType.DBDate: // Date 
                    sqlType = SqlDbType.Date; 
                    break;
                case (OleDbType)132: // Udt 
                    sqlType = SqlDbType.Udt;
                    break;
                case (OleDbType)141: // Xml
                    sqlType = SqlDbType.Xml; 
                    break;
                case (OleDbType)145: // Time 
                    sqlType = SqlDbType.Time; 
                    break;
                case (OleDbType)146: // DateTimeOffset 
                    sqlType = SqlDbType.DateTimeOffset;
                    break;
                //
                default: 
                    break; // no direct mapping, just use SqlDbType.Variant;
                } 
 
                return sqlType;
        } 

        internal static MetaType GetSqlDataType(int tdsType, UInt32 userType, int length) {
// the DEBUG section exists only to help verify what is in GetSqlDataType1 is a correct
// update of the now GetSqlDataType2.  Once verified, we can remove the following DEBUG section 
#if DEBUG
            MetaType meta = GetSqlDataType1(tdsType, userType, length); 
            Debug.Assert(meta.SqlDbType == GetSqlDataType2(tdsType, userType, length), "SqlDbType differs"); 
            Debug.Assert(meta == GetMetaTypeFromSqlDbType(meta.SqlDbType, true/**/), "MetaType differs");
            return meta; 
        }

        internal static MetaType GetSqlDataType1(int tdsType, UInt32 userType, int length) {
#endif 
            switch (tdsType) {
            case TdsEnums.SQLMONEYN:            return ((4 == length) ? MetaSmallMoney : MetaMoney); 
            case TdsEnums.SQLDATETIMN:          return ((4 == length) ? MetaSmallDateTime : MetaDateTime); 
            case TdsEnums.SQLINTN:              return ((4 <= length) ? ((4 == length) ? MetaInt : MetaBigInt) : ((2 == length) ? MetaSmallInt : MetaTinyInt));
            case TdsEnums.SQLFLTN:              return ((4 == length) ? MetaReal : MetaFloat); 
            case TdsEnums.SQLTEXT:              return MetaText;
            case TdsEnums.SQLVARBINARY:         return MetaSmallVarBinary;
            case TdsEnums.SQLBIGVARBINARY:      return MetaVarBinary;
 
            case TdsEnums.SQLVARCHAR:           //goto TdsEnums.SQLBIGVARCHAR;
            case TdsEnums.SQLBIGVARCHAR:        return MetaVarChar; 
 
            case TdsEnums.SQLBINARY:            //goto TdsEnums.SQLBIGBINARY;
            case TdsEnums.SQLBIGBINARY:         return ((TdsEnums.SQLTIMESTAMP == userType) ? MetaTimestamp : MetaBinary); 

            case TdsEnums.SQLIMAGE:             return MetaImage;

            case TdsEnums.SQLCHAR:              //goto TdsEnums.SQLBIGCHAR; 
            case TdsEnums.SQLBIGCHAR:           return MetaChar;
 
            case TdsEnums.SQLINT1:              return MetaTinyInt; 

            case TdsEnums.SQLBIT:               //goto TdsEnums.SQLBITN; 
            case TdsEnums.SQLBITN:              return MetaBit;

            case TdsEnums.SQLINT2:              return MetaSmallInt;
            case TdsEnums.SQLINT4:              return MetaInt; 
            case TdsEnums.SQLINT8:              return MetaBigInt;
            case TdsEnums.SQLMONEY:             return MetaMoney; 
            case TdsEnums.SQLDATETIME:          return MetaDateTime; 
            case TdsEnums.SQLFLT8:              return MetaFloat;
            case TdsEnums.SQLFLT4:              return MetaReal; 
            case TdsEnums.SQLMONEY4:            return MetaSmallMoney;
            case TdsEnums.SQLDATETIM4:          return MetaSmallDateTime;

            case TdsEnums.SQLDECIMALN:          //goto TdsEnums.SQLNUMERICN; 
            case TdsEnums.SQLNUMERICN:          return MetaDecimal;
 
            case TdsEnums.SQLUNIQUEID:          return MetaUniqueId ; 
            case TdsEnums.SQLNCHAR:             return MetaNChar;
            case TdsEnums.SQLNVARCHAR:          return MetaNVarChar; 
            case TdsEnums.SQLNTEXT:             return MetaNText;
            case TdsEnums.SQLVARIANT:           return MetaVariant;
            case TdsEnums.SQLUDT:               return MetaUdt;
            case TdsEnums.SQLXMLTYPE:           return MetaXml; 
            case TdsEnums.SQLTABLE:             return MetaTable;
            case TdsEnums.SQLDATE:              return MetaDate; 
            case TdsEnums.SQLTIME:              return MetaTime; 
            case TdsEnums.SQLDATETIME2:         return MetaDateTime2;
            case TdsEnums.SQLDATETIMEOFFSET:    return MetaDateTimeOffset; 

            case TdsEnums.SQLVOID:
            default:
                Debug.Assert(false, "Unknown type " + tdsType.ToString(CultureInfo.InvariantCulture)); 
                throw SQL.InvalidSqlDbType((SqlDbType)tdsType);
            }// case 
        } 
#if DEBUG
        private static SqlDbType GetSqlDataType2(int tdsType, UInt32 userType, int length) { 
           SqlDbType type = SqlDbType.Variant;

            // deal with nullable types
            switch (tdsType) { 
                case TdsEnums.SQLMONEYN:
                    tdsType = (length == 4 ? TdsEnums.SQLMONEY4 : TdsEnums.SQLMONEY); 
                    break; 
                case TdsEnums.SQLDATETIMN:
                    tdsType = (length == 4 ? TdsEnums.SQLDATETIM4 : TdsEnums.SQLDATETIME); 
                    break;
                case TdsEnums.SQLINTN:
                    if (length == 1)
                        tdsType = TdsEnums.SQLINT1; 
                    else
                        if (length == 2) 
                        tdsType = TdsEnums.SQLINT2; 
                    else
                        if (length == 4) 
                        tdsType = TdsEnums.SQLINT4;
                    else {
                        Debug.Assert(8 == length, "invalid length for SQLINTN");
                        tdsType = TdsEnums.SQLINT8; 
                    }
                    break; 
                case TdsEnums.SQLFLTN: 
                    tdsType = (length == 4 ? TdsEnums.SQLFLT4 : TdsEnums.SQLFLT8);
                    break; 
            }

            // since we dealt with var-len types, drop down into realy worker
            switch (tdsType) { 
            case TdsEnums.SQLVOID:
                    Debug.Assert(false, "Unexpected SQLVOID type"); 
                    break; 
                case TdsEnums.SQLTEXT:
                    type = SqlDbType.Text; 
                    break;
                case TdsEnums.SQLVARBINARY:
                    // HACK!!!  We have an internal type for smallvarbinarys stored on TdsEnums.  We
                    // store on TdsEnums instead of SqlDbType because we do not want to expose 
                    // this type to the user!
                    type = TdsEnums.SmallVarBinary; 
                    break; 
                case TdsEnums.SQLBIGVARBINARY:
                    type = SqlDbType.VarBinary; 
                    break;
                case TdsEnums.SQLVARCHAR:
                case TdsEnums.SQLBIGVARCHAR:
                    type = SqlDbType.VarChar; 
                    break;
                case TdsEnums.SQLBINARY: 
                case TdsEnums.SQLBIGBINARY: 
                    if (userType == TdsEnums.SQLTIMESTAMP)
                        type = SqlDbType.Timestamp; 
                    else
                        type = SqlDbType.Binary;
                    break;
                case TdsEnums.SQLIMAGE: 
                    type = SqlDbType.Image;
                    break; 
                case TdsEnums.SQLCHAR: 
                case TdsEnums.SQLBIGCHAR:
                    type = SqlDbType.Char; 
                    break;
                case TdsEnums.SQLINT1:
                    type = SqlDbType.TinyInt;
                    break; 
                case TdsEnums.SQLBIT:
                case TdsEnums.SQLBITN: 
                    type = SqlDbType.Bit; 
                    break;
                case TdsEnums.SQLINT2: 
                    type = SqlDbType.SmallInt;
                    break;
                case TdsEnums.SQLINT4:
                    type = SqlDbType.Int; 
                    break;
                case TdsEnums.SQLINT8: 
                    type = SqlDbType.BigInt; 
                    break;
                case TdsEnums.SQLMONEY: 
                    type = SqlDbType.Money;
                    break;
                case TdsEnums.SQLDATETIME:
                    type = SqlDbType.DateTime; 
                    break;
                case TdsEnums.SQLFLT8: 
                    type = SqlDbType.Float; 
                    break;
                case TdsEnums.SQLFLT4: 
                    type = SqlDbType.Real;
                    break;
                case TdsEnums.SQLMONEY4:
                    type = SqlDbType.SmallMoney; 
                    break;
                case TdsEnums.SQLDATETIM4: 
                    type = SqlDbType.SmallDateTime; 
                    break;
                case TdsEnums.SQLDECIMALN: 
                case TdsEnums.SQLNUMERICN:
                    type = SqlDbType.Decimal;
                    break;
                case TdsEnums.SQLUNIQUEID: 
                    type = SqlDbType.UniqueIdentifier;
                    break; 
                case TdsEnums.SQLNCHAR: 
                    type = SqlDbType.NChar;
                    break; 
                case TdsEnums.SQLNVARCHAR:
                    type = SqlDbType.NVarChar;
                    break;
                case TdsEnums.SQLNTEXT: 
                    type = SqlDbType.NText;
                    break; 
                case TdsEnums.SQLVARIANT: 
                    type = SqlDbType.Variant;
                    break; 
                case TdsEnums.SQLUDT:
                    type = SqlDbType.Udt;
                    break;
                case TdsEnums.SQLXMLTYPE: 
                    type = SqlDbType.Xml;
                    break; 
                case TdsEnums.SQLTABLE: 
                    type = SqlDbType.Structured;
                    break; 
                case TdsEnums.SQLDATE:
                    type = SqlDbType.Date;
                    break;
                case TdsEnums.SQLTIME: 
                    type = SqlDbType.Time;
                    break; 
                case TdsEnums.SQLDATETIME2: 
                    type = SqlDbType.DateTime2;
                    break; 
                case TdsEnums.SQLDATETIMEOFFSET:
                    type = SqlDbType.DateTimeOffset;
                    break;
 
            default:
                Debug.Assert(false, "Unknown type " + tdsType.ToString(CultureInfo.InvariantCulture)); 
                    break; 
            }// case
            return type; 
        } // GetSqlDataType
#endif
        internal static MetaType GetDefaultMetaType() {
            return MetaNVarChar; 
        }
 
        // Converts an XmlReader into String 
        internal static String GetStringFromXml(XmlReader  xmlreader) {
            SqlXml sxml = new SqlXml(xmlreader); 
            return sxml.Value;
        }

        private static readonly MetaType MetaBigInt = new MetaType 
            (19, 255, 8, true, false, false, TdsEnums.SQLINT8, TdsEnums.SQLINTN, MetaTypeName.BIGINT, typeof(System.Int64), typeof(SqlInt64), SqlDbType.BigInt, DbType.Int64, 0);
 
        private static readonly MetaType MetaFloat = new MetaType 
            (15, 255, 8, true, false, false, TdsEnums.SQLFLT8, TdsEnums.SQLFLTN, MetaTypeName.FLOAT, typeof(System.Double), typeof(SqlDouble), SqlDbType.Float, DbType.Double, 0);
 
        private static readonly MetaType MetaReal = new MetaType
            (7, 255, 4, true, false, false, TdsEnums.SQLFLT4, TdsEnums.SQLFLTN, MetaTypeName.REAL, typeof(System.Single), typeof(SqlSingle), SqlDbType.Real, DbType.Single, 0);

        // MetaBinary has two bytes of properties for binary and varbinary 
        // 2 byte maxlen
        private static readonly MetaType MetaBinary = new MetaType 
            (255, 255, -1, false, false, false, TdsEnums.SQLBIGBINARY, TdsEnums.SQLBIGBINARY, MetaTypeName.BINARY, typeof(System.Byte[]), typeof(SqlBinary), SqlDbType.Binary, DbType.Binary, 2); 

        // syntatic sugar for the user...timestamps are 8-byte fixed length binary columns 
        private static readonly MetaType MetaTimestamp = new MetaType
            (255, 255, -1, false, false, false, TdsEnums.SQLBIGBINARY, TdsEnums.SQLBIGBINARY, MetaTypeName.TIMESTAMP, typeof(System.Byte[]), typeof(SqlBinary), SqlDbType.Timestamp, DbType.Binary, 2);

        internal static readonly MetaType MetaVarBinary = new MetaType 
            (255, 255, -1, false, false, false, TdsEnums.SQLBIGVARBINARY, TdsEnums.SQLBIGVARBINARY, MetaTypeName.VARBINARY, typeof(System.Byte[]), typeof(SqlBinary), SqlDbType.VarBinary, DbType.Binary, 2);
 
        internal static readonly MetaType MetaMaxVarBinary = new MetaType 
            (255, 255, -1, false, true, true, TdsEnums.SQLBIGVARBINARY, TdsEnums.SQLBIGVARBINARY, MetaTypeName.VARBINARY, typeof(System.Byte[]), typeof(SqlBinary), SqlDbType.VarBinary, DbType.Binary, 2);
 
        // HACK!!!  We have an internal type for smallvarbinarys stored on TdsEnums.  We
        // store on TdsEnums instead of SqlDbType because we do not want to expose
        // this type to the user!
        private static readonly MetaType MetaSmallVarBinary = new MetaType 
            (255, 255, -1, false, false, false, TdsEnums.SQLVARBINARY, TdsEnums.SQLBIGBINARY, ADP.StrEmpty, typeof(System.Byte[]), typeof(SqlBinary), TdsEnums.SmallVarBinary, DbType.Binary, 2);
 
        internal static readonly MetaType MetaImage = new MetaType 
            (255, 255, -1, false, true, false, TdsEnums.SQLIMAGE, TdsEnums.SQLIMAGE, MetaTypeName.IMAGE, typeof(System.Byte[]), typeof(SqlBinary), SqlDbType.Image, DbType.Binary, 0);
 
        private static readonly MetaType MetaBit = new MetaType
            (255, 255, 1, true, false, false, TdsEnums.SQLBIT, TdsEnums.SQLBITN, MetaTypeName.BIT, typeof(System.Boolean), typeof(SqlBoolean), SqlDbType.Bit, DbType.Boolean, 0);

        private static readonly MetaType MetaTinyInt = new MetaType 
            (3, 255, 1, true, false, false, TdsEnums.SQLINT1, TdsEnums.SQLINTN, MetaTypeName.TINYINT, typeof(System.Byte), typeof(SqlByte), SqlDbType.TinyInt, DbType.Byte, 0);
 
        private static readonly MetaType MetaSmallInt = new MetaType 
            (5, 255, 2, true, false, false, TdsEnums.SQLINT2, TdsEnums.SQLINTN, MetaTypeName.SMALLINT, typeof(System.Int16), typeof(SqlInt16), SqlDbType.SmallInt, DbType.Int16, 0);
 
        private static readonly MetaType MetaInt = new MetaType
            (10, 255, 4, true, false, false, TdsEnums.SQLINT4, TdsEnums.SQLINTN, MetaTypeName.INT, typeof(System.Int32), typeof(SqlInt32), SqlDbType.Int, DbType.Int32, 0);

        // MetaVariant has seven bytes of properties for MetaChar and MetaVarChar 
        // 5 byte tds collation
        // 2 byte maxlen 
        private static readonly MetaType MetaChar = new MetaType 
            (255, 255, -1, false, false, false, TdsEnums.SQLBIGCHAR, TdsEnums.SQLBIGCHAR, MetaTypeName.CHAR, typeof(System.String), typeof(SqlString), SqlDbType.Char, DbType.AnsiStringFixedLength, 7);
 
        private static readonly MetaType MetaVarChar = new MetaType
            (255, 255, -1, false, false, false, TdsEnums.SQLBIGVARCHAR, TdsEnums.SQLBIGVARCHAR, MetaTypeName.VARCHAR, typeof(System.String), typeof(SqlString), SqlDbType.VarChar, DbType.AnsiString, 7);

        internal static readonly MetaType MetaMaxVarChar = new MetaType 
            (255, 255, -1, false, true, true, TdsEnums.SQLBIGVARCHAR, TdsEnums.SQLBIGVARCHAR, MetaTypeName.VARCHAR, typeof(System.String), typeof(SqlString), SqlDbType.VarChar, DbType.AnsiString, 7);
 
        internal static readonly MetaType MetaText = new MetaType 
            (255, 255, -1, false, true, false, TdsEnums.SQLTEXT, TdsEnums.SQLTEXT, MetaTypeName.TEXT, typeof(System.String), typeof(SqlString), SqlDbType.Text, DbType.AnsiString, 0);
 
        // MetaVariant has seven bytes of properties for MetaNChar and MetaNVarChar
        // 5 byte tds collation
        // 2 byte maxlen
        private static readonly MetaType MetaNChar = new MetaType 
            (255, 255, -1, false, false, false, TdsEnums.SQLNCHAR, TdsEnums.SQLNCHAR, MetaTypeName.NCHAR, typeof(System.String), typeof(SqlString), SqlDbType.NChar, DbType.StringFixedLength, 7);
 
        internal static readonly MetaType MetaNVarChar = new MetaType 
            (255, 255, -1, false, false, false, TdsEnums.SQLNVARCHAR, TdsEnums.SQLNVARCHAR, MetaTypeName.NVARCHAR, typeof(System.String), typeof(SqlString), SqlDbType.NVarChar, DbType.String, 7);
 
        internal static readonly MetaType MetaMaxNVarChar = new MetaType
            (255, 255, -1, false, true, true, TdsEnums.SQLNVARCHAR, TdsEnums.SQLNVARCHAR, MetaTypeName.NVARCHAR, typeof(System.String), typeof(SqlString), SqlDbType.NVarChar, DbType.String, 7);

        internal static readonly MetaType MetaNText = new MetaType 
            (255, 255, -1, false, true, false, TdsEnums.SQLNTEXT, TdsEnums.SQLNTEXT, MetaTypeName.NTEXT, typeof(System.String), typeof(SqlString), SqlDbType.NText, DbType.String, 7);
 
        // MetaVariant has two bytes of properties for numeric/decimal types 
        // 1 byte precision
        // 1 byte scale 
        internal static readonly MetaType MetaDecimal = new MetaType
            (38, 4, 17, true, false, false, TdsEnums.SQLNUMERICN, TdsEnums.SQLNUMERICN, MetaTypeName.DECIMAL, typeof(System.Decimal), typeof(SqlDecimal), SqlDbType.Decimal, DbType.Decimal, 2);

        internal static readonly MetaType MetaXml = new MetaType 
            (255, 255, -1, false, true, true, TdsEnums.SQLXMLTYPE, TdsEnums.SQLXMLTYPE, MetaTypeName.XML, typeof(System.String), typeof(SqlXml), SqlDbType.Xml, DbType.Xml, 0);
 
        private static readonly MetaType MetaDateTime = new MetaType 
            (23, 3, 8, true, false, false, TdsEnums.SQLDATETIME, TdsEnums.SQLDATETIMN, MetaTypeName.DATETIME, typeof(System.DateTime), typeof(SqlDateTime), SqlDbType.DateTime, DbType.DateTime, 0);
 
        private static readonly MetaType MetaSmallDateTime = new MetaType
            (16, 0, 4, true, false, false, TdsEnums.SQLDATETIM4, TdsEnums.SQLDATETIMN, MetaTypeName.SMALLDATETIME, typeof(System.DateTime), typeof(SqlDateTime), SqlDbType.SmallDateTime, DbType.DateTime, 0);

        private static readonly MetaType MetaMoney = new MetaType 
            (19, 255, 8, true, false, false, TdsEnums.SQLMONEY, TdsEnums.SQLMONEYN, MetaTypeName.MONEY, typeof(System.Decimal), typeof(SqlMoney), SqlDbType.Money, DbType.Currency, 0);
 
        private static readonly MetaType MetaSmallMoney = new MetaType 
            (10, 255, 4, true, false, false, TdsEnums.SQLMONEY4, TdsEnums.SQLMONEYN, MetaTypeName.SMALLMONEY, typeof(System.Decimal), typeof(SqlMoney), SqlDbType.SmallMoney, DbType.Currency, 0);
 
        private static readonly MetaType MetaUniqueId = new MetaType
            (255, 255, 16, true, false, false, TdsEnums.SQLUNIQUEID, TdsEnums.SQLUNIQUEID, MetaTypeName.ROWGUID, typeof(System.Guid), typeof(SqlGuid), SqlDbType.UniqueIdentifier, DbType.Guid, 0);

        private static readonly MetaType MetaVariant = new MetaType 
            (255, 255, -1, true, false, false, TdsEnums.SQLVARIANT, TdsEnums.SQLVARIANT, MetaTypeName.VARIANT, typeof(System.Object), typeof(System.Object), SqlDbType.Variant, DbType.Object, 0);
 
        internal static readonly MetaType MetaUdt = new MetaType 
            (255, 255, -1, false, false, true, TdsEnums.SQLUDT, TdsEnums.SQLUDT, MetaTypeName.UDT, typeof(System.Object), typeof(System.Object), SqlDbType.Udt, DbType.Object, 0);
 
        private static readonly MetaType MetaMaxUdt = new MetaType
            (255, 255, -1, false, true, true, TdsEnums.SQLUDT, TdsEnums.SQLUDT, MetaTypeName.UDT, typeof(System.Object), typeof(System.Object), SqlDbType.Udt, DbType.Object, 0);

        private static readonly MetaType MetaTable = new MetaType 
            (255, 255, -1, false, false, false, TdsEnums.SQLTABLE, TdsEnums.SQLTABLE, MetaTypeName.TABLE, typeof(IEnumerable), typeof(IEnumerable), SqlDbType.Structured, DbType.Object, 0);
 
        // 

        private static readonly MetaType MetaSUDT = new MetaType 
            (255, 255, -1, false, false, false, TdsEnums.SQLVOID, TdsEnums.SQLVOID, "", typeof(MSS.SqlDataRecord), typeof(MSS.SqlDataRecord), SqlDbType.Structured, DbType.Object, 0);

        private static readonly MetaType MetaDate = new MetaType
            (255, 255, 3, true, false, false, TdsEnums.SQLDATE, TdsEnums.SQLDATE, MetaTypeName.DATE, typeof(System.DateTime), typeof(System.DateTime), SqlDbType.Date, DbType.Date, 0); 

        internal static readonly MetaType MetaTime = new MetaType 
            (255, 7, -1, false, false, false, TdsEnums.SQLTIME, TdsEnums.SQLTIME, MetaTypeName.TIME, typeof(System.TimeSpan), typeof(System.TimeSpan), SqlDbType.Time, DbType.Time, 1); 

        private static readonly MetaType MetaDateTime2 = new MetaType 
            (255, 7, -1, false, false, false, TdsEnums.SQLDATETIME2, TdsEnums.SQLDATETIME2, MetaTypeName.DATETIME2, typeof(System.DateTime), typeof(System.DateTime), SqlDbType.DateTime2, DbType.DateTime2, 1);

        internal static readonly MetaType MetaDateTimeOffset = new MetaType
            (255, 7, -1, false, false, false, TdsEnums.SQLDATETIMEOFFSET, TdsEnums.SQLDATETIMEOFFSET, MetaTypeName.DATETIMEOFFSET, typeof(System.DateTimeOffset), typeof(System.DateTimeOffset), SqlDbType.DateTimeOffset, DbType.DateTimeOffset, 1); 

        public static TdsDateTime FromDateTime(DateTime dateTime, byte cb) { 
            SqlDateTime sqlDateTime; 
            TdsDateTime tdsDateTime = new TdsDateTime();
 
            Debug.Assert(cb == 8 || cb == 4, "Invalid date time size!");

            if (cb == 8) {
                sqlDateTime = new SqlDateTime(dateTime); 
                tdsDateTime.time = sqlDateTime.TimeTicks;
            } 
            else { 
                // note that smalldatetime is days&minutes.
                // Adding 30 seconds ensures proper roundup if the seconds are >= 30 
                // The AddSeconds function handles eventual carryover
                sqlDateTime = new SqlDateTime(dateTime.AddSeconds(30));
                tdsDateTime.time = sqlDateTime.TimeTicks / SqlDateTime.SQLTicksPerMinute;
            } 
            tdsDateTime.days = sqlDateTime.DayTicks;
            return tdsDateTime; 
        } 

 
        public static DateTime ToDateTime(int sqlDays, int sqlTime, int length) {
            if (length == 4) {
                return new SqlDateTime(sqlDays, sqlTime * SqlDateTime.SQLTicksPerMinute).Value;
            } 
            else {
                Debug.Assert(length == 8, "invalid length for DateTime"); 
                return new SqlDateTime(sqlDays, sqlTime).Value; 
            }
        } 

        internal static int GetTimeSizeFromScale(byte scale)
        {
            Debug.Assert(0 <= scale && scale <= 7); 

            if (scale <= 2) 
                return 3; 

            if (scale <= 4) 
                return 4;

            return 5;
        } 

        // 
        // please leave string sorted alphabetically 
        // note that these names should only be used in the context of parameters.  We always send over BIG* and nullable types for SQL Server
        // 
        private static class MetaTypeName {
            public const string BIGINT         = "bigint";
            public const string BINARY         = "binary";
            public const string BIT            = "bit"; 
            public const string CHAR           = "char";
            public const string DATETIME       = "datetime"; 
            public const string DECIMAL        = "decimal"; 
            public const string FLOAT          = "float";
            public const string IMAGE          = "image"; 
            public const string INT            = "int";
            public const string MONEY          = "money";
            public const string NCHAR          = "nchar";
            public const string NTEXT          = "ntext"; 
            public const string NVARCHAR       = "nvarchar";
            public const string REAL           = "real"; 
            public const string ROWGUID        = "uniqueidentifier"; 
            public const string SMALLDATETIME  = "smalldatetime";
            public const string SMALLINT       = "smallint"; 
            public const string SMALLMONEY     = "smallmoney";
            public const string TEXT           = "text";
            public const string TIMESTAMP      = "timestamp";
            public const string TINYINT        = "tinyint"; 
            public const string UDT            = "udt";
            public const string VARBINARY      = "varbinary"; 
            public const string VARCHAR        = "varchar"; 
            public const string VARIANT        = "sql_variant";
            public const string XML            = "xml"; 
            public const string TABLE          = "table";
            public const string DATE           = "date";
            public const string TIME           = "time";
            public const string DATETIME2      = "datetime2"; 
            public const string DATETIMEOFFSET = "datetimeoffset";
        } 
    } 

    // 
    // note: it is the client's responsibility to know what size date time he is working with
    //
    internal struct TdsDateTime {
        public int days;  // offset in days from 1/1/1900 
        //     private UInt32 time;  // if smalldatetime, this is # of minutes since midnight
        // otherwise: # of 1/300th of a second since midnight 
        public int time; // 
    }
 
}


// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
// [....]
//----------------------------------------------------------------------------- 
 
namespace System.Data.SqlClient {
 

    using System;
    using System.Collections.Generic;
    using System.ComponentModel; 
    using System.Data.Common;
    using System.Data.OleDb; 
    using System.Data.SqlTypes; 
    using System.Diagnostics;
    using System.Globalization; 
    using System.Xml;
    using System.IO;
    using System.Data.Sql;
 
    using MSS=Microsoft.SqlServer.Server;
 
    internal sealed class MetaType { 
        internal readonly Type      ClassType;   // com+ type
        internal readonly Type      SqlType; 

        internal readonly int       FixedLength; // fixed length size in bytes (-1 for variable)
        internal readonly bool      IsFixed;     // true if fixed length, note that sqlchar and sqlbinary are not considered fixed length
        internal readonly bool      IsLong;      // true if long 
        internal readonly bool      IsPlp;       // Column is Partially Length Prefixed (MAX)
        internal readonly byte      Precision;   // maxium precision for numeric types // $ 
        internal readonly byte      Scale; 
        internal readonly byte      TDSType;
        internal readonly byte      NullableType; 

        internal readonly string    TypeName;    // string name of this type
        internal readonly SqlDbType SqlDbType;
        internal readonly DbType    DbType; 

        //  holds count of property bytes expected for a SQLVariant structure 
        internal readonly byte PropBytes; 

 
        // pre-computed fields
        internal readonly bool IsAnsiType;
        internal readonly bool IsBinType;
        internal readonly bool IsCharType; 
        internal readonly bool IsNCharType;
        internal readonly bool IsSizeInCharacters; 
 
        internal readonly bool Is70Supported;
        internal readonly bool Is80Supported; 
        internal readonly bool Is90Supported;
        internal readonly bool Is100Supported;

        public MetaType(byte precision, byte scale, int fixedLength, bool isFixed, bool isLong, bool isPlp, byte tdsType, byte nullableTdsType, string typeName, Type classType, Type sqlType, SqlDbType sqldbType, DbType dbType, byte propBytes) { 
            this.Precision    = precision;
            this.Scale        = scale; 
            this.FixedLength  = fixedLength; 
            this.IsFixed      = isFixed;
            this.IsLong       = isLong; 
            this.IsPlp        = isPlp;
            // can we get rid of this (?just have a mapping?)
            this.TDSType      = tdsType;
            this.NullableType = nullableTdsType; 
            this.TypeName     = typeName;
            this.SqlDbType    = sqldbType; 
            this.DbType       = dbType; 

            this.ClassType    = classType; 
            this.SqlType      = sqlType;
            this.PropBytes    = propBytes;

            IsAnsiType  = _IsAnsiType(sqldbType); 
            IsBinType   = _IsBinType(sqldbType);
            IsCharType  = _IsCharType(sqldbType); 
            IsNCharType = _IsNCharType(sqldbType); 
            IsSizeInCharacters = _IsSizeInCharacters(SqlDbType);
 
            Is70Supported = _Is70Supported(SqlDbType);
            Is80Supported = _Is80Supported(SqlDbType);
            Is90Supported = _Is90Supported(SqlDbType);
            Is100Supported = _Is100Supported(SqlDbType); 
        }
 
        // properties should be inlined so there should be no perf penalty for using these accessor functions 
        public int TypeId {             // partial length prefixed (xml, nvarchar(max),...)
            get { return 0;} 
        }

        private static bool _IsAnsiType(SqlDbType type) {
            return(type == SqlDbType.Char || 
                   type == SqlDbType.VarChar ||
                   type == SqlDbType.Text); 
        } 

        // is this type size expressed as count of characters or bytes? 
        private static bool _IsSizeInCharacters(SqlDbType type) {
            return(type == SqlDbType.NChar ||
                   type == SqlDbType.NVarChar ||
                   type == SqlDbType.Xml || 
                   type == SqlDbType.NText);
        } 
 
        private static bool _IsCharType(SqlDbType type) {
            return(type == SqlDbType.NChar || 
                   type == SqlDbType.NVarChar ||
                   type == SqlDbType.NText ||
                   type == SqlDbType.Char ||
                   type == SqlDbType.VarChar || 
                   type == SqlDbType.Text ||
                   type == SqlDbType.Xml); 
        } 

        private static bool _IsNCharType(SqlDbType type) { 
            return(type == SqlDbType.NChar ||
                   type == SqlDbType.NVarChar ||
                   type == SqlDbType.NText ||
                   type == SqlDbType.Xml); 
        }
 
        private static bool _IsBinType(SqlDbType type) { 
            return(type == SqlDbType.Image ||
                   type == SqlDbType.Binary || 
                   type == SqlDbType.VarBinary ||
                   type == SqlDbType.Timestamp ||
                   type == SqlDbType.Udt ||
                   (int) type == 24 /*SqlSmallVarBinary*/); 
        }
 
        private static bool _Is70Supported(SqlDbType type) { 
            return((type != SqlDbType.BigInt) && ((int)type > 0) &&
                   ((int)type <= (int) SqlDbType.VarChar)); 
        }

        private static bool _Is80Supported(SqlDbType type) {
            return((int)type >= 0 && 
                ((int)type <= (int) SqlDbType.Variant));
        } 
 
        private static bool _Is90Supported(SqlDbType type) {
            return _Is80Supported(type) || 
                    SqlDbType.Xml == type ||
                    SqlDbType.Udt == type;
        }
 
        private static bool _Is100Supported(SqlDbType type) {
            return _Is90Supported(type) || 
                    SqlDbType.Date == type || 
                    SqlDbType.Time == type ||
                    SqlDbType.DateTime2 == type || 
                    SqlDbType.DateTimeOffset == type;
        }

/*        private static bool _Is10Supported(SqlDbType type) { 
            return _Is90Supported(type) ||
                _IsNewKatmaiType(type); 
        } 
*/
        private static bool _IsNewKatmaiType(SqlDbType type) { 
            return SqlDbType.Structured == type;
        }

        internal bool IsNewKatmaiType { 
            get {
                return _IsNewKatmaiType(this.SqlDbType); 
            } 
        }
 
        internal static bool _IsVarTime(SqlDbType type) {
            return (type == SqlDbType.Time || type == SqlDbType.DateTime2 || type == SqlDbType.DateTimeOffset);
        }
 
        internal bool IsVarTime {
            get { 
                return _IsVarTime(this.SqlDbType); 
            }
        } 

        //
        // map SqlDbType to MetaType class
        // 
        internal static MetaType GetMetaTypeFromSqlDbType(SqlDbType target, bool isMultiValued) { // WebData 113289
            switch(target) { 
            case SqlDbType.BigInt:            return MetaBigInt; 
            case SqlDbType.Binary:            return MetaBinary;
            case SqlDbType.Bit:               return MetaBit; 
            case SqlDbType.Char:              return MetaChar;
            case SqlDbType.DateTime:          return MetaDateTime;
            case SqlDbType.Decimal:           return MetaDecimal;
            case SqlDbType.Float:             return MetaFloat; 
            case SqlDbType.Image:             return MetaImage;
            case SqlDbType.Int:               return MetaInt; 
            case SqlDbType.Money:             return MetaMoney; 
            case SqlDbType.NChar:             return MetaNChar;
            case SqlDbType.NText:             return MetaNText; 
            case SqlDbType.NVarChar:          return MetaNVarChar;
            case SqlDbType.Real:              return MetaReal;
            case SqlDbType.UniqueIdentifier:  return MetaUniqueId;
            case SqlDbType.SmallDateTime:     return MetaSmallDateTime; 
            case SqlDbType.SmallInt:          return MetaSmallInt;
            case SqlDbType.SmallMoney:        return MetaSmallMoney; 
            case SqlDbType.Text:              return MetaText; 
            case SqlDbType.Timestamp:         return MetaTimestamp;
            case SqlDbType.TinyInt:           return MetaTinyInt; 
            case SqlDbType.VarBinary:         return MetaVarBinary;
            case SqlDbType.VarChar:           return MetaVarChar;
            case SqlDbType.Variant:           return MetaVariant;
            case (SqlDbType)TdsEnums.SmallVarBinary: return MetaSmallVarBinary; 
            case SqlDbType.Xml:               return MetaXml;
            case SqlDbType.Udt:               return MetaUdt; 
            case SqlDbType.Structured: 
                if (isMultiValued) {
                    return MetaTable; 
                }
                else {
                    return MetaSUDT;
                } 
            case SqlDbType.Date:              return MetaDate;
            case SqlDbType.Time:              return MetaTime; 
            case SqlDbType.DateTime2:         return MetaDateTime2; 
            case SqlDbType.DateTimeOffset:    return MetaDateTimeOffset;
            default:                          throw SQL.InvalidSqlDbType(target); 
            }
        }

        // 
        // map DbType to MetaType class
        // 
        internal static MetaType GetMetaTypeFromDbType(DbType target) { 
            // if we can't map it, we need to throw
            switch (target) { 
            case DbType.AnsiString:             return MetaVarChar;
            case DbType.AnsiStringFixedLength:  return MetaChar;
            case DbType.Binary:                 return MetaVarBinary;
            case DbType.Byte:                   return MetaTinyInt; 
            case DbType.Boolean:                return MetaBit;
            case DbType.Currency:               return MetaMoney; 
            case DbType.Date: 
            case DbType.DateTime:               return MetaDateTime;
            case DbType.Decimal:                return MetaDecimal; 
            case DbType.Double:                 return MetaFloat;
            case DbType.Guid:                   return MetaUniqueId;
            case DbType.Int16:                  return MetaSmallInt;
            case DbType.Int32:                  return MetaInt; 
            case DbType.Int64:                  return MetaBigInt;
            case DbType.Object:                 return MetaVariant; 
            case DbType.Single:                 return MetaReal; 
            case DbType.String:                 return MetaNVarChar;
            case DbType.StringFixedLength:      return MetaNChar; 
            case DbType.Time:                   return MetaDateTime;
            case DbType.Xml:                    return MetaXml;
            case DbType.DateTime2:              return MetaDateTime2;
            case DbType.DateTimeOffset:         return MetaDateTimeOffset; 
            case DbType.SByte:                  // unsupported
            case DbType.UInt16: 
            case DbType.UInt32: 
            case DbType.UInt64:
            case DbType.VarNumeric: 
            default:                            throw ADP.DbTypeNotSupported(target, typeof(SqlDbType)); // no direct mapping, error out
            }
        }
 
        internal static MetaType GetMaxMetaTypeFromMetaType(MetaType mt) {
            // if we can't map it, we need to throw 
            switch (mt.SqlDbType) { 
            case SqlDbType.VarBinary:
            case SqlDbType.Binary: 
                return MetaMaxVarBinary;
            case SqlDbType.VarChar:
            case SqlDbType.Char:
                return MetaMaxVarChar; 
            case SqlDbType.NVarChar:
            case SqlDbType.NChar: 
                return MetaMaxNVarChar; 
            case SqlDbType.Udt:
                // 
                return MetaMaxUdt;
            default:
                return mt;
           } 
        }
 
#if WINFSFunctionality 
        internal static MetaType GetUdtMetaType(bool isLarge) {
            // if we can't map it, we need to throw 
            if (isLarge) {
                return MetaMaxUdt;
            }
            else { 
                return MetaUdt;
            } 
        } 
#endif
 
        //
        // map COM+ Type to MetaType class
        //
        static internal MetaType GetMetaTypeFromType(Type dataType) { 
            return GetMetaTypeFromValue(dataType, null, false);
        } 
        static internal MetaType GetMetaTypeFromValue(object value) { 
            return GetMetaTypeFromValue(value.GetType(), value, true);
        } 

        static private MetaType GetMetaTypeFromValue(Type dataType, object value, bool inferLen) {
            switch (Type.GetTypeCode(dataType)) {
                case TypeCode.Empty:     throw ADP.InvalidDataType(TypeCode.Empty); 
                case TypeCode.Object:
                    if (dataType == typeof(System.Byte[])) { 
                        // mdac 90455 must not default to image if inferLen is false ... 
                        //
                        if (!inferLen || ((byte[]) value).Length <= TdsEnums.TYPE_SIZE_LIMIT) { 
                            return MetaVarBinary;
                        }
                        else {
                            return MetaImage; 
                        }
                    } 
                    else if (dataType == typeof(System.Guid)) { 
                        return MetaUniqueId;
                    } 
                    else if (dataType == typeof(System.Object)) {
                        return MetaVariant;
                    } // check sql types now
                    else if (dataType == typeof(SqlBinary)) 
                        return MetaVarBinary;
                    else if (dataType == typeof(SqlBoolean)) 
                        return MetaBit; 
                    else if (dataType == typeof(SqlByte))
                        return MetaTinyInt; 
                    else if (dataType == typeof(SqlBytes))
                        return MetaVarBinary;
                    else if (dataType == typeof(SqlChars))
                        return  MetaNVarChar; // MDAC 87587 
                    else if (dataType == typeof(SqlDateTime))
                        return MetaDateTime; 
                    else if (dataType == typeof(SqlDouble)) 
                        return MetaFloat;
                    else if (dataType == typeof(SqlGuid)) 
                        return MetaUniqueId;
                    else if (dataType == typeof(SqlInt16))
                        return MetaSmallInt;
                    else if (dataType == typeof(SqlInt32)) 
                        return MetaInt;
                    else if (dataType == typeof(SqlInt64)) 
                        return MetaBigInt; 
                    else if (dataType == typeof(SqlMoney))
                        return MetaMoney; 
                    else if (dataType == typeof(SqlDecimal))
                        return MetaDecimal;
                    else if (dataType == typeof(SqlSingle))
                        return MetaReal; 
                    else if (dataType == typeof(SqlXml))
                        return MetaXml; 
                    else if (dataType == typeof(System.Xml.XmlReader)) 
                        return MetaXml;
                    else if (dataType == typeof(SqlString)) { 
                        return ((inferLen && !((SqlString)value).IsNull) ? PromoteStringType(((SqlString)value).Value) : MetaNVarChar); // MDAC 87587
                    }
                    else if (dataType == typeof(IEnumerable) || dataType == typeof(DataTable)) {
                        return MetaTable; 
                    } else if (dataType == typeof(TimeSpan)) {
                        return MetaTime; 
                    } 
                    else if (dataType == typeof(DateTimeOffset)) {
                        return MetaDateTimeOffset; 
                    }
                    else {
                        SqlUdtInfo attribs = SqlUdtInfo.TryGetFromType(dataType);
                        if (attribs != null) { 
                            return MetaUdt;
                        } 
                    } 
                    throw ADP.UnknownDataType(dataType);
 
                case TypeCode.DBNull:    throw ADP.InvalidDataType(TypeCode.DBNull);
                case TypeCode.Boolean:   return MetaBit;
                case TypeCode.Char:      throw ADP.InvalidDataType(TypeCode.Char);
                case TypeCode.SByte:     throw ADP.InvalidDataType(TypeCode.SByte); 
                case TypeCode.Byte:      return MetaTinyInt;
                case TypeCode.Int16:     return MetaSmallInt; 
                case TypeCode.UInt16:    throw ADP.InvalidDataType(TypeCode.UInt16); 
                case TypeCode.Int32:     return MetaInt;
                case TypeCode.UInt32:    throw ADP.InvalidDataType(TypeCode.UInt32); 
                case TypeCode.Int64:     return MetaBigInt;
                case TypeCode.UInt64:    throw ADP.InvalidDataType(TypeCode.UInt64);
                case TypeCode.Single:    return MetaReal;
                case TypeCode.Double:    return MetaFloat; 
                case TypeCode.Decimal:   return MetaDecimal;
                case TypeCode.DateTime:  return MetaDateTime; 
                case TypeCode.String:    return (inferLen ? PromoteStringType((string)value) : MetaNVarChar); 
                default:                 throw ADP.UnknownDataTypeCode(dataType, Type.GetTypeCode(dataType));
            } 
        }

        internal static object GetNullSqlValue(Type sqlType) {
            if      (sqlType == typeof(SqlSingle))   return SqlSingle.Null; 
            else if (sqlType == typeof(SqlString))   return SqlString.Null;
            else if (sqlType == typeof(SqlDouble))   return SqlDouble.Null; 
            else if (sqlType == typeof(SqlBinary))   return SqlBinary.Null; 
            else if (sqlType == typeof(SqlGuid))     return SqlGuid.Null;
            else if (sqlType == typeof(SqlBoolean))  return SqlBoolean.Null; 
            else if (sqlType == typeof(SqlByte))     return SqlByte.Null;
            else if (sqlType == typeof(SqlInt16))    return SqlInt16.Null;
            else if (sqlType == typeof(SqlInt32))    return SqlInt32.Null;
            else if (sqlType == typeof(SqlInt64))    return SqlInt64.Null; 
            else if (sqlType == typeof(SqlDecimal))  return SqlDecimal.Null;
            else if (sqlType == typeof(SqlDateTime)) return SqlDateTime.Null; 
            else if (sqlType == typeof(SqlMoney))    return SqlMoney.Null; 
            else if (sqlType == typeof(SqlXml))      return SqlXml.Null;
            else if (sqlType == typeof(object))      return DBNull.Value; 
            else if (sqlType == typeof(IEnumerable))  return DBNull.Value;
            else if (sqlType == typeof(DataTable))   return DBNull.Value;
            else if (sqlType == typeof(DateTime))    return DBNull.Value;
            else if (sqlType == typeof(TimeSpan))    return DBNull.Value; 
            else if (sqlType == typeof(DateTimeOffset))             return DBNull.Value;
            else { 
                Debug.Assert(false, "Unknown SqlType!"); 
                return DBNull.Value;
            } 
        }

        internal static MetaType PromoteStringType(string s) {
            int len = s.Length; 

            if ((len << 1) > TdsEnums.TYPE_SIZE_LIMIT) { 
                return MetaVarChar; // try as var char since we can send a 8K characters 
            }
            return MetaNVarChar; // send 4k chars, but send as unicode 
        }

        internal static object GetComValueFromSqlVariant(object sqlVal) {
            object comVal = null; 

            if (ADP.IsNull(sqlVal)) 
                return comVal; 

            if (sqlVal is SqlSingle) 
                comVal = ((SqlSingle)sqlVal).Value;
            else if (sqlVal is SqlString)
                comVal = ((SqlString)sqlVal).Value;
            else if (sqlVal is SqlDouble) 
                comVal = ((SqlDouble)sqlVal).Value;
            else if (sqlVal is SqlBinary) 
                comVal = ((SqlBinary)sqlVal).Value; 
            else if (sqlVal is SqlGuid)
                comVal = ((SqlGuid)sqlVal).Value; 
            else if (sqlVal is SqlBoolean)
                comVal = ((SqlBoolean)sqlVal).Value;
            else if (sqlVal is SqlByte)
                comVal = ((SqlByte)sqlVal).Value; 
            else if (sqlVal is SqlInt16)
                comVal = ((SqlInt16)sqlVal).Value; 
            else if (sqlVal is SqlInt32) 
                comVal = ((SqlInt32)sqlVal).Value;
            else if (sqlVal is SqlInt64) 
                comVal = ((SqlInt64)sqlVal).Value;
            else if (sqlVal is SqlDecimal)
                comVal = ((SqlDecimal)sqlVal).Value;
            else if (sqlVal is SqlDateTime) 
                comVal = ((SqlDateTime)sqlVal).Value;
            else if (sqlVal is SqlMoney) 
                comVal = ((SqlMoney)sqlVal).Value; 
            else if (sqlVal is SqlXml)
                comVal = ((SqlXml)sqlVal).Value; 
            else
                Debug.Assert(false, "unknown SqlType class stored in sqlVal");

            return comVal; 
        }
 
        // devnote: This method should not be used with SqlDbType.Date and SqlDbType.DateTime2. 
        //          With these types the values should be used directly as CLR types instead of being converted to a SqlValue
        internal static object GetSqlValueFromComVariant(object comVal) { 
            object sqlVal = null;
            if ((null != comVal) && (DBNull.Value != comVal)) {
                if (comVal is float)
                    sqlVal = new SqlSingle((float)comVal); 
                else if (comVal is string)
                    sqlVal = new SqlString((string)comVal); 
                else if (comVal is double) 
                    sqlVal = new SqlDouble((double)comVal);
                else if (comVal is System.Byte[]) 
                    sqlVal = new SqlBinary((byte[])comVal);
                else if (comVal is System.Char)
                    sqlVal = new SqlString(((char)comVal).ToString());
                else if (comVal is System.Char[]) 
                    sqlVal = new SqlChars((System.Char[])comVal);
                else if (comVal is System.Guid) 
                    sqlVal = new SqlGuid((Guid)comVal); 
                else if (comVal is bool)
                    sqlVal = new SqlBoolean((bool)comVal); 
                else if (comVal is byte)
                    sqlVal = new SqlByte((byte)comVal);
                else if (comVal is Int16)
                    sqlVal = new SqlInt16((Int16)comVal); 
                else if (comVal is Int32)
                    sqlVal = new SqlInt32((Int32)comVal); 
                else if (comVal is Int64) 
                    sqlVal = new SqlInt64((Int64)comVal);
                else if (comVal is Decimal) 
                    sqlVal = new SqlDecimal((Decimal)comVal);
                else if (comVal is DateTime) {
                    // devnote: Do not use with SqlDbType.Date and SqlDbType.DateTime2. See comment at top of method.
                    sqlVal = new SqlDateTime((DateTime)comVal); 
                } else if (comVal is XmlReader)
                    sqlVal = new SqlXml((XmlReader)comVal); 
                else if (comVal is TimeSpan || comVal is DateTimeOffset) 
                    sqlVal = comVal;
#if DEBUG 
                else
                    Debug.Assert(false, "unknown SqlType class stored in sqlVal");
#endif
            } 
            return sqlVal;
        } 
 
        internal static SqlDbType GetSqlDbTypeFromOleDbType(short dbType, string typeName) {
            SqlDbType sqlType = SqlDbType.Variant; 
            switch ((OleDbType)dbType) {
                case OleDbType.BigInt:
                    sqlType = SqlDbType.BigInt;
                    break; 
                case OleDbType.Boolean:
                    sqlType = SqlDbType.Bit; 
                    break; 
                case OleDbType.Char:
                case OleDbType.VarChar: 
                    // these guys are ambiguous - server sends over DBTYPE_STR in both cases
                    sqlType = (typeName == MetaTypeName.CHAR) ? SqlDbType.Char : SqlDbType.VarChar;
                    break;
                case OleDbType.Currency: 
                    sqlType = (typeName == MetaTypeName.SMALLMONEY) ? SqlDbType.SmallMoney : SqlDbType.Money;
                    break; 
                case OleDbType.Date: 
                case OleDbType.DBTimeStamp:
                case OleDbType.Filetime: 
                    switch (typeName) {
                       case MetaTypeName.SMALLDATETIME:
                            sqlType = SqlDbType.SmallDateTime;
                            break; 
                        case MetaTypeName.DATETIME2:
                            sqlType = SqlDbType.DateTime2; 
                            break; 
                       default:
                            sqlType = SqlDbType.DateTime; 
                            break;
                    }
                    break;
                case OleDbType.Decimal: 
                case OleDbType.Numeric:
                    sqlType = SqlDbType.Decimal; 
                    break; 
                case OleDbType.Double:
                    sqlType = SqlDbType.Float; 
                    break;
                case OleDbType.Guid:
                    sqlType = SqlDbType.UniqueIdentifier;
                    break; 
                case OleDbType.Integer:
                    sqlType = SqlDbType.Int; 
                    break; 
                case OleDbType.LongVarBinary:
                    sqlType = SqlDbType.Image; 
                    break;
                case OleDbType.LongVarChar:
                    sqlType = SqlDbType.Text;
                    break; 
                case OleDbType.LongVarWChar:
                    sqlType = SqlDbType.NText; 
                    break; 
                case OleDbType.Single:
                    sqlType = SqlDbType.Real; 
                    break;
                case OleDbType.SmallInt:
                case OleDbType.UnsignedSmallInt:
                    sqlType = SqlDbType.SmallInt; 
                    break;
                case OleDbType.TinyInt: 
                case OleDbType.UnsignedTinyInt: 
                    sqlType = SqlDbType.TinyInt;
                    break; 
                case OleDbType.VarBinary:
                case OleDbType.Binary:
                    sqlType = (typeName == MetaTypeName.BINARY) ? SqlDbType.Binary : SqlDbType.VarBinary;
                    break; 
                case OleDbType.Variant:
                    sqlType = SqlDbType.Variant; 
                    break; 
                case OleDbType.VarWChar:
                case OleDbType.WChar: 
                case OleDbType.BSTR:
                    // these guys are ambiguous - server sends over DBTYPE_WSTR in both cases
                    // BSTR is always assumed to be NVARCHAR
                    sqlType = (typeName == MetaTypeName.NCHAR) ? SqlDbType.NChar : SqlDbType.NVarChar; 
                    break;
                case OleDbType.DBDate: // Date 
                    sqlType = SqlDbType.Date; 
                    break;
                case (OleDbType)132: // Udt 
                    sqlType = SqlDbType.Udt;
                    break;
                case (OleDbType)141: // Xml
                    sqlType = SqlDbType.Xml; 
                    break;
                case (OleDbType)145: // Time 
                    sqlType = SqlDbType.Time; 
                    break;
                case (OleDbType)146: // DateTimeOffset 
                    sqlType = SqlDbType.DateTimeOffset;
                    break;
                //
                default: 
                    break; // no direct mapping, just use SqlDbType.Variant;
                } 
 
                return sqlType;
        } 

        internal static MetaType GetSqlDataType(int tdsType, UInt32 userType, int length) {
// the DEBUG section exists only to help verify what is in GetSqlDataType1 is a correct
// update of the now GetSqlDataType2.  Once verified, we can remove the following DEBUG section 
#if DEBUG
            MetaType meta = GetSqlDataType1(tdsType, userType, length); 
            Debug.Assert(meta.SqlDbType == GetSqlDataType2(tdsType, userType, length), "SqlDbType differs"); 
            Debug.Assert(meta == GetMetaTypeFromSqlDbType(meta.SqlDbType, true/**/), "MetaType differs");
            return meta; 
        }

        internal static MetaType GetSqlDataType1(int tdsType, UInt32 userType, int length) {
#endif 
            switch (tdsType) {
            case TdsEnums.SQLMONEYN:            return ((4 == length) ? MetaSmallMoney : MetaMoney); 
            case TdsEnums.SQLDATETIMN:          return ((4 == length) ? MetaSmallDateTime : MetaDateTime); 
            case TdsEnums.SQLINTN:              return ((4 <= length) ? ((4 == length) ? MetaInt : MetaBigInt) : ((2 == length) ? MetaSmallInt : MetaTinyInt));
            case TdsEnums.SQLFLTN:              return ((4 == length) ? MetaReal : MetaFloat); 
            case TdsEnums.SQLTEXT:              return MetaText;
            case TdsEnums.SQLVARBINARY:         return MetaSmallVarBinary;
            case TdsEnums.SQLBIGVARBINARY:      return MetaVarBinary;
 
            case TdsEnums.SQLVARCHAR:           //goto TdsEnums.SQLBIGVARCHAR;
            case TdsEnums.SQLBIGVARCHAR:        return MetaVarChar; 
 
            case TdsEnums.SQLBINARY:            //goto TdsEnums.SQLBIGBINARY;
            case TdsEnums.SQLBIGBINARY:         return ((TdsEnums.SQLTIMESTAMP == userType) ? MetaTimestamp : MetaBinary); 

            case TdsEnums.SQLIMAGE:             return MetaImage;

            case TdsEnums.SQLCHAR:              //goto TdsEnums.SQLBIGCHAR; 
            case TdsEnums.SQLBIGCHAR:           return MetaChar;
 
            case TdsEnums.SQLINT1:              return MetaTinyInt; 

            case TdsEnums.SQLBIT:               //goto TdsEnums.SQLBITN; 
            case TdsEnums.SQLBITN:              return MetaBit;

            case TdsEnums.SQLINT2:              return MetaSmallInt;
            case TdsEnums.SQLINT4:              return MetaInt; 
            case TdsEnums.SQLINT8:              return MetaBigInt;
            case TdsEnums.SQLMONEY:             return MetaMoney; 
            case TdsEnums.SQLDATETIME:          return MetaDateTime; 
            case TdsEnums.SQLFLT8:              return MetaFloat;
            case TdsEnums.SQLFLT4:              return MetaReal; 
            case TdsEnums.SQLMONEY4:            return MetaSmallMoney;
            case TdsEnums.SQLDATETIM4:          return MetaSmallDateTime;

            case TdsEnums.SQLDECIMALN:          //goto TdsEnums.SQLNUMERICN; 
            case TdsEnums.SQLNUMERICN:          return MetaDecimal;
 
            case TdsEnums.SQLUNIQUEID:          return MetaUniqueId ; 
            case TdsEnums.SQLNCHAR:             return MetaNChar;
            case TdsEnums.SQLNVARCHAR:          return MetaNVarChar; 
            case TdsEnums.SQLNTEXT:             return MetaNText;
            case TdsEnums.SQLVARIANT:           return MetaVariant;
            case TdsEnums.SQLUDT:               return MetaUdt;
            case TdsEnums.SQLXMLTYPE:           return MetaXml; 
            case TdsEnums.SQLTABLE:             return MetaTable;
            case TdsEnums.SQLDATE:              return MetaDate; 
            case TdsEnums.SQLTIME:              return MetaTime; 
            case TdsEnums.SQLDATETIME2:         return MetaDateTime2;
            case TdsEnums.SQLDATETIMEOFFSET:    return MetaDateTimeOffset; 

            case TdsEnums.SQLVOID:
            default:
                Debug.Assert(false, "Unknown type " + tdsType.ToString(CultureInfo.InvariantCulture)); 
                throw SQL.InvalidSqlDbType((SqlDbType)tdsType);
            }// case 
        } 
#if DEBUG
        private static SqlDbType GetSqlDataType2(int tdsType, UInt32 userType, int length) { 
           SqlDbType type = SqlDbType.Variant;

            // deal with nullable types
            switch (tdsType) { 
                case TdsEnums.SQLMONEYN:
                    tdsType = (length == 4 ? TdsEnums.SQLMONEY4 : TdsEnums.SQLMONEY); 
                    break; 
                case TdsEnums.SQLDATETIMN:
                    tdsType = (length == 4 ? TdsEnums.SQLDATETIM4 : TdsEnums.SQLDATETIME); 
                    break;
                case TdsEnums.SQLINTN:
                    if (length == 1)
                        tdsType = TdsEnums.SQLINT1; 
                    else
                        if (length == 2) 
                        tdsType = TdsEnums.SQLINT2; 
                    else
                        if (length == 4) 
                        tdsType = TdsEnums.SQLINT4;
                    else {
                        Debug.Assert(8 == length, "invalid length for SQLINTN");
                        tdsType = TdsEnums.SQLINT8; 
                    }
                    break; 
                case TdsEnums.SQLFLTN: 
                    tdsType = (length == 4 ? TdsEnums.SQLFLT4 : TdsEnums.SQLFLT8);
                    break; 
            }

            // since we dealt with var-len types, drop down into realy worker
            switch (tdsType) { 
            case TdsEnums.SQLVOID:
                    Debug.Assert(false, "Unexpected SQLVOID type"); 
                    break; 
                case TdsEnums.SQLTEXT:
                    type = SqlDbType.Text; 
                    break;
                case TdsEnums.SQLVARBINARY:
                    // HACK!!!  We have an internal type for smallvarbinarys stored on TdsEnums.  We
                    // store on TdsEnums instead of SqlDbType because we do not want to expose 
                    // this type to the user!
                    type = TdsEnums.SmallVarBinary; 
                    break; 
                case TdsEnums.SQLBIGVARBINARY:
                    type = SqlDbType.VarBinary; 
                    break;
                case TdsEnums.SQLVARCHAR:
                case TdsEnums.SQLBIGVARCHAR:
                    type = SqlDbType.VarChar; 
                    break;
                case TdsEnums.SQLBINARY: 
                case TdsEnums.SQLBIGBINARY: 
                    if (userType == TdsEnums.SQLTIMESTAMP)
                        type = SqlDbType.Timestamp; 
                    else
                        type = SqlDbType.Binary;
                    break;
                case TdsEnums.SQLIMAGE: 
                    type = SqlDbType.Image;
                    break; 
                case TdsEnums.SQLCHAR: 
                case TdsEnums.SQLBIGCHAR:
                    type = SqlDbType.Char; 
                    break;
                case TdsEnums.SQLINT1:
                    type = SqlDbType.TinyInt;
                    break; 
                case TdsEnums.SQLBIT:
                case TdsEnums.SQLBITN: 
                    type = SqlDbType.Bit; 
                    break;
                case TdsEnums.SQLINT2: 
                    type = SqlDbType.SmallInt;
                    break;
                case TdsEnums.SQLINT4:
                    type = SqlDbType.Int; 
                    break;
                case TdsEnums.SQLINT8: 
                    type = SqlDbType.BigInt; 
                    break;
                case TdsEnums.SQLMONEY: 
                    type = SqlDbType.Money;
                    break;
                case TdsEnums.SQLDATETIME:
                    type = SqlDbType.DateTime; 
                    break;
                case TdsEnums.SQLFLT8: 
                    type = SqlDbType.Float; 
                    break;
                case TdsEnums.SQLFLT4: 
                    type = SqlDbType.Real;
                    break;
                case TdsEnums.SQLMONEY4:
                    type = SqlDbType.SmallMoney; 
                    break;
                case TdsEnums.SQLDATETIM4: 
                    type = SqlDbType.SmallDateTime; 
                    break;
                case TdsEnums.SQLDECIMALN: 
                case TdsEnums.SQLNUMERICN:
                    type = SqlDbType.Decimal;
                    break;
                case TdsEnums.SQLUNIQUEID: 
                    type = SqlDbType.UniqueIdentifier;
                    break; 
                case TdsEnums.SQLNCHAR: 
                    type = SqlDbType.NChar;
                    break; 
                case TdsEnums.SQLNVARCHAR:
                    type = SqlDbType.NVarChar;
                    break;
                case TdsEnums.SQLNTEXT: 
                    type = SqlDbType.NText;
                    break; 
                case TdsEnums.SQLVARIANT: 
                    type = SqlDbType.Variant;
                    break; 
                case TdsEnums.SQLUDT:
                    type = SqlDbType.Udt;
                    break;
                case TdsEnums.SQLXMLTYPE: 
                    type = SqlDbType.Xml;
                    break; 
                case TdsEnums.SQLTABLE: 
                    type = SqlDbType.Structured;
                    break; 
                case TdsEnums.SQLDATE:
                    type = SqlDbType.Date;
                    break;
                case TdsEnums.SQLTIME: 
                    type = SqlDbType.Time;
                    break; 
                case TdsEnums.SQLDATETIME2: 
                    type = SqlDbType.DateTime2;
                    break; 
                case TdsEnums.SQLDATETIMEOFFSET:
                    type = SqlDbType.DateTimeOffset;
                    break;
 
            default:
                Debug.Assert(false, "Unknown type " + tdsType.ToString(CultureInfo.InvariantCulture)); 
                    break; 
            }// case
            return type; 
        } // GetSqlDataType
#endif
        internal static MetaType GetDefaultMetaType() {
            return MetaNVarChar; 
        }
 
        // Converts an XmlReader into String 
        internal static String GetStringFromXml(XmlReader  xmlreader) {
            SqlXml sxml = new SqlXml(xmlreader); 
            return sxml.Value;
        }

        private static readonly MetaType MetaBigInt = new MetaType 
            (19, 255, 8, true, false, false, TdsEnums.SQLINT8, TdsEnums.SQLINTN, MetaTypeName.BIGINT, typeof(System.Int64), typeof(SqlInt64), SqlDbType.BigInt, DbType.Int64, 0);
 
        private static readonly MetaType MetaFloat = new MetaType 
            (15, 255, 8, true, false, false, TdsEnums.SQLFLT8, TdsEnums.SQLFLTN, MetaTypeName.FLOAT, typeof(System.Double), typeof(SqlDouble), SqlDbType.Float, DbType.Double, 0);
 
        private static readonly MetaType MetaReal = new MetaType
            (7, 255, 4, true, false, false, TdsEnums.SQLFLT4, TdsEnums.SQLFLTN, MetaTypeName.REAL, typeof(System.Single), typeof(SqlSingle), SqlDbType.Real, DbType.Single, 0);

        // MetaBinary has two bytes of properties for binary and varbinary 
        // 2 byte maxlen
        private static readonly MetaType MetaBinary = new MetaType 
            (255, 255, -1, false, false, false, TdsEnums.SQLBIGBINARY, TdsEnums.SQLBIGBINARY, MetaTypeName.BINARY, typeof(System.Byte[]), typeof(SqlBinary), SqlDbType.Binary, DbType.Binary, 2); 

        // syntatic sugar for the user...timestamps are 8-byte fixed length binary columns 
        private static readonly MetaType MetaTimestamp = new MetaType
            (255, 255, -1, false, false, false, TdsEnums.SQLBIGBINARY, TdsEnums.SQLBIGBINARY, MetaTypeName.TIMESTAMP, typeof(System.Byte[]), typeof(SqlBinary), SqlDbType.Timestamp, DbType.Binary, 2);

        internal static readonly MetaType MetaVarBinary = new MetaType 
            (255, 255, -1, false, false, false, TdsEnums.SQLBIGVARBINARY, TdsEnums.SQLBIGVARBINARY, MetaTypeName.VARBINARY, typeof(System.Byte[]), typeof(SqlBinary), SqlDbType.VarBinary, DbType.Binary, 2);
 
        internal static readonly MetaType MetaMaxVarBinary = new MetaType 
            (255, 255, -1, false, true, true, TdsEnums.SQLBIGVARBINARY, TdsEnums.SQLBIGVARBINARY, MetaTypeName.VARBINARY, typeof(System.Byte[]), typeof(SqlBinary), SqlDbType.VarBinary, DbType.Binary, 2);
 
        // HACK!!!  We have an internal type for smallvarbinarys stored on TdsEnums.  We
        // store on TdsEnums instead of SqlDbType because we do not want to expose
        // this type to the user!
        private static readonly MetaType MetaSmallVarBinary = new MetaType 
            (255, 255, -1, false, false, false, TdsEnums.SQLVARBINARY, TdsEnums.SQLBIGBINARY, ADP.StrEmpty, typeof(System.Byte[]), typeof(SqlBinary), TdsEnums.SmallVarBinary, DbType.Binary, 2);
 
        internal static readonly MetaType MetaImage = new MetaType 
            (255, 255, -1, false, true, false, TdsEnums.SQLIMAGE, TdsEnums.SQLIMAGE, MetaTypeName.IMAGE, typeof(System.Byte[]), typeof(SqlBinary), SqlDbType.Image, DbType.Binary, 0);
 
        private static readonly MetaType MetaBit = new MetaType
            (255, 255, 1, true, false, false, TdsEnums.SQLBIT, TdsEnums.SQLBITN, MetaTypeName.BIT, typeof(System.Boolean), typeof(SqlBoolean), SqlDbType.Bit, DbType.Boolean, 0);

        private static readonly MetaType MetaTinyInt = new MetaType 
            (3, 255, 1, true, false, false, TdsEnums.SQLINT1, TdsEnums.SQLINTN, MetaTypeName.TINYINT, typeof(System.Byte), typeof(SqlByte), SqlDbType.TinyInt, DbType.Byte, 0);
 
        private static readonly MetaType MetaSmallInt = new MetaType 
            (5, 255, 2, true, false, false, TdsEnums.SQLINT2, TdsEnums.SQLINTN, MetaTypeName.SMALLINT, typeof(System.Int16), typeof(SqlInt16), SqlDbType.SmallInt, DbType.Int16, 0);
 
        private static readonly MetaType MetaInt = new MetaType
            (10, 255, 4, true, false, false, TdsEnums.SQLINT4, TdsEnums.SQLINTN, MetaTypeName.INT, typeof(System.Int32), typeof(SqlInt32), SqlDbType.Int, DbType.Int32, 0);

        // MetaVariant has seven bytes of properties for MetaChar and MetaVarChar 
        // 5 byte tds collation
        // 2 byte maxlen 
        private static readonly MetaType MetaChar = new MetaType 
            (255, 255, -1, false, false, false, TdsEnums.SQLBIGCHAR, TdsEnums.SQLBIGCHAR, MetaTypeName.CHAR, typeof(System.String), typeof(SqlString), SqlDbType.Char, DbType.AnsiStringFixedLength, 7);
 
        private static readonly MetaType MetaVarChar = new MetaType
            (255, 255, -1, false, false, false, TdsEnums.SQLBIGVARCHAR, TdsEnums.SQLBIGVARCHAR, MetaTypeName.VARCHAR, typeof(System.String), typeof(SqlString), SqlDbType.VarChar, DbType.AnsiString, 7);

        internal static readonly MetaType MetaMaxVarChar = new MetaType 
            (255, 255, -1, false, true, true, TdsEnums.SQLBIGVARCHAR, TdsEnums.SQLBIGVARCHAR, MetaTypeName.VARCHAR, typeof(System.String), typeof(SqlString), SqlDbType.VarChar, DbType.AnsiString, 7);
 
        internal static readonly MetaType MetaText = new MetaType 
            (255, 255, -1, false, true, false, TdsEnums.SQLTEXT, TdsEnums.SQLTEXT, MetaTypeName.TEXT, typeof(System.String), typeof(SqlString), SqlDbType.Text, DbType.AnsiString, 0);
 
        // MetaVariant has seven bytes of properties for MetaNChar and MetaNVarChar
        // 5 byte tds collation
        // 2 byte maxlen
        private static readonly MetaType MetaNChar = new MetaType 
            (255, 255, -1, false, false, false, TdsEnums.SQLNCHAR, TdsEnums.SQLNCHAR, MetaTypeName.NCHAR, typeof(System.String), typeof(SqlString), SqlDbType.NChar, DbType.StringFixedLength, 7);
 
        internal static readonly MetaType MetaNVarChar = new MetaType 
            (255, 255, -1, false, false, false, TdsEnums.SQLNVARCHAR, TdsEnums.SQLNVARCHAR, MetaTypeName.NVARCHAR, typeof(System.String), typeof(SqlString), SqlDbType.NVarChar, DbType.String, 7);
 
        internal static readonly MetaType MetaMaxNVarChar = new MetaType
            (255, 255, -1, false, true, true, TdsEnums.SQLNVARCHAR, TdsEnums.SQLNVARCHAR, MetaTypeName.NVARCHAR, typeof(System.String), typeof(SqlString), SqlDbType.NVarChar, DbType.String, 7);

        internal static readonly MetaType MetaNText = new MetaType 
            (255, 255, -1, false, true, false, TdsEnums.SQLNTEXT, TdsEnums.SQLNTEXT, MetaTypeName.NTEXT, typeof(System.String), typeof(SqlString), SqlDbType.NText, DbType.String, 7);
 
        // MetaVariant has two bytes of properties for numeric/decimal types 
        // 1 byte precision
        // 1 byte scale 
        internal static readonly MetaType MetaDecimal = new MetaType
            (38, 4, 17, true, false, false, TdsEnums.SQLNUMERICN, TdsEnums.SQLNUMERICN, MetaTypeName.DECIMAL, typeof(System.Decimal), typeof(SqlDecimal), SqlDbType.Decimal, DbType.Decimal, 2);

        internal static readonly MetaType MetaXml = new MetaType 
            (255, 255, -1, false, true, true, TdsEnums.SQLXMLTYPE, TdsEnums.SQLXMLTYPE, MetaTypeName.XML, typeof(System.String), typeof(SqlXml), SqlDbType.Xml, DbType.Xml, 0);
 
        private static readonly MetaType MetaDateTime = new MetaType 
            (23, 3, 8, true, false, false, TdsEnums.SQLDATETIME, TdsEnums.SQLDATETIMN, MetaTypeName.DATETIME, typeof(System.DateTime), typeof(SqlDateTime), SqlDbType.DateTime, DbType.DateTime, 0);
 
        private static readonly MetaType MetaSmallDateTime = new MetaType
            (16, 0, 4, true, false, false, TdsEnums.SQLDATETIM4, TdsEnums.SQLDATETIMN, MetaTypeName.SMALLDATETIME, typeof(System.DateTime), typeof(SqlDateTime), SqlDbType.SmallDateTime, DbType.DateTime, 0);

        private static readonly MetaType MetaMoney = new MetaType 
            (19, 255, 8, true, false, false, TdsEnums.SQLMONEY, TdsEnums.SQLMONEYN, MetaTypeName.MONEY, typeof(System.Decimal), typeof(SqlMoney), SqlDbType.Money, DbType.Currency, 0);
 
        private static readonly MetaType MetaSmallMoney = new MetaType 
            (10, 255, 4, true, false, false, TdsEnums.SQLMONEY4, TdsEnums.SQLMONEYN, MetaTypeName.SMALLMONEY, typeof(System.Decimal), typeof(SqlMoney), SqlDbType.SmallMoney, DbType.Currency, 0);
 
        private static readonly MetaType MetaUniqueId = new MetaType
            (255, 255, 16, true, false, false, TdsEnums.SQLUNIQUEID, TdsEnums.SQLUNIQUEID, MetaTypeName.ROWGUID, typeof(System.Guid), typeof(SqlGuid), SqlDbType.UniqueIdentifier, DbType.Guid, 0);

        private static readonly MetaType MetaVariant = new MetaType 
            (255, 255, -1, true, false, false, TdsEnums.SQLVARIANT, TdsEnums.SQLVARIANT, MetaTypeName.VARIANT, typeof(System.Object), typeof(System.Object), SqlDbType.Variant, DbType.Object, 0);
 
        internal static readonly MetaType MetaUdt = new MetaType 
            (255, 255, -1, false, false, true, TdsEnums.SQLUDT, TdsEnums.SQLUDT, MetaTypeName.UDT, typeof(System.Object), typeof(System.Object), SqlDbType.Udt, DbType.Object, 0);
 
        private static readonly MetaType MetaMaxUdt = new MetaType
            (255, 255, -1, false, true, true, TdsEnums.SQLUDT, TdsEnums.SQLUDT, MetaTypeName.UDT, typeof(System.Object), typeof(System.Object), SqlDbType.Udt, DbType.Object, 0);

        private static readonly MetaType MetaTable = new MetaType 
            (255, 255, -1, false, false, false, TdsEnums.SQLTABLE, TdsEnums.SQLTABLE, MetaTypeName.TABLE, typeof(IEnumerable), typeof(IEnumerable), SqlDbType.Structured, DbType.Object, 0);
 
        // 

        private static readonly MetaType MetaSUDT = new MetaType 
            (255, 255, -1, false, false, false, TdsEnums.SQLVOID, TdsEnums.SQLVOID, "", typeof(MSS.SqlDataRecord), typeof(MSS.SqlDataRecord), SqlDbType.Structured, DbType.Object, 0);

        private static readonly MetaType MetaDate = new MetaType
            (255, 255, 3, true, false, false, TdsEnums.SQLDATE, TdsEnums.SQLDATE, MetaTypeName.DATE, typeof(System.DateTime), typeof(System.DateTime), SqlDbType.Date, DbType.Date, 0); 

        internal static readonly MetaType MetaTime = new MetaType 
            (255, 7, -1, false, false, false, TdsEnums.SQLTIME, TdsEnums.SQLTIME, MetaTypeName.TIME, typeof(System.TimeSpan), typeof(System.TimeSpan), SqlDbType.Time, DbType.Time, 1); 

        private static readonly MetaType MetaDateTime2 = new MetaType 
            (255, 7, -1, false, false, false, TdsEnums.SQLDATETIME2, TdsEnums.SQLDATETIME2, MetaTypeName.DATETIME2, typeof(System.DateTime), typeof(System.DateTime), SqlDbType.DateTime2, DbType.DateTime2, 1);

        internal static readonly MetaType MetaDateTimeOffset = new MetaType
            (255, 7, -1, false, false, false, TdsEnums.SQLDATETIMEOFFSET, TdsEnums.SQLDATETIMEOFFSET, MetaTypeName.DATETIMEOFFSET, typeof(System.DateTimeOffset), typeof(System.DateTimeOffset), SqlDbType.DateTimeOffset, DbType.DateTimeOffset, 1); 

        public static TdsDateTime FromDateTime(DateTime dateTime, byte cb) { 
            SqlDateTime sqlDateTime; 
            TdsDateTime tdsDateTime = new TdsDateTime();
 
            Debug.Assert(cb == 8 || cb == 4, "Invalid date time size!");

            if (cb == 8) {
                sqlDateTime = new SqlDateTime(dateTime); 
                tdsDateTime.time = sqlDateTime.TimeTicks;
            } 
            else { 
                // note that smalldatetime is days&minutes.
                // Adding 30 seconds ensures proper roundup if the seconds are >= 30 
                // The AddSeconds function handles eventual carryover
                sqlDateTime = new SqlDateTime(dateTime.AddSeconds(30));
                tdsDateTime.time = sqlDateTime.TimeTicks / SqlDateTime.SQLTicksPerMinute;
            } 
            tdsDateTime.days = sqlDateTime.DayTicks;
            return tdsDateTime; 
        } 

 
        public static DateTime ToDateTime(int sqlDays, int sqlTime, int length) {
            if (length == 4) {
                return new SqlDateTime(sqlDays, sqlTime * SqlDateTime.SQLTicksPerMinute).Value;
            } 
            else {
                Debug.Assert(length == 8, "invalid length for DateTime"); 
                return new SqlDateTime(sqlDays, sqlTime).Value; 
            }
        } 

        internal static int GetTimeSizeFromScale(byte scale)
        {
            Debug.Assert(0 <= scale && scale <= 7); 

            if (scale <= 2) 
                return 3; 

            if (scale <= 4) 
                return 4;

            return 5;
        } 

        // 
        // please leave string sorted alphabetically 
        // note that these names should only be used in the context of parameters.  We always send over BIG* and nullable types for SQL Server
        // 
        private static class MetaTypeName {
            public const string BIGINT         = "bigint";
            public const string BINARY         = "binary";
            public const string BIT            = "bit"; 
            public const string CHAR           = "char";
            public const string DATETIME       = "datetime"; 
            public const string DECIMAL        = "decimal"; 
            public const string FLOAT          = "float";
            public const string IMAGE          = "image"; 
            public const string INT            = "int";
            public const string MONEY          = "money";
            public const string NCHAR          = "nchar";
            public const string NTEXT          = "ntext"; 
            public const string NVARCHAR       = "nvarchar";
            public const string REAL           = "real"; 
            public const string ROWGUID        = "uniqueidentifier"; 
            public const string SMALLDATETIME  = "smalldatetime";
            public const string SMALLINT       = "smallint"; 
            public const string SMALLMONEY     = "smallmoney";
            public const string TEXT           = "text";
            public const string TIMESTAMP      = "timestamp";
            public const string TINYINT        = "tinyint"; 
            public const string UDT            = "udt";
            public const string VARBINARY      = "varbinary"; 
            public const string VARCHAR        = "varchar"; 
            public const string VARIANT        = "sql_variant";
            public const string XML            = "xml"; 
            public const string TABLE          = "table";
            public const string DATE           = "date";
            public const string TIME           = "time";
            public const string DATETIME2      = "datetime2"; 
            public const string DATETIMEOFFSET = "datetimeoffset";
        } 
    } 

    // 
    // note: it is the client's responsibility to know what size date time he is working with
    //
    internal struct TdsDateTime {
        public int days;  // offset in days from 1/1/1900 
        //     private UInt32 time;  // if smalldatetime, this is # of minutes since midnight
        // otherwise: # of 1/300th of a second since midnight 
        public int time; // 
    }
 
}


// File provided for Reference Use Only by Microsoft Corporation (c) 2007.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK