diff --git a/jOOQ/src/main/java/org/jooq/Block.java b/jOOQ/src/main/java/org/jooq/Block.java new file mode 100644 index 0000000000..f610cd40d7 --- /dev/null +++ b/jOOQ/src/main/java/org/jooq/Block.java @@ -0,0 +1,47 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Other licenses: + * ----------------------------------------------------------------------------- + * Commercial licenses for this work are available. These replace the above + * ASL 2.0 and offer limited warranties, support, maintenance, and commercial + * database integrations. + * + * For more information, please visit: http://www.jooq.org/licenses + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ +package org.jooq; + +/** + * A query that models an anonymous procedural block + * + * @author Lukas Eder + */ +public interface Block extends Query { + +} diff --git a/jOOQ/src/main/java/org/jooq/DSLContext.java b/jOOQ/src/main/java/org/jooq/DSLContext.java index 9c99715ee7..79761d7443 100644 --- a/jOOQ/src/main/java/org/jooq/DSLContext.java +++ b/jOOQ/src/main/java/org/jooq/DSLContext.java @@ -688,6 +688,22 @@ public interface DSLContext extends Scope , AutoCloseable { @Support Queries queries(Collection queries); + /** + * Wrap a collection of queries in an anonymous procedural block. + * + * @see DSL#begin(Query...) + */ + @Support({ POSTGRES }) + Block begin(Query... queries); + + /** + * Wrap a collection of queries in an anoymous procedural block. + * + * @see DSL#begin(Collection) + */ + @Support({ POSTGRES }) + Block begin(Collection queries); + // ------------------------------------------------------------------------- // XXX Plain SQL API // ------------------------------------------------------------------------- diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractQuery.java b/jOOQ/src/main/java/org/jooq/impl/AbstractQuery.java index e9a65ea933..04eabd1c54 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractQuery.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractQuery.java @@ -488,6 +488,7 @@ abstract class AbstractQuery extends AbstractQueryPart implements Query { Rendered result; // [#3542] [#4977] Some dialects do not support bind values in DDL statements + // [#6474] [#6929] Can this be communicated in a leaner way? if (ctx.type() == DDL) { ctx.data(DATA_FORCE_STATIC_STATEMENT, true); DefaultRenderContext render = new DefaultRenderContext(configuration); diff --git a/jOOQ/src/main/java/org/jooq/impl/BlockImpl.java b/jOOQ/src/main/java/org/jooq/impl/BlockImpl.java new file mode 100644 index 0000000000..74eff85f76 --- /dev/null +++ b/jOOQ/src/main/java/org/jooq/impl/BlockImpl.java @@ -0,0 +1,161 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Other licenses: + * ----------------------------------------------------------------------------- + * Commercial licenses for this work are available. These replace the above + * ASL 2.0 and offer limited warranties, support, maintenance, and commercial + * database integrations. + * + * For more information, please visit: http://www.jooq.org/licenses + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ +package org.jooq.impl; + +// ... +import static org.jooq.conf.ParamType.INLINED; +import static org.jooq.impl.Keywords.K_BEGIN; +import static org.jooq.impl.Keywords.K_DO; +import static org.jooq.impl.Keywords.K_END; +import static org.jooq.impl.Keywords.K_EXECUTE_IMMEDIATE; +import static org.jooq.impl.Keywords.K_NULL; +import static org.jooq.impl.Tools.decrement; +import static org.jooq.impl.Tools.increment; +import static org.jooq.impl.Tools.DataKey.DATA_BLOCK_NESTING; +import static org.jooq.impl.Tools.DataKey.DATA_FORCE_STATIC_STATEMENT; + +import java.util.Collection; +import java.util.EnumSet; + +import org.jooq.Block; +import org.jooq.Clause; +import org.jooq.Configuration; +import org.jooq.Context; +import org.jooq.DDLQuery; +import org.jooq.Query; +import org.jooq.SQLDialect; + +/** + * @author Lukas Eder + */ +final class BlockImpl extends AbstractQuery implements Block { + + /** + * Generated UID + */ + private static final long serialVersionUID = 6881305779639901498L; + + + + + + private final Collection queries; + + BlockImpl(Configuration configuration, Collection queries) { + super(configuration); + + this.queries = queries; + } + + @Override + public final void accept(Context ctx) { + switch (ctx.family()) { + case POSTGRES: { + if (increment(ctx.data(), DATA_BLOCK_NESTING)) { + ctx.paramType(INLINED) + .visit(K_DO).sql(" $$") + .formatSeparator(); + + ctx.data(DATA_FORCE_STATIC_STATEMENT, true); + } + + accept0(ctx); + + if (decrement(ctx.data(), DATA_BLOCK_NESTING)) + ctx.formatSeparator() + .sql("$$"); + + break; + } + + + + + default: { + accept0(ctx); + break; + } + } + } + + private final void accept0(Context ctx) { + ctx.visit(K_BEGIN) + .formatIndentStart(); + + if (queries.isEmpty()) { + switch (ctx.family()) { + + + + default: + ctx.formatSeparator().visit(K_NULL).sql(';'); + } + } + else { + for (Query query : queries) { + ctx.formatSeparator(); + + + + + + + + ctx.visit(query); + + + + + + + if (!(query instanceof Block)) + ctx.sql(';'); + } + } + + ctx.formatIndentEnd() + .formatSeparator() + .visit(K_END) + .sql(';'); + } + + @Override + public final Clause[] clauses(Context ctx) { + return null; + } +} diff --git a/jOOQ/src/main/java/org/jooq/impl/DSL.java b/jOOQ/src/main/java/org/jooq/impl/DSL.java index 327a5c19e0..030a0d8771 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DSL.java +++ b/jOOQ/src/main/java/org/jooq/impl/DSL.java @@ -109,6 +109,7 @@ import org.jooq.AlterTableStep; import org.jooq.AlterViewStep; import org.jooq.ArrayAggOrderByStep; // ... +import org.jooq.Block; import org.jooq.Case; import org.jooq.CaseConditionStep; import org.jooq.CaseValueStep; @@ -9238,6 +9239,26 @@ public class DSL { return DSL.using(new DefaultConfiguration()).queries(queries); } + /** + * Wrap a collection of queries in an anonymous procedural block. + * + * @see DSLContext#begin(Query...) + */ + @Support({ POSTGRES }) + public static Block begin(Query... queries) { + return begin(Arrays.asList(queries)); + } + + /** + * Wrap a collection of queries in an anonymous procedural block. + * + * @see DSLContext#begin(Collection) + */ + @Support({ POSTGRES }) + public static Block begin(Collection queries) { + return DSL.using(new DefaultConfiguration()).begin(queries); + } + diff --git a/jOOQ/src/main/java/org/jooq/impl/DefaultDSLContext.java b/jOOQ/src/main/java/org/jooq/impl/DefaultDSLContext.java index 140244b153..d110460b0e 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DefaultDSLContext.java +++ b/jOOQ/src/main/java/org/jooq/impl/DefaultDSLContext.java @@ -96,6 +96,7 @@ import org.jooq.Attachable; import org.jooq.Batch; import org.jooq.BatchBindStep; import org.jooq.BindContext; +import org.jooq.Block; import org.jooq.Catalog; import org.jooq.CommonTableExpression; import org.jooq.Condition; @@ -740,6 +741,16 @@ public class DefaultDSLContext extends AbstractScope implements DSLContext, Seri return new QueriesImpl(configuration(), queries); } + @Override + public Block begin(Query... queries) { + return begin(Arrays.asList(queries)); + } + + @Override + public Block begin(Collection queries) { + return new BlockImpl(configuration(), queries); + } + // ------------------------------------------------------------------------- // XXX Plain SQL API // -------------------------------------------------------------------------