X Tutup
#region License // The PostgreSQL License // // Copyright (C) 2015 The Npgsql Development Team // // Permission to use, copy, modify, and distribute this software and its // documentation for any purpose, without fee, and without a written // agreement is hereby granted, provided that the above copyright notice // and this paragraph and the following two paragraphs appear in all copies. // // IN NO EVENT SHALL THE NPGSQL DEVELOPMENT TEAM BE LIABLE TO ANY PARTY // FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, // INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS // DOCUMENTATION, EVEN IF THE NPGSQL DEVELOPMENT TEAM HAS BEEN ADVISED OF // THE POSSIBILITY OF SUCH DAMAGE. // // THE NPGSQL DEVELOPMENT TEAM SPECIFICALLY DISCLAIMS ANY WARRANTIES, // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY // AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS // ON AN "AS IS" BASIS, AND THE NPGSQL DEVELOPMENT TEAM HAS NO OBLIGATIONS // TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. #endregion using System; using System.ComponentModel; using System.Data; using System.Data.Common; using System.Diagnostics.Contracts; using System.Reflection; using NpgsqlTypes; #if WITHDESIGN using Npgsql.Design; #endif namespace Npgsql { /// /// This class represents a parameter to a command that will be sent to server /// #if WITHDESIGN [TypeConverter(typeof(NpgsqlParameterConverter))] #endif #if DNXCORE50 public sealed class NpgsqlParameter : DbParameter #else public sealed class NpgsqlParameter : DbParameter, ICloneable #endif { #region Fields and Properties // Fields to implement IDbDataParameter interface. byte _precision; byte _scale; int _size; // Fields to implement IDataParameter NpgsqlDbType? _npgsqlDbType; DbType? _dbType; Type _specificType; string _name = String.Empty; object _value; object _npgsqlValue; /// /// Can be used to communicate a value from the validation phase to the writing phase. /// internal object ConvertedValue { get; set; } NpgsqlParameterCollection _collection; internal LengthCache LengthCache { get; private set; } internal bool IsBound { get; private set; } internal TypeHandler Handler { get; private set; } internal FormatCode FormatCode { get; private set; } internal bool _autoAssignedName; #endregion #region Constructors /// /// Initializes a new instance of the NpgsqlParameter class. /// public NpgsqlParameter() { SourceColumn = String.Empty; Direction = ParameterDirection.Input; #if !DNXCORE50 SourceVersion = DataRowVersion.Current; #endif } /// /// Initializes a new instance of the NpgsqlParameter /// class with the parameter name and a value of the new NpgsqlParameter. /// /// The name of the parameter to map. /// An Object that is the value of the NpgsqlParameter. /// ///

When you specify an Object /// in the value parameter, the DbType is /// inferred from the .NET Framework type of the Object.

///

When using this constructor, you must be aware of a possible misuse of the constructor which takes a DbType parameter. /// This happens when calling this constructor passing an int 0 and the compiler thinks you are passing a value of DbType. /// Use Convert.ToInt32(value) for example to have compiler calling the correct constructor.

///
public NpgsqlParameter(String parameterName, object value) : this() { ParameterName = parameterName; Value = value; } /// /// Initializes a new instance of the NpgsqlParameter /// class with the parameter name and the data type. /// /// The name of the parameter to map. /// One of the DbType values. public NpgsqlParameter(string parameterName, NpgsqlDbType parameterType) : this(parameterName, parameterType, 0, String.Empty) { } /// /// Initializes a new instance of the NpgsqlParameter. /// /// The name of the parameter to map. /// One of the DbType values. public NpgsqlParameter(string parameterName, DbType parameterType) : this(parameterName, parameterType, 0, String.Empty) { } /// /// Initializes a new instance of the NpgsqlParameter. /// /// The name of the parameter to map. /// One of the NpgsqlDbType values. /// The length of the parameter. public NpgsqlParameter(string parameterName, NpgsqlDbType parameterType, int size) : this(parameterName, parameterType, size, String.Empty) { } /// /// Initializes a new instance of the NpgsqlParameter. /// /// The name of the parameter to map. /// One of the DbType values. /// The length of the parameter. public NpgsqlParameter(string parameterName, DbType parameterType, int size) : this(parameterName, parameterType, size, String.Empty) { } /// /// Initializes a new instance of the NpgsqlParameter /// /// The name of the parameter to map. /// One of the NpgsqlDbType values. /// The length of the parameter. /// The name of the source column. public NpgsqlParameter(string parameterName, NpgsqlDbType parameterType, int size, string sourceColumn) : this() { ParameterName = parameterName; NpgsqlDbType = parameterType; _size = size; SourceColumn = sourceColumn; } /// /// Initializes a new instance of the NpgsqlParameter. /// /// The name of the parameter to map. /// One of the DbType values. /// The length of the parameter. /// The name of the source column. public NpgsqlParameter(string parameterName, DbType parameterType, int size, string sourceColumn) : this() { ParameterName = parameterName; DbType = parameterType; _size = size; SourceColumn = sourceColumn; } #if !DNXCORE50 /// /// Initializes a new instance of the NpgsqlParameter. /// /// The name of the parameter to map. /// One of the NpgsqlDbType values. /// The length of the parameter. /// The name of the source column. /// One of the ParameterDirection values. /// true if the value of the field can be null, otherwise false. /// The total number of digits to the left and right of the decimal point to which /// Value is resolved. /// The total number of decimal places to which /// Value is resolved. /// One of the DataRowVersion values. /// An Object that is the value /// of the NpgsqlParameter. public NpgsqlParameter(string parameterName, NpgsqlDbType parameterType, int size, string sourceColumn, ParameterDirection direction, bool isNullable, byte precision, byte scale, DataRowVersion sourceVersion, object value) : this() { ParameterName = parameterName; Size = size; SourceColumn = sourceColumn; Direction = direction; IsNullable = isNullable; Precision = precision; Scale = scale; SourceVersion = sourceVersion; Value = value; NpgsqlDbType = parameterType; } /// /// Initializes a new instance of the NpgsqlParameter. /// /// The name of the parameter to map. /// One of the DbType values. /// The length of the parameter. /// The name of the source column. /// One of the ParameterDirection values. /// true if the value of the field can be null, otherwise false. /// The total number of digits to the left and right of the decimal point to which /// Value is resolved. /// The total number of decimal places to which /// Value is resolved. /// One of the DataRowVersion values. /// An Object that is the value /// of the NpgsqlParameter. public NpgsqlParameter(string parameterName, DbType parameterType, int size, string sourceColumn, ParameterDirection direction, bool isNullable, byte precision, byte scale, DataRowVersion sourceVersion, object value) : this() { ParameterName = parameterName; Size = size; SourceColumn = sourceColumn; Direction = direction; IsNullable = isNullable; Precision = precision; Scale = scale; SourceVersion = sourceVersion; Value = value; DbType = parameterType; } #endif #endregion #region Public Properties /// /// Gets or sets the value of the parameter. /// /// An Object that is the value of the parameter. /// The default value is null. #if !DNXCORE50 [TypeConverter(typeof(StringConverter)), Category("Data")] #endif public override object Value { get { return _value; } // [TODO] Check and validate data type. set { ClearBind(); _value = value; _npgsqlValue = value; ConvertedValue = null; } } /// /// Gets or sets the value of the parameter. /// /// An Object that is the value of the parameter. /// The default value is null. #if !DNXCORE50 [Category("Data")] #endif [TypeConverter(typeof(StringConverter))] public object NpgsqlValue { get { return _npgsqlValue; } set { ClearBind(); _value = value; _npgsqlValue = value; ConvertedValue = null; } } /// /// Gets or sets a value that indicates whether the parameter accepts null values. /// public override bool IsNullable { get; set; } /// /// Gets or sets a value indicating whether the parameter is input-only, /// output-only, bidirectional, or a stored procedure return value parameter. /// /// One of the ParameterDirection /// values. The default is Input. [DefaultValue(ParameterDirection.Input)] #if !DNXCORE50 [Category("Data")] #endif public override ParameterDirection Direction { get; set; } // Implementation of IDbDataParameter /// /// Gets or sets the maximum number of digits used to represent the /// Value property. /// /// The maximum number of digits used to represent the /// Value property. /// The default value is 0, which indicates that the data provider /// sets the precision for Value. [DefaultValue((Byte)0)] #if !DNXCORE50 [Category("Data")] #endif public override byte Precision { get { return _precision; } set { _precision = value; ClearBind(); } } /// /// Gets or sets the number of decimal places to which /// Value is resolved. /// /// The number of decimal places to which /// Value is resolved. The default is 0. [DefaultValue((Byte)0)] #if !DNXCORE50 [Category("Data")] #endif public override byte Scale { get { return _scale; } set { _scale = value; ClearBind(); } } /// /// Gets or sets the maximum size, in bytes, of the data within the column. /// /// The maximum size, in bytes, of the data within the column. /// The default value is inferred from the parameter value. [DefaultValue(0)] #if !DNXCORE50 [Category("Data")] #endif public override int Size { get { return _size; } set { if (value < -1) throw new ArgumentException(String.Format("Invalid parameter Size value '{0}'. The value must be greater than or equal to 0.", value)); Contract.EndContractBlock(); _size = value; ClearBind(); } } /// /// Gets or sets the DbType of the parameter. /// /// One of the DbType values. The default is Object. [DefaultValue(DbType.Object)] #if !DNXCORE50 [Category("Data"), RefreshProperties(RefreshProperties.All)] #endif public override DbType DbType { get { if (_dbType.HasValue) { return _dbType.Value; } if (_value != null) { // Infer from value return TypeHandlerRegistry.ToDbType(_value.GetType()); } return DbType.Object; } set { ClearBind(); if (value == DbType.Object) { _dbType = null; _npgsqlDbType = null; } else { _dbType = value; _npgsqlDbType = TypeHandlerRegistry.ToNpgsqlDbType(value); } } } /// /// Gets or sets the NpgsqlDbType of the parameter. /// /// One of the NpgsqlDbType values. The default is Unknown. [DefaultValue(NpgsqlDbType.Unknown)] #if !DNXCORE50 [Category("Data"), RefreshProperties(RefreshProperties.All)] #endif public NpgsqlDbType NpgsqlDbType { get { if (_npgsqlDbType.HasValue) { return _npgsqlDbType.Value; } if (_value != null) { // Infer from value return TypeHandlerRegistry.ToNpgsqlDbType(_value.GetType()); } return NpgsqlDbType.Unknown; } set { if (value == NpgsqlDbType.Array) { throw new ArgumentOutOfRangeException("value", "Cannot set NpgsqlDbType to just Array, Binary-Or with the element type (e.g. Array of Box is NpgsqlDbType.Array | NpgsqlDbType.Box)."); } if (value == NpgsqlDbType.Range) { throw new ArgumentOutOfRangeException("value", "Cannot set NpgsqlDbType to just Range, Binary-Or with the element type (e.g. Range of integer is NpgsqlDbType.Range | NpgsqlDbType.Integer)"); } Contract.EndContractBlock(); ClearBind(); _npgsqlDbType = value; _dbType = TypeHandlerRegistry.ToDbType(value); } } /// /// Gets or sets The name of the NpgsqlParameter. /// /// The name of the NpgsqlParameter. /// The default is an empty string. [DefaultValue("")] public override string ParameterName { get { return _name; } set { _name = value; if (value == null) { _name = String.Empty; } // no longer prefix with : so that The name returned is The name set _name = _name.Trim(); if (_collection != null) { _collection.InvalidateHashLookups(); ClearBind(); } _autoAssignedName = false; } } /// /// Gets or sets The name of the source column that is mapped to the /// DataSet and used for loading or /// returning the Value. /// /// The name of the source column that is mapped to the /// DataSet. The default is an empty string. [DefaultValue("")] #if !DNXCORE50 [Category("Data")] #endif public override String SourceColumn { get; set; } #if !DNXCORE50 /// /// Gets or sets the DataRowVersion /// to use when loading Value. /// /// One of the DataRowVersion values. /// The default is Current. [Category("Data"), DefaultValue(DataRowVersion.Current)] public override DataRowVersion SourceVersion { get; set; } #endif /// /// Source column mapping. /// public override bool SourceColumnNullMapping { get; set; } /// /// Used in combination with NpgsqlDbType.Enum or NpgsqlDbType.Array | NpgsqlDbType.Enum to indicate the enum type. /// For other NpgsqlDbTypes, this field is not used. /// [Obsolete("Use the SpecificType property instead")] public Type EnumType { get { return SpecificType; } set { SpecificType = value; } } /// /// Used in combination with NpgsqlDbType.Enum or NpgsqlDbType.Composite to indicate the specific enum or composite type. /// For other NpgsqlDbTypes, this field is not used. /// public Type SpecificType { get { if (_specificType != null) return _specificType; // Try to infer type if NpgsqlDbType is Enum or has not been set if ((!_npgsqlDbType.HasValue || _npgsqlDbType == NpgsqlDbType.Enum) && _value != null) { var type = _value.GetType(); if (type.GetTypeInfo().IsEnum) return type; if (type.IsArray && type.GetElementType().GetTypeInfo().IsEnum) return type.GetElementType(); } return null; } set { _specificType = value; } } /// /// The collection to which this parameter belongs, if any. /// public NpgsqlParameterCollection Collection { get { return _collection; } internal set { _collection = value; ClearBind(); } } #endregion #region Internals /// /// The name scrubbed of any optional marker /// internal string CleanName { get { string name = ParameterName; if (name.Length > 0 && (name[0] == ':' || name[0] == '@')) { return name.Substring(1); } return name; } } /// /// Returns whether this parameter has had its type set explicitly via DbType or NpgsqlDbType /// (and not via type inference) /// internal bool IsTypeExplicitlySet { get { return _npgsqlDbType.HasValue || _dbType.HasValue; } } internal void ResolveHandler(TypeHandlerRegistry registry) { if (Handler != null) { return; } if (_npgsqlDbType.HasValue) { Handler = registry[_npgsqlDbType.Value, SpecificType]; } else if (_dbType.HasValue) { Handler = registry[_dbType.Value]; } else if (_value != null) { Handler = registry[_value]; } else { throw new InvalidOperationException(string.Format("Parameter '{0}' must have its value set", ParameterName)); } } internal void Bind(TypeHandlerRegistry registry) { ResolveHandler(registry); Contract.Assert(Handler != null); FormatCode = Handler.PreferTextWrite ? FormatCode.Text : FormatCode.Binary; IsBound = true; } internal int ValidateAndGetLength() { if (_value == null) { throw new InvalidCastException(string.Format("Parameter {0} must be set", ParameterName)); } if (_value is DBNull) { return 0; } // No length caching for simple types var asSimpleWriter = Handler as ISimpleTypeHandler; if (asSimpleWriter != null) { return asSimpleWriter.ValidateAndGetLength(Value, this); } var asChunkingWriter = Handler as IChunkingTypeHandler; Contract.Assert(asChunkingWriter != null, String.Format("Handler {0} doesn't implement either ISimpleTypeWriter or IChunkingTypeWriter", Handler.GetType().Name)); var lengthCache = LengthCache; var len = asChunkingWriter.ValidateAndGetLength(Value, ref lengthCache, this); LengthCache = lengthCache; return len; } void ClearBind() { IsBound = false; Handler = null; } /// /// Reset DBType. /// public override void ResetDbType() { //type_info = NpgsqlTypesHelper.GetNativeTypeInfo(typeof(String)); _dbType = null; _npgsqlDbType = null; Value = Value; ClearBind(); } internal bool IsInputDirection { get { return Direction == ParameterDirection.InputOutput || Direction == ParameterDirection.Input; } } internal bool IsOutputDirection { get { return Direction == ParameterDirection.InputOutput || Direction == ParameterDirection.Output; } } #endregion #region Clone /// /// Creates a new NpgsqlParameter that /// is a copy of the current instance. /// /// A new NpgsqlParameter that is a copy of this instance. public NpgsqlParameter Clone() { // use fields instead of properties // to avoid auto-initializing something like type_info var clone = new NpgsqlParameter(); clone._precision = _precision; clone._scale = _scale; clone._size = _size; clone._dbType = _dbType; clone._npgsqlDbType = _npgsqlDbType; clone._specificType = _specificType; clone.Direction = Direction; clone.IsNullable = IsNullable; clone._name = _name; clone.SourceColumn = SourceColumn; #if !DNXCORE50 clone.SourceVersion = SourceVersion; #endif clone._value = _value; clone._npgsqlValue = _npgsqlValue; clone.SourceColumnNullMapping = SourceColumnNullMapping; clone._autoAssignedName = _autoAssignedName; return clone; } #if !DNXCORE50 object ICloneable.Clone() { return Clone(); } #endif #endregion } }
X Tutup