diff --git a/jOOQ/src/main/java/org/jooq/DeleteConditionStep.java b/jOOQ/src/main/java/org/jooq/DeleteConditionStep.java index 3023661a75..e3df4c1f87 100644 --- a/jOOQ/src/main/java/org/jooq/DeleteConditionStep.java +++ b/jOOQ/src/main/java/org/jooq/DeleteConditionStep.java @@ -71,7 +71,7 @@ import org.jooq.impl.DSL; * * @author Lukas Eder */ -public interface DeleteConditionStep extends DeleteReturningStep { +public interface DeleteConditionStep extends DeleteOrderByStep { /** * Combine the currently assembled conditions with another one using the diff --git a/jOOQ/src/main/java/org/jooq/DeleteLimitStep.java b/jOOQ/src/main/java/org/jooq/DeleteLimitStep.java new file mode 100644 index 0000000000..b564480a7b --- /dev/null +++ b/jOOQ/src/main/java/org/jooq/DeleteLimitStep.java @@ -0,0 +1,88 @@ +/* + * 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; + +// ... +import static org.jooq.SQLDialect.MARIADB; +import static org.jooq.SQLDialect.MYSQL; + +/** + * This type is used for the {@link Delete}'s DSL API. + *

+ * Example:

+ * DSLContext create = DSL.using(configuration);
+ *
+ * create.delete(table)
+ *       .where(field1.greaterThan(100))
+ *       .execute();
+ * 
+ *

+ *

Referencing XYZ*Step types directly from client code

+ *

+ * It is usually not recommended to reference any XYZ*Step types + * directly from client code, or assign them to local variables. When writing + * dynamic SQL, creating a statement's components dynamically, and passing them + * to the DSL API statically is usually a better choice. See the manual's + * section about dynamic SQL for details: https://www.jooq.org/doc/latest/manual/sql-building/dynamic-sql. + *

+ * Drawbacks of referencing the XYZ*Step types directly: + *

    + *
  • They're operating on mutable implementations (as of jOOQ 3.x)
  • + *
  • They're less composable and not easy to get right when dynamic SQL gets + * complex
  • + *
  • They're less readable
  • + *
  • They might have binary incompatible changes between minor releases
  • + *
+ * + * @author Lukas Eder + */ +public interface DeleteLimitStep extends DeleteReturningStep { + + /** + * Add a LIMIT clause to the query + */ + @Support({ MARIADB, MYSQL }) + DeleteReturningStep limit(Number numberOfRows); + + /** + * Add a LIMIT clause to the query using named parameters + */ + @Support({ MARIADB, MYSQL }) + DeleteReturningStep limit(Param numberOfRows); +} \ No newline at end of file diff --git a/jOOQ/src/main/java/org/jooq/DeleteOrderByStep.java b/jOOQ/src/main/java/org/jooq/DeleteOrderByStep.java new file mode 100644 index 0000000000..550f14888d --- /dev/null +++ b/jOOQ/src/main/java/org/jooq/DeleteOrderByStep.java @@ -0,0 +1,102 @@ +/* + * 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; + +// ... +import static org.jooq.SQLDialect.MARIADB; +import static org.jooq.SQLDialect.MYSQL; + +import java.util.Collection; + +/** + * This type is used for the {@link Delete}'s DSL API. + *

+ * Example:

+ * DSLContext create = DSL.using(configuration);
+ *
+ * create.delete(table)
+ *       .where(field1.greaterThan(100))
+ *       .execute();
+ * 
+ *

+ *

Referencing XYZ*Step types directly from client code

+ *

+ * It is usually not recommended to reference any XYZ*Step types + * directly from client code, or assign them to local variables. When writing + * dynamic SQL, creating a statement's components dynamically, and passing them + * to the DSL API statically is usually a better choice. See the manual's + * section about dynamic SQL for details: https://www.jooq.org/doc/latest/manual/sql-building/dynamic-sql. + *

+ * Drawbacks of referencing the XYZ*Step types directly: + *

    + *
  • They're operating on mutable implementations (as of jOOQ 3.x)
  • + *
  • They're less composable and not easy to get right when dynamic SQL gets + * complex
  • + *
  • They're less readable
  • + *
  • They might have binary incompatible changes between minor releases
  • + *
+ * + * @author Lukas Eder + */ +public interface DeleteOrderByStep extends DeleteLimitStep { + + /** + * Add an ORDER BY clause to the query + */ + @Support({ MARIADB, MYSQL }) + DeleteLimitStep orderBy(OrderField... fields); + + /** + * Add an ORDER BY clause to the query + */ + @Support({ MARIADB, MYSQL }) + DeleteLimitStep orderBy(Collection> fields); + + /** + * Add an ORDER BY clause to the query + *

+ * Indexes start at 1 in SQL! + *

+ * Note, you can use orderBy(DSL.val(1).desc()) or + * orderBy(DSL.literal(1).desc()) to apply descending + * ordering + */ + @Support({ MARIADB, MYSQL }) + DeleteLimitStep orderBy(int... fieldIndexes); +} \ No newline at end of file diff --git a/jOOQ/src/main/java/org/jooq/DeleteQuery.java b/jOOQ/src/main/java/org/jooq/DeleteQuery.java index fb83f00a96..b4d51b3a57 100644 --- a/jOOQ/src/main/java/org/jooq/DeleteQuery.java +++ b/jOOQ/src/main/java/org/jooq/DeleteQuery.java @@ -38,9 +38,12 @@ package org.jooq; +// ... // ... // ... import static org.jooq.SQLDialect.FIREBIRD; +import static org.jooq.SQLDialect.MARIADB; +import static org.jooq.SQLDialect.MYSQL; // ... import static org.jooq.SQLDialect.POSTGRES; @@ -101,6 +104,38 @@ public interface DeleteQuery extends ConditionProvider, Delete @Support void addConditions(Operator operator, Collection conditions); + /** + * Adds ordering fields. + * + * @param fields The ordering fields + */ + @Support({ MARIADB, MYSQL }) + void addOrderBy(OrderField... fields); + + /** + * Adds ordering fields. + * + * @param fields The ordering fields + */ + @Support({ MARIADB, MYSQL }) + void addOrderBy(Collection> fields); + + /** + * Limit the results of this select. + * + * @param numberOfRows The number of rows to return + */ + @Support({ MARIADB, MYSQL }) + void addLimit(Number numberOfRows); + + /** + * Limit the results of this select using named parameters. + * + * @param numberOfRows The number of rows to return + */ + @Support({ MARIADB, MYSQL }) + void addLimit(Param numberOfRows); + // ------------------------------------------------------------------------ // XXX: Methods for the DELETE .. RETURNING syntax // ------------------------------------------------------------------------ diff --git a/jOOQ/src/main/java/org/jooq/DeleteWhereStep.java b/jOOQ/src/main/java/org/jooq/DeleteWhereStep.java index e5582c5729..7e9b1f3aa6 100644 --- a/jOOQ/src/main/java/org/jooq/DeleteWhereStep.java +++ b/jOOQ/src/main/java/org/jooq/DeleteWhereStep.java @@ -72,7 +72,7 @@ import org.jooq.impl.DSL; * * @author Lukas Eder */ -public interface DeleteWhereStep extends DeleteReturningStep { +public interface DeleteWhereStep extends DeleteOrderByStep { /** * Add conditions to the query, connecting them with each other with diff --git a/jOOQ/src/main/java/org/jooq/UpdateConditionStep.java b/jOOQ/src/main/java/org/jooq/UpdateConditionStep.java index 08ab3f817f..60aee1d185 100644 --- a/jOOQ/src/main/java/org/jooq/UpdateConditionStep.java +++ b/jOOQ/src/main/java/org/jooq/UpdateConditionStep.java @@ -73,7 +73,7 @@ import org.jooq.impl.DSL; * * @author Lukas Eder */ -public interface UpdateConditionStep extends UpdateReturningStep { +public interface UpdateConditionStep extends UpdateOrderByStep { /** * Combine the currently assembled conditions with another one using the diff --git a/jOOQ/src/main/java/org/jooq/UpdateLimitStep.java b/jOOQ/src/main/java/org/jooq/UpdateLimitStep.java new file mode 100644 index 0000000000..629e0a2f49 --- /dev/null +++ b/jOOQ/src/main/java/org/jooq/UpdateLimitStep.java @@ -0,0 +1,92 @@ +/* + * 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; + +// ... +import static org.jooq.SQLDialect.MARIADB; +import static org.jooq.SQLDialect.MYSQL; + +/** + * This type is used for the {@link Update}'s DSL API. + *

+ * Example:

+ * DSLContext create = DSL.using(configuration);
+ *
+ * create.update(table)
+ *       .set(field1, value1)
+ *       .set(field2, value2)
+ *       .where(field1.greaterThan(100))
+ *       .execute();
+ * 
+ *

+ *

Referencing XYZ*Step types directly from client code

+ *

+ * It is usually not recommended to reference any XYZ*Step types + * directly from client code, or assign them to local variables. When writing + * dynamic SQL, creating a statement's components dynamically, and passing them + * to the DSL API statically is usually a better choice. See the manual's + * section about dynamic SQL for details: https://www.jooq.org/doc/latest/manual/sql-building/dynamic-sql. + *

+ * Drawbacks of referencing the XYZ*Step types directly: + *

    + *
  • They're operating on mutable implementations (as of jOOQ 3.x)
  • + *
  • They're less composable and not easy to get right when dynamic SQL gets + * complex
  • + *
  • They're less readable
  • + *
  • They might have binary incompatible changes between minor releases
  • + *
+ * + * @author Lukas Eder + */ +public interface UpdateLimitStep extends UpdateReturningStep { + + /** + * Add a LIMIT clause to the query + */ + @Support({ MARIADB, MYSQL }) + UpdateReturningStep limit(Number numberOfRows); + + /** + * Add a LIMIT clause to the query using named parameters + */ + @Support({ MARIADB, MYSQL }) + UpdateReturningStep limit(Param numberOfRows); + + +} diff --git a/jOOQ/src/main/java/org/jooq/UpdateOrderByStep.java b/jOOQ/src/main/java/org/jooq/UpdateOrderByStep.java new file mode 100644 index 0000000000..5d80207df3 --- /dev/null +++ b/jOOQ/src/main/java/org/jooq/UpdateOrderByStep.java @@ -0,0 +1,105 @@ +/* + * 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; + +// ... +import static org.jooq.SQLDialect.MARIADB; +import static org.jooq.SQLDialect.MYSQL; + +import java.util.Collection; + +/** + * This type is used for the {@link Update}'s DSL API. + *

+ * Example:

+ * DSLContext create = DSL.using(configuration);
+ *
+ * create.update(table)
+ *       .set(field1, value1)
+ *       .set(field2, value2)
+ *       .where(field1.greaterThan(100))
+ *       .execute();
+ * 
+ *

+ *

Referencing XYZ*Step types directly from client code

+ *

+ * It is usually not recommended to reference any XYZ*Step types + * directly from client code, or assign them to local variables. When writing + * dynamic SQL, creating a statement's components dynamically, and passing them + * to the DSL API statically is usually a better choice. See the manual's + * section about dynamic SQL for details: https://www.jooq.org/doc/latest/manual/sql-building/dynamic-sql. + *

+ * Drawbacks of referencing the XYZ*Step types directly: + *

    + *
  • They're operating on mutable implementations (as of jOOQ 3.x)
  • + *
  • They're less composable and not easy to get right when dynamic SQL gets + * complex
  • + *
  • They're less readable
  • + *
  • They might have binary incompatible changes between minor releases
  • + *
+ * + * @author Lukas Eder + */ +public interface UpdateOrderByStep extends UpdateLimitStep { + + /** + * Add an ORDER BY clause to the query + */ + @Support({ MARIADB, MYSQL }) + UpdateLimitStep orderBy(OrderField... fields); + + /** + * Add an ORDER BY clause to the query + */ + @Support({ MARIADB, MYSQL }) + UpdateLimitStep orderBy(Collection> fields); + + /** + * Add an ORDER BY clause to the query + *

+ * Indexes start at 1 in SQL! + *

+ * Note, you can use orderBy(DSL.val(1).desc()) or + * orderBy(DSL.literal(1).desc()) to apply descending + * ordering + */ + @Support({ MARIADB, MYSQL }) + UpdateLimitStep orderBy(int... fieldIndexes); + +} diff --git a/jOOQ/src/main/java/org/jooq/UpdateQuery.java b/jOOQ/src/main/java/org/jooq/UpdateQuery.java index b179e3eb82..4be025942a 100644 --- a/jOOQ/src/main/java/org/jooq/UpdateQuery.java +++ b/jOOQ/src/main/java/org/jooq/UpdateQuery.java @@ -38,6 +38,7 @@ package org.jooq; +// ... // ... // ... import static org.jooq.SQLDialect.FIREBIRD; @@ -45,6 +46,8 @@ import static org.jooq.SQLDialect.H2; // ... import static org.jooq.SQLDialect.HSQLDB; // ... +import static org.jooq.SQLDialect.MARIADB; +import static org.jooq.SQLDialect.MYSQL; // ... import static org.jooq.SQLDialect.POSTGRES; // ... @@ -411,6 +414,38 @@ public interface UpdateQuery extends StoreQuery, ConditionP @Support void addConditions(Operator operator, Collection conditions); + /** + * Adds ordering fields. + * + * @param fields The ordering fields + */ + @Support({ MARIADB, MYSQL }) + void addOrderBy(OrderField... fields); + + /** + * Adds ordering fields. + * + * @param fields The ordering fields + */ + @Support({ MARIADB, MYSQL }) + void addOrderBy(Collection> fields); + + /** + * Limit the results of this select. + * + * @param numberOfRows The number of rows to return + */ + @Support({ MARIADB, MYSQL }) + void addLimit(Number numberOfRows); + + /** + * Limit the results of this select using named parameters. + * + * @param numberOfRows The number of rows to return + */ + @Support({ MARIADB, MYSQL }) + void addLimit(Param numberOfRows); + // ------------------------------------------------------------------------ // XXX: Methods for the UPDATE .. RETURNING syntax // ------------------------------------------------------------------------ diff --git a/jOOQ/src/main/java/org/jooq/UpdateWhereStep.java b/jOOQ/src/main/java/org/jooq/UpdateWhereStep.java index c24a525bec..e6b11be4a8 100644 --- a/jOOQ/src/main/java/org/jooq/UpdateWhereStep.java +++ b/jOOQ/src/main/java/org/jooq/UpdateWhereStep.java @@ -74,7 +74,7 @@ import org.jooq.impl.DSL; * * @author Lukas Eder */ -public interface UpdateWhereStep extends UpdateReturningStep { +public interface UpdateWhereStep extends UpdateOrderByStep { /** * Add conditions to the query, connecting them with each other with diff --git a/jOOQ/src/main/java/org/jooq/impl/DeleteImpl.java b/jOOQ/src/main/java/org/jooq/impl/DeleteImpl.java index 63dbb32c5d..9ace33d616 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DeleteImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/DeleteImpl.java @@ -52,6 +52,8 @@ import org.jooq.DeleteResultStep; import org.jooq.DeleteWhereStep; import org.jooq.Field; import org.jooq.Operator; +import org.jooq.OrderField; +import org.jooq.Param; import org.jooq.QueryPart; import org.jooq.Record; import org.jooq.Record1; @@ -291,6 +293,35 @@ final class DeleteImpl return or(notExists(select)); } + @Override + public final DeleteImpl orderBy(OrderField... fields) { + getDelegate().addOrderBy(fields); + return this; + } + + @Override + public final DeleteImpl orderBy(Collection> fields) { + getDelegate().addOrderBy(fields); + return this; + } + + @Override + public final DeleteImpl orderBy(int... fieldIndexes) { + return orderBy(Tools.inline(fieldIndexes)); + } + + @Override + public final DeleteImpl limit(Number numberOfRows) { + getDelegate().addLimit(numberOfRows); + return this; + } + + @Override + public final DeleteImpl limit(Param numberOfRows) { + getDelegate().addLimit(numberOfRows); + return this; + } + @Override public final DeleteImpl returning() { getDelegate().setReturning(); diff --git a/jOOQ/src/main/java/org/jooq/impl/DeleteQueryImpl.java b/jOOQ/src/main/java/org/jooq/impl/DeleteQueryImpl.java index 9c57279b4a..10d73e961e 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DeleteQueryImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/DeleteQueryImpl.java @@ -48,8 +48,11 @@ import static org.jooq.SQLDialect.MYSQL; import static org.jooq.conf.SettingsTools.getExecuteDeleteWithoutWhere; import static org.jooq.impl.Keywords.K_DELETE; import static org.jooq.impl.Keywords.K_FROM; +import static org.jooq.impl.Keywords.K_LIMIT; +import static org.jooq.impl.Keywords.K_ORDER_BY; import static org.jooq.impl.Keywords.K_WHERE; +import java.util.Arrays; import java.util.Collection; import java.util.EnumSet; @@ -59,6 +62,8 @@ import org.jooq.Configuration; import org.jooq.Context; import org.jooq.DeleteQuery; import org.jooq.Operator; +import org.jooq.OrderField; +import org.jooq.Param; import org.jooq.Record; import org.jooq.SQLDialect; import org.jooq.Table; @@ -72,12 +77,15 @@ final class DeleteQueryImpl extends AbstractDMLQuery implem private static final Clause[] CLAUSES = { DELETE }; private static final EnumSet SPECIAL_DELETE_AS_SYNTAX = EnumSet.of(MARIADB, MYSQL); - private final ConditionProviderImpl condition; + private final ConditionProviderImpl condition; + private final SortFieldList orderBy; + private Param limit; DeleteQueryImpl(Configuration configuration, WithImpl with, Table table) { super(configuration, with, table); this.condition = new ConditionProviderImpl(); + this.orderBy = new SortFieldList(); } final Condition getWhere() { @@ -118,6 +126,26 @@ final class DeleteQueryImpl extends AbstractDMLQuery implem condition.addConditions(operator, conditions); } + @Override + public final void addOrderBy(OrderField... fields) { + addOrderBy(Arrays.asList(fields)); + } + + @Override + public final void addOrderBy(Collection> fields) { + orderBy.addAll(Tools.sortFields(fields)); + } + + @Override + public final void addLimit(Number numberOfRows) { + addLimit(DSL.val(numberOfRows)); + } + + @Override + public final void addLimit(Param numberOfRows) { + limit = numberOfRows; + } + @Override final void accept0(Context ctx) { boolean declare = ctx.declareTables(); @@ -147,11 +175,20 @@ final class DeleteQueryImpl extends AbstractDMLQuery implem .visit(K_WHERE).sql(' ') .visit(getWhere()); - ctx.end(DELETE_WHERE) - .start(DELETE_RETURNING); + ctx.end(DELETE_WHERE); + if (!orderBy.isEmpty()) + ctx.formatSeparator() + .visit(K_ORDER_BY).sql(' ') + .visit(orderBy); + + if (limit != null) + ctx.formatSeparator() + .visit(K_LIMIT).sql(' ') + .visit(limit); + + ctx.start(DELETE_RETURNING); toSQLReturning(ctx); - ctx.end(DELETE_RETURNING); } diff --git a/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java b/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java index 45142e6fa3..7e8afe52aa 100644 --- a/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java @@ -2174,13 +2174,7 @@ final class SelectQueryImpl extends AbstractResultQuery imp @Override public final void addOrderBy(int... fieldIndexes) { - Field[] fields = new Field[fieldIndexes.length]; - - for (int i = 0; i < fieldIndexes.length; i++) { - fields[i] = inline(fieldIndexes[i]); - } - - addOrderBy(fields); + addOrderBy(Tools.inline(fieldIndexes)); } @Override diff --git a/jOOQ/src/main/java/org/jooq/impl/Tools.java b/jOOQ/src/main/java/org/jooq/impl/Tools.java index 614cf72a61..f064ada05b 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Tools.java +++ b/jOOQ/src/main/java/org/jooq/impl/Tools.java @@ -1601,6 +1601,19 @@ final class Tools { return result; } + @SuppressWarnings("unchecked") + static final Field[] inline(int[] fieldIndexes) { + if (fieldIndexes == null) + return (Field[]) EMPTY_FIELD; + + Field[] result = new Field[fieldIndexes.length]; + + for (int i = 0; i < fieldIndexes.length; i++) + result[i] = DSL.inline(fieldIndexes[i]); + + return result; + } + /** * A utility method that fails with an exception if * {@link Row#indexOf(Field)} doesn't return any index. diff --git a/jOOQ/src/main/java/org/jooq/impl/UpdateImpl.java b/jOOQ/src/main/java/org/jooq/impl/UpdateImpl.java index cf939e96c1..d0451574da 100644 --- a/jOOQ/src/main/java/org/jooq/impl/UpdateImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/UpdateImpl.java @@ -52,6 +52,8 @@ import org.jooq.Configuration; import org.jooq.Field; import org.jooq.Name; import org.jooq.Operator; +import org.jooq.OrderField; +import org.jooq.Param; import org.jooq.QueryPart; import org.jooq.Record; import org.jooq.Record1; @@ -679,6 +681,35 @@ final class UpdateImpl return or(notExists(select)); } + @Override + public final UpdateImpl orderBy(OrderField... fields) { + getDelegate().addOrderBy(fields); + return this; + } + + @Override + public final UpdateImpl orderBy(Collection> fields) { + getDelegate().addOrderBy(fields); + return this; + } + + @Override + public final UpdateImpl orderBy(int... fieldIndexes) { + return orderBy(Tools.inline(fieldIndexes)); + } + + @Override + public final UpdateImpl limit(Number numberOfRows) { + getDelegate().addLimit(numberOfRows); + return this; + } + + @Override + public final UpdateImpl limit(Param numberOfRows) { + getDelegate().addLimit(numberOfRows); + return this; + } + @Override public final UpdateImpl returning() { getDelegate().setReturning(); diff --git a/jOOQ/src/main/java/org/jooq/impl/UpdateQueryImpl.java b/jOOQ/src/main/java/org/jooq/impl/UpdateQueryImpl.java index 1df207eada..7831099176 100644 --- a/jOOQ/src/main/java/org/jooq/impl/UpdateQueryImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/UpdateQueryImpl.java @@ -60,6 +60,8 @@ import static org.jooq.SQLDialect.POSTGRES_10; import static org.jooq.conf.SettingsTools.getExecuteUpdateWithoutWhere; import static org.jooq.impl.DSL.select; import static org.jooq.impl.Keywords.K_FROM; +import static org.jooq.impl.Keywords.K_LIMIT; +import static org.jooq.impl.Keywords.K_ORDER_BY; import static org.jooq.impl.Keywords.K_ROW; import static org.jooq.impl.Keywords.K_SET; import static org.jooq.impl.Keywords.K_UPDATE; @@ -76,6 +78,8 @@ import org.jooq.Configuration; import org.jooq.Context; import org.jooq.Field; import org.jooq.Operator; +import org.jooq.OrderField; +import org.jooq.Param; import org.jooq.Record; import org.jooq.Record1; import org.jooq.Record10; @@ -147,6 +151,8 @@ final class UpdateQueryImpl extends AbstractStoreQuery impl private Row multiRow; private Row multiValue; private Select multiSelect; + private final SortFieldList orderBy; + private Param limit; UpdateQueryImpl(Configuration configuration, WithImpl with, Table table) { super(configuration, with, table); @@ -154,6 +160,7 @@ final class UpdateQueryImpl extends AbstractStoreQuery impl this.updateMap = new FieldMapForUpdate(table, UPDATE_SET_ASSIGNMENT); this.from = new TableList(); this.condition = new ConditionProviderImpl(); + this.orderBy = new SortFieldList(); } @Override @@ -456,6 +463,26 @@ final class UpdateQueryImpl extends AbstractStoreQuery impl condition.addConditions(operator, conditions); } + @Override + public final void addOrderBy(OrderField... fields) { + addOrderBy(Arrays.asList(fields)); + } + + @Override + public final void addOrderBy(Collection> fields) { + orderBy.addAll(Tools.sortFields(fields)); + } + + @Override + public final void addLimit(Number numberOfRows) { + addLimit(DSL.val(numberOfRows)); + } + + @Override + public final void addLimit(Param numberOfRows) { + limit = numberOfRows; + } + final Condition getWhere() { return condition.getWhere(); } @@ -609,11 +636,20 @@ final class UpdateQueryImpl extends AbstractStoreQuery impl .visit(K_WHERE).sql(' ') .visit(getWhere()); - ctx.end(UPDATE_WHERE) - .start(UPDATE_RETURNING); + ctx.end(UPDATE_WHERE); + if (!orderBy.isEmpty()) + ctx.formatSeparator() + .visit(K_ORDER_BY).sql(' ') + .visit(orderBy); + + if (limit != null) + ctx.formatSeparator() + .visit(K_LIMIT).sql(' ') + .visit(limit); + + ctx.start(UPDATE_RETURNING); toSQLReturning(ctx); - ctx.end(UPDATE_RETURNING); }