public virtual void WriteGroupByExpressionQueryParameter( GroupByQueryExpression groupByQueryExpression, QueryExpressionVisitor queryExpressionVisitor ) { WriteIfNotNull(groupByQueryExpression.Expression, queryExpressionVisitor); }
public virtual void WriteMultipleStatements( MultipleStatementQueryExpression multipleStatementQueryExpression, QueryExpressionVisitor queryExpressionVisitor ) { WriteExpressionCollection(multipleStatementQueryExpression.Queries, queryExpressionVisitor, seperator: " "); }
public void Visit(QueryExpressionVisitor visitor) { foreach (var query in Queries) { visitor.Visit(query); } }
public virtual void WriteHavingQueryParameters( HavingQueryExpression whereQueryExpression, QueryExpressionVisitor queryExpressionVisitor) { queryText.Append(" HAVING "); queryExpressionVisitor.Visit(whereQueryExpression.Expression); }
public virtual void WriteFromQueryParameter( FromQueryExpression fromQueryExpression, QueryExpressionVisitor queryExpressionVisitor) { queryText.Append(" FROM "); queryExpressionVisitor.Visit(fromQueryExpression.Expression); }
public virtual void WriteWhereQueryParameters( WhereQueryExpression whereQueryExpression, QueryExpressionVisitor queryExpressionVisitor) { queryText.Append(" WHERE "); queryExpressionVisitor.Visit(whereQueryExpression.Expression); }
public virtual void WriteDeleteStatement( DeleteStatementQueryExpression deleteStatementQueryExpression, QueryExpressionVisitor queryExpressionVisitor ) { statementStack.Push(deleteStatementQueryExpression); if (IsSubQuery()) { queryText.Append(" ( "); } queryText.Append("DELETE "); WriteIfNotNull(deleteStatementQueryExpression.From, queryExpressionVisitor); WriteIfNotNull(deleteStatementQueryExpression.Where, queryExpressionVisitor); if (IsSubQuery()) { queryText.Append(" ) "); } else { queryText.Append("; "); } statementStack.Pop(); }
public virtual void WriteIsInOperator( IsInOperatorQueryExpression isInFunctionCallQueryExpression, QueryExpressionVisitor queryExpressionVisitor ) { queryExpressionVisitor.Visit(isInFunctionCallQueryExpression.Expression); if (isInFunctionCallQueryExpression.IsNotIn) { queryText.Append(" NOT "); } queryText.Append(" IN "); var expressionsAreQueries = isInFunctionCallQueryExpression.InExpressions[0] is ExecutableQueryExpression; if (!expressionsAreQueries) { queryText.Append("("); } WriteExpressionCollection(isInFunctionCallQueryExpression.InExpressions, queryExpressionVisitor); if (!expressionsAreQueries) { queryText.Append(")"); } queryText.Append(" "); }
private static async Task ExecuteSubExpression( QueryContext context, QueryExpressionVisitor visitor, IQueryExecutor executor, Expression expression, CancellationToken cancellationToken) { // get element type Type elementType = null; var queryType = expression.Type.FindGenericType(typeof(IQueryable <>)); if (queryType != null) { elementType = queryType.GetGenericArguments()[0]; } var query = visitor.BaseQuery.Provider.CreateQuery(expression); var method = typeof(IQueryExecutor) .GetMethod("ExecuteQueryAsync") .MakeGenericMethod(elementType); var parameters = new object[] { context, query, cancellationToken }; var task = method.Invoke(executor, parameters) as Task <QueryResult>; var result = await task.ConfigureAwait(false); var any = result.Results.Cast <object>().Any(); if (!any) { // Which means previous expression does not have result, and should throw ResourceNotFoundException. throw new ResourceNotFoundException(Resources.ResourceNotFound); } }
public virtual void WriteGroupByQueryParameter( GroupByCollectionQueryExpression groupByCollectionQueryExpression, QueryExpressionVisitor queryExpressionVisitor ) { queryText.Append(" GROUP BY "); WriteExpressionCollection(groupByCollectionQueryExpression.Expressions, queryExpressionVisitor); }
public virtual void WriteOrderByQueryParameter( OrderByCollectionQueryExpression orderByCollectionQuery, QueryExpressionVisitor queryExpressionVisitor ) { queryText.Append(" ORDER BY "); WriteExpressionCollection(orderByCollectionQuery.Expressions, queryExpressionVisitor); }
public virtual void WriteIntoQueryParameter( IntoQueryExpression intoQueryExpression, QueryExpressionVisitor queryExpressionVisitor ) { queryText.Append(" INTO "); queryExpressionVisitor.Visit(intoQueryExpression.Expression); }
protected void WriteIfNotNull(QueryExpression queryExpression, QueryExpressionVisitor queryExpressionVisitor) { if (queryExpression == null) { return; } queryExpressionVisitor.Visit(queryExpression); }
public override void WriteExtension(QueryExpression queryExpression, QueryExpressionVisitor queryExpressionVisitor) { if (queryExpression is ISqlServerExtension sqlServerExtension) { sqlServerExtension.Write(this, queryExpressionVisitor); } base.WriteExtension(queryExpression, queryExpressionVisitor); }
public virtual void WriteCountFunction( CountFunctionCallQueryExpression countFunctionCallQueryExpression, QueryExpressionVisitor queryExpressionVisitor) { queryText.Append(" COUNT("); WriteIfNotNull(countFunctionCallQueryExpression.Expression, queryExpressionVisitor); queryText.Append(") "); }
public override void WriteExtension(QueryExpression queryExpression, QueryExpressionVisitor queryExpressionVisitor) { if (queryExpression is IPostgresqlExtension postgresqlExtension) { postgresqlExtension.Write(this, queryExpressionVisitor); } base.WriteExtension(queryExpression, queryExpressionVisitor); }
public override void WriteExtension(QueryExpression queryExpression, QueryExpressionVisitor queryExpressionVisitor) { if (queryExpression is IMySQLExtension mysqlExtension) { mysqlExtension.Write(this, queryExpressionVisitor); } base.WriteExtension(queryExpression, queryExpressionVisitor); }
public virtual void WriteMaxFunction( MaxFunctionCallQueryExpression maxFunctionCallQueryExpression, QueryExpressionVisitor queryExpressionVisitor) { queryText.Append(" MAX("); WriteIfNotNull(maxFunctionCallQueryExpression.Expression, queryExpressionVisitor); queryText.Append(") "); }
public static IEnumerable <Expression> Query(this Expression self, Func <Expression, bool> predicate) { var queryVisitor = new QueryExpressionVisitor(predicate); queryVisitor.Visit(self); return(queryVisitor.Expressions); }
public virtual void WriteConcatFunction( ConcatFunctionCallQueryExpression concatFunctionCallQueryExpression, QueryExpressionVisitor queryExpressionVisitor ) { queryText.Append(" CONCAT("); WriteExpressionCollection(concatFunctionCallQueryExpression.Expressions, queryExpressionVisitor); queryText.Append(") "); }
public virtual void WriteAsOperator( AsOperatorQueryExpression asFunctionCallQueryExpression, QueryExpressionVisitor queryExpressionVisitor ) { queryExpressionVisitor.Visit(asFunctionCallQueryExpression.Expression); queryText.Append(" AS "); WriteIdentifier(asFunctionCallQueryExpression.Alias, queryExpressionVisitor); }
private static async Task CheckSubExpressionResult( QueryContext context, CancellationToken cancellationToken, IEnumerable enumerableResult, QueryExpressionVisitor visitor, IQueryExecutor executor, Expression expression) { if (enumerableResult.GetEnumerator().MoveNext()) { // If there is some result, will not have additional processing return; } var methodCallExpression = expression as MethodCallExpression; // This will remove unneeded statement which includes $expand, $select,$top,$skip,$orderby methodCallExpression = methodCallExpression.RemoveUnneededStatement(); if (methodCallExpression == null || methodCallExpression.Arguments.Count != 2) { return; } if (methodCallExpression.Method.Name == ExpressionMethodNameOfWhere) { // Throw exception if key as last where statement, or remove $filter where statement methodCallExpression = CheckWhereCondition(methodCallExpression); if (methodCallExpression == null || methodCallExpression.Arguments.Count != 2) { return; } // Call without $filter where statement and with Key where statement if (methodCallExpression.Method.Name == ExpressionMethodNameOfWhere) { // The last where from $filter is removed and run with key where statement await ExecuteSubExpression(context, cancellationToken, visitor, executor, methodCallExpression); return; } } if (methodCallExpression.Method.Name != ExpressionMethodNameOfSelect && methodCallExpression.Method.Name != ExpressionMethodNameOfSelectMany) { // If last statement is not select property, will no further checking return; } var subExpression = methodCallExpression.Arguments[0]; // Remove appended statement like Where(Param_0 => (Param_0.Prop != null)) if there is one subExpression = subExpression.RemoveAppendWhereStatement(); await ExecuteSubExpression(context, cancellationToken, visitor, executor, subExpression); }
public virtual void WriteOrderByExpressionQueryParameter( OrderByQueryExpression orderByQueryExpression, QueryExpressionVisitor queryExpressionVisitor ) { WriteIfNotNull(orderByQueryExpression.Expression, queryExpressionVisitor); if (orderByQueryExpression.Direction == OrderByDirection.Descending) { queryText.Append(" DESC "); } }
public virtual void WriteLastInsertedIdFunction( LastInsertedIdFunctionCallExpression lastInsertedIdFunctionCallExpression, QueryExpressionVisitor queryExpressionVisitor ) { // todo: decide what to do about this // last insert id is literally different on every single platform // the obvious thing to do would be to make QueryWriter abstract // but that means writing an implementation of a writer for testing // purposes and use in other contexts I can't think of now throw new NotImplementedException(); }
public virtual void WriteLimitExpressionParameter( LimitQueryExpression limitQueryExpression, QueryExpressionVisitor queryExpressionVisitor ) { queryText.Append(" LIMIT "); WriteIfNotNull(limitQueryExpression.Limit, queryExpressionVisitor); if (limitQueryExpression.Offset != null) { queryText.Append(" OFFSET "); WriteIfNotNull(limitQueryExpression.Offset, queryExpressionVisitor); } }
public virtual void WriteSelectStatement( SelectStatementQueryExpression selectStatementQueryExpression, QueryExpressionVisitor queryExpressionVisitor) { statementStack.Push(selectStatementQueryExpression); if (IsSubQuery()) { queryText.Append(" ( "); } queryText.Append("SELECT "); if (selectStatementQueryExpression.Projection == null || selectStatementQueryExpression.Projection.Expressions == null || selectStatementQueryExpression.Projection.Expressions.Length < 1) { throw new ProjectionMissingException("SELECT query must include a projection."); } queryExpressionVisitor.Visit(selectStatementQueryExpression.Projection); WriteIfNotNull(selectStatementQueryExpression.From, queryExpressionVisitor); if (selectStatementQueryExpression.Joins != null && selectStatementQueryExpression.Joins.Length > 0) { WriteExpressionCollection(selectStatementQueryExpression.Joins, queryExpressionVisitor, seperator: " "); } WriteIfNotNull(selectStatementQueryExpression.Where, queryExpressionVisitor); WriteIfNotNull(selectStatementQueryExpression.GroupBy, queryExpressionVisitor); WriteIfNotNull(selectStatementQueryExpression.Having, queryExpressionVisitor); WriteIfNotNull(selectStatementQueryExpression.OrderBy, queryExpressionVisitor); WriteIfNotNull(selectStatementQueryExpression.Limit, queryExpressionVisitor); if (IsSubQuery()) { queryText.Append(" ) "); } else { queryText.Append("; "); } statementStack.Pop(); }
DbCommandFactor GenerateCommandFactor() { IQueryState qs = QueryExpressionVisitor.VisitQueryExpression(this._query.QueryExpression); MappingData data = qs.GenerateMappingData(); IObjectActivator objectActivator; objectActivator = data.ObjectActivatorCreator.CreateObjectActivator(); IDbExpressionTranslator translator = this._query.DbContext._dbContextServiceProvider.CreateDbExpressionTranslator(); List <DbParam> parameters; string cmdText = translator.Translate(data.SqlQuery, out parameters); DbCommandFactor commandFactor = new DbCommandFactor(objectActivator, cmdText, parameters.ToArray()); return(commandFactor); }
public virtual void WriteIdentifier(IdentifierQueryExpression identifierQueryExpression, QueryExpressionVisitor queryExpressionVisitor) { if (identifierQueryExpression is NestedIdentifierQueryExpression nestedIdentifierQueryExpression && nestedIdentifierQueryExpression.ParentIdentifier != null) { WriteIdentifier(nestedIdentifierQueryExpression.ParentIdentifier, queryExpressionVisitor); queryText.Append("."); } if (identifierQueryExpression.IdentifierName == "*") { queryText.Append(" * "); } else { queryText.Append($" [{identifierQueryExpression.IdentifierName}] "); } }
public virtual void WriteInsertStatement( InsertStatementQueryExpression insertStatementQueryExpression, QueryExpressionVisitor queryExpressionVisitor ) { statementStack.Push(insertStatementQueryExpression); if (IsSubQuery()) { queryText.Append(" ( "); } queryText.Append("INSERT "); WriteIfNotNull(insertStatementQueryExpression.Into, queryExpressionVisitor); queryText.Append(" ( "); WriteExpressionCollection(insertStatementQueryExpression.Columns, queryExpressionVisitor); queryText.Append(" ) "); queryText.Append(" VALUES "); for (var i = 0; i < insertStatementQueryExpression.RowsExpressions.Length; i++) { queryText.Append(" ( "); WriteExpressionCollection(insertStatementQueryExpression.RowsExpressions[i], queryExpressionVisitor); queryText.Append(" ) "); if (i < insertStatementQueryExpression.RowsExpressions.Length - 1) { queryText.Append(", "); } } if (IsSubQuery()) { queryText.Append(" ) "); } else { queryText.Append("; "); } statementStack.Pop(); }
private static async Task ExecuteSubExpression( QueryContext context, QueryExpressionVisitor visitor, IQueryExecutor executor, Expression expression, CancellationToken cancellationToken) { // get element type Type elementType = null; var queryType = expression.Type.FindGenericType(typeof(IQueryable <>)); if (queryType != null) { elementType = queryType.GetGenericArguments()[0]; } var query = visitor.BaseQuery.Provider.CreateQuery(expression); var method = typeof(IQueryExecutor) .GetMethod("ExecuteQueryAsync") .MakeGenericMethod(elementType); var parameters = new object[] { context, query, cancellationToken }; var task = method.Invoke(executor, parameters) as Task <QueryResult>; await task.ConfigureAwait(false); // RWM: This code currently returns 404s if there are no results, instead of returning empty queries. // This means that legit EntitySets that just have no data in the table also return 404. No bueno. //var task = method.Invoke(executor, parameters) as Task<QueryResult>; //var result = await task.ConfigureAwait(false); //var any = result.Results.Cast<object>().Any(); //if (!any) //{ // // Which means previous expression does not have result, and should throw ResourceNotFoundException. // throw new ResourceNotFoundException(Resources.ResourceNotFound); //} }
/// <summary> /// Asynchronously executes the query flow. /// </summary> /// <param name="context"> /// The query context. /// </param> /// <param name="cancellationToken"> /// A cancellation token. /// </param> /// <returns> /// A task that represents the asynchronous /// operation whose result is a query result. /// </returns> public static async Task<QueryResult> QueryAsync( QueryContext context, CancellationToken cancellationToken) { Ensure.NotNull(context, "context"); // process query expression var expression = context.Request.Expression; var visitor = new QueryExpressionVisitor(context); expression = visitor.Visit(expression); // get element type Type elementType = null; var queryType = expression.Type.FindGenericType(typeof(IQueryable<>)); if (queryType != null) { elementType = queryType.GetGenericArguments()[0]; } // append count expression if requested if (elementType != null && context.Request.ShouldReturnCount) { expression = ExpressionHelpers.Count(expression, elementType); elementType = null; // now return type is single int } // execute query QueryResult result; var executor = context.GetHookHandler<IQueryExecutor>(); if (executor == null) { throw new NotSupportedException(Resources.QueryExecutorMissing); } if (elementType != null) { var query = visitor.BaseQuery.Provider.CreateQuery(expression); var method = typeof(IQueryExecutor) .GetMethod("ExecuteQueryAsync") .MakeGenericMethod(elementType); var parameters = new object[] { context, query, cancellationToken }; var task = method.Invoke(executor, parameters) as Task<QueryResult>; result = await task; } else { var method = typeof(IQueryExecutor) .GetMethod("ExecuteSingleAsync") .MakeGenericMethod(expression.Type); var parameters = new object[] { context, visitor.BaseQuery, expression, cancellationToken }; var task = method.Invoke(executor, parameters) as Task<QueryResult>; result = await task; } if (result != null) { result.ResultsSource = visitor.EntitySet; } return result; }
private static async Task ExecuteSubExpression( QueryContext context, CancellationToken cancellationToken, QueryExpressionVisitor visitor, IQueryExecutor executor, Expression expression) { // get element type Type elementType = null; var queryType = expression.Type.FindGenericType(typeof(IQueryable<>)); if (queryType != null) { elementType = queryType.GetGenericArguments()[0]; } var query = visitor.BaseQuery.Provider.CreateQuery(expression); var method = typeof(IQueryExecutor) .GetMethod("ExecuteQueryAsync") .MakeGenericMethod(elementType); var parameters = new object[] { context, query, cancellationToken }; var task = method.Invoke(executor, parameters) as Task<QueryResult>; var result = await task; var any = result.Results.Cast<object>().Any(); if (!any) { // Which means previous expression does not have result, and should throw ResourceNotFoundException. throw new ResourceNotFoundException(Resources.ResourceNotFound); } }
/// <summary> /// Asynchronously executes the query flow. /// </summary> /// <param name="context"> /// The query context. /// </param> /// <param name="cancellationToken"> /// A cancellation token. /// </param> /// <returns> /// A task that represents the asynchronous /// operation whose result is a query result. /// </returns> public async Task<QueryResult> QueryAsync( QueryContext context, CancellationToken cancellationToken) { Ensure.NotNull(context, "context"); // STEP 1: pre-filter var filters = context.GetHookPoints<IQueryFilter>(); foreach (var filter in filters.Reverse()) { await filter.FilterRequestAsync(context, cancellationToken); if (context.Result != null) { return context.Result; } } // STEP 2: process query expression var expression = context.Request.Expression; var visitor = new QueryExpressionVisitor(context); expression = visitor.Visit(expression); // STEP 3: execute query QueryResult result = null; var executor = context.GetHookPoint<IQueryExecutor>(); if (executor == null) { throw new NotSupportedException(); } var queryType = expression.Type .FindGenericType(typeof(IQueryable<>)); if (queryType != null) { var query = visitor.BaseQuery.Provider.CreateQuery(expression); var method = typeof(IQueryExecutor) .GetMethod("ExecuteQueryAsync") .MakeGenericMethod(queryType.GetGenericArguments()[0]); var parameters = new object[] { context, query, cancellationToken }; var task = method.Invoke(executor, parameters) as Task<QueryResult>; result = await task; } else { var method = typeof(IQueryExecutor) .GetMethod("ExecuteSingleAsync") .MakeGenericMethod(expression.Type); var parameters = new object[] { context, visitor.BaseQuery, expression, cancellationToken }; var task = method.Invoke(executor, parameters) as Task<QueryResult>; result = await task; } if (result != null) { result.ResultsSource = visitor.EntitySet; } context.Result = result; // STEP 4: post-filter foreach (var filter in filters) { await filter.FilterResultAsync(context, cancellationToken); } return context.Result; }