Skip to content

Commit 9ac3446

Browse files
authored
Merge pull request #220 from jeffgbutler/gh_213
Add Ability to Easily Use Non-Standard Database Operators
2 parents 8ad566f + 13e5bb6 commit 9ac3446

23 files changed

+573
-93
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,18 @@ This log will detail notable changes to MyBatis Dynamic SQL. Full details are av
66

77
GitHub milestone: [https://github.com/mybatis/mybatis-dynamic-sql/issues?q=milestone%3A1.1.5+](https://github.com/mybatis/mybatis-dynamic-sql/issues?q=milestone%3A1.1.5+)
88

9+
### General Announcements
10+
11+
This release includes a significant refactoring of the classes in the "org.mybatis.dynamic.sql.select.function" package. The new classes are more consistent and flexible and should be compatible with existing code at the source level (meaning that code should be recompiled for the new version of the library).
12+
13+
If you have written your own set of functions to extend the library, you will notice that the base classes 'AbstractFunction" and "AbstractMultipleColumnArithmeticFunction" are now deprecated. Their replacement classes are "AbstractUniTypeFunction" and "OperatorFunction" respectively.
14+
915
### Added
1016

1117
- Added a general insert statement that does not require a separate record class to hold values for the insert. ([#201](https://github.com/mybatis/mybatis-dynamic-sql/issues/201))
1218
- Added the capability to specify a rendering strategy on a column to override the defaut rendering strategy for a statement. This will allow certain edge cases where a parameter marker needs to be formatted in a unique way (for example, "::jsonb" needs to be added to parameter markers for JSON fields in PostgreSQL) ([#200](https://github.com/mybatis/mybatis-dynamic-sql/issues/200))
1319
- Added the ability to write a function that will change the column data type ([#197](https://github.com/mybatis/mybatis-dynamic-sql/issues/197))
20+
- Added the `applyOperator` function to make it easy to use non-standard database operators in expressions ([#220](https://github.com/mybatis/mybatis-dynamic-sql/issues/220))
1421

1522
## Release 1.1.4 - November 23, 2019
1623

src/main/java/org/mybatis/dynamic/sql/BindableColumn.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,13 @@ public interface BindableColumn<T> extends BasicColumn {
3838
@Override
3939
BindableColumn<T> as(String alias);
4040

41-
Optional<JDBCType> jdbcType();
41+
default Optional<JDBCType> jdbcType() {
42+
return Optional.empty();
43+
}
4244

43-
Optional<String> typeHandler();
45+
default Optional<String> typeHandler() {
46+
return Optional.empty();
47+
}
4448

4549
default Optional<RenderingStrategy> renderingStrategy() {
4650
return Optional.empty();

src/main/java/org/mybatis/dynamic/sql/Constant.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2016-2018 the original author or authors.
2+
* Copyright 2016-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -20,7 +20,7 @@
2020

2121
import org.mybatis.dynamic.sql.render.TableAliasCalculator;
2222

23-
public class Constant implements BasicColumn {
23+
public class Constant<T> implements BindableColumn<T> {
2424

2525
private String alias;
2626
private String value;
@@ -40,13 +40,13 @@ public String renderWithTableAlias(TableAliasCalculator tableAliasCalculator) {
4040
}
4141

4242
@Override
43-
public Constant as(String alias) {
44-
Constant copy = new Constant(value);
43+
public Constant<T> as(String alias) {
44+
Constant<T> copy = new Constant<>(value);
4545
copy.alias = alias;
4646
return copy;
4747
}
4848

49-
public static Constant of(String value) {
50-
return new Constant(value);
49+
public static <T> Constant<T> of(String value) {
50+
return new Constant<>(value);
5151
}
5252
}

src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,11 @@
4040
import org.mybatis.dynamic.sql.select.aggregate.Min;
4141
import org.mybatis.dynamic.sql.select.aggregate.Sum;
4242
import org.mybatis.dynamic.sql.select.function.Add;
43+
import org.mybatis.dynamic.sql.select.function.Concatenate;
4344
import org.mybatis.dynamic.sql.select.function.Divide;
4445
import org.mybatis.dynamic.sql.select.function.Lower;
4546
import org.mybatis.dynamic.sql.select.function.Multiply;
47+
import org.mybatis.dynamic.sql.select.function.OperatorFunction;
4648
import org.mybatis.dynamic.sql.select.function.Substring;
4749
import org.mybatis.dynamic.sql.select.function.Subtract;
4850
import org.mybatis.dynamic.sql.select.function.Upper;
@@ -256,7 +258,7 @@ static Sum sum(BasicColumn column) {
256258
}
257259

258260
// constants
259-
static Constant constant(String constant) {
261+
static <T> Constant<T> constant(String constant) {
260262
return Constant.of(constant);
261263
}
262264

@@ -285,6 +287,16 @@ static <T extends Number> Subtract<T> subtract(BindableColumn<T> firstColumn, Ba
285287
return Subtract.of(firstColumn, secondColumn, Arrays.asList(subsequentColumns));
286288
}
287289

290+
static <T> Concatenate<T> concatenate(BindableColumn<T> firstColumn, BasicColumn secondColumn,
291+
BasicColumn... subsequentColumns) {
292+
return Concatenate.concatenate(firstColumn, secondColumn, subsequentColumns);
293+
}
294+
295+
static <T> OperatorFunction<T> applyOperator(String operator, BindableColumn<T> firstColumn, BasicColumn secondColumn,
296+
BasicColumn... subsequentColumns) {
297+
return OperatorFunction.of(operator, firstColumn, secondColumn, subsequentColumns);
298+
}
299+
288300
static Lower lower(BindableColumn<String> column) {
289301
return Lower.of(column);
290302
}

src/main/java/org/mybatis/dynamic/sql/StringConstant.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2016-2018 the original author or authors.
2+
* Copyright 2016-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -20,7 +20,7 @@
2020

2121
import org.mybatis.dynamic.sql.render.TableAliasCalculator;
2222

23-
public class StringConstant implements BasicColumn {
23+
public class StringConstant implements BindableColumn<String> {
2424

2525
private String alias;
2626
private String value;

src/main/java/org/mybatis/dynamic/sql/select/function/AbstractFunction.java

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,38 @@
1616
package org.mybatis.dynamic.sql.select.function;
1717

1818
import java.sql.JDBCType;
19+
import java.util.Objects;
1920
import java.util.Optional;
2021

2122
import org.mybatis.dynamic.sql.BindableColumn;
2223

23-
public abstract class AbstractFunction<T, U extends AbstractFunction<T, U>>
24-
extends AbstractTypeConvertingFunction<T, T, U> {
24+
/**
25+
* @deprecated in favor of {@link AbstractUniTypeFunction}
26+
*
27+
* @author Jeff Butler
28+
*/
29+
@Deprecated
30+
public abstract class AbstractFunction<T, U extends AbstractFunction<T, U>> implements BindableColumn<T> {
31+
32+
protected BindableColumn<T> column;
33+
protected String alias;
2534

2635
protected AbstractFunction(BindableColumn<T> column) {
27-
super(column);
36+
this.column = Objects.requireNonNull(column);
2837
}
2938

39+
@Override
40+
public Optional<String> alias() {
41+
return Optional.ofNullable(alias);
42+
}
43+
44+
@Override
45+
public U as(String alias) {
46+
U newThing = copy();
47+
newThing.alias = alias;
48+
return newThing;
49+
}
50+
3051
@Override
3152
public Optional<JDBCType> jdbcType() {
3253
return column.jdbcType();
@@ -36,4 +57,6 @@ public Optional<JDBCType> jdbcType() {
3657
public Optional<String> typeHandler() {
3758
return column.typeHandler();
3859
}
60+
61+
protected abstract U copy();
3962
}

src/main/java/org/mybatis/dynamic/sql/select/function/AbstractMultipleColumnArithmeticFunction.java

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2016-2018 the original author or authors.
2+
* Copyright 2016-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -26,13 +26,19 @@
2626
import org.mybatis.dynamic.sql.BindableColumn;
2727
import org.mybatis.dynamic.sql.render.TableAliasCalculator;
2828

29+
/**
30+
* @deprecated in favor of {@link OperatorFunction}.
31+
*
32+
* @author Jeff Butler
33+
*/
34+
@Deprecated
2935
public abstract class AbstractMultipleColumnArithmeticFunction<T extends Number,
3036
U extends AbstractMultipleColumnArithmeticFunction<T, U>>
31-
extends AbstractFunction<T, AbstractMultipleColumnArithmeticFunction<T,U>> {
32-
37+
extends AbstractFunction<T, AbstractMultipleColumnArithmeticFunction<T, U>> {
38+
3339
protected BasicColumn secondColumn;
3440
protected List<BasicColumn> subsequentColumns = new ArrayList<>();
35-
41+
3642
protected AbstractMultipleColumnArithmeticFunction(BindableColumn<T> firstColumn, BasicColumn secondColumn,
3743
List<BasicColumn> subsequentColumns) {
3844
super(firstColumn);
@@ -42,13 +48,13 @@ protected AbstractMultipleColumnArithmeticFunction(BindableColumn<T> firstColumn
4248

4349
@Override
4450
public String renderWithTableAlias(TableAliasCalculator tableAliasCalculator) {
45-
// note - the cast below is added for a type inference bug in the Java9 compiler.
51+
// note - the cast below is added for a type inference bug in the Java9
52+
// compiler.
4653
return Stream.of(Stream.of((BasicColumn) column), Stream.of(secondColumn), subsequentColumns.stream())
47-
.flatMap(Function.identity())
48-
.map(column -> column.renderWithTableAlias(tableAliasCalculator))
54+
.flatMap(Function.identity()).map(column -> column.renderWithTableAlias(tableAliasCalculator))
4955
.collect(Collectors.joining(padOperator(), "(", ")")); //$NON-NLS-1$ //$NON-NLS-2$
5056
}
51-
57+
5258
private String padOperator() {
5359
return " " + operator() + " "; //$NON-NLS-1$ //$NON-NLS-2$
5460
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/**
2+
* Copyright 2016-2020 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.mybatis.dynamic.sql.select.function;
17+
18+
import java.sql.JDBCType;
19+
import java.util.Optional;
20+
21+
import org.mybatis.dynamic.sql.BindableColumn;
22+
23+
/**
24+
* Represents a function that does not change the underlying data type.
25+
*
26+
* @author Jeff Butler
27+
*
28+
* @param <T> The type of the underlying column
29+
* @param <U> the specific subtype that implements the function
30+
*/
31+
public abstract class AbstractUniTypeFunction<T, U extends AbstractUniTypeFunction<T, U>>
32+
extends AbstractTypeConvertingFunction<T, T, U> {
33+
34+
protected AbstractUniTypeFunction(BindableColumn<T> column) {
35+
super(column);
36+
}
37+
38+
@Override
39+
public Optional<JDBCType> jdbcType() {
40+
return column.jdbcType();
41+
}
42+
43+
@Override
44+
public Optional<String> typeHandler() {
45+
return column.typeHandler();
46+
}
47+
}

src/main/java/org/mybatis/dynamic/sql/select/function/Add.java

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2016-2018 the original author or authors.
2+
* Copyright 2016-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -20,23 +20,18 @@
2020
import org.mybatis.dynamic.sql.BasicColumn;
2121
import org.mybatis.dynamic.sql.BindableColumn;
2222

23-
public class Add<T extends Number> extends AbstractMultipleColumnArithmeticFunction<T, Add<T>> {
23+
public class Add<T extends Number> extends OperatorFunction<T> {
2424

2525
private Add(BindableColumn<T> firstColumn, BasicColumn secondColumn,
2626
List<BasicColumn> subsequentColumns) {
27-
super(firstColumn, secondColumn, subsequentColumns);
27+
super("+", firstColumn, secondColumn, subsequentColumns); //$NON-NLS-1$
2828
}
2929

3030
@Override
3131
protected Add<T> copy() {
3232
return new Add<>(column, secondColumn, subsequentColumns);
3333
}
3434

35-
@Override
36-
protected String operator() {
37-
return "+"; //$NON-NLS-1$
38-
}
39-
4035
public static <T extends Number> Add<T> of(BindableColumn<T> firstColumn, BasicColumn secondColumn,
4136
List<BasicColumn> subsequentColumns) {
4237
return new Add<>(firstColumn, secondColumn, subsequentColumns);
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/**
2+
* Copyright 2016-2020 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.mybatis.dynamic.sql.select.function;
17+
18+
import java.util.Arrays;
19+
import java.util.List;
20+
21+
import org.mybatis.dynamic.sql.BasicColumn;
22+
import org.mybatis.dynamic.sql.BindableColumn;
23+
24+
public class Concatenate<T> extends OperatorFunction<T> {
25+
26+
protected Concatenate(BindableColumn<T> firstColumn, BasicColumn secondColumn,
27+
List<BasicColumn> subsequentColumns) {
28+
super("||", firstColumn, secondColumn, subsequentColumns); //$NON-NLS-1$
29+
}
30+
31+
@Override
32+
protected Concatenate<T> copy() {
33+
return new Concatenate<>(column, secondColumn, subsequentColumns);
34+
}
35+
36+
public static <T> Concatenate<T> concatenate(BindableColumn<T> firstColumn, BasicColumn secondColumn,
37+
BasicColumn... subsequentColumns) {
38+
return new Concatenate<>(firstColumn, secondColumn, Arrays.asList(subsequentColumns));
39+
}
40+
}

0 commit comments

Comments
 (0)