-
Notifications
You must be signed in to change notification settings - Fork 21
Feature/decouple query builder from query execution #694
Feature/decouple query builder from query execution #694
Conversation
|
When I designed reactive-wizard, the static sql queries was an important part for some different reasons:
I also think that you could build functionality like in this PR on top of the ConnectionProvider and therefore have a module that is separate from reactive-wizard but still giving you the same features. Either in an internal or public repo. I vote for not including this in reactive-wizard based on my arguments above. |
You really want to have the caller provide the label even if if the number of unique statement texts generated by jooq will have low cardinality. All meaningful application context is lost once it has been translated to text. Crash on missing metric label instead of attempting to solve it. Edit. Since we'll want to emit trace spans and will need the same type of label/tag there. Would using the tracing context be a suitable way to propagate this information down from the method that corresponds to the *Dao methods? |
Since the end goal here is to enable a usable and safe DSL over string hacking like #680 it may be counterproductive to use string representations of queries as the interface here. The only place where you really need to be able to execute both jooq and rw dao statements back to back on the same connection is during a write transaction. Could the DaoTransactions interface be a better extension point than the statement level? |
Thanks for the comments Jonas!
Few weeks ago I have created all this functionality outside of the RW, just to see if this is possible at all. But as I said I have copied a lot of the code from RW-dao. Which means that when RW-dao gets an update (like migration from Observable to Flux and Mono), I would need to update my code too. I understand the reasons why you want to support only static sql in RW, but will my changes actually change how RW is used by developers? Only implementation details are refactored. Will developers even notice? If developer wants to build sql in other way and continue to use RW to execute it, this is possible even right now (as my changes linked above show). This PR just makes it easier to build on top of RW. The goal is to build sql with JOOQ query builder. It has predefined building methods and type safety that reduce a risk of writing an invalid sql. If I was not able to convince you, would you agree to keep first 3 commits? It will remove the need to duplicate big part of RW-dao code. |
Just wanted to update everyone that there are discussions ongoing regarding this, so it's not standing still but not yet ready to be approved or merged :) |
The hypothesis here at the moment is that we'd probably want to merge the first 3-5 commits that are clean ups of the existing code. That would make it significantly easier to review the contentious changes and revisit the design of them in a follow-up PR. |
There are a lot of changes in this PR. So to make the review process easier PR #706 was opened instead, which is 4 times smaller. We may discuss other changes later. |
Goal
The goal of this PR is to allow execution of a custom SQL (for example, built by JOOQ library) with Reactive Wizard.
Usage
Potential usage may look like something like this:
Changes
To simplify the review process, PR is divided to several commits:
1. Remove resultConverter from ReactiveStatementFactory
ReactiveStatementFactory
always createsMono
if dao method return type isMono
andFlux
if return type isFlux
. So it looks like there is no need for a converter.The check that return type is Mono or Flux was moved to
ReactiveStatementFactory
.2. Remove paramSerializer from DbProxy
I did not find any usages of
paramSerializer
inDbProxy
so I have removed it.3. Move dao method related code from ReactiveStatementFactory to DaoMethodHandler
As example code above shows, the idea is that
ReactiveStatementFactory
can be used as a tool to createMono
orFlux
that executes aStatement
.Everything related to a dao method was moved out from
ReactiveStatementFactory
and everything required for an execution of a statement was moved in fromDbProxy
class.Previously
ReactiveStatementFactory
was representing pre-calculations done for a dao method. Now this logic has been moved toDaoMethodHandler
class.4. Rename DbResultSetDeserializer to DbResultSetDeserializerImpl
I have created interface named
DbResultSetDeserializer
in the next step, so implementation class was renamed.5. Add DbResultSetDeserializer interface and generic types
DbResultSetDeserializer
interface is added to allow to swap the implementation if needed.Generic types were provided in several places to remove compiler warnings.
6. Add Statement implementation that is independent from ParameterizedQuery
New implementations of
Statement
were added. They work the same, but they are independent fromParameterizedQuery
. They accept already built sql and parameter setters based onPreparedStatementParameters
class.StatementDebug.log(preparedStatement);
is executed in all cases now.7. Make StatementFactory create new Statement implementation
ParameterizedQuery
was updated to be used with newStatement
s: it does not create prepared statement and add parameters anymore, it builds sql and creates parameters setters instead.Old
StatementFactory
s were removed. NewStatementFactory
s create new Statement implementations instead.Questions
When sql is built by jooq, everything is done at runtime. It is not possible to pre-calculate anything. But it should not be a problem, right?
When we have doa method, the metric name is the method name. But with jooq, there is no identifier, we can only use sql, but it can be too long. Can you suggest anything better?
If statement parameter is a list, then it is possible to check its generic type and use proper parameter setter (see
ParamQueryPart#getListElementType
). But with jooq we don't know the generic type of the list at runtime. Is it fine to check that all list elements are of a specific type instead?If dao method returns Mono, but select query returns multiple values, we throw an exception. But if update statement returning generated values returns multiple values, then we just returns the first one. Is it intended? I did not change this logic.
The PR is quite big. Let me know if you want to have a meeting to discuss it.