[#8302] Emulate procedural languages in H2

This commit is contained in:
lukaseder 2019-02-06 15:32:01 +01:00
parent 850c922da8
commit d3dc0ac857
21 changed files with 315 additions and 14 deletions

View File

@ -742,7 +742,7 @@ public interface DSLContext extends Scope , AutoCloseable {
*
* @see DSL#begin(Statement...)
*/
@Support({ FIREBIRD, MARIADB, POSTGRES })
@Support({ FIREBIRD, H2, MARIADB, POSTGRES })
Block begin(Statement... statements);
/**
@ -750,7 +750,7 @@ public interface DSLContext extends Scope , AutoCloseable {
*
* @see DSL#begin(Collection)
*/
@Support({ FIREBIRD, MARIADB, POSTGRES })
@Support({ FIREBIRD, H2, MARIADB, POSTGRES })
Block begin(Collection<? extends Statement> statements);

View File

@ -106,6 +106,7 @@ package org.jooq;

View File

@ -64,6 +64,8 @@ package org.jooq;

View File

@ -89,6 +89,7 @@ package org.jooq;

View File

@ -73,6 +73,7 @@ package org.jooq;

View File

@ -67,6 +67,7 @@ package org.jooq;

View File

@ -67,6 +67,7 @@ package org.jooq;

View File

@ -59,6 +59,7 @@ package org.jooq;

View File

@ -93,6 +93,7 @@ package org.jooq;

View File

@ -72,6 +72,57 @@ package org.jooq.impl;

View File

@ -41,15 +41,20 @@ package org.jooq.impl;
// ...
// ...
import static org.jooq.SQLDialect.FIREBIRD;
import static org.jooq.SQLDialect.H2;
import static org.jooq.SQLDialect.MARIADB;
// ...
import static org.jooq.SQLDialect.POSTGRES;
import static org.jooq.conf.ParamType.INLINED;
import static org.jooq.impl.Keywords.K_ALIAS;
import static org.jooq.impl.Keywords.K_AS;
import static org.jooq.impl.Keywords.K_ATOMIC;
import static org.jooq.impl.Keywords.K_BEGIN;
import static org.jooq.impl.Keywords.K_CALL;
import static org.jooq.impl.Keywords.K_CREATE;
import static org.jooq.impl.Keywords.K_DECLARE;
import static org.jooq.impl.Keywords.K_DO;
import static org.jooq.impl.Keywords.K_DROP;
import static org.jooq.impl.Keywords.K_END;
import static org.jooq.impl.Keywords.K_EXECUTE_BLOCK;
import static org.jooq.impl.Keywords.K_EXECUTE_IMMEDIATE;
@ -73,8 +78,10 @@ import org.jooq.DDLQuery;
// ...
import org.jooq.Field;
// ...
import org.jooq.Query;
import org.jooq.SQLDialect;
import org.jooq.Statement;
// ...
/**
* @author Lukas Eder
@ -158,6 +165,36 @@ final class BlockImpl extends AbstractQuery implements Block {
break;
}
case H2: {
String name = "block_" + System.currentTimeMillis() + "_" + (long) (10000000L * Math.random());
// TODO: create a non-ambiguous name
if (increment(ctx.data(), DATA_BLOCK_NESTING)) {
ctx.paramType(INLINED)
.visit(K_CREATE).sql(' ')
.visit(K_ALIAS).sql(' ').sql(name).sql(' ')
.visit(K_AS).sql(" $$")
.formatIndentStart()
.formatSeparator()
.sql("void x(Connection c) throws SQLException ");
ctx.data(DATA_FORCE_STATIC_STATEMENT, true);
}
accept0(ctx);
if (decrement(ctx.data(), DATA_BLOCK_NESTING))
ctx.formatIndentEnd()
.formatSeparator()
.sql("$$;")
.formatSeparator()
.visit(K_CALL).sql(' ').sql(name).sql("();")
.formatSeparator()
.visit(K_DROP).sql(' ').visit(K_ALIAS).sql(' ').sql(name).sql(';');
break;
}
@ -261,6 +298,9 @@ final class BlockImpl extends AbstractQuery implements Block {
ctx.sql(';');
}
@ -276,7 +316,10 @@ final class BlockImpl extends AbstractQuery implements Block {
private static final void acceptNonDeclarations(Context<?> ctx, List<Statement> statements, boolean wrapInBeginEnd) {
if (wrapInBeginEnd) {
ctx.visit(K_BEGIN);
if (ctx.family() == H2)
ctx.sql('{');
else
ctx.visit(K_BEGIN);
if (ctx.family() == MARIADB)
ctx.sql(' ').visit(K_NOT).sql(' ').visit(K_ATOMIC);
@ -297,6 +340,7 @@ final class BlockImpl extends AbstractQuery implements Block {
case H2:
case FIREBIRD:
case MARIADB:
default:
@ -330,7 +374,37 @@ final class BlockImpl extends AbstractQuery implements Block {
ctx.visit(s);
if (ctx.family() == H2 && s instanceof Query && !(s instanceof Block)) {
ArrayList<Variable<?>> list = new ArrayList<Variable<?>>();
ctx.data(STATEMENT_VARIABLES, list);
ctx.sql("try (PreparedStatement s = c.prepareStatement(")
.formatIndentStart()
.formatNewLine()
.sql('"')
.sql(ctx.render(s).replace("\"", "\\\"").replace("\n", "\\n\" +\n\""))
.sql('"')
.formatIndentEnd()
.formatNewLine()
.sql(")) {")
.formatIndentStart()
.formatSeparator();
for (int j = 0; j < list.size(); j++)
ctx.sql("s.setObject(" + (j + 1) + ", ")
.sql(list.get(j).getName())
.sql(");")
.formatSeparator();
ctx.sql("s.execute();")
.formatIndentEnd()
.formatSeparator()
.sql('}');
ctx.data().remove(STATEMENT_VARIABLES);
}
else
ctx.visit(s);
@ -347,12 +421,17 @@ final class BlockImpl extends AbstractQuery implements Block {
private static final void end(Context<?> ctx) {
ctx.formatIndentEnd()
.formatSeparator()
.visit(K_END);
.formatSeparator();
switch (ctx.family()) {
case FIREBIRD:
break;
if (ctx.family() == H2)
ctx.sql('}');
else
ctx.visit(K_END);
switch (ctx.family()) {
case H2:
case FIREBIRD:
break;
@ -365,8 +444,22 @@ final class BlockImpl extends AbstractQuery implements Block {
default:
ctx.sql(';');
}
default:
ctx.sql(';');
}
}
static final String STATEMENT_VARIABLES = "org.jooq.impl.BlockImpl.statement-variables";
}

View File

@ -107,6 +107,16 @@ package org.jooq.impl;

View File

@ -9750,7 +9750,7 @@ public class DSL {
*
* @see DSLContext#begin(Statement...)
*/
@Support({ FIREBIRD, MARIADB, POSTGRES })
@Support({ FIREBIRD, H2, MARIADB, POSTGRES })
public static Block begin(Statement... statements) {
return begin(Arrays.asList(statements));
}
@ -9760,7 +9760,7 @@ public class DSL {
*
* @see DSLContext#begin(Collection)
*/
@Support({ FIREBIRD, MARIADB, POSTGRES })
@Support({ FIREBIRD, H2, MARIADB, POSTGRES })
public static Block begin(Collection<? extends Statement> statements) {
return DSL.using(new DefaultConfiguration()).begin(statements);
}

View File

@ -101,6 +101,24 @@ package org.jooq.impl;

View File

@ -108,6 +108,16 @@ package org.jooq.impl;

View File

@ -170,6 +170,22 @@ package org.jooq.impl;

View File

@ -49,6 +49,7 @@ import org.jooq.Keyword;
final class Keywords {
static final Keyword K_ADD = keyword("add");
static final Keyword K_ALIAS = keyword("alias");
static final Keyword K_ALTER = keyword("alter");
static final Keyword K_ALTER_COLUMN = keyword("alter column");
static final Keyword K_ALTER_CONSTRAINT = keyword("alter constraint");
@ -72,6 +73,7 @@ final class Keywords {
static final Keyword K_BULK_COLLECT_INTO = keyword("bulk collect into");
static final Keyword K_BY = keyword("by");
static final Keyword K_CACHE = keyword("cache");
static final Keyword K_CALL = keyword("call");
static final Keyword K_CASCADE = keyword("cascade");
static final Keyword K_CASE = keyword("case");
static final Keyword K_CAST = keyword("cast");

View File

@ -81,6 +81,7 @@ package org.jooq.impl;

View File

@ -82,6 +82,7 @@ package org.jooq.impl;

View File

@ -199,6 +199,78 @@ package org.jooq.impl;

View File

@ -74,6 +74,24 @@ package org.jooq.impl;