OleDbParameter.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Data / System / Data / OleDb / OleDbParameter.cs / 1305376 / OleDbParameter.cs

                            //------------------------------------------------------------------------------ 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
// [....]
//----------------------------------------------------------------------------- 
 
namespace System.Data.OleDb {
 
    using System;
    using System.ComponentModel;
    using System.Data;
    using System.Data.Common; 
    using System.Data.ProviderBase;
    using System.Diagnostics; 
    using System.Globalization; 

    [ 
    System.ComponentModel.TypeConverterAttribute(typeof(System.Data.OleDb.OleDbParameter.OleDbParameterConverter))
    ]
    public sealed partial class OleDbParameter : DbParameter, ICloneable, IDbDataParameter {
        private NativeDBType _metaType; 
        private int _changeID;
 
        private string _parameterName; 
        private byte _precision;
        private byte _scale; 
        private bool _hasScale;

        private NativeDBType _coerceMetaType;
 
        public OleDbParameter() : base() { // V1.0 nothing
        } 
 
        public OleDbParameter(string name, object value) : this() { // MDAC 59521
            Debug.Assert(!(value is OleDbType), "use OleDbParameter(string, OleDbType)"); 
            Debug.Assert(!(value is SqlDbType), "use OleDbParameter(string, OleDbType)");

            ParameterName = name;
            Value = value; 
        }
 
        public OleDbParameter(string name, OleDbType dataType) : this() { 
            ParameterName = name;
            OleDbType = dataType; 
        }

        public OleDbParameter(string name, OleDbType dataType, int size) : this() {
            ParameterName = name; 
            OleDbType = dataType;
            Size = size; 
        } 

        public OleDbParameter(string name, OleDbType dataType, int size, string srcColumn) : this() { 
            ParameterName = name;
            OleDbType = dataType;
            Size = size;
            SourceColumn = srcColumn; 
        }
 
        [ EditorBrowsableAttribute(EditorBrowsableState.Advanced) ] // MDAC 69508 
        public OleDbParameter(string parameterName,
                              OleDbType dbType, int size, 
                              ParameterDirection direction, Boolean isNullable,
                              Byte precision, Byte scale,
                              string srcColumn, DataRowVersion srcVersion,
                              object value) : this() { // V1.0 everything 
            ParameterName = parameterName;
            OleDbType = dbType; 
            Size = size; 
            Direction = direction;
            IsNullable = isNullable; 
            PrecisionInternal = precision;
            ScaleInternal = scale;
            SourceColumn = srcColumn;
            SourceVersion = srcVersion; 
            Value = value;
        } 
 
        [ EditorBrowsableAttribute(EditorBrowsableState.Advanced) ] // MDAC 69508
        public OleDbParameter(string parameterName, 
                              OleDbType dbType, int size,
                              ParameterDirection direction,
                              Byte precision, Byte scale,
                              string sourceColumn, DataRowVersion sourceVersion, bool sourceColumnNullMapping, 
                              object value) : this() { // V2.0 everything - round trip all browsable properties + precision/scale
            ParameterName = parameterName; 
            OleDbType = dbType; 
            Size = size;
            Direction = direction; 
            PrecisionInternal = precision;
            ScaleInternal = scale;
            SourceColumn = sourceColumn;
            SourceVersion = sourceVersion; 
            SourceColumnNullMapping = sourceColumnNullMapping;
            Value = value; 
        } 

        internal int ChangeID { 
            get {
                return _changeID;
            }
        } 

        override public DbType DbType { 
            get { 
                return GetBindType(Value).enumDbType;
            } 
            set {
                NativeDBType dbtype = _metaType;
                if ((null == dbtype) || (dbtype.enumDbType != value)) { // MDAC 63571
                    PropertyTypeChanging(); 
                    _metaType = NativeDBType.FromDbType(value);
                } 
            } 
        }
 
        public override void ResetDbType() {
            ResetOleDbType();
        }
 
        [
        RefreshProperties(RefreshProperties.All), 
        ResCategoryAttribute(Res.DataCategory_Data), 
        ResDescriptionAttribute(Res.OleDbParameter_OleDbType),
        System.Data.Common.DbProviderSpecificTypePropertyAttribute(true), 
        ]
        public OleDbType OleDbType {
            get {
                return GetBindType(Value).enumOleDbType; 
            }
            set { 
                NativeDBType dbtype = _metaType; 
                if ((null == dbtype) || (dbtype.enumOleDbType != value)) { // MDAC 63571
                    PropertyTypeChanging(); 
                    _metaType = NativeDBType.FromDataType(value);
                }
            }
        } 

        private bool ShouldSerializeOleDbType() { 
            return (null != _metaType); 
        }
 
        public void ResetOleDbType() {
            if (null != _metaType) {
                PropertyTypeChanging();
                _metaType = null; 
            }
        } 
 
        [
        ResCategoryAttribute(Res.DataCategory_Data), 
        ResDescriptionAttribute(Res.DbParameter_ParameterName),
        ]
        override public string ParameterName { // V1.2.3300, XXXParameter V1.0.3300
            get { 
                string parameterName = _parameterName;
                return ((null != parameterName) ? parameterName : ADP.StrEmpty); 
            } 
            set {
                if (_parameterName != value) { 
                    PropertyChanging();
                    _parameterName = value;
                }
            } 
        }
 
        [DefaultValue((Byte)0)] // MDAC 65862 
        [ResCategoryAttribute(Res.DataCategory_Data)]
        [ResDescriptionAttribute(Res.DbDataParameter_Precision)] 
        public Byte Precision {
            get {
                return PrecisionInternal;
            } 
            set {
                PrecisionInternal = value; 
            } 
        }
        internal byte PrecisionInternal { 
            get {
                byte precision = _precision;
                if (0 == precision) {
                    precision = ValuePrecision(Value); 
                }
                return precision; 
            } 
            set {
                if (_precision != value) { 
                    PropertyChanging();
                    _precision = value;
                }
            } 
        }
        private bool ShouldSerializePrecision() { 
            return (0 != _precision); 
        }
 
        [DefaultValue((Byte)0)] // MDAC 65862
        [ResCategoryAttribute(Res.DataCategory_Data)]
        [ResDescriptionAttribute(Res.DbDataParameter_Scale)]
        public Byte Scale { 
            get {
                return ScaleInternal; 
            } 
            set {
                ScaleInternal = value; 
            }
        }
        internal byte ScaleInternal {
            get { 
                byte scale = _scale;
                if (!ShouldSerializeScale(scale)) { // WebData 94688 
                    scale = ValueScale(Value); 
                }
                return scale; 
            }
            set {
                if (_scale != value || !_hasScale) {
                    PropertyChanging(); 
                    _scale = value;
                    _hasScale = true; 
                } 
            }
        } 
        private bool ShouldSerializeScale() {
            return ShouldSerializeScale(_scale);
        }
 
        private bool ShouldSerializeScale(byte scale) {
            return _hasScale && ((0 != scale) ||  ShouldSerializePrecision()); 
        } 

        object ICloneable.Clone() { 
            return new OleDbParameter(this);
        }

        private void CloneHelper(OleDbParameter destination) { 
            CloneHelperCore(destination);
            destination._metaType = _metaType; 
            destination._parameterName = _parameterName; 
            destination._precision = _precision;
            destination._scale = _scale; 
            destination._hasScale = _hasScale;
        }

        private void PropertyChanging() { 
            unchecked { _changeID++; }
        } 
 
        private void PropertyTypeChanging() {
            PropertyChanging(); 
            _coerceMetaType = null;
            CoercedValue = null;
        }
 
        // goal: call virtual property getters only once per parameter
        internal bool BindParameter(int index, Bindings bindings) { 
            int changeID = _changeID; 
            object value = Value;
 
            NativeDBType dbtype = GetBindType(value);
            if (OleDbType.Empty == dbtype.enumOleDbType) {
                throw ODB.UninitializedParameters(index, dbtype.enumOleDbType);
            } 
            _coerceMetaType = dbtype;
            value = CoerceValue(value, dbtype); 
            CoercedValue = value; 

            ParameterDirection direction = Direction; 

            byte precision;
            if (ShouldSerializePrecision()) {
                precision = PrecisionInternal; 
            }
            else { 
                precision = ValuePrecision(value); 
            }
            if (0 == precision) { 
                precision = dbtype.maxpre;
            }

            byte scale; 
            if (ShouldSerializeScale()) {
                scale = ScaleInternal; 
            } 
            else {
                scale = ValueScale(value); 
            }

            int wtype = dbtype.wType;
            int bytecount, size; 

            if (dbtype.islong) { // long data (image, text, ntext) 
                bytecount = ADP.PtrSize; 
                if (ShouldSerializeSize()) {
                    size = Size; 
                }
                else {
                    if (NativeDBType.STR == dbtype.dbType) {
                        size = Int32.MaxValue; // WebData 98940 
                    }
                    else if (NativeDBType.WSTR == dbtype.dbType) { 
                        size = Int32.MaxValue/2; 
                    }
                    else { 
                        size = Int32.MaxValue;
                    }
                }
                wtype |= NativeDBType.BYREF; 
            }
            else if (dbtype.IsVariableLength) { // variable length data (varbinary, varchar, nvarchar) 
                if (!ShouldSerializeSize() && ADP.IsDirection(this, ParameterDirection.Output)) { 
                    throw ADP.UninitializedParameterSize(index, _coerceMetaType.dataType);
                } 

                bool computedSize;
                if (ShouldSerializeSize()) {
                    size = Size; 
                    computedSize = false;
                } 
                else { 
                    size = ValueSize(value);
                    computedSize = true; 
                }
                if (0 < size) {
                    if (NativeDBType.WSTR == dbtype.wType) {
                        // maximum 0x3FFFFFFE characters, computed this way to avoid overflow exception 
                        bytecount = Math.Min(size, 0x3FFFFFFE) * 2 + 2;
                    } 
                    else { 
                        Debug.Assert(NativeDBType.STR != dbtype.wType, "should have ANSI binding, describing is okay");
                        bytecount = size; 
                    }

                    if (computedSize) {
                        if (NativeDBType.STR == dbtype.dbType) { // WebData 98140 
                            // maximum 0x7ffffffe characters, computed this way to avoid overflow exception
                            size = Math.Min(size, 0x3FFFFFFE) * 2; 
                        } 
                    }
 
                    if (ODB.LargeDataSize < bytecount) {
                        bytecount = ADP.PtrSize;
                        wtype |= NativeDBType.BYREF;
                    } 
                }
                else if (0 == size) { 
                    if (NativeDBType.WSTR == wtype) { // allow space for null termination character 
                        bytecount = 2;
                        // 0 == size, okay for (STR == dbType) 
                    }
                    else {
                        Debug.Assert(NativeDBType.STR != dbtype.wType, "should have ANSI binding, describing is okay");
                        bytecount = 0; 
                    }
                } 
                else if (-1 == size) { 
                    bytecount = ADP.PtrSize;
                    wtype |= NativeDBType.BYREF; 
                }
                else {
                    throw ADP.InvalidSizeValue(size);
                } 
            }
            else { // fixed length data 
                bytecount = dbtype.fixlen; 
                size = bytecount;
            } 
            bindings.CurrentIndex = index;

            // tagDBPARAMBINDINFO info for SetParameterInfo
            bindings.DataSourceType = dbtype.dbString.DangerousGetHandle(); // NOTE: This is a constant and isn't exposed publicly, so there really isn't a potential for Handle Recycling. 
            bindings.Name = ADP.PtrZero;
            bindings.ParamSize = new IntPtr(size); 
            bindings.Flags = GetBindFlags(direction); 
          //bindings.Precision    = precision;
          //bindings.Scale        = scale; 

            // tagDBBINDING info for CreateAccessor
            bindings.Ordinal      = (IntPtr)(index+1);
            bindings.Part         = dbtype.dbPart; 
            bindings.ParamIO      = GetBindDirection(direction);
            bindings.Precision    = precision; 
            bindings.Scale        = scale; 
            bindings.DbType       = wtype;
            bindings.MaxLen       = bytecount; // also increments databuffer size (uses DbType) 
          //bindings.ValueOffset  = bindings.DataBufferSize; // set via MaxLen
          //bindings.LengthOffset = i * sizeof_int64;
          //bindings.StatusOffset = i * sizeof_int64 + sizeof_int32;
          //bindings.TypeInfoPtr  = 0; 
          //bindings.ObjectPtr    = 0;
          //bindings.BindExtPtr   = 0; 
          //bindings.MemOwner     = /*DBMEMOWNER_CLIENTOWNED*/0; 
          //bindings.Flags        = 0;
 
          //bindings.ParameterChangeID = changeID; // bind until something changes
            Debug.Assert(_changeID == changeID, "parameter has unexpectedly changed");

            if (Bid.AdvancedOn) { 
                Bid.Trace(" index=%d, parameterName='%ls'\n", index, ParameterName);//, bindings.BindInfo[index]);
                Bid.Trace("\n");//, bindings.DBBinding[index]); 
            } 
            return IsParameterComputed();
        } 

        private static object CoerceValue(object value, NativeDBType destinationType) {
            Debug.Assert(null != destinationType, "null destinationType");
            if ((null != value) && (DBNull.Value != value) && (typeof(object) != destinationType.dataType)) { 
                Type currentType = value.GetType();
                if (currentType != destinationType.dataType) { 
                    try { 
                        if ((typeof(string) == destinationType.dataType) && (typeof(char[]) == currentType)) {
                        } 
                        else if ((NativeDBType.CY == destinationType.dbType) && (typeof(string) == currentType)) {
                            value = Decimal.Parse((string)value, NumberStyles.Currency, (IFormatProvider)null); // WebData 99376
                        }
                        else { 
                            value = Convert.ChangeType(value, destinationType.dataType, (IFormatProvider)null);
                        } 
                    } 
                    catch (Exception e) {
                        // 
                        if (!ADP.IsCatchableExceptionType(e)) {
                            throw;
                        }
 
                        throw ADP.ParameterConversionFailed(value, destinationType.dataType, e); // WebData 75433
                    } 
                } 
            }
            return value; 
        }

        private NativeDBType GetBindType(object value) {
            NativeDBType dbtype = _metaType; 
            if (null == dbtype) {
                if (ADP.IsNull(value)) { 
                    dbtype = OleDb.NativeDBType.Default; 
                }
                else { 
                    dbtype = NativeDBType.FromSystemType(value);
                }
            }
            return dbtype; 
        }
 
        internal object GetCoercedValue() { 
            object value = CoercedValue; // will also be set during binding, will rebind everytime if _metaType not set
            if (null == value) { 
                value = CoerceValue(Value, _coerceMetaType);
                CoercedValue = value;
            }
            return value; 
        }
 
        internal bool IsParameterComputed() { 
            NativeDBType metaType = _metaType;
            return ((null == metaType) 
                    || (!ShouldSerializeSize() && metaType.IsVariableLength)
                    || ((NativeDBType.DECIMAL == metaType.dbType) || (NativeDBType.NUMERIC == metaType.dbType)
                        && (!ShouldSerializeScale() || !ShouldSerializePrecision())
                        ) 
                    ); // MDAC 69299
        } 
 
        // @devnote: use IsParameterComputed which is called in the normal case
        // only to call Prepare to throw the specialized error message 
        // reducing the overall number of methods to actually jit
        internal void Prepare(OleDbCommand cmd) { // MDAC 70232
            Debug.Assert(IsParameterComputed(), "Prepare computed parameter");
            if (null == _metaType) { 
                throw ADP.PrepareParameterType(cmd);
            } 
            else if (!ShouldSerializeSize() && _metaType.IsVariableLength) { 
                throw ADP.PrepareParameterSize(cmd);
            } 
            else if (!ShouldSerializePrecision() && !ShouldSerializeScale() && ((NativeDBType.DECIMAL == _metaType.wType) || (NativeDBType.NUMERIC == _metaType.wType))) { // MDAC 71441
                throw ADP.PrepareParameterScale(cmd, _metaType.wType.ToString("G", CultureInfo.InvariantCulture));
            }
            Debug.Assert(false, "OleDbParameter.Prepare didn't throw"); 
        }
 
        [ 
        RefreshProperties(RefreshProperties.All),
        ResCategoryAttribute(Res.DataCategory_Data), 
        ResDescriptionAttribute(Res.DbParameter_Value),
        TypeConverterAttribute(typeof(StringConverter)),
        ]
        override public object Value { // V1.2.3300, XXXParameter V1.0.3300 
            get {
                return _value; 
            } 
            set {
                _coercedValue = null; 
                _value = value;
            }
        }
 
        private byte ValuePrecision(object value) {
            return ValuePrecisionCore(value); 
        } 

        private byte ValueScale(object value) { 
            return ValueScaleCore(value);
        }

        private int ValueSize(object value) { 
            return ValueSizeCore(value);
        } 
 
        static private int GetBindDirection(ParameterDirection direction) {
            return (ODB.ParameterDirectionFlag & (int)direction); 
            /*switch(Direction) {
            default:
            case ParameterDirection.Input:
                return ODB.DBPARAMIO_INPUT; 
            case ParameterDirection.Output:
            case ParameterDirection.ReturnValue: 
                return ODB.DBPARAMIO_OUTPUT; 
            case ParameterDirection.InputOutput:
                return (ODB.DBPARAMIO_INPUT | ODB.DBPARAMIO_OUTPUT); 
            }*/
        }

        static private int GetBindFlags(ParameterDirection direction) { 
            return (ODB.ParameterDirectionFlag & (int)direction);
            /*switch(Direction) { 
            default: 
            case ParameterDirection.Input:
                return ODB.DBPARAMFLAGS_ISINPUT; 
            case ParameterDirection.Output:
            case ParameterDirection.ReturnValue:
                return ODB.DBPARAMFLAGS_ISOUTPUT;
            case ParameterDirection.InputOutput: 
                return (ODB.DBPARAMFLAGS_ISINPUT | ODB.DBPARAMFLAGS_ISOUTPUT);
            }*/ 
        } 

        // implemented as nested class to take advantage of the private/protected ShouldSerializeXXX methods 
        sealed internal class OleDbParameterConverter : System.ComponentModel.ExpandableObjectConverter {

            // converter classes should have public ctor
            public OleDbParameterConverter() { 
            }
 
            public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { 
                if (typeof(System.ComponentModel.Design.Serialization.InstanceDescriptor) == destinationType) {
                    return true; 
                }
                return base.CanConvertTo(context, destinationType);
            }
 
            public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) {
                if (null == destinationType) { 
                    throw ADP.ArgumentNull("destinationType"); 
                }
                if ((typeof(System.ComponentModel.Design.Serialization.InstanceDescriptor) == destinationType) && (value is OleDbParameter)) { 
                    return ConvertToInstanceDescriptor(value as OleDbParameter);
                }
                return base.ConvertTo(context, culture, value, destinationType);
            } 

            private System.ComponentModel.Design.Serialization.InstanceDescriptor ConvertToInstanceDescriptor(OleDbParameter p) { 
                int flags = 0; 

                if (p.ShouldSerializeOleDbType()) { 
                    flags |= 1;
                }
                if (p.ShouldSerializeSize()) {
                    flags |= 2; 
                }
                if (!ADP.IsEmpty(p.SourceColumn)) { 
                    flags |= 4; 
                }
                if (null != p.Value) { 
                    flags |= 8;
                }
                if ((ParameterDirection.Input != p.Direction) || p.IsNullable
                    || p.ShouldSerializePrecision() || p.ShouldSerializeScale() 
                    || (DataRowVersion.Current != p.SourceVersion)) {
                    flags |= 16; // V1.0 everything 
                } 
                if (p.SourceColumnNullMapping) {
                    flags |= 32; // v2.0 everything 
                }

                Type[] ctorParams;
                object[] ctorValues; 
                switch(flags) {
                case  0: // ParameterName 
                case  1: // OleDbType 
                    ctorParams = new Type[] { typeof(string), typeof(OleDbType) };
                    ctorValues = new object[] { p.ParameterName, p.OleDbType }; 
                    break;
                case  2: // Size
                case  3: // Size, OleDbType
                    ctorParams = new Type[] { typeof(string), typeof(OleDbType), typeof(int) }; 
                    ctorValues = new object[] { p.ParameterName, p.OleDbType, p.Size };
                    break; 
                case  4: // SourceColumn 
                case  5: // SourceColumn, OleDbType
                case  6: // SourceColumn, Size 
                case  7: // SourceColumn, Size, OleDbType
                    ctorParams = new Type[] { typeof(string), typeof(OleDbType), typeof(int), typeof(string) };
                    ctorValues = new object[] { p.ParameterName, p.OleDbType, p.Size, p.SourceColumn };
                    break; 
                case  8: // Value
                    ctorParams = new Type[] { typeof(string), typeof(object) }; 
                    ctorValues = new object[] { p.ParameterName, p.Value }; 
                    break;
                default: // everything else 
                    if (0 == (32 & flags)) { // V1.0 everything
                        ctorParams = new Type[] {
                            typeof(string), typeof(OleDbType), typeof(int), typeof(ParameterDirection),
                            typeof(bool), typeof(byte), typeof(byte), typeof(string), 
                            typeof(DataRowVersion), typeof(object) };
                        ctorValues = new object[] { 
                            p.ParameterName, p.OleDbType,  p.Size, p.Direction, 
                            p.IsNullable, p.PrecisionInternal, p.ScaleInternal, p.SourceColumn,
                            p.SourceVersion, p.Value }; 
                    }
                    else { // v2.0 everything - round trip all browsable properties + precision/scale
                        ctorParams = new Type[] {
                            typeof(string), typeof(OleDbType), typeof(int), typeof(ParameterDirection), 
                            typeof(byte), typeof(byte),
                            typeof(string), typeof(DataRowVersion), typeof(bool), 
                            typeof(object) }; 
                        ctorValues = new object[] {
                            p.ParameterName, p.OleDbType,  p.Size, p.Direction, 
                            p.PrecisionInternal, p.ScaleInternal,
                            p.SourceColumn, p.SourceVersion, p.SourceColumnNullMapping,
                            p.Value };
                    } 
                    break;
                } 
                System.Reflection.ConstructorInfo ctor = typeof(OleDbParameter).GetConstructor(ctorParams); 
                return new System.ComponentModel.Design.Serialization.InstanceDescriptor(ctor, ctorValues);
            } 
        }
    }
}

// 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