Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / whidbey / NetFxQFE / 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
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- IPGlobalProperties.cs
- ContentOperations.cs
- DesignerDataConnection.cs
- WebPartEditorOkVerb.cs
- NamedElement.cs
- WorkflowInstanceTerminatedRecord.cs
- serverconfig.cs
- TagElement.cs
- DataListCommandEventArgs.cs
- TextServicesCompartmentEventSink.cs
- EventLogReader.cs
- QueryAccessibilityHelpEvent.cs
- BoolExpression.cs
- SqlSelectStatement.cs
- FontFamilyIdentifier.cs
- SqlClientWrapperSmiStreamChars.cs
- ExecutorLocksHeldException.cs
- HostingPreferredMapPath.cs
- CSharpCodeProvider.cs
- DeclaredTypeValidatorAttribute.cs
- DSACryptoServiceProvider.cs
- Stackframe.cs
- ProfileGroupSettings.cs
- PersistenceContextEnlistment.cs
- FixedBufferAttribute.cs
- UserNamePasswordServiceCredential.cs
- Collection.cs
- ResourceReferenceKeyNotFoundException.cs
- ValueUtilsSmi.cs
- NamespaceCollection.cs
- DataRecordInternal.cs
- infer.cs
- FormParameter.cs
- Variant.cs
- Matrix3DValueSerializer.cs
- SettingsPropertyValueCollection.cs
- WorkflowPersistenceContext.cs
- ListViewSortEventArgs.cs
- TheQuery.cs
- CodeNamespaceImport.cs
- SendAgentStatusRequest.cs
- AppSettingsSection.cs
- SudsCommon.cs
- NominalTypeEliminator.cs
- InsufficientMemoryException.cs
- DependencyPropertyKind.cs
- LogLogRecord.cs
- RowToParametersTransformer.cs
- WrapPanel.cs
- AspNetCacheProfileAttribute.cs
- ListViewEditEventArgs.cs
- TypeDescriptionProviderAttribute.cs
- WorkflowViewService.cs
- ManagedIStream.cs
- PositiveTimeSpanValidatorAttribute.cs
- DbgUtil.cs
- Quaternion.cs
- FrameSecurityDescriptor.cs
- IfAction.cs
- ZipPackagePart.cs
- ReflectionHelper.cs
- Models.cs
- ObjectDataSourceDesigner.cs
- StoreItemCollection.cs
- TaskResultSetter.cs
- Int32Animation.cs
- EasingKeyFrames.cs
- DateTimeFormatInfo.cs
- InstallHelper.cs
- Canvas.cs
- RadioButton.cs
- SecUtil.cs
- TokenCreationParameter.cs
- ApplicationServicesHostFactory.cs
- DesignerMetadata.cs
- FieldAccessException.cs
- ErrorStyle.cs
- BitmapSourceSafeMILHandle.cs
- GridViewRowCollection.cs
- ProxyFragment.cs
- CallbackDebugBehavior.cs
- PathTooLongException.cs
- Ref.cs
- EnumType.cs
- DataGridViewHeaderCell.cs
- StorageAssociationSetMapping.cs
- dsa.cs
- ExpandoObject.cs
- TemplateControlParser.cs
- FixedPage.cs
- PipeStream.cs
- PeerNearMe.cs
- XmlUtil.cs
- WebBrowserSiteBase.cs
- XsdCachingReader.cs
- ObjectSet.cs
- BitmapEffectGroup.cs
- Annotation.cs
- TagMapInfo.cs
- ExtendedProperty.cs