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; }
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; }