Skip to content

Commit

Permalink
Merge pull request #259 from jeffgbutler/aggregates-are-functions
Browse files Browse the repository at this point in the history
Refactor Aggregates to Behave Like Functions
  • Loading branch information
jeffgbutler committed Sep 15, 2020
2 parents e7721be + 2a681dc commit f07b8a1
Show file tree
Hide file tree
Showing 14 changed files with 206 additions and 92 deletions.
8 changes: 4 additions & 4 deletions src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -331,19 +331,19 @@ static CountDistinct countDistinct(BasicColumn column) {
return CountDistinct.of(column);
}

static Max max(BasicColumn column) {
static <T> Max<T> max(BindableColumn<T> column) {
return Max.of(column);
}

static Min min(BasicColumn column) {
static <T> Min<T> min(BindableColumn<T> column) {
return Min.of(column);
}

static Avg avg(BasicColumn column) {
static <T> Avg<T> avg(BindableColumn<T> column) {
return Avg.of(column);
}

static Sum sum(BasicColumn column) {
static <T> Sum<T> sum(BindableColumn<T> column) {
return Sum.of(column);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,15 @@

/**
* This class is the base class for aggregate functions.
*
*
* @deprecated in favor of {@link org.mybatis.dynamic.sql.select.function.AbstractUniTypeFunction} as there is
* virtually no difference between an aggregate and a function
*
* @author Jeff Butler
*
* @param <T> the subclass type
*/
@Deprecated
public abstract class AbstractAggregate<T extends AbstractAggregate<T>> implements BasicColumn {
protected final BasicColumn column;
protected String alias;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright 2016-2020 the original author or authors.
*
* 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.
*/
package org.mybatis.dynamic.sql.select.aggregate;

import java.util.Optional;
import org.mybatis.dynamic.sql.BindableColumn;

/**
* Count functions are implemented differently than the other aggregates. This is primarily to preserve
* backwards compatibility. Count functions are configured as BindableColumns of type Long
* as it is assumed that the count functions always return a number.
*
* @param <T> the subtype of this class
*/
public abstract class AbstractCount<T extends AbstractCount<T>> implements BindableColumn<Long> {
private final String alias;

protected AbstractCount(String alias) {
this.alias = alias;
}

@Override
public Optional<String> alias() {
return Optional.ofNullable(alias);
}

@Override
public T as(String alias) {
return copyWithAlias(alias);
}

protected abstract T copyWithAlias(String alias);
}
22 changes: 12 additions & 10 deletions src/main/java/org/mybatis/dynamic/sql/select/aggregate/Avg.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,27 @@
*/
package org.mybatis.dynamic.sql.select.aggregate;

import org.mybatis.dynamic.sql.BasicColumn;
import org.mybatis.dynamic.sql.BindableColumn;
import org.mybatis.dynamic.sql.render.TableAliasCalculator;
import org.mybatis.dynamic.sql.select.function.AbstractUniTypeFunction;

public class Avg extends AbstractAggregate<Avg> {
public class Avg<T> extends AbstractUniTypeFunction<T, Avg<T>> {

private Avg(BasicColumn column) {
private Avg(BindableColumn<T> column) {
super(column);
}

@Override
protected String render(String columnName) {
return "avg(" + columnName + ")"; //$NON-NLS-1$ //$NON-NLS-2$
public String renderWithTableAlias(TableAliasCalculator tableAliasCalculator) {
return "avg(" + column.renderWithTableAlias(tableAliasCalculator) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
}

@Override
protected Avg copy() {
return new Avg(column);
protected Avg<T> copy() {
return new Avg<>(column);
}

public static Avg of(BasicColumn column) {
return new Avg(column);
public static <T> Avg<T> of(BindableColumn<T> column) {
return new Avg<>(column);
}
}
28 changes: 17 additions & 11 deletions src/main/java/org/mybatis/dynamic/sql/select/aggregate/Count.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,31 @@
*/
package org.mybatis.dynamic.sql.select.aggregate;

import java.util.Objects;

import org.mybatis.dynamic.sql.BasicColumn;
import org.mybatis.dynamic.sql.render.TableAliasCalculator;

public class Count extends AbstractCount<Count> {

private final BasicColumn column;

public class Count extends AbstractAggregate<Count> {

private Count(BasicColumn column) {
super(column);
private Count(BasicColumn column, String alias) {
super(alias);
this.column = Objects.requireNonNull(column);
}

@Override
protected String render(String columnName) {
return "count(" + columnName + ")"; //$NON-NLS-1$ //$NON-NLS-2$
public String renderWithTableAlias(TableAliasCalculator tableAliasCalculator) {
return "count(" + column.renderWithTableAlias(tableAliasCalculator) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
}

@Override
protected Count copy() {
return new Count(column);
protected Count copyWithAlias(String alias) {
return new Count(column, alias);
}

public static Count of(BasicColumn column) {
return new Count(column);
return new Count(column, null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,40 +15,25 @@
*/
package org.mybatis.dynamic.sql.select.aggregate;

import java.util.Optional;

import org.mybatis.dynamic.sql.BasicColumn;
import org.mybatis.dynamic.sql.render.TableAliasCalculator;

/**
* CountAll seems like the other aggregates, but it is special because there is no column.
* Rather than dealing with a useless and confusing abstraction, we simply implement
* BasicColumn directly.
*
* @author Jeff Butler
*/
public class CountAll implements BasicColumn {

private String alias;
public class CountAll extends AbstractCount<CountAll> {

public CountAll() {
super();
super(null);
}

@Override
public String renderWithTableAlias(TableAliasCalculator tableAliasCalculator) {
return "count(*)"; //$NON-NLS-1$
private CountAll(String alias) {
super(alias);
}

@Override
public Optional<String> alias() {
return Optional.ofNullable(alias);
public String renderWithTableAlias(TableAliasCalculator tableAliasCalculator) {
return "count(*)"; //$NON-NLS-1$
}

@Override
public CountAll as(String alias) {
CountAll copy = new CountAll();
copy.alias = alias;
return copy;
protected CountAll copyWithAlias(String alias) {
return new CountAll(alias);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,31 @@
*/
package org.mybatis.dynamic.sql.select.aggregate;

import java.util.Objects;

import org.mybatis.dynamic.sql.BasicColumn;
import org.mybatis.dynamic.sql.render.TableAliasCalculator;

public class CountDistinct extends AbstractCount<CountDistinct> {

private final BasicColumn column;

public class CountDistinct extends AbstractAggregate<CountDistinct> {

private CountDistinct(BasicColumn column) {
super(column);
private CountDistinct(BasicColumn column, String alias) {
super(alias);
this.column = Objects.requireNonNull(column);
}

@Override
protected String render(String columnName) {
return "count(distinct " + columnName + ")"; //$NON-NLS-1$ //$NON-NLS-2$
public String renderWithTableAlias(TableAliasCalculator tableAliasCalculator) {
return "count(distinct " + column.renderWithTableAlias(tableAliasCalculator) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
}

@Override
protected CountDistinct copy() {
return new CountDistinct(column);
public CountDistinct copyWithAlias(String alias) {
return new CountDistinct(column, alias);
}

public static CountDistinct of(BasicColumn column) {
return new CountDistinct(column);
return new CountDistinct(column, null);
}
}
22 changes: 12 additions & 10 deletions src/main/java/org/mybatis/dynamic/sql/select/aggregate/Max.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,27 @@
*/
package org.mybatis.dynamic.sql.select.aggregate;

import org.mybatis.dynamic.sql.BasicColumn;
import org.mybatis.dynamic.sql.BindableColumn;
import org.mybatis.dynamic.sql.render.TableAliasCalculator;
import org.mybatis.dynamic.sql.select.function.AbstractUniTypeFunction;

public class Max extends AbstractAggregate<Max> {
public class Max<T> extends AbstractUniTypeFunction<T, Max<T>> {

private Max(BasicColumn column) {
private Max(BindableColumn<T> column) {
super(column);
}

@Override
protected String render(String columnName) {
return "max(" + columnName + ")"; //$NON-NLS-1$ //$NON-NLS-2$
public String renderWithTableAlias(TableAliasCalculator tableAliasCalculator) {
return "max(" + column.renderWithTableAlias(tableAliasCalculator) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
}

@Override
protected Max copy() {
return new Max(column);
protected Max<T> copy() {
return new Max<>(column);
}

public static Max of(BasicColumn column) {
return new Max(column);
public static <T> Max<T> of(BindableColumn<T> column) {
return new Max<>(column);
}
}
22 changes: 12 additions & 10 deletions src/main/java/org/mybatis/dynamic/sql/select/aggregate/Min.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,27 @@
*/
package org.mybatis.dynamic.sql.select.aggregate;

import org.mybatis.dynamic.sql.BasicColumn;
import org.mybatis.dynamic.sql.BindableColumn;
import org.mybatis.dynamic.sql.render.TableAliasCalculator;
import org.mybatis.dynamic.sql.select.function.AbstractUniTypeFunction;

public class Min extends AbstractAggregate<Min> {
public class Min<T> extends AbstractUniTypeFunction<T, Min<T>> {

private Min(BasicColumn column) {
private Min(BindableColumn<T> column) {
super(column);
}

@Override
protected String render(String columnName) {
return "min(" + columnName + ")"; //$NON-NLS-1$ //$NON-NLS-2$
public String renderWithTableAlias(TableAliasCalculator tableAliasCalculator) {
return "min(" + column.renderWithTableAlias(tableAliasCalculator) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
}

@Override
protected Min copy() {
return new Min(column);
protected Min<T> copy() {
return new Min<>(column);
}

public static Min of(BasicColumn column) {
return new Min(column);
public static <T> Min<T> of(BindableColumn<T> column) {
return new Min<>(column);
}
}
22 changes: 12 additions & 10 deletions src/main/java/org/mybatis/dynamic/sql/select/aggregate/Sum.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,27 @@
*/
package org.mybatis.dynamic.sql.select.aggregate;

import org.mybatis.dynamic.sql.BasicColumn;
import org.mybatis.dynamic.sql.BindableColumn;
import org.mybatis.dynamic.sql.render.TableAliasCalculator;
import org.mybatis.dynamic.sql.select.function.AbstractUniTypeFunction;

public class Sum extends AbstractAggregate<Sum> {
public class Sum<T> extends AbstractUniTypeFunction<T, Sum<T>> {

private Sum(BasicColumn column) {
private Sum(BindableColumn<T> column) {
super(column);
}

@Override
protected String render(String columnName) {
return "sum(" + columnName + ")"; //$NON-NLS-1$ //$NON-NLS-2$
public String renderWithTableAlias(TableAliasCalculator tableAliasCalculator) {
return "sum(" + column.renderWithTableAlias(tableAliasCalculator) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
}

@Override
protected Sum copy() {
return new Sum(column);
protected Sum<T> copy() {
return new Sum<>(column);
}

public static Sum of(BasicColumn column) {
return new Sum(column);
public static <T> Sum<T> of(BindableColumn<T> column) {
return new Sum<>(column);
}
}
Loading

0 comments on commit f07b8a1

Please sign in to comment.