/// <summary> /// Determines whether a given type supports arithmetic operations /// </summary> /// <param name="queryScalarType">The type to test for arithmetic operation support</param> /// <returns>A boolean value indicating whether the type supports arithmetic operations</returns> protected bool SupportsArithmeticOperations(QueryScalarType queryScalarType) { foreach (QueryBinaryOperation op in this.arithmeticOperations) { if (!queryScalarType.Supports(op)) { return(false); } } return(true); }
/// <summary> /// Checks whether 2 QueryScalarTypes are representing the same type. /// </summary> /// <param name="type1">The first scalar type.</param> /// <param name="type2">The second scalar type.</param> /// <returns>True if the scalar types are the same, false otherwise.</returns> public static bool IsSameQueryScalarType(this QueryScalarType type1, QueryScalarType type2) { // All query scalar types have clr types, its sufficient to filter out constants that the same clr type. var clrType1 = type1 as IQueryClrType; var clrType2 = type2 as IQueryClrType; ExceptionUtilities.Assert(clrType1 != null, "Scalar Types must always have a Clr type"); ExceptionUtilities.Assert(clrType2 != null, "Scalar Types must always have a Clr type"); if (clrType1.ClrType == clrType2.ClrType) { return(true); } return(false); }
/// <summary> /// Compares the given values of the given type, and throws a DataComparisonException or AssertionFailedException if values don't match /// </summary> /// <param name="type">The expected type</param> /// <param name="expected">The expected value</param> /// <param name="actual">The actual value</param> /// <param name="assert">The assertion handler to use</param> protected virtual void Compare(QueryScalarType type, object expected, object actual, AssertionHandler assert) { ExceptionUtilities.CheckArgumentNotNull(type, "type"); ExceptionUtilities.CheckArgumentNotNull(assert, "assert"); if (expected == type.NullValue.Value) { assert.IsNull(actual, "Primitive value unexpectedly non-null"); } else { assert.IsNotNull(actual, "Primitive value unexpectedly null"); assert.AreEqual(expected.GetType(), actual.GetType(), EqualityComparer<Type>.Default, "Types did not match"); var comparer = new DelegateBasedEqualityComparer<QueryScalarValue>((v1, v2) => v1.Type.EvaluationStrategy.Compare(v1, v2) == 0); assert.AreEqual(type.CreateValue(expected), type.CreateValue(actual), comparer, "Primitive value did not match"); } }
/// <summary> /// Build the collection of primitive types which will be set on the constructed repository /// </summary> /// <param name="queryTypeLibrary">Query Type Library to build Types from</param> protected override void BuildPrimitiveTypes(QueryTypeLibrary queryTypeLibrary) { this.intType = (QueryScalarType)queryTypeLibrary.GetDefaultQueryType(EdmDataTypes.Int32); this.stringType = (QueryScalarType)queryTypeLibrary.GetDefaultQueryType(EdmDataTypes.String()); this.PrimitiveTypes = new List<QueryScalarType>() { // this is just a sample this.intType, this.stringType, (QueryScalarType)queryTypeLibrary.GetDefaultQueryType(EdmDataTypes.Boolean), (QueryScalarType)queryTypeLibrary.GetDefaultQueryType(EdmDataTypes.DateTime()), (QueryScalarType)queryTypeLibrary.GetDefaultQueryType(EdmDataTypes.Decimal()), (QueryScalarType)queryTypeLibrary.GetDefaultQueryType(EdmDataTypes.Int64), (QueryScalarType)queryTypeLibrary.GetDefaultQueryType(EdmDataTypes.Int16), (QueryScalarType)queryTypeLibrary.GetDefaultQueryType(EdmDataTypes.Byte), (QueryScalarType)queryTypeLibrary.GetDefaultQueryType(EdmDataTypes.Single), (QueryScalarType)queryTypeLibrary.GetDefaultQueryType(EdmDataTypes.Double), (QueryScalarType)queryTypeLibrary.GetDefaultQueryType(EdmDataTypes.Binary()), (QueryScalarType)queryTypeLibrary.GetDefaultQueryType(EdmDataTypes.Guid), }; }
/// <summary> /// Sets query types for a given Enum Type /// </summary> /// <param name="enumType">The enum type</param> /// <param name="queryType">The corresponding query type.</param> internal void SetQueryEnumType(EnumType enumType, QueryScalarType queryType) { this.defaultQueryEnumTypes[enumType] = queryType; }
/// <summary> /// Determines whether data of this type can do certain operation with data of another type /// </summary> /// <param name="operation">the operation</param> /// <param name="otherScalarType">the other data type</param> /// <returns>Value <c>true</c> if operation can be performed; otherwise, <c>false</c>.</returns> public bool Supports(QueryBinaryOperation operation, QueryScalarType otherScalarType) { ExceptionUtilities.CheckArgumentNotNull(otherScalarType, "otherScalarType"); return this.EvaluationStrategy.Supports(operation, this, otherScalarType); }
/// <summary> /// Determines whether a given type supports arithmetic operations /// </summary> /// <param name="queryScalarType">The type to test for arithmetic operation support</param> /// <returns>A boolean value indicating whether the type supports arithmetic operations</returns> protected bool SupportsArithmeticOperations(QueryScalarType queryScalarType) { foreach (QueryBinaryOperation op in this.arithmeticOperations) { if (!queryScalarType.Supports(op)) { return false; } } return true; }
/// <summary> /// Evaluates canonical function. /// </summary> /// <param name="resultType">The function result type.</param> /// <param name="classType">Type of the class.</param> /// <param name="methodName">Name of the method.</param> /// <param name="arguments">The arguments for the function call.</param> /// <returns> /// Query value which is the result of the function evaluation. /// </returns> private QueryValue EvaluateMethod(QueryScalarType resultType, Type classType, string methodName, params QueryScalarValue[] arguments) { var argsTypes = arguments.Select(a => ((IQueryClrType)a.Type).ClrType).ToArray(); var method = classType.GetMethod(methodName, argsTypes); if (method == null) { argsTypes = argsTypes.Skip(1).ToArray(); method = classType.GetMethod(methodName, argsTypes, true, false); } ExceptionUtilities.CheckObjectNotNull(method, "Could not find instance or static method '{0}' on type '{1}'", methodName, classType.FullName); object[] argsValues = arguments.Select(a => a.Value).ToArray(); object value = null; if (method.IsStatic) { value = method.Invoke(null, argsValues); } else if (argsValues[0] != null) { // null needs to be propagated for instance methods, otherwise this will fail value = method.Invoke(argsValues[0], argsValues.Skip(1).ToArray()); } return resultType.CreateValue(value); }
/// <summary> /// Determines whether a typed data can do certain operation with another typed data /// </summary> /// <param name="operation">the operation</param> /// <param name="sourceType">the type of data to operation on</param> /// <param name="otherType">the other type</param> /// <returns>Value <c>true</c> if operation can be performed; otherwise, <c>false</c>.</returns> public override bool Supports(QueryBinaryOperation operation, QueryScalarType sourceType, QueryScalarType otherType) { if (this.IsSpatialType((IQueryClrType)sourceType) || this.IsSpatialType((IQueryClrType)otherType)) { return false; } return base.Supports(operation, sourceType, otherType); }
/// <summary> /// Gets the common type to which both types can be promoted. /// </summary> /// <param name="leftType">First type.</param> /// <param name="rightType">Second type.</param> /// <returns>Common type to which both types can be promoted. Throws if unable to find a common type.</returns> public QueryScalarType GetCommonType(QueryScalarType leftType, QueryScalarType rightType) { throw new TaupoNotSupportedException("Attempt to use evaluation strategy from " + typeof(QueryUnresolvedType).Name + ". Please resolve expression first."); }
/// <summary> /// Casts a <see cref="QueryScalarValue"/> to a <see cref="QueryScalarType"/>. The cast will return the value type cast to the new type. /// </summary> /// <param name="source">The source for the cast operation.</param> /// <param name="type">The type for the cast operation.</param> /// <returns><see cref="QueryScalarValue"/> which is cast to the appropriate type</returns> public QueryScalarValue Cast(QueryScalarValue source, QueryScalarType type) { throw new TaupoNotSupportedException("Attempt to use evaluation strategy from " + typeof(QueryUnresolvedType).Name + ". Please resolve expression first."); }
/// <summary> /// Transforms a value from one scalar type to another. /// </summary> /// <param name="valueToTransform">The value to transform.</param> /// <param name="targetType">The target type of the value.</param> /// <returns>The value transformed to the target type.</returns> public static QueryScalarValue MaterializeValueIfEnum(this QueryScalarValue valueToTransform, QueryScalarType targetType) { ExceptionUtilities.CheckArgumentNotNull(targetType, "targetType"); var clrType = ((IQueryClrType)targetType).ClrType; Type clrEnumType; object enumValue = null; if (TryExtractEnumType(clrType, out clrEnumType)) { if (valueToTransform.Value != null) { enumValue = Enum.ToObject(clrEnumType, valueToTransform.Value); } return(targetType.CreateValue(enumValue)); } else { return(valueToTransform); } }
private void UpdateRootScalarBag(QueryCollectionValue instance, IEnumerable<NamedValue> namedValues, QueryScalarType scalarElementDataType) { int i = 0; var scalarCollection = new List<QueryValue>(); List<NamedValue> scalarItemNamedValues = namedValues.Where(pp => pp.Name == i.ToString(CultureInfo.InvariantCulture)).ToList(); while (scalarItemNamedValues.Any()) { ExceptionUtilities.Assert(scalarItemNamedValues.Count() < 2, "Should not get more than one value for a scalar Bag item for path '{0}'", i.ToString(CultureInfo.InvariantCulture)); var value = scalarItemNamedValues.Single(); scalarCollection.Add(scalarElementDataType.CreateValue(value.Value)); this.unusedNamedValuePaths.Remove(value.Name); i++; scalarItemNamedValues = namedValues.Where(pp => pp.Name == i.ToString(CultureInfo.InvariantCulture)).ToList(); } if (scalarCollection.Any()) { this.SetCollectionValue(instance, scalarCollection); } }
private void UpdateScalarBag(QueryStructuralValue instance, QueryProperty memberProperty, string propertyPath, IEnumerable<NamedValue> namedValues, QueryScalarType scalarElementDataType) { int i = 0; var scalarCollection = new List<QueryValue>(); List<NamedValue> scalarItemNamedValues = namedValues.Where(pp => pp.Name == propertyPath + "." + i).ToList(); while (scalarItemNamedValues.Any()) { ExceptionUtilities.Assert(scalarItemNamedValues.Count() < 2, "Should not get more than one value for a scalar Bag item for path '{0}'", propertyPath + "." + i); var value = scalarItemNamedValues.Single(); scalarCollection.Add(scalarElementDataType.CreateValue(value.Value)); this.unusedNamedValuePaths.Remove(value.Name); i++; scalarItemNamedValues = namedValues.Where(pp => pp.Name == propertyPath + "." + i).ToList(); } if (scalarCollection.Any()) { this.SetCollectionProperty(instance, memberProperty, scalarCollection); } }
/// <summary> /// Evaluates the property. /// </summary> /// <param name="resultType">Type of the result.</param> /// <param name="propertyName">Name of the property.</param> /// <param name="instance">The instance.</param> /// <returns> /// Query value which is the result of the function evaluation. /// </returns> private QueryValue EvaluateProperty(QueryScalarType resultType, string propertyName, QueryScalarValue instance) { if (instance.Value == null) { // TODO: evaluation error? return resultType.NullValue; } var type = instance.Value.GetType(); var propertyInfo = type.GetProperty(propertyName); ExceptionUtilities.CheckObjectNotNull(propertyInfo, "Could not find property named '{0}' on '{1}'", propertyName, instance.Value); var value = propertyInfo.GetValue(instance.Value, null); return resultType.CreateValue(value); }
/// <summary> /// Compares the given values of the given type, and throws a DataComparisonException or AssertionFailedException if values don't match /// </summary> /// <param name="type">The expected type</param> /// <param name="expected">The expected value</param> /// <param name="actual">The actual value</param> /// <param name="assert">The assertion handler to use</param> protected override void Compare(QueryScalarType type, object expected, object actual, AssertionHandler assert) { expected = this.Converter.Normalize(expected); actual = this.Converter.Normalize(actual); base.Compare(type, expected, actual, assert); }
private bool ScalarTypesAreEqualComparable(QueryScalarType firstScalarType, QueryScalarType secondScalarType) { return(firstScalarType.Supports(QueryBinaryOperation.EqualTo, secondScalarType)); }
/// <summary> /// Removes any length constraints from the type /// </summary> /// <param name="type">The type from which to remove the constraints</param> /// <returns>The new type with length constraints removed.</returns> public QueryScalarType RemoveLengthConstraints(QueryScalarType type) { throw new TaupoNotSupportedException("Attempt to use evaluation strategy from " + typeof(QueryUnresolvedType).Name + ". Please resolve expression first."); }
/// <summary> /// Factory method to create the <see cref="QueryConstantExpression"/>. /// </summary> /// <param name="value">Value of the expression.</param> /// <param name="valueType">Type of the expression.</param> /// <returns>The <see cref="QueryConstantExpression"/> with the provided arguments.</returns> public static QueryConstantExpression Constant(object value, QueryScalarType valueType) { ExceptionUtilities.CheckArgumentNotNull(valueType, "valueType"); if (value == null) { ExceptionUtilities.Assert(!valueType.IsUnresolved, "When value is null type cannot be unresolved."); } return Constant(valueType.CreateValue(value)); }
/// <summary> /// Determines whether an operation between two types is supported /// </summary> /// <param name="operation">the operation</param> /// <param name="sourceType">the type of data to operation on</param> /// <param name="otherType">the other type</param> /// <returns>Value <c>true</c> if operation can be performed; otherwise, <c>false</c>.</returns> public bool Supports(QueryBinaryOperation operation, QueryScalarType sourceType, QueryScalarType otherType) { throw new TaupoNotSupportedException("Attempt to use evaluation strategy from " + typeof(QueryUnresolvedType).Name + ". Please resolve expression first."); }
/// <summary> /// Determines whether data of this type can do certain operation with data of another type /// </summary> /// <param name="operation">the operation</param> /// <param name="otherScalarType">the other data type</param> /// <returns>Value <c>true</c> if operation can be performed; otherwise, <c>false</c>.</returns> public bool Supports(QueryBinaryOperation operation, QueryScalarType otherScalarType) { ExceptionUtilities.CheckArgumentNotNull(otherScalarType, "otherScalarType"); return(this.EvaluationStrategy.Supports(operation, this, otherScalarType)); }
/// <summary> /// Determines whether a type supports ordering. /// </summary> /// <param name="sourceType">the type of data to operation on</param> /// <returns>Value <c>true</c> if ordering can be performed; otherwise, <c>false</c>.</returns> public bool SupportsOrderComparison(QueryScalarType sourceType) { throw new TaupoNotSupportedException("Attempt to use evaluation strategy from " + typeof(QueryUnresolvedType).Name + ". Please resolve expression first."); }