/* ****************************************************************************************************** * * --------------------------- HELPING METHODS ------------------------------ * * ****************************************************************************************************** */ private FunctionInformation BasicAggregateImplementation(MethodCallExpression methodExpression, string functionName, FunctionInformation.FunctionType functionType) { int argumentCount = methodExpression.Arguments.Count; FunctionInformation information = new FunctionInformation() { Name = functionName, Type = functionType, MeaningfulArguments = new object[1] }; System.Type argumentType = methodExpression.Arguments[0].Type.GenericTypeArguments[0]; string entityFullName = argumentType.IsInterface ? default(string) : argumentType.FullName; string fqn = new FullyQualifiedNameVisitor().BringFQN(methodExpression); fqn = fqn ?? entityFullName + (argumentCount > 1 ? GetSelectorBody(methodExpression.Arguments[1]) : ""); information.MeaningfulArguments[0] = fqn; information.WhereContribution = argumentCount > 1 ? OQLBuilder.BuildWhereClause(currentContext, methodExpression.Arguments[1], out OQLBuilder oqlBuilder).Trim() : default(string); Logger.Log( "Function Information: " + information.ToLog(), Microsoft.Extensions.Logging.LogLevel.Debug ); return(information); }
public override FunctionInformation OrderBy(MethodCallExpression methodExpression) { FunctionInformation information = new FunctionInformation { Name = "ORDER BY", MeaningfulArguments = new object[1], WhereContribution = default(string), Type = FunctionInformation.FunctionType.Miscellaneous }; Expression expression = ((LambdaExpression)((UnaryExpression)methodExpression.Arguments[1]).Operand).Body; if (expression.NodeType == ExpressionType.MemberAccess) { information.MeaningfulArguments[0] = ((MemberExpression)expression).Member.Name; } else if (expression.NodeType == ExpressionType.Parameter) { // Handling cases of OrderBy(a => a) string fqn = new FullyQualifiedNameVisitor().BringFQN(methodExpression); string[] splitFQN = fqn.Split('.'); information.MeaningfulArguments[0] = splitFQN[splitFQN.Length - 1]; } Logger.Log( "Function Information: " + information.ToLog(), Microsoft.Extensions.Logging.LogLevel.Debug ); return(information); }
public override FunctionInformation Select(MethodCallExpression methodExpression) { FunctionInformation information = new FunctionInformation(); Logger.Log( "Function Information (Select): " + information.ToLog(), Microsoft.Extensions.Logging.LogLevel.Debug ); return(information); }
public override FunctionInformation OrderByDescending(MethodCallExpression methodExpression) { FunctionInformation information = OrderBy(methodExpression); Logger.Log( "Function Information (Descending): " + information.ToLog(), Microsoft.Extensions.Logging.LogLevel.Debug ); return(information); }
public override FunctionInformation Count(MethodCallExpression methodExpression) { FunctionInformation information = BasicAggregateImplementation(methodExpression, "COUNT", FunctionInformation.FunctionType.Aggregate); // Remove attribute from the COUNT's argument as OQL works on the supposition that the COUNT's argument // is an entity and it is indexed. information.MeaningfulArguments[0] = RemoveAttributeAndCheckExistence(information.MeaningfulArguments[0].ToString()); Logger.Log( "Function Information: " + information.ToLog(), Microsoft.Extensions.Logging.LogLevel.Debug ); return(information); }
private string BuildFunction(FunctionInformation information, out string whereCriteria) { StringBuilder builder = new StringBuilder(); whereCriteria = information.WhereContribution; switch (information.Type) { case FunctionInformation.FunctionType.None: // // Do nothing // break; case FunctionInformation.FunctionType.Aggregate: builder.Append(information.Name).Append("("); for (int i = 0; i < information.MeaningfulArguments.Length; i++) { object arg = information.MeaningfulArguments[i]; builder.Append(i > 0 ? Comma + Space : ""); builder.Append(arg.ToString()); } builder.Append(")"); break; case FunctionInformation.FunctionType.QueryMethod: // // It would would seem that nothing needs to be done here as of yet // break; case FunctionInformation.FunctionType.Miscellaneous: for (int i = 0; i < information.MeaningfulArguments.Length; i++) { object arg = information.MeaningfulArguments[i]; builder.Append(i > 0 ? Comma + Space : ""); builder.Append("this").Append(Dot).Append(arg.ToString()); } break; } return(builder.ToString()); }
private object EvaluateMethodAndCall(MethodCallExpression methodExpression) { // // Halt user from using unsupported operations // if (IsUnsupportedQueryMethod(methodExpression.Method.Name)) { throw new Exception(methodExpression.Method.Name + " feature is not supported."); } if (IsUnsupportedAggregate(methodExpression.Method.Name)) { throw new Exception(methodExpression.Method.Name + " aggregate is not supported."); } if (IsUnsupportedMiscellaneous(methodExpression.Method.Name)) { throw new Exception(methodExpression.Method.Name + " is not supported."); } // // Now let's see what we can do with the stuff we support // if (IsSupportedQueryMethod(methodExpression.Method.Name)) { // Do nothing. Go with the flow. Logger.Log(methodExpression.Method.Name + " is a supported query method.", Microsoft.Extensions.Logging.LogLevel.Trace); return(null); } if (IsSupportedAggregate(methodExpression.Method.Name)) { // Keep the aggregate in mind and go with the flow. Logger.Log(methodExpression.Method.Name + " is a supported aggregate function.", Microsoft.Extensions.Logging.LogLevel.Trace); if (aggregateFunction == default(string)) { FunctionInformation information = functionParser.Parse(methodExpression.Method.Name, methodExpression); // // If something else needs to be done. // aggregateFunction = BuildFunction(information, out string where); } else { throw new Exception("More than one aggregates are not supported!"); } return(null); } if (IsSupportedMiscellaneous(methodExpression.Method.Name)) { Logger.Log(methodExpression.Method.Name + " is a supported miscellaneous function.", Microsoft.Extensions.Logging.LogLevel.Trace); if (miscellaneousOperations.ContainsKey(methodExpression.Method.Name.ToLower())) { throw new Exception("More than one " + methodExpression.Method.Name + " is not supported."); } else { FunctionInformation information = functionParser.Parse(methodExpression.Method.Name, methodExpression); // // If something else needs to be done. // miscellaneousOperations.Add( methodExpression.Method.Name.ToLower(), BuildFunction(information, out string where) ); } return(null); } if (IsDateTime(methodExpression)) { Logger.Log("Encountered DateTime in Method Call.", Microsoft.Extensions.Logging.LogLevel.Trace); whereBuilder .Append("DateTime('") .Append(InvokeMethodCall(methodExpression).ToString()) .Append("')"); return('\t'); } else { // We have a method that needs to be invoked and the result needs to be // returned to the calling method. This method is not part of LINQ. The // user passed this method for criteria checking. if (methodExpression.Object != null) { } // [NOTE] : Behavioral methods are still invoked. try { return(InvokeMethodCall(methodExpression)); } catch (TargetInvocationException tie) { Logger.Log(tie, Microsoft.Extensions.Logging.LogLevel.Critical); } } return(null); }