> Yes, it would certainly be possible to add a sql()
> method to a top-level type, e.g. QueryPart. But
> the huge drawback of this is that the whole
> QueryPart type tree would need to be generified to
> allow for:
> 
> interface QueryPart<Q extends QueryPart> {
>     Q sql(String sql);
> }

That's indeed necessary.
Pervase change: Yes.
Huge Problem? I don't see that.
 
> Q is necessary to allow for fluent injection of SQL.

Ack.

> We'd probably have to check whether appending or
> prepending is more useful (or both?).

For comments, appending would be enough.
Other use cases that I can see off the top of my head are appending, too, so 
that is the default case.

However, to deal with the odd "but I need something prepended" case, I'd offer 
a variant of sql() that wraps the SQL between a prefix and a postfix. 
sql(String) would then be

Q sql(String after) {
  return sql("", after);
}
abstract Q sql(String before, after);

> In the context of a SELECT statement, it could only
> be "appending".

A use case for wrapping over appending could be that the programmer wants to 
wrap an expression or select in a subselect, using database-specific 
functionality that Jooq doesn't support yet.

> But the slim added value clearly doesn't pull the weight
> of the new generic type parameter.

Ehm... replacing all of hint() and similar extension points with a single, 
uniform-semantics function isn't "slim" in my book.
It's taking the pressure out of "this database-specific isn't implemented yet", 
which is a huge bonus for programmers who live with a 
not-yet-well-supported-by-Jooq database.

> Think about Field:
> 
> interface Field<T, Q extends QueryPart> extend QueryPart<Q> {
> }
> 
> interface TableField<R extends Record, T, Q extends QueryPart> extends 
> Field<T, Q> {
> }

Maybe more like

interface Field<T, Q extends QueryPart<Q>> extends QueryPart<Q>
interface TableField<R extends Record, T, Q extends QueryPart<Q>> extends 
Field<T, Q>

> That would be a very "unfriendly" addition for the end-user :-)

Yes, the dependent-typing syntax of Java sucks. Mainly because you can't name 
type subexpressions, so it gets repetitive ad nauseam.
For application programmers implementing these interfaces, it's essentially 
still

interface Field<T, Q>
interface TableField<R, T, Q>

With the additional constraint that Q must be a QueryPart - that's doable for 
an application programmer.

Maybe a paragraph "reading generic declarations" in the Jooq docs is in order, 
saying that
a) One should read a generic declaration twice
b) First pass: just collect the type names (R, T, Q for TableField)
c) Second pass: for each type, read its constraint
d) Just fill all type parameters you need filled. Something that implements 
QueryPart<String> won't work, but Jooq doesn't declare classes with that kind 
of nonsensical definition (nor would Java allow the existence of such a class).

These interfaces are actually quite straightforward. The Q extends QueryPart<Q> 
thing is a bit hairy because it's circular, but then application programmers 
aren't supposed to write subclasses of QueryPart.

Mastering generics at that level is a bit of a wild ride I'll admit. I did a 
bit of that recently and don't find it THAT esoteric anymore. It would be an 
experiment I guess, and it could fail.

> Should be simple:
> 
> // Construct your statement:
> Select<?> select = //...
> 
> // Render it with inlined bind values:
> String sql = DSL
> .using((Connection) null, dialect, new Settings()
>             .withStatementType(STATIC_STATEMENT)
>             .withRenderFormatted(true) // possibly?
> ).render(select);
> 
> String view = "CREATE OR REPLACE VIEW my_view AS " + sql;
 
Yes.
The point was that I'd want to insert comments, sometimes at the field level.

Here's an example:

CREATE OR REPLACE FORCE VIEW HF_LAGERMENGEN AS 
select
  -- Used in:
  --   <modules that need to be updated if this view changes>
  fi_nr,
  lgnr,
  identnr,
  lamenge,
  -- nondispositive (<some more explanations>)
  nd,
  -- reserved (not in arrival)
  nvl (res, 0) as res,
  -- in arrival (not reserved)
  arr - nvl (res_arr, 0) as arr,
  -- reserved, in arrival
  nvl (res_arr, 0) as res_arr
from
  ... etc. pp. ...

I have other views where the join conditions have comments. Or where the 
selection of tables that got joined warrants an explanation.

Heh. Here's an idea to toss around:
For a single-database developer, Jooq would become even more useful if he could 
simply plop in some SQL as string constant, using Jooq just to generate those 
parts that are variable. He'd use strings where the SQL is constant, and build 
AST fragments where he needs to be variable. It would take the syntactic pain 
out of generated SQL, without imposing the somewhat higher verbosity of the DSL 
on those parts that could simply be written in SQL directly.

-- 
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