Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Query-Pre-Processor #46

Open
mp911de opened this issue Jan 4, 2019 · 15 comments
Open

Add Query-Pre-Processor #46

mp911de opened this issue Jan 4, 2019 · 15 comments
Labels
type: enhancement A general enhancement

Comments

@mp911de
Copy link
Member

mp911de commented Jan 4, 2019

We should consider adding a Query Pre-Processor API that allows generic pre-processing of queries. The first use-case of query-pre-processing is named parameter expansion (see #23). Another case can be generic query augmentation to add or remove parts of a query and to mutate bound parameters. Query pre-processors can be modeled as a filter function to compose a chain of functions.

@wellingtoncosta
Copy link

Should this be implemented at compile time or at runtime? Sorry if it is a stupid question.

@mp911de
Copy link
Member Author

mp911de commented Jan 17, 2019

There’s no such thing as a stupid question. We want to provide a runtime API so code can intercept and modify queries prior to execution.

@mp911de mp911de added the type: enhancement A general enhancement label Jan 18, 2019
@wellingtoncosta
Copy link

Got it. What kind of modifications? Optimizations? I'm so curious.

@mp911de
Copy link
Member Author

mp911de commented Jan 18, 2019

You can use it to generate events, modify the query to e.g. implement security requirements, implement multi-tenancy, add generic query predicates.

@thekalinga
Copy link

Does this also support transparent routing of all queries to read/replica server and all CUDs to write/primary server

@mp911de
Copy link
Member Author

mp911de commented Jan 20, 2019 via email

@uaihebert
Copy link
Contributor

@mp911de is this still required? I could take a look into it.

@mp911de
Copy link
Member Author

mp911de commented Feb 25, 2019

I think this ticket requires some design up-front. Looking into Spring 5's WebClient and ExchangeFunction is a good exercise to learn about delegation, filtering, and pre-/post-processing.

@mp911de
Copy link
Member Author

mp911de commented Mar 18, 2019

#73 brings PreparedOperation which can form a base to encapsulate operations that should happen on a Statement (SQL-rendering and binding of values)

@Shabin
Copy link

Shabin commented Jun 15, 2020

I am migrating from a non reactive to a reactive app. I have a requirement to update all my queries with a custom value, where I replace some pattern like :id in the query with a value specific to the current execution context.
In non reactive, I had extended JdbcTemplate and intercepted all the query methods to change the sql with the required value.

public class CustomJdbcTemplate extends JdbcTemplate {
    public <T> T query(String sql, Object[] args, int[] argTypes, ResultSetExtractor<T> rse) throws DataAccessException {
       // replace placeholders
       String statement = QueryHelper.getInstance().populateDefinedQueryPlaceHolders(sql);
       return super.query(statement, newArgTypePreparedStatementSetter(args, argTypes), rse);
   }
   //similar code in all query methods
}

What would be the correct approach for this with DatabaseClient? I assume a common query preprocessor would be a solution for this.

@mp911de
Copy link
Member Author

mp911de commented Jun 15, 2020

Ideally, intercept calls execute with a custom DatabaseClient implementation that just pre-processes your sql.

@Shabin
Copy link

Shabin commented Jun 15, 2020

Tried doing that. Found it complicated that I had to implement all the GenericExecuteSpec, SelectFromSpec etc, for simply doing a query preprocessor.
If DefaultDatabaseClient was public I could have simply extended it.

@crahul19
Copy link

Any update on if this is gonna be implemented soon? I need to add a filter like " AND someCode IN (A,B,C)" to all my queries and there's 100's of them. It would be really helpful if there was a simple way of achieving this 3-4 years after this ticket was created?

@mp911de
Copy link
Member Author

mp911de commented Aug 25, 2023

The most straightforward workaround is to provide a DatabaseClient implementation that intercepts the sql(…) method, does its rewrite, and delegates to the DatabaseClient instance created by Spring.

@crahul19
Copy link

Do I need to use AOP for intercepting the sql(…) method of DatabaseClient? We have mostly used ReactiveCrudRepository in the DAO where we use both the @query annotation and method name for generating the query but I can use the same DatabaseClient implementation for the Repository by defining a bean of type R2dbcEntityOperations.

If you could provide some hint on how can I intercept the sql() method then that will be highly appreciated.

Thanks In Advance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

6 participants