Created a new issue for jOOQ 4.0, to keep in the back of our heads:If the two APIs can be maintained in parallel, the change might also be introduced in a minor release in 3.x
With Christopher Decker's recent helping in creating a railroad-diagram tool [1] and Peter Verhas's inspiration, mapping a finite state-machine to a fluent API (and / or a BNF), the language-aspects of jOOQ will hopefully be heavily improved in the near future [3].
Hi Lukas,There starts to be several discussions that could be brought together, revolving around the actual construction of the jOOQ DSL, its formalism, supported dialects and versions, etc.
Created a new issue for jOOQ 4.0, to keep in the back of our heads:If the two APIs can be maintained in parallel, the change might also be introduced in a minor release in 3.x
"For backwards-compatibility reasons, it would be important to maintain the two APIs in parallel, potentially using a code generator to generate one API from the other"With Christopher Decker's recent helping in creating a railroad-diagram tool [1] and Peter Verhas's inspiration, mapping a finite state-machine to a fluent API (and / or a BNF), the language-aspects of jOOQ will hopefully be heavily improved in the near future [3].So, what would be the ideal solution of creating jOOQ to have all the features we dream of?
Suppose a user wants one of (these are just some of the possible examples):
- strict API for a particular dialect and version of one RDBMS.
- strict+simulated for a common subset of dialects.
- all strict+simulated for all dialects.
- naming strategy as all caps.
- naming strategy as camelCase.- documentation with BNF syntax and railroad diagrams for their selected subset.
It would be interesting to have the standard jOOQ being one set of these possible choices but the user be able to generate/download his flavor that restricts/adjusts jOOQ API.
Then, it means the DSL generator is the central piece. The DSL generator generates interfaces and methods (with Javadoc) that match the desired criteria, as well as a BNF notation, from which syntax can be studied eventually in the form of railroad diagrams.
The generator would somehow generate the implementation of these interfaces that call core classes that never change. The whole jOOQ internals never change, only the facade that is exposed to the user. A different set of criteria simply means a different facade. Code completion would be great and to the point!
For example, my very own set of criteria would be:- all caps.- union of strict APIs for SQLServer 2008+ and Oracle 10.
That way, the API would not simutate anything (strict SQL) and I would be able to call SQLServer or Oracle specific functions conditionally when I need. Of course, I would have to be careful not to call Oracle-specific stuff when on SQLServer, but I would likely generate the strict API of each just to keep the corresponding documentations and railroad diagrams at hand.
Nice. So the API generation configuration dimensions are:- Dialect support- Strictness- API naming strategies
Note, I'm thinking about distinguishing "strictness" between- No simulation (strict)- "simple" simulation: syntactic equivalence, such as NVL(a, b) = CASE WHEN a IS NOT NULL THEN a ELSE b END- "transformative" simulation: transforming SQL to form very different SQL, e.g. LIMIT / OFFSET in Oracle, SQLServer 2008, LPAD() in SQLite (see other thread), or row value expressions and IN predicates:
I'm even dreaming of putting RRDiagram SVGs into the generated Javadoc :-)
All of this will certainly have to be prototyped, as it is currently not clear how clean the separation of DSL and model API can be made.
So, you think that an API union of strict APIs is useful?
According to your use-case, would API union / intersection include data types?
How about stored procedures? There will be caveats, of course :-)
> So, you think that an API union of strict APIsMy wishlist item for this would be:
> is useful? Or did you mean an API intersection
> (removing features that aren't available in *both*
> databases)?
The intersection of exactly those dialects I care about, plus anything that can be emulated without resorting to potentially surprising behaviour.
I'm not sure how to organize this, much less implement it; it's definitely an architectural challenge to cleanly cater for all 2^N subsets of N supported dialects, brute-force solutions won't work for that.
Maybe it's enough to offer diagnostics. Say, whenever Jooq is configured for dialect, it accepts the dialect to use, and the set of dialects to restrict its API to. That way, Jooq can emit diagnostics if the application tries things that happen to work with the currently selected dialect but wouldn't for other dialects that the application is supposed to be compatible with.
Hi Lukas,Nice. So the API generation configuration dimensions are:- Dialect support- Strictness- API naming strategiesIn fact, I wonder if there should not be an additional item:- Target language of choiceIf you specify "Java" as your language criteria, keywords and operators may be different than if you say "Scala". This also has something do to with language-specific reserved keywords and syntax sugar.
Note, I'm thinking about distinguishing "strictness" between- No simulation (strict)- "simple" simulation: syntactic equivalence, such as NVL(a, b) = CASE WHEN a IS NOT NULL THEN a ELSE b END- "transformative" simulation: transforming SQL to form very different SQL, e.g. LIMIT / OFFSET in Oracle, SQLServer 2008, LPAD() in SQLite (see other thread), or row value expressions and IN predicates:Yes, this probably makes sense though I fear we developers are going to argue what is considered "simple" :)
I'm even dreaming of putting RRDiagram SVGs into the generated Javadoc :-)Ah, if only our free time were infinite and conversion of DSL to BNF be an easy problem! ;)
All of this will certainly have to be prototyped, as it is currently not clear how clean the separation of DSL and model API can be made.Yes, this might be the only way to find the right solution.I currently don't know whether the model API should be somewhat exposed or if it can only be an internal thing, so that the exposed facade is the only API. I tend to think that the model should be hidden as an internal API, after all, all jOOQ objects are interfaces (Row, Field, etc.) which could call that internal immutable API in their implementation.
So, you think that an API union of strict APIs is useful?I really meant union :)jOOQ defaults to a union of all possible dialects, but in my case I just want to restrict to the 2 (or more) database dialects that we use. That way, we use the common subset, except when we have an issue and make a switch/case on the dialect to perform dialect-specific operations. Having this union means I would remove the noise of dialects that we definitely not care about.
According to your use-case, would API union / intersection include data types?It should :)But this multi-dialect handling in jOOQ is not clear for me, as I mentioned in an earlier post.You could also consider that multi-dialect is a marginal case that you don't want to support, to reduce the issue to one or all dialects.
How about stored procedures? There will be caveats, of course :-)I know, but in case of doubt, well, ignore the criteria.
Speaking about the model, when a user decides to not use the default facade, they would probably have to regenerate their model using their criterias. Generated model and DSL have to be in sync.
Hi Christopher,2013/6/25 Christopher Deckers <chr...@gmail.com>
Hi Lukas,Nice. So the API generation configuration dimensions are:- Dialect support- Strictness- API naming strategiesIn fact, I wonder if there should not be an additional item:- Target language of choiceIf you specify "Java" as your language criteria, keywords and operators may be different than if you say "Scala". This also has something do to with language-specific reserved keywords and syntax sugar.That would be nice. In fact, it would be very useful, if jOOQ Scala APIs could explicitly overload operators, instead of relying on implicit defs in a separate Java to Scala conversion object, as it is implemented now.Of course, it would be good to think about other Scala language elements, which could be leveraged that way, e.g. the use of Field[Option[Int]] for what is a nullable Field[Integer] in Java, e.g. the use of Scala collections instead of Java ones, etc.But I think that will be food for thought for jOOQ 5.0. :-)
What I'm trying to say is, it may be worth evaluating to write scooq, instead of adding 1-2 utilities to jOOQ. Or since Scala is mainly functional, not OO, a "better" name might be scfq ;-)
Hi Lukas,What I'm trying to say is, it may be worth evaluating to write scooq, instead of adding 1-2 utilities to jOOQ. Or since Scala is mainly functional, not OO, a "better" name might be scfq ;-)Remember that Java 8 is coming and you may have to think of "jFQ" too :)
What I'm trying to say is, it may be worth evaluating to write scooq, instead of adding 1-2 utilities to jOOQ. Or since Scala is mainly functional, not OO, a "better" name might be scfq ;-)