Skip to content

Commit f07b8a1

Browse files
authored
Merge pull request #259 from jeffgbutler/aggregates-are-functions
Refactor Aggregates to Behave Like Functions
2 parents e7721be + 2a681dc commit f07b8a1

File tree

14 files changed

+206
-92
lines changed

14 files changed

+206
-92
lines changed

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -331,19 +331,19 @@ static CountDistinct countDistinct(BasicColumn column) {
331331
return CountDistinct.of(column);
332332
}
333333

334-
static Max max(BasicColumn column) {
334+
static <T> Max<T> max(BindableColumn<T> column) {
335335
return Max.of(column);
336336
}
337337

338-
static Min min(BasicColumn column) {
338+
static <T> Min<T> min(BindableColumn<T> column) {
339339
return Min.of(column);
340340
}
341341

342-
static Avg avg(BasicColumn column) {
342+
static <T> Avg<T> avg(BindableColumn<T> column) {
343343
return Avg.of(column);
344344
}
345345

346-
static Sum sum(BasicColumn column) {
346+
static <T> Sum<T> sum(BindableColumn<T> column) {
347347
return Sum.of(column);
348348
}
349349

src/main/java/org/mybatis/dynamic/sql/select/aggregate/AbstractAggregate.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,15 @@
2323

2424
/**
2525
* This class is the base class for aggregate functions.
26-
*
26+
*
27+
* @deprecated in favor of {@link org.mybatis.dynamic.sql.select.function.AbstractUniTypeFunction} as there is
28+
* virtually no difference between an aggregate and a function
29+
*
2730
* @author Jeff Butler
2831
*
2932
* @param <T> the subclass type
3033
*/
34+
@Deprecated
3135
public abstract class AbstractAggregate<T extends AbstractAggregate<T>> implements BasicColumn {
3236
protected final BasicColumn column;
3337
protected String alias;
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
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.aggregate;
17+
18+
import java.util.Optional;
19+
import org.mybatis.dynamic.sql.BindableColumn;
20+
21+
/**
22+
* Count functions are implemented differently than the other aggregates. This is primarily to preserve
23+
* backwards compatibility. Count functions are configured as BindableColumns of type Long
24+
* as it is assumed that the count functions always return a number.
25+
*
26+
* @param <T> the subtype of this class
27+
*/
28+
public abstract class AbstractCount<T extends AbstractCount<T>> implements BindableColumn<Long> {
29+
private final String alias;
30+
31+
protected AbstractCount(String alias) {
32+
this.alias = alias;
33+
}
34+
35+
@Override
36+
public Optional<String> alias() {
37+
return Optional.ofNullable(alias);
38+
}
39+
40+
@Override
41+
public T as(String alias) {
42+
return copyWithAlias(alias);
43+
}
44+
45+
protected abstract T copyWithAlias(String alias);
46+
}

src/main/java/org/mybatis/dynamic/sql/select/aggregate/Avg.java

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,25 +15,27 @@
1515
*/
1616
package org.mybatis.dynamic.sql.select.aggregate;
1717

18-
import org.mybatis.dynamic.sql.BasicColumn;
18+
import org.mybatis.dynamic.sql.BindableColumn;
19+
import org.mybatis.dynamic.sql.render.TableAliasCalculator;
20+
import org.mybatis.dynamic.sql.select.function.AbstractUniTypeFunction;
1921

20-
public class Avg extends AbstractAggregate<Avg> {
22+
public class Avg<T> extends AbstractUniTypeFunction<T, Avg<T>> {
2123

22-
private Avg(BasicColumn column) {
24+
private Avg(BindableColumn<T> column) {
2325
super(column);
2426
}
25-
27+
2628
@Override
27-
protected String render(String columnName) {
28-
return "avg(" + columnName + ")"; //$NON-NLS-1$ //$NON-NLS-2$
29+
public String renderWithTableAlias(TableAliasCalculator tableAliasCalculator) {
30+
return "avg(" + column.renderWithTableAlias(tableAliasCalculator) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
2931
}
3032

3133
@Override
32-
protected Avg copy() {
33-
return new Avg(column);
34+
protected Avg<T> copy() {
35+
return new Avg<>(column);
3436
}
3537

36-
public static Avg of(BasicColumn column) {
37-
return new Avg(column);
38+
public static <T> Avg<T> of(BindableColumn<T> column) {
39+
return new Avg<>(column);
3840
}
3941
}

src/main/java/org/mybatis/dynamic/sql/select/aggregate/Count.java

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,25 +15,31 @@
1515
*/
1616
package org.mybatis.dynamic.sql.select.aggregate;
1717

18+
import java.util.Objects;
19+
1820
import org.mybatis.dynamic.sql.BasicColumn;
21+
import org.mybatis.dynamic.sql.render.TableAliasCalculator;
22+
23+
public class Count extends AbstractCount<Count> {
24+
25+
private final BasicColumn column;
1926

20-
public class Count extends AbstractAggregate<Count> {
21-
22-
private Count(BasicColumn column) {
23-
super(column);
27+
private Count(BasicColumn column, String alias) {
28+
super(alias);
29+
this.column = Objects.requireNonNull(column);
2430
}
25-
31+
2632
@Override
27-
protected String render(String columnName) {
28-
return "count(" + columnName + ")"; //$NON-NLS-1$ //$NON-NLS-2$
33+
public String renderWithTableAlias(TableAliasCalculator tableAliasCalculator) {
34+
return "count(" + column.renderWithTableAlias(tableAliasCalculator) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
2935
}
3036

3137
@Override
32-
protected Count copy() {
33-
return new Count(column);
38+
protected Count copyWithAlias(String alias) {
39+
return new Count(column, alias);
3440
}
35-
41+
3642
public static Count of(BasicColumn column) {
37-
return new Count(column);
43+
return new Count(column, null);
3844
}
3945
}

src/main/java/org/mybatis/dynamic/sql/select/aggregate/CountAll.java

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -15,40 +15,25 @@
1515
*/
1616
package org.mybatis.dynamic.sql.select.aggregate;
1717

18-
import java.util.Optional;
19-
20-
import org.mybatis.dynamic.sql.BasicColumn;
2118
import org.mybatis.dynamic.sql.render.TableAliasCalculator;
2219

23-
/**
24-
* CountAll seems like the other aggregates, but it is special because there is no column.
25-
* Rather than dealing with a useless and confusing abstraction, we simply implement
26-
* BasicColumn directly.
27-
*
28-
* @author Jeff Butler
29-
*/
30-
public class CountAll implements BasicColumn {
31-
32-
private String alias;
20+
public class CountAll extends AbstractCount<CountAll> {
3321

3422
public CountAll() {
35-
super();
23+
super(null);
3624
}
3725

38-
@Override
39-
public String renderWithTableAlias(TableAliasCalculator tableAliasCalculator) {
40-
return "count(*)"; //$NON-NLS-1$
26+
private CountAll(String alias) {
27+
super(alias);
4128
}
4229

4330
@Override
44-
public Optional<String> alias() {
45-
return Optional.ofNullable(alias);
31+
public String renderWithTableAlias(TableAliasCalculator tableAliasCalculator) {
32+
return "count(*)"; //$NON-NLS-1$
4633
}
4734

4835
@Override
49-
public CountAll as(String alias) {
50-
CountAll copy = new CountAll();
51-
copy.alias = alias;
52-
return copy;
36+
protected CountAll copyWithAlias(String alias) {
37+
return new CountAll(alias);
5338
}
5439
}

src/main/java/org/mybatis/dynamic/sql/select/aggregate/CountDistinct.java

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,25 +15,31 @@
1515
*/
1616
package org.mybatis.dynamic.sql.select.aggregate;
1717

18+
import java.util.Objects;
19+
1820
import org.mybatis.dynamic.sql.BasicColumn;
21+
import org.mybatis.dynamic.sql.render.TableAliasCalculator;
22+
23+
public class CountDistinct extends AbstractCount<CountDistinct> {
24+
25+
private final BasicColumn column;
1926

20-
public class CountDistinct extends AbstractAggregate<CountDistinct> {
21-
22-
private CountDistinct(BasicColumn column) {
23-
super(column);
27+
private CountDistinct(BasicColumn column, String alias) {
28+
super(alias);
29+
this.column = Objects.requireNonNull(column);
2430
}
25-
31+
2632
@Override
27-
protected String render(String columnName) {
28-
return "count(distinct " + columnName + ")"; //$NON-NLS-1$ //$NON-NLS-2$
33+
public String renderWithTableAlias(TableAliasCalculator tableAliasCalculator) {
34+
return "count(distinct " + column.renderWithTableAlias(tableAliasCalculator) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
2935
}
3036

3137
@Override
32-
protected CountDistinct copy() {
33-
return new CountDistinct(column);
38+
public CountDistinct copyWithAlias(String alias) {
39+
return new CountDistinct(column, alias);
3440
}
35-
41+
3642
public static CountDistinct of(BasicColumn column) {
37-
return new CountDistinct(column);
43+
return new CountDistinct(column, null);
3844
}
3945
}

src/main/java/org/mybatis/dynamic/sql/select/aggregate/Max.java

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,25 +15,27 @@
1515
*/
1616
package org.mybatis.dynamic.sql.select.aggregate;
1717

18-
import org.mybatis.dynamic.sql.BasicColumn;
18+
import org.mybatis.dynamic.sql.BindableColumn;
19+
import org.mybatis.dynamic.sql.render.TableAliasCalculator;
20+
import org.mybatis.dynamic.sql.select.function.AbstractUniTypeFunction;
1921

20-
public class Max extends AbstractAggregate<Max> {
22+
public class Max<T> extends AbstractUniTypeFunction<T, Max<T>> {
2123

22-
private Max(BasicColumn column) {
24+
private Max(BindableColumn<T> column) {
2325
super(column);
2426
}
25-
27+
2628
@Override
27-
protected String render(String columnName) {
28-
return "max(" + columnName + ")"; //$NON-NLS-1$ //$NON-NLS-2$
29+
public String renderWithTableAlias(TableAliasCalculator tableAliasCalculator) {
30+
return "max(" + column.renderWithTableAlias(tableAliasCalculator) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
2931
}
3032

3133
@Override
32-
protected Max copy() {
33-
return new Max(column);
34+
protected Max<T> copy() {
35+
return new Max<>(column);
3436
}
3537

36-
public static Max of(BasicColumn column) {
37-
return new Max(column);
38+
public static <T> Max<T> of(BindableColumn<T> column) {
39+
return new Max<>(column);
3840
}
3941
}

src/main/java/org/mybatis/dynamic/sql/select/aggregate/Min.java

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,25 +15,27 @@
1515
*/
1616
package org.mybatis.dynamic.sql.select.aggregate;
1717

18-
import org.mybatis.dynamic.sql.BasicColumn;
18+
import org.mybatis.dynamic.sql.BindableColumn;
19+
import org.mybatis.dynamic.sql.render.TableAliasCalculator;
20+
import org.mybatis.dynamic.sql.select.function.AbstractUniTypeFunction;
1921

20-
public class Min extends AbstractAggregate<Min> {
22+
public class Min<T> extends AbstractUniTypeFunction<T, Min<T>> {
2123

22-
private Min(BasicColumn column) {
24+
private Min(BindableColumn<T> column) {
2325
super(column);
2426
}
25-
27+
2628
@Override
27-
protected String render(String columnName) {
28-
return "min(" + columnName + ")"; //$NON-NLS-1$ //$NON-NLS-2$
29+
public String renderWithTableAlias(TableAliasCalculator tableAliasCalculator) {
30+
return "min(" + column.renderWithTableAlias(tableAliasCalculator) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
2931
}
3032

3133
@Override
32-
protected Min copy() {
33-
return new Min(column);
34+
protected Min<T> copy() {
35+
return new Min<>(column);
3436
}
3537

36-
public static Min of(BasicColumn column) {
37-
return new Min(column);
38+
public static <T> Min<T> of(BindableColumn<T> column) {
39+
return new Min<>(column);
3840
}
3941
}

src/main/java/org/mybatis/dynamic/sql/select/aggregate/Sum.java

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,25 +15,27 @@
1515
*/
1616
package org.mybatis.dynamic.sql.select.aggregate;
1717

18-
import org.mybatis.dynamic.sql.BasicColumn;
18+
import org.mybatis.dynamic.sql.BindableColumn;
19+
import org.mybatis.dynamic.sql.render.TableAliasCalculator;
20+
import org.mybatis.dynamic.sql.select.function.AbstractUniTypeFunction;
1921

20-
public class Sum extends AbstractAggregate<Sum> {
22+
public class Sum<T> extends AbstractUniTypeFunction<T, Sum<T>> {
2123

22-
private Sum(BasicColumn column) {
24+
private Sum(BindableColumn<T> column) {
2325
super(column);
2426
}
25-
27+
2628
@Override
27-
protected String render(String columnName) {
28-
return "sum(" + columnName + ")"; //$NON-NLS-1$ //$NON-NLS-2$
29+
public String renderWithTableAlias(TableAliasCalculator tableAliasCalculator) {
30+
return "sum(" + column.renderWithTableAlias(tableAliasCalculator) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
2931
}
3032

3133
@Override
32-
protected Sum copy() {
33-
return new Sum(column);
34+
protected Sum<T> copy() {
35+
return new Sum<>(column);
3436
}
3537

36-
public static Sum of(BasicColumn column) {
37-
return new Sum(column);
38+
public static <T> Sum<T> of(BindableColumn<T> column) {
39+
return new Sum<>(column);
3840
}
3941
}

0 commit comments

Comments
 (0)