internal string Format(ExpressionContext context) { if (_operator == ExpressionOperator.None) { return this.Reference != null ? FormatReference(context) : this.Function != null ? FormatFunction(context) : FormatValue(context); } else if (_operator == ExpressionOperator.NOT || _operator == ExpressionOperator.NEG) { var left = FormatExpression(_left, context); var op = FormatOperator(context); if (NeedsGrouping(_left)) return string.Format("{0}({1})", op, left); else return string.Format("{0} {1}", op, left); } else { var left = FormatExpression(_left, context); var right = FormatExpression(_right, context); var op = FormatOperator(context); if (NeedsGrouping(_left)) return string.Format("({0}) {1} {2}", left, op, right); else if (NeedsGrouping(_right)) return string.Format("{0} {1} ({2})", left, op, right); else return string.Format("{0} {1} {2}", left, op, right); } }
private string FormatReference(ExpressionContext context) { var elementNames = new List<string>(this.Reference.Split('.')); var entityCollection = context.EntityCollection; var segmentNames = BuildReferencePath(new List<string>(), entityCollection, elementNames, context); return string.Join("/", segmentNames); }
private static string FormatExpression(ODataExpression expr, ExpressionContext context) { if (ReferenceEquals(expr, null)) { return "null"; } else { return expr.Format(context); } }
private string FormatValue(object value, FormattingStyle formattingStyle, ExpressionContext context) { return value == null ? "null" : value is FilterExpression ? (value as FilterExpression).Format(context) : value is string ? string.Format("'{0}'", value) : value is DateTime ? ((DateTime)value).ToIso8601String() : value is bool ? value.ToString().ToLower() : (value is long || value is ulong) ? value + (formattingStyle == FormattingStyle.Content ? "L" : string.Empty) : value is float ? ((float)value).ToString(CultureInfo.InvariantCulture) : value is double ? ((double)value).ToString(CultureInfo.InvariantCulture) : value is decimal ? ((decimal)value).ToString(CultureInfo.InvariantCulture) : value.ToString(); }
private string FormatFunction(ExpressionContext context) { FunctionMapping mapping; if (FunctionMapping.SupportedFunctions.TryGetValue(new ExpressionFunction.FunctionCall(this.Function.FunctionName, this.Function.Arguments.Count()), out mapping)) { var mappedFunction = mapping.FunctionMapper(this.Function.FunctionName, _functionCaller.Format(context), this.Function.Arguments).Function; return string.Format("{0}({1})", mappedFunction.FunctionName, string.Join(",", (IEnumerable<object>)mappedFunction.Arguments.Select(x => FormatExpression(x, context)))); } else { throw new NotSupportedException(string.Format("The function {0} is not supported or called with wrong number of arguments", this.Function.FunctionName)); } }
private string FormatValue(object value, FormattingStyle formattingStyle, ExpressionContext context) { return value == null ? "null" : value is FilterExpression ? (value as FilterExpression).Format(context) : value is string ? string.Format("'{0}'", value) : value is DateTime ? ((DateTime)value).ToODataString(formattingStyle) : value is DateTimeOffset ? ((DateTimeOffset)value).ToODataString(formattingStyle) : value is TimeSpan ? ((TimeSpan)value).ToODataString(formattingStyle) : value is Guid ? ((Guid)value).ToODataString(formattingStyle) : value is bool ? value.ToString().ToLower() : value is long ? ((long)value).ToODataString(formattingStyle) : value is ulong ? ((ulong)value).ToODataString(formattingStyle) : value is float ? ((float)value).ToString(CultureInfo.InvariantCulture) : value is double ? ((double)value).ToString(CultureInfo.InvariantCulture) : value is decimal ? ((decimal)value).ToODataString(formattingStyle) : value.ToString(); }
internal string Format(ExpressionContext context) { if (_operator == ExpressionOperator.None && _conversionType == null) { return this.Reference != null ? FormatReference(context) : this.Function != null ? FormatFunction(context) : FormatValue(context); } else if (_conversionType != null) { var expr = _left; if (expr.Reference == null && expr.Function == null) { object result; if (Utils.TryConvert(expr.Value, _conversionType, out result)) { expr = new ODataExpression(result); } } return FormatExpression(expr, context); } else if (_operator == ExpressionOperator.NOT || _operator == ExpressionOperator.NEG) { var left = FormatExpression(_left, context); var op = FormatOperator(context); if (NeedsGrouping(_left)) return string.Format("{0}({1})", op, left); else return string.Format("{0} {1}", op, left); } else { var left = FormatExpression(_left, context); var right = FormatExpression(_right, context); var op = FormatOperator(context); if (NeedsGrouping(_left)) return string.Format("({0}) {1} {2}", left, op, right); else if (NeedsGrouping(_right)) return string.Format("{0} {1} ({2})", left, op, right); else return string.Format("{0} {1} {2}", left, op, right); } }
private string FormatFunction(ExpressionContext context) { FunctionMapping mapping; var adapterVersion = context.Session == null ? AdapterVersion.Default : context.Session.Adapter.AdapterVersion; if (FunctionMapping.TryGetFunctionMapping(this.Function.FunctionName, this.Function.Arguments.Count(), adapterVersion, out mapping)) { var mappedFunction = mapping.FunctionMapper(this.Function.FunctionName, _functionCaller.Format(context), this.Function.Arguments).Function; var formattedArguments = string.Join(",", (IEnumerable<object>)mappedFunction.Arguments.Select(x => FormatExpression(x, context))); return string.Format("{0}({1})", mappedFunction.FunctionName, formattedArguments); } else if (string.Equals(this.Function.FunctionName, ODataLiteral.Any, StringComparison.OrdinalIgnoreCase) || string.Equals(this.Function.FunctionName, ODataLiteral.All, StringComparison.OrdinalIgnoreCase)) { var formattedArguments = string.Format("x{0}:x{0}/{1}", ArgumentCounter >= 0 ? (1 + (ArgumentCounter++) % 9).ToString() : string.Empty, FormatExpression(this.Function.Arguments.First(), new ExpressionContext(context.Session, new EntityCollection(_functionCaller.Reference, context.EntityCollection)))); return string.Format("{0}/{1}({2})", _functionCaller.Format(context), this.Function.FunctionName.ToLower(), formattedArguments); } else if (string.Equals(this.Function.FunctionName, ODataLiteral.IsOf, StringComparison.OrdinalIgnoreCase) || string.Equals(this.Function.FunctionName, ODataLiteral.Cast, StringComparison.OrdinalIgnoreCase)) { var formattedArguments = string.Empty; if (!ReferenceEquals(this.Function.Arguments.First(), null) && !this.Function.Arguments.First().IsNull) { formattedArguments += FormatExpression(this.Function.Arguments.First(), new ExpressionContext(context.Session)); formattedArguments += ","; } formattedArguments += FormatExpression(this.Function.Arguments.Last(), new ExpressionContext(context.Session)); return string.Format("{0}({1})", this.Function.FunctionName.ToLower(), formattedArguments); } else { throw new NotSupportedException(string.Format("The function {0} is not supported or called with wrong number of arguments", this.Function.FunctionName)); } }
private string FormatScope(string text, ExpressionContext context) { return string.IsNullOrEmpty(context.ScopeQualifier) ? text : string.Format("{0}/{1}", context.ScopeQualifier, text); }
internal string Format(ExpressionContext context) { if (context.IsQueryOption && _operator != ExpressionOperator.None && _operator != ExpressionOperator.AND && _operator != ExpressionOperator.EQ) { throw new InvalidOperationException("Invalid custom query option"); } if (_operator == ExpressionOperator.None && _conversionType == null) { return this.Reference != null ? FormatReference(context) : this.Function != null ? FormatFunction(context) : FormatValue(context); } else if (_conversionType != null) { var expr = _left; if (expr.Reference == null && expr.Function == null && expr._conversionType == null) { object result; if (expr.Value != null && expr.Value.GetType().IsEnumType()) { expr = new ODataExpression(expr.Value); } else if (Utils.TryConvert(expr.Value, _conversionType, out result)) { expr = new ODataExpression(result); } } return FormatExpression(expr, context); } else if (_operator == ExpressionOperator.NOT || _operator == ExpressionOperator.NEG) { var left = FormatExpression(_left, context); var op = FormatOperator(context); if (NeedsGrouping(_left)) return string.Format("{0}({1})", op, left); else return string.Format("{0} {1}", op, left); } else { var left = FormatExpression(_left, context); var right = FormatExpression(_right, context); var op = FormatOperator(context); if (context.IsQueryOption) { return string.Format("{0}{1}{2}", left, op, right); } else { if (NeedsGrouping(_left)) return string.Format("({0}) {1} {2}", left, op, right); else if (NeedsGrouping(_right)) return string.Format("{0} {1} ({2})", left, op, right); else return string.Format("{0} {1} {2}", left, op, right); } } }
private string FormatAsFunction(string objectName, ExpressionContext context) { FunctionMapping mapping; if (FunctionMapping.SupportedFunctions.TryGetValue(new ExpressionFunction.FunctionCall(objectName, 0), out mapping)) { string targetName = _functionCaller.Format(context); var mappedFunction = mapping.FunctionMapper(objectName, targetName, null).Function; return string.Format("{0}({1})", mappedFunction.FunctionName, targetName); } else { return null; } }
private IEnumerable<string> BuildReferencePath(List<string> pathNames, Table table, List<string> elementNames, ExpressionContext context) { if (!elementNames.Any()) { return pathNames; } var objectName = elementNames.First(); if (table != null) { if (table.HasColumn(objectName)) { pathNames.Add(table.FindColumn(objectName).ActualName); return BuildReferencePath(pathNames, null, elementNames.Skip(1).ToList(), context); } else if (table.HasAssociation(objectName)) { var association = table.FindAssociation(objectName); pathNames.Add(association.ActualName); return BuildReferencePath(pathNames, context.Schema.FindTable(association.ReferenceTableName), elementNames.Skip(1).ToList(), context); } else { var formattedFunction = FormatAsFunction(objectName, context); if (!string.IsNullOrEmpty(formattedFunction)) { pathNames.Add(formattedFunction); return BuildReferencePath(pathNames, null, elementNames.Skip(1).ToList(), context); } else { throw new UnresolvableObjectException(objectName, string.Format("Invalid referenced object {0}", objectName)); } } } else if (FunctionMapping.SupportedFunctions.ContainsKey(new ExpressionFunction.FunctionCall(elementNames.First(), 0))) { var formattedFunction = FormatAsFunction(objectName, context); pathNames.Add(formattedFunction); return BuildReferencePath(pathNames, null, elementNames.Skip(1).ToList(), context); } else { pathNames.AddRange(elementNames); return BuildReferencePath(pathNames, null, new List<string>(), context); } }
private EntityCollection NavigateToCollection(ExpressionContext context, EntityCollection rootCollection, string path) { var items = path.Split('/'); var associationName = context.Session.Metadata.GetNavigationPropertyExactName(rootCollection.Name, items.First()); var entityCollection = context.Session.Metadata.GetEntityCollection( context.Session.Metadata.GetNavigationPropertyPartnerName(rootCollection.Name, associationName)); if (items.Count() == 1) { return entityCollection; } else { path = path.Substring(items.First().Length + 1); return NavigateToCollection(context, entityCollection, path); } }
public string FormatExpressionValue(object value, ExpressionContext context) { return FormatValue(value, FormattingStyle.QueryString, context); }
private string FormatValue(ExpressionContext context) { return (new ValueFormatter()).FormatExpressionValue(Value, context); }
private string FormatFunction(ExpressionContext context) { FunctionMapping mapping; var adapterVersion = context.Session == null ? AdapterVersion.Default : context.Session.Adapter.AdapterVersion; if (FunctionMapping.TryGetFunctionMapping(this.Function.FunctionName, this.Function.Arguments.Count(), adapterVersion, out mapping)) { return FormatMappedFunction(context, mapping); } else if (string.Equals(this.Function.FunctionName, ODataLiteral.Any, StringComparison.OrdinalIgnoreCase) || string.Equals(this.Function.FunctionName, ODataLiteral.All, StringComparison.OrdinalIgnoreCase)) { return FormatAnyAllFunction(context); } else if (string.Equals(this.Function.FunctionName, ODataLiteral.IsOf, StringComparison.OrdinalIgnoreCase) || string.Equals(this.Function.FunctionName, ODataLiteral.Cast, StringComparison.OrdinalIgnoreCase)) { return FormatIsOfCastFunction(context); } else if (string.Equals(this.Function.FunctionName, "get_Item", StringComparison.Ordinal) && this.Function.Arguments.Count == 1) { return FormatArrayIndexFunction(context); } else if (string.Equals(this.Function.FunctionName, "ToString", StringComparison.Ordinal) && this.Function.Arguments.Count == 0) { return _functionCaller.Reference; } else if (_functionCaller.IsNull && this.Function.Arguments.Count == 1) { var val = this.Function.Arguments.First(); if (val.Value != null) { var formattedVal = ODataExpression.FromValue( string.Equals(this.Function.FunctionName, "ToBoolean", StringComparison.Ordinal) ? Convert.ToBoolean(val.Value) : string.Equals(this.Function.FunctionName, "ToByte", StringComparison.Ordinal) ? Convert.ToByte(val.Value) : string.Equals(this.Function.FunctionName, "ToChar", StringComparison.Ordinal) ? Convert.ToChar(val.Value) : string.Equals(this.Function.FunctionName, "ToDateTime", StringComparison.Ordinal) ? Convert.ToDateTime(val.Value) : string.Equals(this.Function.FunctionName, "ToDecimal", StringComparison.Ordinal) ? Convert.ToDecimal(val.Value) : string.Equals(this.Function.FunctionName, "ToDouble", StringComparison.Ordinal) ? Convert.ToDouble(val.Value) : string.Equals(this.Function.FunctionName, "ToInt16", StringComparison.Ordinal) ? Convert.ToInt16(val.Value) : string.Equals(this.Function.FunctionName, "ToInt32", StringComparison.Ordinal) ? Convert.ToInt32(val.Value) : string.Equals(this.Function.FunctionName, "ToInt64", StringComparison.Ordinal) ? Convert.ToInt64(val.Value) : string.Equals(this.Function.FunctionName, "ToSByte", StringComparison.Ordinal) ? Convert.ToSByte(val.Value) : string.Equals(this.Function.FunctionName, "ToSingle", StringComparison.Ordinal) ? Convert.ToSingle(val.Value) : string.Equals(this.Function.FunctionName, "ToString", StringComparison.Ordinal) ? Convert.ToString(val.Value) : string.Equals(this.Function.FunctionName, "ToUInt16", StringComparison.Ordinal) ? Convert.ToUInt16(val.Value) : string.Equals(this.Function.FunctionName, "ToUInt32", StringComparison.Ordinal) ? Convert.ToUInt32(val.Value) : string.Equals(this.Function.FunctionName, "ToUInt64", StringComparison.Ordinal) ? (object)Convert.ToUInt64(val.Value) : null); if (formattedVal.Value != null) return FormatExpression(formattedVal, context); } } throw new NotSupportedException(string.Format("The function {0} is not supported or called with wrong number of arguments", this.Function.FunctionName)); }
private IEnumerable<string> BuildReferencePath(List<string> segmentNames, EntityCollection entityCollection, List<string> elementNames, ExpressionContext context) { if (!elementNames.Any()) { return segmentNames; } var objectName = elementNames.First(); if (entityCollection != null) { if (context.Session.Metadata.HasStructuralProperty(entityCollection.Name, objectName)) { var propertyName = context.Session.Metadata.GetStructuralPropertyExactName( entityCollection.Name, objectName); segmentNames.Add(propertyName); return BuildReferencePath(segmentNames, null, elementNames.Skip(1).ToList(), context); } else if (context.Session.Metadata.HasNavigationProperty(entityCollection.Name, objectName)) { var propertyName = context.Session.Metadata.GetNavigationPropertyExactName( entityCollection.Name, objectName); var linkName = context.Session.Metadata.GetNavigationPropertyPartnerName( entityCollection.Name, objectName); var linkedEntityCollection = context.Session.Metadata.GetEntityCollection(linkName); segmentNames.Add(propertyName); return BuildReferencePath(segmentNames, linkedEntityCollection, elementNames.Skip(1).ToList(), context); } else if (IsFunction(objectName, context)) { var formattedFunction = FormatAsFunction(objectName, context); segmentNames.Add(formattedFunction); return BuildReferencePath(segmentNames, null, elementNames.Skip(1).ToList(), context); } else if (context.Session.Metadata.IsOpenType(entityCollection.Name)) { segmentNames.Add(objectName); return BuildReferencePath(segmentNames, null, elementNames.Skip(1).ToList(), context); } else { throw new UnresolvableObjectException(objectName, string.Format("Invalid referenced object {0}", objectName)); } } else if (FunctionMapping.ContainsFunction(elementNames.First(), 0)) { var formattedFunction = FormatAsFunction(objectName, context); segmentNames.Add(formattedFunction); return BuildReferencePath(segmentNames, null, elementNames.Skip(1).ToList(), context); } else { segmentNames.AddRange(elementNames); return BuildReferencePath(segmentNames, null, new List<string>(), context); } }
private string FormatValue(ExpressionContext context) { if (Value is ODataExpression) { return (Value as ODataExpression).Format(context); } else if (Value is Type) { var typeName = context.Session.Adapter.GetMetadata().GetEntityCollectionQualifiedTypeName((Value as Type).Name); return context.Session.Adapter.ConvertValueToUriLiteral(typeName); } else { return context.Session.Adapter.ConvertValueToUriLiteral(Value); } }
private string FormatFunction(ExpressionContext context) { FunctionMapping mapping; var adapterVersion = context.Session == null ? AdapterVersion.Default : context.Session.Adapter.AdapterVersion; if (FunctionMapping.TryGetFunctionMapping(this.Function.FunctionName, this.Function.Arguments.Count(), adapterVersion, out mapping)) { return FormatMappedFunction(context, mapping); } else if (string.Equals(this.Function.FunctionName, ODataLiteral.Any, StringComparison.OrdinalIgnoreCase) || string.Equals(this.Function.FunctionName, ODataLiteral.All, StringComparison.OrdinalIgnoreCase)) { return FormatAnyAllFunction(context); } else if (string.Equals(this.Function.FunctionName, ODataLiteral.IsOf, StringComparison.OrdinalIgnoreCase) || string.Equals(this.Function.FunctionName, ODataLiteral.Cast, StringComparison.OrdinalIgnoreCase)) { return FormatIsOfCastFunction(context); } else if (string.Equals(this.Function.FunctionName, "get_Item", StringComparison.Ordinal) && this.Function.Arguments.Count == 1) { return FormatArrayIndexFunction(context); } else if (string.Equals(this.Function.FunctionName, "ToString", StringComparison.Ordinal) && this.Function.Arguments.Count == 0) { return _functionCaller.Reference; } else { throw new NotSupportedException(string.Format("The function {0} is not supported or called with wrong number of arguments", this.Function.FunctionName)); } }
private string FormatArrayIndexFunction(ExpressionContext context) { var propertyName = FormatExpression(this.Function.Arguments.First(), new ExpressionContext(context.Session)).Trim('\''); return _functionCaller.Reference == context.DynamicPropertiesContainerName ? propertyName : string.Format("{0}.{1}", _functionCaller.Reference, propertyName); }
private string FormatIsOfCastFunction(ExpressionContext context) { var formattedArguments = string.Empty; if (!ReferenceEquals(this.Function.Arguments.First(), null) && !this.Function.Arguments.First().IsNull) { formattedArguments += FormatExpression(this.Function.Arguments.First(), new ExpressionContext(context.Session)); formattedArguments += ","; } formattedArguments += FormatExpression(this.Function.Arguments.Last(), new ExpressionContext(context.Session)); return string.Format("{0}({1})", this.Function.FunctionName.ToLower(), formattedArguments); }
private string FormatReference(ExpressionContext context) { var elementNames = new List<string>(this.Reference.Split('.')); var pathNames = BuildReferencePath(new List<string>(), context.Table, elementNames, context); return string.Join("/", pathNames); }
private string FormatOperator(ExpressionContext context) { switch (_operator) { case ExpressionType.And: return context.IsQueryOption ? "&" : "and"; case ExpressionType.Or: return "or"; case ExpressionType.Not: return "not"; case ExpressionType.Equal: return context.IsQueryOption ? "=" : "eq"; case ExpressionType.NotEqual: return "ne"; case ExpressionType.GreaterThan: return "gt"; case ExpressionType.GreaterThanOrEqual: return "ge"; case ExpressionType.LessThan: return "lt"; case ExpressionType.LessThanOrEqual: return "le"; case ExpressionType.Add: return "add"; case ExpressionType.Subtract: return "sub"; case ExpressionType.Multiply: return "mul"; case ExpressionType.Divide: return "div"; case ExpressionType.Modulo: return "mod"; case ExpressionType.Negate: return "-"; default: return null; } }
private string FormatAsFunction(string objectName, ExpressionContext context) { FunctionMapping mapping; var adapterVersion = context.Session == null ? AdapterVersion.Default : context.Session.Adapter.AdapterVersion; if (FunctionMapping.TryGetFunctionMapping(objectName, 0, adapterVersion, out mapping)) { string targetName = _functionCaller.Format(context); var mappedFunction = mapping.FunctionMapper(objectName, targetName, null).Function; return string.Format("{0}({1})", mappedFunction.FunctionName, targetName); } else { return null; } }
private string FormatOperator(ExpressionContext context) { switch (_operator) { case ExpressionOperator.AND: return "and"; case ExpressionOperator.OR: return "or"; case ExpressionOperator.NOT: return "not"; case ExpressionOperator.EQ: return "eq"; case ExpressionOperator.NE: return "ne"; case ExpressionOperator.GT: return "gt"; case ExpressionOperator.GE: return "ge"; case ExpressionOperator.LT: return "lt"; case ExpressionOperator.LE: return "le"; case ExpressionOperator.ADD: return "add"; case ExpressionOperator.SUB: return "sub"; case ExpressionOperator.MUL: return "mul"; case ExpressionOperator.DIV: return "div"; case ExpressionOperator.MOD: return "mod"; case ExpressionOperator.NEG: return "-"; default: return null; } }
private string FormatMappedFunction(ExpressionContext context, FunctionMapping mapping) { var mappedFunction = mapping.FunctionMapper( this.Function.FunctionName, _functionCaller.Format(context), this.Function.Arguments).Function; var formattedArguments = string.Join(",", (IEnumerable<object>)mappedFunction.Arguments.Select(x => FormatExpression(x, context))); return string.Format("{0}({1})", mappedFunction.FunctionName, formattedArguments); }
private bool IsFunction(string objectName, ExpressionContext context) { FunctionMapping mapping; var adapterVersion = context.Session == null ? AdapterVersion.Default : context.Session.Adapter.AdapterVersion; return FunctionMapping.TryGetFunctionMapping(objectName, 0, adapterVersion, out mapping); }
private string FormatAnyAllFunction(ExpressionContext context) { var navigationPath = _functionCaller.Reference.Replace('.', '/'); var entityCollection = NavigateToCollection(context, context.EntityCollection, navigationPath); var formattedArguments = string.Format("x{0}:x{0}/{1}", ArgumentCounter >= 0 ? (1 + (ArgumentCounter++) % 9).ToString() : string.Empty, FormatExpression(this.Function.Arguments.First(), new ExpressionContext(context.Session, entityCollection, context.DynamicPropertiesContainerName))); return string.Format("{0}/{1}({2})", context.Session.Adapter.GetCommandFormatter().FormatNavigationPath(context.EntityCollection, navigationPath), this.Function.FunctionName.ToLower(), formattedArguments); }