Hi Witold,

And thanks for clarifying.

2013/4/7 Witold Szczerba <[email protected]>:
> 7 kwi 2013 10:48, "Lukas Eder" <[email protected]> wrote:
>>
>>
>> I'm not convinced yet. But not because I "strongly believe" that the
>> current solution is perfect, I might just (still!) not understand your
>> point of view. Let's put it this way:
>>
>> // jOOQ 2.x:
>> new Factory(...).select();
>>
>> // jOOQ 3.0-RC1 and RC2:
>> new Executor(...).select();
>>
>> // jOOQ 3.0-RC3
>> DSL.using(...).select();
>
> Hi,
> to a answer your question, what I specifically don't like is that now,
> starting from 3.0, JOOQ will propagate an anti pattern of getting the
> configuration object to be able to "enter" the DSL.
>
> Look at the very first example of 2.6 branch from jooq.org landing page:
>
> ----------------------
> create.selectFrom(BOOK)
>       .where(PUBLISHED_IN.equal(2011))
>       .orderBy(TITLE)
> ----------------------
>
> That is it. Entire example. What does it tell you? Get the "create" (I call
> this instance a jooq in my app) and then write the code as in example. Where
> to get the "create" from? It doesn't matter. This is not the business of
> JOOQ. Create it by yourself, use Spring, Guice, CDI, inject manually, use
> the lookup pattern, there are many options, none of them are the JOOQ's
> interest.

True. Let's have a look at an example:

    DSLContext create = DSL.using(configuration);

In every day work, no difference there :-)

Rest assured that because of a significant amount of inertia and
lazyness, I'm not going to rewrite the whole manual and replace all
the examples. I don't even think that you should be writing "using()"
in front of every database call, myself. There will be a couple of
examples actually promoting the use of "using()". But I agree with you
that most of the time, people will store this DSLContext instance
somewhere, or create a factory method for it, or whatever. It doesn't
matter in everyday SQL work. So, things will stay the same. In other
words, I'd expect people to do the right thing out of lazyness.

I want to repeat my example of the XML Transformer. The complete call
chain to transform a document is this:

    TransformerFactory.newInstance().newTransformer().transform(source, target);

But users will soon get wary of this and store the TransformerFactory
and / or the Transformer instance in some local context, e.g. by
pooling transformers. The above will become

    transformer.transform(source, target);

The same applies to JDBC. No one will explicitly fetch a Connection
from a DataSource for every statement:

    dataSource.getConnection().createStatement();

They have some sort of local context, where the Connection is stored:

    connection.createStatement();

But it would be terribly wrong for jOOQ not to provide *some* sort of
API to construct that local DSLContext for you. And from what I've
learned in recent discussions, people had preferred writing
"DSL.using()", rather than "new Executor()".

Now as far as the "anti-pattern" is concerned, I understand what you
mean. You mean that org.jooq.DSL shouldn't do two things at once. But
I disagree with you, here. Unlike Ceylon, for instance, Java doesn't
have package-level (i.e. "top-level") methods, which are global in
scope. Unlike Scala, Java doesn't have implicit methods either. In
Java, every method has to be put in a class and dereferenced
explicitly. My personal preference would be not to need any
org.jooq.DSL type at all, but to put all DSL methods (including
"using()") into the top-level, i.e. into the "org.jooq" package. In
JavaScript, I'd still create a DSL global namespace-object for that.
There has to be some entry-point to the DSL. And that's this one
class.

While, in the context of a "regular API", I'd probably agree with you,
I don't entirely agree with you in the context of an internal DSL. As
a matter of fact, I don't even think that there are best practices or
"patterns" vs. "anti-patterns" in modern internal DSLs. I'm not aware
of many Java tools out there, that actually go as far as jOOQ.

So the driving force here is the learning curve, which is less steep,
if "using()" and "other types" of top-level DSL methods are all put
into the "org.jooq.DSL" type.

> Now, I can see all the examples are going to be rewritten like:
>
> ----------------------
> using(configuration)
>       .selectFrom(BOOK)
>       .where(PUBLISHED_IN.equal(2011))
>       .orderBy(TITLE)
> ----------------------
>
> ,which means: get the configuration from somewhere, which is breaking, at
> least, the principle of least knowledge. IMHO this is one of the most
> important and also most ignored principle in programing in general.

Then, as I said, the principle was broken before. Before, we could've written:
----------------------
new Factory(configuration)
      .selectFrom(BOOK)
      .where(PUBLISHED_IN.equal(2011))
      .orderBy(TITLE)
----------------------

This is exactly the same. It's even worse as the DSL is broken through
the non-DSL "new" keyword.

> Also, I do believe this is polluting the DSL, because there is no equivalent
> of the first statement in SQL.

In your own examples, you mentioned the use of CONNECT. I don't think
that "using()" is too far away from that.

> And last, but not least, when writing:
> import static org.jooq.DSL.*
> we do import all the goodness of JOOQ plus the "using" evil stuff. One
> cannot import everything BUT the "using" stuff. This is of course the minor
> problem. We can just ignore that method, but the "damage" caused by
> encouraging developers to use it, as the "official" documentation says, as
> the DSL API says, is the thing I am trying to avoid.

Then, those rules will have to make it into your own "best practices".
Many users use jOOQ as a scripting / batch DSL for SQL. A nice example
can be seen here:
https://github.com/jOOQ/jOOQ/issues/2372

"using()" may come in handy in such situations. Or not, as users might
still assign the DSLContext instance to a "create" reference. It's up
to you.

So thanks again, for clarifying your thoughts. The conclusion here is
that the "anti-pattern" of putting "too much" into org.jooq.DSL stands
against the "anti-pattern" of distributing DSL entry points across
various API elements.

Or to put things positively, I chose a gentle learning curve over a
clean separation of concerns in the case of DSL entry points. This
conclusion will make it into the tutorial and manual.

Cheers
Lukas!

-- 
You received this message because you are subscribed to the Google Groups "jOOQ 
User Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to