I would like to use wait(int)
as the signature of a method in a fluent API (used for http://www.jooq.org). The goal is to be able to construct SQL queries like this example:
SELECT * FROM T_AUTHOR
WHERE ROWNUM <= 1
FOR UPDATE OF FIRST_NAME, LAST_NAME
WAIT 5
The full FOR UPDATE
clause syntax specification (at least for Oracle) can be seen here:
FOR UPDATE [ OF [ [ schema. ] { table | view } . ] column
[, [ [ schema. ] { table | view } . ] column]...]
[ { NOWAIT | WAIT integer | SKIP LOCKED } ]
http://download.oracle.com/docs/cd/B28359_01/server.111/b28286/img_text/for_update_clause.htm
With jOOQ, I really want to stay close to the SQL syntax. So I'd like to be able to model the above SQL clause with the jOOQ fluent API like this:
Result<Record> result = create.select()
.from(T_AUTHOR)
.limit(1)
.forUpdate()
.of(FIRST_NAME, LAST_NAME)
.wait(5) // Here's the issue
.fetch();
The fetch method is used to render the API's underlying object as SQL and run the SQL statement against an Oracle (or any other) database. The above can be legally specified in an interface:
/**
* A type that models a "step" in the creation of a query using the fluent API
*/
public interface SelectForUpdateWaitStep extends SelectFinalStep {
// [...]
/**
* Add a "FOR UPDATE .. WAIT n" clause to the query
*/
SelectFinalStep wait(int seconds);
// [...]
}
I have some doubts about this, though, because there is a risk of collision with another method:
public class Object {
// [...]
public final native void wait(long timeout) throws InterruptedException;
// [...]
}
Thanks to method-overloading (int
vs. long
arguments), I can actually do this. But I'm afraid it might confuse my users and lead to mistakes. So this would be wrong:
.forUpdate()
.of(FIRST_NAME, LAST_NAME)
.wait((long) 5) // This doesn't make sense
.fetch(); // This doesn't compile
So my questions are:
Object.wait(long)
altoghether? I don't think so because it's declared final
but maybe someone knows a compiler-trick, or something else?doWait(int)
or WAIT(int)
?You might try using a waitFor
method instead, which specifies both a time and a "condition" to wait for. The implementation detail would be hidden, but one possible implementation would be to try your action immediately and loop until the specified condition has been met, with an appropriate pause between attempts.
Here's a sample interface for a Condition
I use myself (as you can see, it doesn't need to be complex):
public interface Condition {
public boolean met();
}
Hacking around with core Java for the sake of DSL is simply not a good idea.
Why not make your DSL more expressive?
What does wait(int n) mean anyway? wait for N milliseconds, seconds, minutes?
A better signature would be:
wait(long duration, java.util.concurrent.TimeUnit){ ... }
which reads better, for example:
wait(30, TimeUnit.MILLISECONDS)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With