예제 #1
0
        /// <include file='../../../../../../../../doc/snippets/Microsoft.Data.SqlClient.Server/SqlDataRecord.xml' path='docs/members[@name="SqlDataRecord"]/GetSqlValue/*' />
        public virtual object GetSqlValue(int ordinal)
        {
            EnsureSubclassOverride();
            SmiMetaData metaData = GetSmiMetaData(ordinal);

            return(ValueUtilsSmi.GetSqlValue200(_eventSink, _recordBuffer, ordinal, metaData));
        }
예제 #2
0
        /// <include file='..\..\..\..\..\..\..\..\doc\snippets\Microsoft.Data.SqlClient.Server\SqlDataRecord.xml' path='docs/members[@name="SqlDataRecord"]/GetValue/*' />
        public virtual Object GetValue(int ordinal)
        {
            EnsureSubclassOverride();
            SmiMetaData metaData = GetSmiMetaData(ordinal);

            if (SmiVersion >= SmiContextFactory.KatmaiVersion)
            {
                return(ValueUtilsSmi.GetValue200(
                           _eventSink,
                           _recordBuffer,
                           ordinal,
                           metaData,
                           _recordContext
                           ));
            }
            else
            {
                return(ValueUtilsSmi.GetValue(
                           _eventSink,
                           (ITypedGettersV3)_recordBuffer,
                           ordinal,
                           metaData,
                           _recordContext
                           ));
            }
        }
 private static void GetNullOutputParameterSmi(SmiMetaData metaData, SqlBuffer targetBuffer, ref object result)
 {
     if (SqlDbType.Udt == metaData.SqlDbType)
     {
         result = NullUdtInstance(metaData);
     }
     else
     {
         SqlBuffer.StorageType stype = SqlDbTypeToStorageType(metaData.SqlDbType);
         if (SqlBuffer.StorageType.Empty == stype)
         {
             result = DBNull.Value;
         }
         else if (SqlBuffer.StorageType.SqlBinary == stype)
         {
             // special case SqlBinary, 'cause tds parser never sets SqlBuffer to null, just to empty!
             targetBuffer.SqlBinary = SqlBinary.Null;
         }
         else if (SqlBuffer.StorageType.SqlGuid == stype)
         {
             targetBuffer.SqlGuid = SqlGuid.Null;
         }
         else
         {
             targetBuffer.SetToNullOfType(stype);
         }
     }
 }
 internal void SetInt64(long value)
 {
     if (SqlDbType.Variant == this._metaData.SqlDbType)
     {
         if (this._variantType == null)
         {
             this._stateObj.Parser.WriteSqlVariantHeader(10, 0x7f, 0, this._stateObj);
             this._stateObj.Parser.WriteLong(value, this._stateObj);
         }
         else
         {
             this._stateObj.Parser.WriteSqlVariantHeader(10, 60, 0, this._stateObj);
             this._stateObj.Parser.WriteInt((int)(value >> 0x20), this._stateObj);
             this._stateObj.Parser.WriteInt((int)value, this._stateObj);
             this._variantType = null;
         }
     }
     else
     {
         this._stateObj.Parser.WriteByte((byte)this._metaData.MaxLength, this._stateObj);
         if (SqlDbType.SmallMoney == this._metaData.SqlDbType)
         {
             this._stateObj.Parser.WriteInt((int)value, this._stateObj);
         }
         else if (SqlDbType.Money == this._metaData.SqlDbType)
         {
             this._stateObj.Parser.WriteInt((int)(value >> 0x20), this._stateObj);
             this._stateObj.Parser.WriteInt((int)value, this._stateObj);
         }
         else
         {
             this._stateObj.Parser.WriteLong(value, this._stateObj);
         }
     }
 }
예제 #5
0
        internal static bool IsGetterAccessValid(SmiMetaData metaData, SmiXetterTypeCode xetterType)
        {
            // Make sure no-one adds a new xetter type without updating this file!
            Debug.Assert(SmiXetterTypeCode.XetBoolean <= xetterType && SmiXetterTypeCode.XetDateTimeOffset >= xetterType);

            return(__isGetterAccessValid[(int)metaData.SqlDbType, (int)xetterType]);
        }
예제 #6
0
        // valid for DateTimeOffset
        internal void SetDateTimeOffset(DateTimeOffset value)
        {
            Debug.Assert(
                SmiXetterAccessMap.IsSetterAccessValid(_metaData, SmiXetterTypeCode.XetDateTimeOffset));
            byte scale;
            byte length;

            if (SqlDbType.Variant == _metaData.SqlDbType)
            {
                // VSTFDevDiv #885208 - DateTimeOffset throws ArgumentException for when passing DateTimeOffset value to a sql_variant TVP
                //                      using a SqlDataRecord or SqlDataReader
                SmiMetaData dateTimeOffsetMetaData = SmiMetaData.DefaultDateTimeOffset;
                scale  = MetaType.MetaDateTimeOffset.Scale;
                length = (byte)dateTimeOffsetMetaData.MaxLength;
                _stateObj.Parser.WriteSqlVariantHeader(13, TdsEnums.SQLDATETIMEOFFSET, 1, _stateObj);
                _stateObj.WriteByte(scale); //propbytes: scale
            }
            else
            {
                scale  = _metaData.Scale;
                length = (byte)_metaData.MaxLength;
                _stateObj.WriteByte(length);
            }
            DateTime utcDateTime = value.UtcDateTime;
            Int64    time        = utcDateTime.TimeOfDay.Ticks / TdsEnums.TICKS_FROM_SCALE[scale];
            int      days        = utcDateTime.Subtract(DateTime.MinValue).Days;
            Int16    offset      = (Int16)value.Offset.TotalMinutes;

            _stateObj.WriteByteArray(BitConverter.GetBytes(time), length - 5, 0); // time
            _stateObj.WriteByteArray(BitConverter.GetBytes(days), 3, 0);          // date
            _stateObj.WriteByte((byte)(offset & 0xff));                           // offset byte 1
            _stateObj.WriteByte((byte)((offset >> 8) & 0xff));                    // offset byte 2
        }
예제 #7
0
 // Does this type use PLP format values?
 internal static bool IsPlpFormat(SmiMetaData metaData)
 {
     return(metaData.MaxLength == SmiMetaData.UnlimitedMaxLengthIndicator ||
            metaData.SqlDbType == SqlDbType.Image ||
            metaData.SqlDbType == SqlDbType.NText ||
            metaData.SqlDbType == SqlDbType.Text ||
            metaData.SqlDbType == SqlDbType.Udt);
 }
 internal TdsValueSetter(TdsParserStateObject stateObj, SmiMetaData md)
 {
     this._stateObj       = stateObj;
     this._metaData       = md;
     this._isPlp          = MetaDataUtilsSmi.IsPlpFormat(md);
     this._plpUnknownSent = false;
     this._encoder        = null;
 }
 internal TdsRecordBufferSetter(TdsParserStateObject stateObj, SmiMetaData md)
 {
     this._fieldSetters = new TdsValueSetter[md.FieldMetaData.Count];
     for (int i = 0; i < md.FieldMetaData.Count; i++)
     {
         this._fieldSetters[i] = new TdsValueSetter(stateObj, md.FieldMetaData[i]);
     }
     this._stateObj = stateObj;
     this._metaData = md;
 }
예제 #10
0
        private object GetSqlValueFrameworkSpecific(int ordinal)
        {
            SmiMetaData metaData = GetSmiMetaData(ordinal);

            if (SmiVersion >= SmiContextFactory.Sql2008Version)
            {
                return(ValueUtilsSmi.GetSqlValue200(_eventSink, _recordBuffer, ordinal, metaData, _recordContext));
            }
            return(ValueUtilsSmi.GetSqlValue(_eventSink, _recordBuffer, ordinal, metaData, _recordContext));
        }
예제 #11
0
        /// <include file='../../../../../../../../doc/snippets/Microsoft.Data.SqlClient.Server/SqlDataRecord.xml' path='docs/members[@name="SqlDataRecord"]/GetSqlValue/*' />
        public virtual object GetSqlValue(int ordinal)
        {
            SmiMetaData metaData = GetSmiMetaData(ordinal);

            if (SmiVersion >= SmiContextFactory.KatmaiVersion)
            {
                return(ValueUtilsSmi.GetSqlValue200(_eventSink, _recordBuffer, ordinal, metaData, _recordContext));
            }
            return(ValueUtilsSmi.GetSqlValue(_eventSink, _recordBuffer, ordinal, metaData, _recordContext));
        }
예제 #12
0
        public virtual void SetVariantMetaData(SmiEventSink sink, int ordinal, SmiMetaData metaData)
        {
            // ******** OBSOLETING from SMI -- this should have been removed from ITypedSettersV3
            //  Intended to be removed prior to RTM.  Sub-classes need not implement

            // Implement body with throw because there are only a couple of ways to get to this code:
            //  1) Client is calling this method even though the server negotiated for V3+ and dropped support for V2-.
            //  2) Server didn't implement V2- on some interface and negotiated V2-.
            throw Microsoft.Data.Common.ADP.InternalError(Microsoft.Data.Common.ADP.InternalErrorCode.UnimplementedSMIMethod);
        }
예제 #13
0
        // valid for DateTime, SmallDateTime, Date, DateTime2
        internal void SetDateTime(DateTime value)
        {
            Debug.Assert(
                SmiXetterAccessMap.IsSetterAccessValid(_metaData, SmiXetterTypeCode.XetDateTime));
            if (SqlDbType.Variant == _metaData.SqlDbType)
            {
                if ((_variantType != null) && (_variantType.SqlDbType == SqlDbType.DateTime2))
                {
                    _stateObj.Parser.WriteSqlVariantDateTime2(value, _stateObj);
                }
                else if ((_variantType != null) && (_variantType.SqlDbType == SqlDbType.Date))
                {
                    _stateObj.Parser.WriteSqlVariantDate(value, _stateObj);
                }
                else
                {
                    TdsDateTime dt = MetaType.FromDateTime(value, 8);
                    _stateObj.Parser.WriteSqlVariantHeader(10, TdsEnums.SQLDATETIME, 0, _stateObj);
                    _stateObj.Parser.WriteInt(dt.days, _stateObj);
                    _stateObj.Parser.WriteInt(dt.time, _stateObj);
                }

                // Clean the variant metadata to prevent sharing it with next row.
                // As a reminder, SetVariantType raises an assert if _variantType is not clean
                _variantType = null;
            }
            else
            {
                _stateObj.WriteByte((byte)_metaData.MaxLength);
                if (SqlDbType.SmallDateTime == _metaData.SqlDbType)
                {
                    TdsDateTime dt = MetaType.FromDateTime(value, (byte)_metaData.MaxLength);
                    Debug.Assert(0 <= dt.days && dt.days <= ushort.MaxValue, "Invalid DateTime '" + value + "' for SmallDateTime");

                    _stateObj.Parser.WriteShort(dt.days, _stateObj);
                    _stateObj.Parser.WriteShort(dt.time, _stateObj);
                }
                else if (SqlDbType.DateTime == _metaData.SqlDbType)
                {
                    TdsDateTime dt = MetaType.FromDateTime(value, (byte)_metaData.MaxLength);
                    _stateObj.Parser.WriteInt(dt.days, _stateObj);
                    _stateObj.Parser.WriteInt(dt.time, _stateObj);
                }
                else
                { // date and datetime2
                    int days = value.Subtract(DateTime.MinValue).Days;
                    if (SqlDbType.DateTime2 == _metaData.SqlDbType)
                    {
                        long time = value.TimeOfDay.Ticks / TdsEnums.TICKS_FROM_SCALE[_metaData.Scale];
                        _stateObj.WriteByteArray(BitConverter.GetBytes(time), (int)_metaData.MaxLength - 3, 0);
                    }
                    _stateObj.WriteByteArray(BitConverter.GetBytes(days), 3, 0);
                }
            }
        }
        public override object GetSqlValue(int ordinal)
        {
            this.EnsureCanGetCol("GetSqlValue", ordinal);
            SmiMetaData metaData = this._currentMetaData[ordinal];

            if (this._currentConnection.IsKatmaiOrNewer)
            {
                return(ValueUtilsSmi.GetSqlValue200(this._readerEventSink, (SmiTypedGetterSetter)this._currentColumnValuesV3, ordinal, metaData, this._currentConnection.InternalContext));
            }
            return(ValueUtilsSmi.GetSqlValue(this._readerEventSink, this._currentColumnValuesV3, ordinal, metaData, this._currentConnection.InternalContext));
        }
예제 #15
0
 // compare SmiMetaData to SqlMetaData and determine if they are compatible.
 internal static bool IsCompatible(SmiMetaData firstMd, SqlMetaData secondMd)
 {
     return(firstMd.SqlDbType == secondMd.SqlDbType &&
            firstMd.MaxLength == secondMd.MaxLength &&
            firstMd.Precision == secondMd.Precision &&
            firstMd.Scale == secondMd.Scale &&
            firstMd.CompareOptions == secondMd.CompareOptions &&
            firstMd.LocaleId == secondMd.LocaleId &&
            firstMd.SqlDbType != SqlDbType.Structured && // SqlMetaData doesn't support Structured types
            !firstMd.IsMultiValued);                     // SqlMetaData doesn't have a "multivalued" option
 }
예제 #16
0
        private int _currentOffset;                      // for chunking, verify that caller is using correct offsets
#endif

        #endregion

        #region Exposed Construct/factory methods

        internal TdsValueSetter(TdsParserStateObject stateObj, SmiMetaData md)
        {
            _stateObj       = stateObj;
            _metaData       = md;
            _isPlp          = MetaDataUtilsSmi.IsPlpFormat(md);
            _plpUnknownSent = false;
            _encoder        = null;
#if DEBUG
            _currentOffset = 0;
#endif
        }
        // UDTs and null variants come back via return value, all else is via targetBuffer.
        //  implements SqlClient 1.1-compatible output parameter semantics
        internal static object GetOutputParameterV200Smi(
            SmiEventSink_Default sink,    // event sink for errors
            SmiTypedGetterSetter getters, // getters interface to grab value from
            int ordinal,                  // parameter within getters
            SmiMetaData metaData,         // Getter's type for this ordinal
            SmiContext context,           // used to obtain scratch streams
            SqlBuffer targetBuffer        // destination
            )
        {
            object result = null;   // Workaround for UDT hack in non-Smi code paths.

            if (IsDBNull_Unchecked(sink, getters, ordinal))
            {
                GetNullOutputParameterSmi(metaData, targetBuffer, ref result);
            }
            else
            {
                switch (metaData.SqlDbType)
                {
                // new types go here
                case SqlDbType.Variant:     // Handle variants specifically for v200, since they could contain v200 types
                    // For variants, recur using the current value's sqldbtype
                    metaData = getters.GetVariantType(sink, ordinal);
                    sink.ProcessMessagesAndThrow();
                    Debug.Assert(SqlDbType.Variant != metaData.SqlDbType, "Variant-within-variant not supposed to be possible!");
                    GetOutputParameterV200Smi(sink, getters, ordinal, metaData, context, targetBuffer);
                    break;

                case SqlDbType.Date:
                    targetBuffer.SetToDate(GetDateTime_Unchecked(sink, getters, ordinal));
                    break;

                case SqlDbType.DateTime2:
                    targetBuffer.SetToDateTime2(GetDateTime_Unchecked(sink, getters, ordinal), metaData.Scale);
                    break;

                case SqlDbType.Time:
                    targetBuffer.SetToTime(GetTimeSpan_Unchecked(sink, getters, ordinal), metaData.Scale);
                    break;

                case SqlDbType.DateTimeOffset:
                    targetBuffer.SetToDateTimeOffset(GetDateTimeOffset_Unchecked(sink, getters, ordinal), metaData.Scale);
                    break;

                default:
                    result = GetOutputParameterV3Smi(sink, getters, ordinal, metaData, context, targetBuffer);
                    break;
                }
            }

            return(result);
        }
예제 #18
0
        /// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlClient.Server/SqlDataRecord.xml' path='docs/members[@name="SqlDataRecord"]/GetString/*' />
        public virtual string GetString(int ordinal)
        {
            SmiMetaData colMeta = GetSmiMetaData(ordinal);

            if (_usesStringStorageForXml && colMeta.SqlDbType == SqlDbType.Xml)
            {
                return(ValueUtilsSmi.GetString(_eventSink, _recordBuffer, ordinal, s_maxNVarCharForXml));
            }
            else
            {
                return(ValueUtilsSmi.GetString(_eventSink, _recordBuffer, ordinal, colMeta));
            }
        }
예제 #19
0
        internal SmiSettersStream(SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData)
        {
            Debug.Assert(null != sink);
            Debug.Assert(null != setters);
            Debug.Assert(0 <= ordinal);
            Debug.Assert(null != metaData);

            _sink          = sink;
            _setters       = setters;
            _ordinal       = ordinal;
            _lengthWritten = 0;
            _metaData      = metaData;
        }
예제 #20
0
        internal SmiGettersStream(SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData)
        {
            Debug.Assert(null != sink);
            Debug.Assert(null != getters);
            Debug.Assert(0 <= ordinal);
            Debug.Assert(null != metaData);

            _sink         = sink;
            _getters      = getters;
            _ordinal      = ordinal;
            _readPosition = 0;
            _metaData     = metaData;
        }
        private int _currentField;                          // validate that caller sets columns in correct order.
#endif

        #endregion

        #region Exposed Construct and control methods/properties

        internal TdsRecordBufferSetter(TdsParserStateObject stateObj, SmiMetaData md)
        {
            Debug.Assert(SqlDbType.Structured == md.SqlDbType, "Unsupported SqlDbType: " + md.SqlDbType);
            _fieldSetters = new TdsValueSetter[md.FieldMetaData.Count];
            for (int i = 0; i < md.FieldMetaData.Count; i++)
            {
                _fieldSetters[i] = new TdsValueSetter(stateObj, md.FieldMetaData[i]);
            }
            _stateObj = stateObj;
            _metaData = md;
#if DEBUG
            _currentField = ReadyForToken;
#endif
        }
예제 #22
0
 internal void SetVariantType(SmiMetaData value)
 {
     Debug.Assert(null == _variantType, "Variant type can only be set once");
     Debug.Assert(value != null &&
                  (value.SqlDbType == SqlDbType.Money ||
                   value.SqlDbType == SqlDbType.NVarChar ||
                   value.SqlDbType == SqlDbType.Date ||
                   value.SqlDbType == SqlDbType.DateTime ||
                   value.SqlDbType == SqlDbType.DateTime2 ||
                   value.SqlDbType == SqlDbType.DateTimeOffset ||
                   value.SqlDbType == SqlDbType.SmallDateTime
                  ), "Invalid variant type");
     _variantType = value;
 }
예제 #23
0
        /// <include file='../../../../../../../../doc/snippets/Microsoft.Data.SqlClient.Server/SqlDataRecord.xml' path='docs/members[@name="SqlDataRecord"]/GetString/*' />
        public virtual string GetString(int ordinal)
        {
            EnsureSubclassOverride();
            SmiMetaData colMeta = GetSmiMetaData(ordinal);

            if (_usesStringStorageForXml && SqlDbType.Xml == colMeta.SqlDbType)
            {
                return(ValueUtilsSmi.GetString(_eventSink, _recordBuffer, ordinal, s_maxNVarCharForXml));
            }
            else
            {
                return(ValueUtilsSmi.GetString(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal)));
            }
        }
예제 #24
0
        // valid for SqlDbType.BigInt, SqlDbType.Money, SqlDbType.SmallMoney
        internal void SetInt64(long value)
        {
            Debug.Assert(
                SmiXetterAccessMap.IsSetterAccessValid(_metaData, SmiXetterTypeCode.XetInt64));
            if (SqlDbType.Variant == _metaData.SqlDbType)
            {
                if (null == _variantType)
                {
                    _stateObj.Parser.WriteSqlVariantHeader(10, TdsEnums.SQLINT8, 0, _stateObj);
                    _stateObj.Parser.WriteLong(value, _stateObj);
                }
                else
                {
                    Debug.Assert(SqlDbType.Money == _variantType.SqlDbType, "Invalid variant type");

                    _stateObj.Parser.WriteSqlVariantHeader(10, TdsEnums.SQLMONEY, 0, _stateObj);
                    _stateObj.Parser.WriteInt((int)(value >> 0x20), _stateObj);
                    _stateObj.Parser.WriteInt((int)value, _stateObj);
                    _variantType = null;
                }
            }
            else
            {
                _stateObj.WriteByte((byte)_metaData.MaxLength);
                if (SqlDbType.SmallMoney == _metaData.SqlDbType)
                {
                    _stateObj.Parser.WriteInt((int)value, _stateObj);
                }
                else if (SqlDbType.Money == _metaData.SqlDbType)
                {
                    _stateObj.Parser.WriteInt((int)(value >> 0x20), _stateObj);
                    _stateObj.Parser.WriteInt((int)value, _stateObj);
                }
                else
                {
                    _stateObj.Parser.WriteLong(value, _stateObj);
                }
            }
        }
예제 #25
0
 internal TdsParameterSetter(TdsParserStateObject stateObj, SmiMetaData md)
 {
     _target = new TdsRecordBufferSetter(stateObj, md);
 }
예제 #26
0
        // Map SmiMetaData from a schema table.
        // DEVNOTE: Since we're using SchemaTable, we can assume that we aren't directly using a SqlDataReader
        // so we don't support the Sql-specific stuff, like collation.
        internal static SmiExtendedMetaData SmiMetaDataFromSchemaTableRow(DataRow schemaRow)
        {
            string colName = "";
            object temp    = schemaRow[SchemaTableColumn.ColumnName];

            if (DBNull.Value != temp)
            {
                colName = (string)temp;
            }

            // Determine correct SqlDbType.
            temp = schemaRow[SchemaTableColumn.DataType];
            if (DBNull.Value == temp)
            {
                throw SQL.NullSchemaTableDataTypeNotSupported(colName);
            }

            Type      colType   = (Type)temp;
            SqlDbType colDbType = InferSqlDbTypeFromType_2008(colType);

            if (InvalidSqlDbType == colDbType)
            {
                // Unknown through standard mapping, use VarBinary for columns that are Object typed, otherwise error
                if (typeof(object) == colType)
                {
                    colDbType = SqlDbType.VarBinary;
                }
                else
                {
                    throw SQL.UnsupportedColumnTypeForSqlProvider(colName, colType.ToString());
                }
            }

            // Determine metadata modifier values per type (maxlength, precision, scale, etc)
            long maxLength = 0;
            byte precision = 0;
            byte scale     = 0;

            switch (colDbType)
            {
            case SqlDbType.BigInt:
            case SqlDbType.Bit:
            case SqlDbType.DateTime:
            case SqlDbType.Float:
            case SqlDbType.Image:
            case SqlDbType.Int:
            case SqlDbType.Money:
            case SqlDbType.NText:
            case SqlDbType.Real:
            case SqlDbType.UniqueIdentifier:
            case SqlDbType.SmallDateTime:
            case SqlDbType.SmallInt:
            case SqlDbType.SmallMoney:
            case SqlDbType.Text:
            case SqlDbType.Timestamp:
            case SqlDbType.TinyInt:
            case SqlDbType.Variant:
            case SqlDbType.Xml:
            case SqlDbType.Date:
                // These types require no  metadata modifies
                break;

            case SqlDbType.Binary:
            case SqlDbType.VarBinary:
                // These types need a binary max length
                temp = schemaRow[SchemaTableColumn.ColumnSize];
                if (DBNull.Value == temp)
                {
                    // source isn't specifying a size, so assume the worst
                    if (SqlDbType.Binary == colDbType)
                    {
                        maxLength = SmiMetaData.MaxBinaryLength;
                    }
                    else
                    {
                        maxLength = SmiMetaData.UnlimitedMaxLengthIndicator;
                    }
                }
                else
                {
                    // We (should) have a valid maxlength, so use it.
                    maxLength = Convert.ToInt64(temp, null);

                    // Max length must be 0 to MaxBinaryLength or it can be UnlimitedMAX if type is varbinary.
                    // If it's greater than MaxBinaryLength, just promote it to UnlimitedMAX, if possible.
                    if (maxLength > SmiMetaData.MaxBinaryLength)
                    {
                        maxLength = SmiMetaData.UnlimitedMaxLengthIndicator;
                    }

                    if ((maxLength < 0 &&
                         (maxLength != SmiMetaData.UnlimitedMaxLengthIndicator ||
                          SqlDbType.Binary == colDbType)))
                    {
                        throw SQL.InvalidColumnMaxLength(colName, maxLength);
                    }
                }
                break;

            case SqlDbType.Char:
            case SqlDbType.VarChar:
                // These types need an ANSI max length
                temp = schemaRow[SchemaTableColumn.ColumnSize];
                if (DBNull.Value == temp)
                {
                    // source isn't specifying a size, so assume the worst
                    if (SqlDbType.Char == colDbType)
                    {
                        maxLength = SmiMetaData.MaxANSICharacters;
                    }
                    else
                    {
                        maxLength = SmiMetaData.UnlimitedMaxLengthIndicator;
                    }
                }
                else
                {
                    // We (should) have a valid maxlength, so use it.
                    maxLength = Convert.ToInt64(temp, null);

                    // Max length must be 0 to MaxANSICharacters or it can be UnlimitedMAX if type is varbinary.
                    // If it's greater than MaxANSICharacters, just promote it to UnlimitedMAX, if possible.
                    if (maxLength > SmiMetaData.MaxANSICharacters)
                    {
                        maxLength = SmiMetaData.UnlimitedMaxLengthIndicator;
                    }

                    if ((maxLength < 0 &&
                         (maxLength != SmiMetaData.UnlimitedMaxLengthIndicator ||
                          SqlDbType.Char == colDbType)))
                    {
                        throw SQL.InvalidColumnMaxLength(colName, maxLength);
                    }
                }
                break;

            case SqlDbType.NChar:
            case SqlDbType.NVarChar:
                // These types need a unicode max length
                temp = schemaRow[SchemaTableColumn.ColumnSize];
                if (DBNull.Value == temp)
                {
                    // source isn't specifying a size, so assume the worst
                    if (SqlDbType.NChar == colDbType)
                    {
                        maxLength = SmiMetaData.MaxUnicodeCharacters;
                    }
                    else
                    {
                        maxLength = SmiMetaData.UnlimitedMaxLengthIndicator;
                    }
                }
                else
                {
                    // We (should) have a valid maxlength, so use it.
                    maxLength = Convert.ToInt64(temp, null);

                    // Max length must be 0 to MaxUnicodeCharacters or it can be UnlimitedMAX if type is varbinary.
                    // If it's greater than MaxUnicodeCharacters, just promote it to UnlimitedMAX, if possible.
                    if (maxLength > SmiMetaData.MaxUnicodeCharacters)
                    {
                        maxLength = SmiMetaData.UnlimitedMaxLengthIndicator;
                    }

                    if ((maxLength < 0 &&
                         (maxLength != SmiMetaData.UnlimitedMaxLengthIndicator ||
                          SqlDbType.NChar == colDbType)))
                    {
                        throw SQL.InvalidColumnMaxLength(colName, maxLength);
                    }
                }
                break;

            case SqlDbType.Decimal:
                // Decimal requires precision and scale
                temp = schemaRow[SchemaTableColumn.NumericPrecision];
                if (DBNull.Value == temp)
                {
                    precision = SmiMetaData.DefaultDecimal.Precision;
                }
                else
                {
                    precision = Convert.ToByte(temp, null);
                }

                temp = schemaRow[SchemaTableColumn.NumericScale];
                if (DBNull.Value == temp)
                {
                    scale = SmiMetaData.DefaultDecimal.Scale;
                }
                else
                {
                    scale = Convert.ToByte(temp, null);
                }

                if (precision < SmiMetaData.MinPrecision ||
                    precision > SqlDecimal.MaxPrecision ||
                    scale < SmiMetaData.MinScale ||
                    scale > SqlDecimal.MaxScale ||
                    scale > precision)
                {
                    throw SQL.InvalidColumnPrecScale();
                }
                break;

            case SqlDbType.Time:
            case SqlDbType.DateTime2:
            case SqlDbType.DateTimeOffset:
                // requires scale
                temp = schemaRow[SchemaTableColumn.NumericScale];
                if (DBNull.Value == temp)
                {
                    scale = SmiMetaData.DefaultTime.Scale;
                }
                else
                {
                    scale = Convert.ToByte(temp, null);
                }

                if (scale > SmiMetaData.MaxTimeScale)
                {
                    throw SQL.InvalidColumnPrecScale();
                }
                else if (scale < 0)
                {
                    scale = SmiMetaData.DefaultTime.Scale;
                }
                break;

            case SqlDbType.Udt:
            case SqlDbType.Structured:
            default:
                // These types are not supported from SchemaTable
                throw SQL.UnsupportedColumnTypeForSqlProvider(colName, colType.ToString());
            }

            return(new SmiExtendedMetaData(
                       colDbType,
                       maxLength,
                       precision,
                       scale,
                       System.Globalization.CultureInfo.CurrentCulture.LCID,
                       SmiMetaData.GetDefaultForType(colDbType).CompareOptions,
                       null,
                       false,       // no support for multi-valued columns in a TVP yet
                       null,        // no support for structured columns yet
                       null,        // no support for structured columns yet
                       colName,
                       null,
                       null,
                       null));
        }
예제 #27
0
        private bool _isMetaSet;         // flag to indicate whether we have set the variant metadata

        internal SqlRecordBuffer(SmiMetaData metaData)
        {
            _isNull = true;
        }
예제 #28
0
        // valid for character types: Char, VarChar, Text, NChar, NVarChar, NText
        internal void SetString(string value, int offset, int length)
        {
            Debug.Assert(
                SmiXetterAccessMap.IsSetterAccessValid(_metaData, SmiXetterTypeCode.XetString));

            // ANSI types must convert to byte[] because that's the tool we have.
            if (MetaDataUtilsSmi.IsAnsiType(_metaData.SqlDbType))
            {
                byte[] bytes;
                // Optimize for common case of writing entire string
                if (offset == 0 && value.Length <= length)
                {
                    bytes = _stateObj.Parser._defaultEncoding.GetBytes(value);
                }
                else
                {
                    char[] chars = value.ToCharArray(offset, length);
                    bytes = _stateObj.Parser._defaultEncoding.GetBytes(chars);
                }
                SetBytes(0, bytes, 0, bytes.Length);
                SetBytesLength(bytes.Length);
            }
            else if (SqlDbType.Variant == _metaData.SqlDbType)
            {
                Debug.Assert(null != _variantType && SqlDbType.NVarChar == _variantType.SqlDbType, "Invalid variant type");

                SqlCollation collation = new SqlCollation();
                collation.LCID = checked ((int)_variantType.LocaleId);
                collation.SqlCompareOptions = _variantType.CompareOptions;

                if (length * ADP.CharSize > TdsEnums.TYPE_SIZE_LIMIT)
                { // send as varchar for length greater than 4000
                    byte[] bytes;
                    // Optimize for common case of writing entire string
                    if (offset == 0 && value.Length <= length)
                    {
                        bytes = _stateObj.Parser._defaultEncoding.GetBytes(value);
                    }
                    else
                    {
                        bytes = _stateObj.Parser._defaultEncoding.GetBytes(value.ToCharArray(offset, length));
                    }
                    _stateObj.Parser.WriteSqlVariantHeader(9 + bytes.Length, TdsEnums.SQLBIGVARCHAR, 7, _stateObj);
                    _stateObj.Parser.WriteUnsignedInt(collation.info, _stateObj); // propbytes: collation.Info
                    _stateObj.WriteByte(collation.sortId);                        // propbytes: collation.SortId
                    _stateObj.Parser.WriteShort(bytes.Length, _stateObj);         // propbyte: varlen
                    _stateObj.WriteByteArray(bytes, bytes.Length, 0);
                }
                else
                {
                    _stateObj.Parser.WriteSqlVariantHeader(9 + length * ADP.CharSize, TdsEnums.SQLNVARCHAR, 7, _stateObj);
                    _stateObj.Parser.WriteUnsignedInt(collation.info, _stateObj);  // propbytes: collation.Info
                    _stateObj.WriteByte(collation.sortId);                         // propbytes: collation.SortId
                    _stateObj.Parser.WriteShort(length * ADP.CharSize, _stateObj); // propbyte: varlen
                    _stateObj.Parser.WriteString(value, length, offset, _stateObj);
                }
                _variantType = null;
            }
            else if (_isPlp)
            {
                // Send the string as a complete PLP chunk.
                _stateObj.Parser.WriteLong(length * ADP.CharSize, _stateObj);   // PLP total length
                _stateObj.Parser.WriteInt(length * ADP.CharSize, _stateObj);    // Chunk length
                _stateObj.Parser.WriteString(value, length, offset, _stateObj); // Data
                if (length != 0)
                {
                    _stateObj.Parser.WriteInt(TdsEnums.SQL_PLP_CHUNK_TERMINATOR, _stateObj); // Terminator
                }
            }
            else
            {
                _stateObj.Parser.WriteShort(length * ADP.CharSize, _stateObj);
                _stateObj.Parser.WriteString(value, length, offset, _stateObj);
            }
        }
 // valid for SqlDbType.Variant
 public override void SetVariantMetaData(SmiEventSink sink, int ordinal, SmiMetaData metaData)
 {
     CheckWritingToColumn(ordinal);
     _fieldSetters[ordinal].SetVariantType(metaData);
 }
 public override void SetVariantMetaData(SmiEventSink sink, int ordinal, SmiMetaData metaData)
 {
     this._fieldSetters[ordinal].SetVariantType(metaData);
 }