Hi Aaron,
OK, these are concrete changes, but now I don't understand how this
has to do with dependency injection...?
I know you really hate implementing JDBC's Connection,
PreparedStatement and ResultSet. But frankly, this is the way to go
here. JDBC offers a clean, well-defined API, which is much more stable
than jOOQ's internals. Let's consider a couple of pro's / con's:
Your approach:
----------------------
1. Lots of work for me
2. Substantial probability of jOOQ evolution leading to breaking your
tests in the near future
3. Very difficult to document / configure
4. Little gain but potential, negative side-effects for the community
due to the added complexity
Implementing JDBC interfaces:
--------------------------------------------
1. No work for me
2. Little probability of breaking in the near future. JDBC doesn't
evolve *that* quickly. If it breaks, just add 3-4 more methods to your
implementation classes. Even if JDBC evolves backwards-incompatibly,
the evolution is very easy to control / maintain.
3. jOOQ evolution will hardly be able to break your tests
4. Community is not involved
Let's have a closer look at your requirements again:
--------------------------------------------------------------
> 1. The method must work with a null connections
Or better, with your mock connection! -> Transparent to jOOQ
... or, let's assume the null check is removed (*)
> 2. It must not create a statement
Or better, create your mock statement! -> Transparent to jOOQ
... or, assuming that the previous null check was removed (*), yes,
various prepare() methods would have to ignore the fact that they
cannot create a statement on a null connection (**)
> 3. I must be able to override
> ExecuteContext ctx = new DefaultExecuteContext(c, this);
> so I can return a mock statement which does nothing for calls like
> ctx.statement().setQueryTimeout(timeout);
> and later ctx.resultSet()
Or better, just let your mock statement (which you've already created
via your mock connection) ignore the setQueryTimeout call
... or, assuming that (*) and (**) were implemented, you could patch
the ctx.statement() with an ExecuteListener (***)
> org.jooq.impl.AbstractResultQuery.execute(ExecuteContext, ExecuteListener):
Of course, I will eventually add an AbstractSpecialQuery and an
AbstractHelloWorldQuery.execute(ABC, XYZ)... Your test might break
> 1. Must work for null / mock connections as above
It works for mock connections
... but it could work for null connections as (*), (**), and (***)
would hold true
> 2. Instead of looping, it should return a predefined ResultImpl
Or better, your mock statement returns the predefined mock ResultSet
--------------------------------------------------------------
I'm really having a hard time seeing the advantage of your projected
approach over just implementing 3-5 JDBC interfaces (depending on
whether you need Statement and CallableStatement as well)...
On the other hand, if you must insist on such heavy intervention into
jOOQ's internals (which I will not maintain), you can still maintain
things yourself. You have the choice:
1. Maintain your own, patched jOOQ code (frequent changes as I will
not make any guarantees to package-private implementation APIs. No one
sane in the open source world would do that)
2. Maintain your own JDBC implementation (infrequent changes that are
easy to maintain)