[jOOQ/jOOQ#12425] Move MODULO to API generator

This includes:
- [jOOQ/jOOQ#12431] Extract arithmetic operations into their own classes
This commit is contained in:
Lukas Eder 2021-09-15 11:57:54 +02:00
parent aac4c38090
commit 6fbbd2e3e0
5 changed files with 157 additions and 109 deletions

View File

@ -778,6 +778,54 @@ extends
@Support({ CUBRID, FIREBIRD, H2, HSQLDB, MARIADB, MYSQL, POSTGRES, SQLITE, YUGABYTE })
Field<T> bitXor(Field<T> arg2);
/**
* The <code>MOD</code> operator.
*
* @param arg2 is wrapped as {@link #val(Object)}.
*/
@NotNull
@Support
Field<T> mod(Number arg2);
/**
* The <code>MOD</code> operator.
*/
@NotNull
@Support
Field<T> mod(Field<? extends Number> arg2);
/**
* The <code>MODULO</code> operator, an alias for the <code>MOD</code> operator.
*
* @param arg2 is wrapped as {@link #val(Object)}.
*/
@NotNull
@Support
Field<T> modulo(Number arg2);
/**
* The <code>MODULO</code> operator, an alias for the <code>MOD</code> operator.
*/
@NotNull
@Support
Field<T> modulo(Field<? extends Number> arg2);
/**
* The <code>REM</code> operator, an alias for the <code>MOD</code> operator.
*
* @param arg2 is wrapped as {@link #val(Object)}.
*/
@NotNull
@Support
Field<T> rem(Number arg2);
/**
* The <code>REM</code> operator, an alias for the <code>MOD</code> operator.
*/
@NotNull
@Support
Field<T> rem(Field<? extends Number> arg2);
/**
* The <code>SHL</code> operator.
* <p>
@ -1120,64 +1168,6 @@ extends
@Support
Field<T> divide(Field<? extends Number> value);
/**
* An arithmetic expression getting the modulo of this divided by value.
* <p>
* This renders the modulo operation where available:
* <code><pre>[this] % [value]</pre></code> ... or the modulo function
* elsewhere: <code><pre>mod([this], [value])</pre></code>
*/
@NotNull
@Support
Field<T> mod(Number value);
/**
* An arithmetic expression getting the modulo of this divided by value.
* <p>
* This renders the modulo operation where available:
* <code><pre>[this] % [value]</pre></code> ... or the modulo function
* elsewhere: <code><pre>mod([this], [value])</pre></code>
*/
@NotNull
@Support
Field<T> mod(Field<? extends Number> value);
/**
* An alias for {@link #mod(Number)}.
*
* @see #mod(Number)
*/
@NotNull
@Support
Field<T> modulo(Number value);
/**
* An alias for {@link #mod(Field)}.
*
* @see #mod(Field)
*/
@NotNull
@Support
Field<T> modulo(Field<? extends Number> value);
/**
* An alias for {@link #mod(Number)}.
*
* @see #mod(Number)
*/
@NotNull
@Support
Field<T> rem(Number value);
/**
* An alias for {@link #mod(Field)}.
*
* @see #mod(Field)
*/
@NotNull
@Support
Field<T> rem(Field<? extends Number> value);
/**
* An arithmetic expression getting this value raised to the power of <code>exponent</code>.
* <p>

View File

@ -103,7 +103,8 @@ import org.jooq.WindowPartitionByStep;
* @author Lukas Eder
*/
abstract class AbstractField<T> extends AbstractTypedNamed<T> implements Field<T>, ScopeMappable {
private static final Clause[] CLAUSES = { FIELD };
private static final Clause[] CLAUSES = { FIELD };
AbstractField(Name name, DataType<T> type) {
this(name, type, null);
@ -414,6 +415,38 @@ abstract class AbstractField<T> extends AbstractTypedNamed<T> implements Field<T
return DSL.bitXor((Field) this, (Field<Number>) arg2);
}
@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
public final Field<T> mod(Number arg2) {
return new Mod(this, Tools.field(arg2));
}
@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
public final Field<T> mod(Field<? extends Number> arg2) {
return new Mod(this, arg2);
}
@Override
public final Field<T> modulo(Number arg2) {
return mod(arg2);
}
@Override
public final Field<T> modulo(Field<? extends Number> arg2) {
return mod(arg2);
}
@Override
public final Field<T> rem(Number arg2) {
return mod(arg2);
}
@Override
public final Field<T> rem(Field<? extends Number> arg2) {
return mod(arg2);
}
@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
public final Field<T> shl(Number count) {
@ -499,16 +532,6 @@ abstract class AbstractField<T> extends AbstractTypedNamed<T> implements Field<T
return new Expression<>(DIVIDE, false, this, nullSafe(value, getDataType()));
}
@Override
public final Field<T> mod(Number value) {
return mod(Tools.field(value));
}
@Override
public final Field<T> mod(Field<? extends Number> value) {
return new Mod<>(this, nullSafe(value, getDataType()));
}
// ------------------------------------------------------------------------
// XXX: Arithmetic operation aliases
// ------------------------------------------------------------------------
@ -573,26 +596,6 @@ abstract class AbstractField<T> extends AbstractTypedNamed<T> implements Field<T
return div(value);
}
@Override
public final Field<T> modulo(Number value) {
return mod(value);
}
@Override
public final Field<T> modulo(Field<? extends Number> value) {
return mod(value);
}
@Override
public final Field<T> rem(Number value) {
return mod(value);
}
@Override
public final Field<T> rem(Field<? extends Number> value) {
return mod(value);
}
// ------------------------------------------------------------------------
// XXX: Conditions created from this field
// ------------------------------------------------------------------------

View File

@ -198,7 +198,6 @@ final class Expression<T> extends AbstractTransformable<T> {
@Override
@SuppressWarnings("null")

View File

@ -71,11 +71,6 @@ enum ExpressionOperator {
*/
DIVIDE("/"),
/**
* Modulo
*/
MODULO("%"),
;
private final String sql;

View File

@ -37,28 +37,55 @@
*/
package org.jooq.impl;
import static org.jooq.impl.ExpressionOperator.MODULO;
import static org.jooq.impl.Keywords.K_MOD;
import static org.jooq.impl.Names.N_MOD;
import static org.jooq.impl.DSL.*;
import static org.jooq.impl.Internal.*;
import static org.jooq.impl.Keywords.*;
import static org.jooq.impl.Names.*;
import static org.jooq.impl.SQLDataType.*;
import static org.jooq.impl.Tools.*;
import static org.jooq.impl.Tools.BooleanDataKey.*;
import static org.jooq.impl.Tools.DataExtendedKey.*;
import static org.jooq.impl.Tools.DataKey.*;
import static org.jooq.SQLDialect.*;
import org.jooq.*;
import org.jooq.Record;
import org.jooq.conf.*;
import org.jooq.impl.*;
import org.jooq.tools.*;
import java.util.*;
import org.jooq.Context;
import org.jooq.Field;
/**
* @author Lukas Eder
* The <code>MOD</code> statement.
*/
final class Mod<T> extends AbstractField<T> {
@SuppressWarnings({ "rawtypes", "unchecked", "unused" })
final class Mod<T extends Number>
extends
AbstractField<T>
{
private final Field<T> arg1;
private final Field<? extends Number> arg2;
Mod(Field<T> arg1, Field<? extends Number> arg2) {
super(N_MOD, arg1.getDataType());
Mod(
Field<T> arg1,
Field<? extends Number> arg2
) {
super(
N_MOD,
allNotNull((DataType) dataType(INTEGER, arg1, false), arg1, arg2)
);
this.arg1 = arg1;
this.arg2 = arg2;
this.arg1 = nullSafeNotNull(arg1, INTEGER);
this.arg2 = nullSafeNotNull(arg2, INTEGER);
}
// -------------------------------------------------------------------------
// XXX: QueryPart API
// -------------------------------------------------------------------------
@Override
public final void accept(Context<?> ctx) {
switch (ctx.family()) {
@ -77,12 +104,46 @@ final class Mod<T> extends AbstractField<T> {
case SQLITE:
ctx.visit(new Expression<>(MODULO, false, arg1, arg2));
case SQLITE: {
ctx.sql('(').visit(arg1).sql(" % ").visit(arg2).sql(')');
break;
}
default:
ctx.visit(K_MOD).sql('(').visit(arg1).sql(", ").visit(arg2).sql(')');
ctx.visit(function(N_MOD, getDataType(), arg1, arg2));
break;
}
}
// -------------------------------------------------------------------------
// The Object API
// -------------------------------------------------------------------------
@Override
public boolean equals(Object that) {
if (that instanceof Mod) {
return
StringUtils.equals(arg1, ((Mod) that).arg1) &&
StringUtils.equals(arg2, ((Mod) that).arg2)
;
}
else
return super.equals(that);
}
}