Beispiel #1
0
		/// <summary>
		/// Get one of the known data types. Data types
		/// are created automatically during model deserialization.
		/// </summary>
		/// <param name="portableType">PortableDataType value</param>
		/// <returns>Known type, or throws if out of range</returns>
		public DataType GetPortableDataType(PortableDataType portableType)
		{
			return myPortableTypes[(int)portableType];
		}
Beispiel #2
0
 /// <summary>
 /// Get one of the known data types. Data types
 /// are created automatically during model deserialization.
 /// </summary>
 /// <param name="portableType">PortableDataType value</param>
 /// <returns>Known type, or throws if out of range</returns>
 public DataType GetPortableDataType(PortableDataType portableType)
 {
     return(myPortableTypes[(int)portableType]);
 }
Beispiel #3
0
        /// <summary>
        /// Check if two data types can be compared. This is a weaker check
        /// than <see cref="IsAssignableValueType"/> in that it does not
        /// do any facet checking to see if one value can store the only,
        /// but only checks if the two can be compared.
        /// </summary>
        /// <param name="valueType1">The first value type to compare.</param>
        /// <param name="valueType2">The second value type to compare.</param>
        /// <param name="equalityOnly">Set to true if the equality or inequality
        /// of the two values is required, but an ordered check is not.</param>
        /// <returns><see langword="true"/> if the two types can be compared.</returns>
        public static bool IsComparableValueType(ObjectType valueType1, ObjectType valueType2, bool equalityOnly)
        {
            DataType dataType1 = valueType1.DataType;
            DataType dataType2 = valueType2.DataType;

            if (dataType1 == dataType2)
            {
                switch (dataType1.PortableDataType)
                {
                case PortableDataType.Unspecified:
                    // Give the user the benefit of the doubt that fixing the
                    // unspecified data type will result in comparable values.
                    return(true);

                case PortableDataType.NumericAutoCounter:
                    // Only support this if the value types are the same. Otherwise, we're mapping different
                    // counters to each other, which is meaningless.
                    return(valueType1 == valueType2);

                default:
                    return(dataType1.CanCompare && (equalityOnly || (dataType1.RangeSupport != DataTypeRangeSupport.None)));
                }
            }
            else if (dataType1.CanCompare &&
                     dataType2.CanCompare &&
                     (equalityOnly || (dataType1.RangeSupport != DataTypeRangeSupport.None && dataType2.RangeSupport != DataTypeRangeSupport.None)))
            {
                // Look at specific types.
                PortableDataType targetType = dataType1.PortableDataType;
                PortableDataType sourceType = dataType2.PortableDataType;
                if (sourceType == PortableDataType.Unspecified)
                {
                    // Give user the benefit of the doubt that the types will be made comparable
                    // if this choice is made.
                    return(true);
                }
                switch (targetType)
                {
                case PortableDataType.Unspecified:
                    // Let user fix
                    return(true);

                case PortableDataType.TextFixedLength:
                case PortableDataType.TextVariableLength:
                case PortableDataType.TextLargeLength:
                    switch (sourceType)
                    {
                    case PortableDataType.TextFixedLength:
                    case PortableDataType.TextVariableLength:
                    case PortableDataType.TextLargeLength:
                        return(true);
                    }
                    break;

                case PortableDataType.NumericSignedInteger:
                case PortableDataType.NumericSignedSmallInteger:
                case PortableDataType.NumericSignedLargeInteger:
                case PortableDataType.NumericUnsignedInteger:
                case PortableDataType.NumericUnsignedTinyInteger:
                case PortableDataType.NumericUnsignedSmallInteger:
                case PortableDataType.NumericUnsignedLargeInteger:
                case PortableDataType.NumericFloatingPoint:
                case PortableDataType.NumericSinglePrecisionFloatingPoint:
                case PortableDataType.NumericDoublePrecisionFloatingPoint:
                case PortableDataType.NumericDecimal:
                case PortableDataType.NumericMoney:
                    switch (sourceType)
                    {
                    case PortableDataType.NumericSignedInteger:
                    case PortableDataType.NumericSignedSmallInteger:
                    case PortableDataType.NumericSignedLargeInteger:
                    case PortableDataType.NumericUnsignedInteger:
                    case PortableDataType.NumericUnsignedTinyInteger:
                    case PortableDataType.NumericUnsignedSmallInteger:
                    case PortableDataType.NumericUnsignedLargeInteger:
                    case PortableDataType.NumericFloatingPoint:
                    case PortableDataType.NumericSinglePrecisionFloatingPoint:
                    case PortableDataType.NumericDoublePrecisionFloatingPoint:
                    case PortableDataType.NumericDecimal:
                    case PortableDataType.NumericMoney:
                        return(true);
                    }
                    break;
                //case PortableDataType.RawDataFixedLength:
                //case PortableDataType.RawDataVariableLength:
                //case PortableDataType.RawDataLargeLength:
                //case PortableDataType.RawDataPicture:
                //case PortableDataType.RawDataOleObject:
                // Raw data types are not comparable, these cases would form a dead code path.

                //case PortableDataType.NumericAutoCounter:
                //case PortableDataType.TemporalTime:
                //case PortableDataType.TemporalDate:
                //case PortableDataType.OtherRowId:
                //case PortableDataType.OtherObjectId:
                // These compare only to themselves, will be caught in first if block

                case PortableDataType.TemporalAutoTimestamp:
                case PortableDataType.TemporalDateAndTime:
                    switch (sourceType)
                    {
                    case PortableDataType.TemporalAutoTimestamp:
                    case PortableDataType.TemporalDateAndTime:
                        return(true);
                    }
                    break;

                case PortableDataType.LogicalTrueOrFalse:
                case PortableDataType.LogicalYesOrNo:
                    switch (sourceType)
                    {
                    case PortableDataType.LogicalTrueOrFalse:
                    case PortableDataType.LogicalYesOrNo:
                        return(true);
                    }
                    break;
                }
            }
            return(false);
        }
Beispiel #4
0
        /// <summary>
        /// Test if an instance of one value type can be always be assigned to
        /// an instance of another value type.
        /// </summary>
        /// <param name="targetValueType">The type of the value being assigned to.</param>
        /// <param name="sourceValueType">The type of the value being assigned from.</param>
        /// <returns><see langword="true"/> if the source value can be assigned to the target value.</returns>
        /// <remarks>If either data type is unspecified, then the assumption is made that there is an error
        /// for this condition elsewhere and that the user will fix it, so this method returns true in these
        /// cases. Autogenerated values are assumed to be incompatible if they come from different value types
        /// because assigning autogenerated values to each other is also meaningingless.</remarks>
        public static bool IsAssignableValueType(ObjectType targetValueType, ObjectType sourceValueType)
        {
            if (targetValueType == sourceValueType)
            {
                return(true);
            }
            ValueTypeHasDataType targetUse;
            ValueTypeHasDataType sourceUse;

            if (null == (targetUse = ValueTypeHasDataType.GetLinkToDataType(targetValueType)) ||
                null == (sourceUse = ValueTypeHasDataType.GetLinkToDataType(sourceValueType)))
            {
                return(false);
            }
            PortableDataType targetType = targetUse.DataType.PortableDataType;
            PortableDataType sourceType = sourceUse.DataType.PortableDataType;

            if (sourceType == PortableDataType.Unspecified)
            {
                // Give user the benefit of the doubt that the types will be made compatible
                // if this choice is made.
                return(true);
            }
            int targetLength;
            int sourceLength;
            int targetScale;
            int sourceScale;

            switch (targetType)
            {
            case PortableDataType.Unspecified:
                // Let user fix
                return(true);

            case PortableDataType.TextFixedLength:
            case PortableDataType.TextVariableLength:
            case PortableDataType.TextLargeLength:
                switch (sourceType)
                {
                case PortableDataType.TextFixedLength:
                case PortableDataType.TextVariableLength:
                case PortableDataType.TextLargeLength:
                    targetLength = targetUse.Length;
                    sourceLength = sourceUse.Length;
                    return((targetLength == 0 ? int.MaxValue : targetLength) >= (sourceLength == 0 ? int.MaxValue : sourceLength));
                }
                break;

            case PortableDataType.NumericSignedInteger:
                switch (sourceType)
                {
                case PortableDataType.NumericSignedInteger:
                case PortableDataType.NumericSignedSmallInteger:
                    return(true);

                case PortableDataType.NumericDecimal:
                    if (sourceUse.Scale == 0)
                    {
                        sourceLength = sourceUse.Length;
                        if (sourceLength != 0 && sourceLength <= 9)                                         // 10 might be too big
                        {
                            return(true);
                        }
                    }
                    break;
                }
                break;

            case PortableDataType.NumericSignedSmallInteger:
                switch (sourceType)
                {
                case PortableDataType.NumericSignedSmallInteger:
                    return(true);

                case PortableDataType.NumericDecimal:
                    if (sourceUse.Scale == 0)
                    {
                        sourceLength = sourceUse.Length;
                        if (sourceLength != 0 && sourceLength <= 4)                                         // 5 might be too big
                        {
                            return(true);
                        }
                    }
                    break;
                }
                break;

            case PortableDataType.NumericSignedLargeInteger:
                switch (sourceType)
                {
                case PortableDataType.NumericSignedInteger:
                case PortableDataType.NumericSignedSmallInteger:
                case PortableDataType.NumericSignedLargeInteger:
                    return(true);

                case PortableDataType.NumericDecimal:
                    if (sourceUse.Scale == 0)
                    {
                        sourceLength = sourceUse.Length;
                        if (sourceLength != 0 && sourceLength <= 18)                                         // 19 might be too big
                        {
                            return(true);
                        }
                    }
                    break;
                }
                break;

            case PortableDataType.NumericUnsignedInteger:
                switch (sourceType)
                {
                case PortableDataType.NumericUnsignedInteger:
                case PortableDataType.NumericUnsignedTinyInteger:
                case PortableDataType.NumericUnsignedSmallInteger:
                    return(true);
                }
                break;

            case PortableDataType.NumericUnsignedTinyInteger:
                switch (sourceType)
                {
                case PortableDataType.NumericUnsignedTinyInteger:
                    return(true);
                }
                break;

            case PortableDataType.NumericUnsignedSmallInteger:
                switch (sourceType)
                {
                case PortableDataType.NumericUnsignedTinyInteger:
                case PortableDataType.NumericUnsignedSmallInteger:
                    return(true);
                }
                break;

            case PortableDataType.NumericUnsignedLargeInteger:
                switch (sourceType)
                {
                case PortableDataType.NumericUnsignedInteger:
                case PortableDataType.NumericUnsignedTinyInteger:
                case PortableDataType.NumericUnsignedSmallInteger:
                case PortableDataType.NumericUnsignedLargeInteger:
                    return(true);
                }
                break;

            //case PortableDataType.NumericAutoCounter:
            // Only support this if the value types are the same. Otherwise, we're mapping different
            // counters to each other, which is meaningless.
            case PortableDataType.NumericFloatingPoint:
            case PortableDataType.NumericSinglePrecisionFloatingPoint:
            case PortableDataType.NumericDoublePrecisionFloatingPoint:
                switch (sourceType)
                {
                case PortableDataType.NumericFloatingPoint:
                    sourceLength = sourceUse.Length;
                    if (sourceLength == 0)
                    {
                        sourceLength = 53;
                    }
                    break;

                case PortableDataType.NumericSinglePrecisionFloatingPoint:
                    sourceLength = 24;
                    break;

                case PortableDataType.NumericDoublePrecisionFloatingPoint:
                    sourceLength = 53;
                    break;

                default:
                    sourceLength = -1;
                    break;
                }
                if (sourceLength != -1)
                {
                    switch (targetType)
                    {
                    case PortableDataType.NumericSinglePrecisionFloatingPoint:
                        targetLength = 24;
                        break;

                    case PortableDataType.NumericDoublePrecisionFloatingPoint:
                        targetLength = 53;
                        break;

                    //case PortableDataType.NumericFloatingPoint:
                    default:
                        targetLength = targetUse.Length;
                        if (targetLength == 0)
                        {
                            targetLength = 53;
                        }
                        break;
                    }
                    if (targetLength >= sourceLength)
                    {
                        return(true);
                    }
                }
                break;

            case PortableDataType.NumericDecimal:
            case PortableDataType.NumericMoney:
                sourceScale = 0;
                switch (sourceType)
                {
                case PortableDataType.NumericDecimal:
                    sourceLength = sourceUse.Length;
                    if (sourceLength == 0)
                    {
                        sourceLength = 18;
                    }
                    else
                    {
                        sourceScale = sourceUse.Scale;
                    }
                    break;

                case PortableDataType.NumericMoney:
                    sourceLength = 19;
                    sourceScale  = 4;
                    break;

                case PortableDataType.NumericSignedInteger:
                case PortableDataType.NumericUnsignedInteger:
                    sourceLength = 10;
                    break;

                case PortableDataType.NumericSignedSmallInteger:
                case PortableDataType.NumericUnsignedSmallInteger:
                    sourceLength = 5;
                    break;

                case PortableDataType.NumericSignedLargeInteger:
                    sourceLength = 19;
                    break;

                case PortableDataType.NumericUnsignedLargeInteger:
                    sourceLength = 20;
                    break;

                case PortableDataType.NumericUnsignedTinyInteger:
                    sourceLength = 3;
                    break;

                default:
                    sourceLength = -1;
                    break;
                }
                if (sourceLength != -1)
                {
                    if (targetType == PortableDataType.NumericMoney)
                    {
                        targetLength = 19;
                        targetScale  = 4;
                    }
                    else
                    {
                        targetLength = targetUse.Length;                                 // Length maps to precision, verify precision first, then scale
                        if (targetLength == 0)
                        {
                            targetLength = 18;
                            targetScale  = 0;
                        }
                        else
                        {
                            targetScale = targetUse.Scale;
                        }
                    }
                    if (targetLength >= sourceLength && targetScale >= sourceScale)
                    {
                        return(true);
                    }
                }
                break;

            case PortableDataType.RawDataFixedLength:
            case PortableDataType.RawDataVariableLength:
            case PortableDataType.RawDataLargeLength:
                switch (sourceType)
                {
                case PortableDataType.RawDataFixedLength:
                case PortableDataType.RawDataVariableLength:
                case PortableDataType.RawDataLargeLength:
                    targetLength = targetUse.Length;
                    sourceLength = sourceUse.Length;
                    return((targetLength == 0 ? int.MaxValue : targetLength) >= (sourceLength == 0 ? int.MaxValue : sourceLength));
                }
                break;

            case PortableDataType.RawDataPicture:
            case PortableDataType.RawDataOleObject:
            case PortableDataType.TemporalTime:
            case PortableDataType.TemporalDate:
            case PortableDataType.OtherRowId:
            case PortableDataType.OtherObjectId:
                if (sourceType == targetType)
                {
                    return(true);
                }
                break;

            case PortableDataType.TemporalAutoTimestamp:
            case PortableDataType.TemporalDateAndTime:
                switch (sourceType)
                {
                case PortableDataType.TemporalAutoTimestamp:
                case PortableDataType.TemporalTime:
                case PortableDataType.TemporalDate:
                case PortableDataType.TemporalDateAndTime:
                    return(true);
                }
                break;

            case PortableDataType.LogicalTrueOrFalse:
            case PortableDataType.LogicalYesOrNo:
                switch (sourceType)
                {
                case PortableDataType.LogicalTrueOrFalse:
                case PortableDataType.LogicalYesOrNo:
                    return(true);
                }
                break;
            }
            return(false);
        }