OleDbParameter.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / whidbey / netfxsp / ndp / fx / src / Data / System / Data / OleDb / OleDbParameter.cs / 1 / 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))
    ]
#if WINFSInternalOnly
    internal 
#else
    public 
#endif 
    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.
//------------------------------------------------------------------------------ 
// 
//      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))
    ]
#if WINFSInternalOnly
    internal 
#else
    public 
#endif 
    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