internal override ProviderType GetApplicationType(int index)
		{
			if(index < 0)
				throw Error.ArgumentOutOfRange("index");
			SqlType result = null;
			if(!applicationTypes.TryGetValue(index, out result))
			{
				result = new SqlType(index);
				applicationTypes.Add(index, result);
			}
			return result;
		}
Пример #2
0
		internal override int? DetermineParameterSize(SqlType declaredType, DbParameter parameter)
		{
			int? parameterSize = base.DetermineParameterSize(declaredType, parameter);
			if(parameterSize.HasValue)
			{
				return parameterSize;
			}

			// Engine team have recommended we use 4k/8k block sizes rather than -1 providing the
			// data fits within that size.
			int? largestDeclarableSize = GetLargestDeclarableSize(declaredType);
			if(largestDeclarableSize.HasValue && largestDeclarableSize.Value >= parameter.Size)
			{
				return largestDeclarableSize.Value;
			}

			// Providers that support the maximum size large type indicator should fall to that.
			return ProviderConstants.LargeTypeSizeIndicator;
		}
		internal override ProviderType GetBestType(ProviderType typeA, ProviderType typeB)
		{
			// first determine the type precedence
			SqlType bestType = (SqlType)(typeA.ComparePrecedenceTo(typeB) > 0 ? typeA : typeB);

			// if one of the types is a not a server type, return
			// that type
			if(typeA.IsApplicationType || typeA.IsRuntimeOnlyType)
			{
				return typeA;
			}
			if(typeB.IsApplicationType || typeB.IsRuntimeOnlyType)
			{
				return typeB;
			}

			SqlType sqlTypeA = (SqlType)typeA;
			SqlType sqlTypeB = (SqlType)typeB;
			if(sqlTypeA.HasPrecisionAndScale && sqlTypeB.HasPrecisionAndScale && bestType.SqlDbType == SqlDbType.Decimal)
			{
				int p0 = sqlTypeA.Precision;
				int s0 = sqlTypeA.Scale;
				int p1 = sqlTypeB.Precision;
				int s1 = sqlTypeB.Scale;
				// precision and scale may be zero if this is an unsized type.
				if(p0 == 0 && s0 == 0 && p1 == 0 && s1 == 0)
				{
					return SqlTypeSystem.Create(bestType.SqlDbType);
				}
				else if(p0 == 0 && s0 == 0)
				{
					return SqlTypeSystem.Create(bestType.SqlDbType, p1, s1);
				}
				else if(p1 == 0 && s1 == 0)
				{
					return SqlTypeSystem.Create(bestType.SqlDbType, p0, s0);
				}
				// determine best scale/precision
				int bestLeft = Math.Max(p0 - s0, p1 - s1);
				int bestRight = Math.Max(s0, s1);
				int precision = Math.Min(bestLeft + bestRight, 38);
				return SqlTypeSystem.Create(bestType.SqlDbType, precision, /*scale*/bestRight);
			}
			else
			{
				// determine the best size
				int? bestSize = null;

				if(sqlTypeA.Size.HasValue && sqlTypeB.Size.HasValue)
				{
					bestSize = (sqlTypeB.Size > sqlTypeA.Size) ? sqlTypeB.Size : sqlTypeA.Size;
				}

				if(sqlTypeB.Size.HasValue && sqlTypeB.Size.Value == ProviderConstants.LargeTypeSizeIndicator
				   || sqlTypeA.Size.HasValue && sqlTypeA.Size.Value == ProviderConstants.LargeTypeSizeIndicator)
				{
					// the large type size trumps all
					bestSize = ProviderConstants.LargeTypeSizeIndicator;
				}

				bestType = new SqlType(bestType.SqlDbType, bestSize);
			}

			return bestType;
		}
		protected object GetParameterValue(SqlType type, object value)
		{
			if(value == null)
			{
				return DBNull.Value;
			}
			else
			{
				Type vType = value.GetType();
				Type pType = type.GetClosestRuntimeType();
				if(pType == vType)
				{
					return value;
				}
				else
				{
					return DBConvert.ChangeType(value, pType);
				}
			}
		}
		protected int? GetLargestDeclarableSize(SqlType declaredType)
		{
			switch(declaredType.SqlDbType)
			{
				case SqlDbType.Image:
				case SqlDbType.Binary:
				case SqlDbType.VarChar:
					return 8000;
				case SqlDbType.NVarChar:
					return 4000;
				default:
					return null;
			}
		}
		internal virtual int? DetermineParameterSize(SqlType declaredType, DbParameter parameter)
		{
			// Output parameters and input-parameters of a fixed-size should be specifically set if value fits.
			bool isInputParameter = parameter.Direction == ParameterDirection.Input;
			if(!isInputParameter || declaredType.IsFixedSize)
			{
				if(declaredType.Size.HasValue && parameter.Size <= declaredType.Size || declaredType.IsLargeType)
				{
					return declaredType.Size.Value;
				}
			}

			// Preserve existing provider & server-driven behaviour for all other cases.
			return null;
		}