Skip to content

Add Ability to Easily Use Non-Standard Database Operators #220

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jul 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,18 @@ This log will detail notable changes to MyBatis Dynamic SQL. Full details are av

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+)

### General Announcements

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).

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.

### Added

- 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))
- 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))
- Added the ability to write a function that will change the column data type ([#197](https://github.com/mybatis/mybatis-dynamic-sql/issues/197))
- 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))

## Release 1.1.4 - November 23, 2019

Expand Down
8 changes: 6 additions & 2 deletions src/main/java/org/mybatis/dynamic/sql/BindableColumn.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,13 @@ public interface BindableColumn<T> extends BasicColumn {
@Override
BindableColumn<T> as(String alias);

Optional<JDBCType> jdbcType();
default Optional<JDBCType> jdbcType() {
return Optional.empty();
}

Optional<String> typeHandler();
default Optional<String> typeHandler() {
return Optional.empty();
}

default Optional<RenderingStrategy> renderingStrategy() {
return Optional.empty();
Expand Down
12 changes: 6 additions & 6 deletions src/main/java/org/mybatis/dynamic/sql/Constant.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright 2016-2018 the original author or authors.
* 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.
Expand All @@ -20,7 +20,7 @@

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

public class Constant implements BasicColumn {
public class Constant<T> implements BindableColumn<T> {

private String alias;
private String value;
Expand All @@ -40,13 +40,13 @@ public String renderWithTableAlias(TableAliasCalculator tableAliasCalculator) {
}

@Override
public Constant as(String alias) {
Constant copy = new Constant(value);
public Constant<T> as(String alias) {
Constant<T> copy = new Constant<>(value);
copy.alias = alias;
return copy;
}

public static Constant of(String value) {
return new Constant(value);
public static <T> Constant<T> of(String value) {
return new Constant<>(value);
}
}
14 changes: 13 additions & 1 deletion src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,11 @@
import org.mybatis.dynamic.sql.select.aggregate.Min;
import org.mybatis.dynamic.sql.select.aggregate.Sum;
import org.mybatis.dynamic.sql.select.function.Add;
import org.mybatis.dynamic.sql.select.function.Concatenate;
import org.mybatis.dynamic.sql.select.function.Divide;
import org.mybatis.dynamic.sql.select.function.Lower;
import org.mybatis.dynamic.sql.select.function.Multiply;
import org.mybatis.dynamic.sql.select.function.OperatorFunction;
import org.mybatis.dynamic.sql.select.function.Substring;
import org.mybatis.dynamic.sql.select.function.Subtract;
import org.mybatis.dynamic.sql.select.function.Upper;
Expand Down Expand Up @@ -256,7 +258,7 @@ static Sum sum(BasicColumn column) {
}

// constants
static Constant constant(String constant) {
static <T> Constant<T> constant(String constant) {
return Constant.of(constant);
}

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

static <T> Concatenate<T> concatenate(BindableColumn<T> firstColumn, BasicColumn secondColumn,
BasicColumn... subsequentColumns) {
return Concatenate.concatenate(firstColumn, secondColumn, subsequentColumns);
}

static <T> OperatorFunction<T> applyOperator(String operator, BindableColumn<T> firstColumn, BasicColumn secondColumn,
BasicColumn... subsequentColumns) {
return OperatorFunction.of(operator, firstColumn, secondColumn, subsequentColumns);
}

static Lower lower(BindableColumn<String> column) {
return Lower.of(column);
}
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/org/mybatis/dynamic/sql/StringConstant.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright 2016-2018 the original author or authors.
* 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.
Expand All @@ -20,7 +20,7 @@

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

public class StringConstant implements BasicColumn {
public class StringConstant implements BindableColumn<String> {

private String alias;
private String value;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,38 @@
package org.mybatis.dynamic.sql.select.function;

import java.sql.JDBCType;
import java.util.Objects;
import java.util.Optional;

import org.mybatis.dynamic.sql.BindableColumn;

public abstract class AbstractFunction<T, U extends AbstractFunction<T, U>>
extends AbstractTypeConvertingFunction<T, T, U> {
/**
* @deprecated in favor of {@link AbstractUniTypeFunction}
*
* @author Jeff Butler
*/
@Deprecated
public abstract class AbstractFunction<T, U extends AbstractFunction<T, U>> implements BindableColumn<T> {

protected BindableColumn<T> column;
protected String alias;

protected AbstractFunction(BindableColumn<T> column) {
super(column);
this.column = Objects.requireNonNull(column);
}

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

@Override
public U as(String alias) {
U newThing = copy();
newThing.alias = alias;
return newThing;
}

@Override
public Optional<JDBCType> jdbcType() {
return column.jdbcType();
Expand All @@ -36,4 +57,6 @@ public Optional<JDBCType> jdbcType() {
public Optional<String> typeHandler() {
return column.typeHandler();
}

protected abstract U copy();
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright 2016-2018 the original author or authors.
* 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.
Expand All @@ -26,13 +26,19 @@
import org.mybatis.dynamic.sql.BindableColumn;
import org.mybatis.dynamic.sql.render.TableAliasCalculator;

/**
* @deprecated in favor of {@link OperatorFunction}.
*
* @author Jeff Butler
*/
@Deprecated
public abstract class AbstractMultipleColumnArithmeticFunction<T extends Number,
U extends AbstractMultipleColumnArithmeticFunction<T, U>>
extends AbstractFunction<T, AbstractMultipleColumnArithmeticFunction<T,U>> {
extends AbstractFunction<T, AbstractMultipleColumnArithmeticFunction<T, U>> {

protected BasicColumn secondColumn;
protected List<BasicColumn> subsequentColumns = new ArrayList<>();

protected AbstractMultipleColumnArithmeticFunction(BindableColumn<T> firstColumn, BasicColumn secondColumn,
List<BasicColumn> subsequentColumns) {
super(firstColumn);
Expand All @@ -42,13 +48,13 @@ protected AbstractMultipleColumnArithmeticFunction(BindableColumn<T> firstColumn

@Override
public String renderWithTableAlias(TableAliasCalculator tableAliasCalculator) {
// note - the cast below is added for a type inference bug in the Java9 compiler.
// note - the cast below is added for a type inference bug in the Java9
// compiler.
return Stream.of(Stream.of((BasicColumn) column), Stream.of(secondColumn), subsequentColumns.stream())
.flatMap(Function.identity())
.map(column -> column.renderWithTableAlias(tableAliasCalculator))
.flatMap(Function.identity()).map(column -> column.renderWithTableAlias(tableAliasCalculator))
.collect(Collectors.joining(padOperator(), "(", ")")); //$NON-NLS-1$ //$NON-NLS-2$
}

private String padOperator() {
return " " + operator() + " "; //$NON-NLS-1$ //$NON-NLS-2$
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**
* 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.function;

import java.sql.JDBCType;
import java.util.Optional;

import org.mybatis.dynamic.sql.BindableColumn;

/**
* Represents a function that does not change the underlying data type.
*
* @author Jeff Butler
*
* @param <T> The type of the underlying column
* @param <U> the specific subtype that implements the function
*/
public abstract class AbstractUniTypeFunction<T, U extends AbstractUniTypeFunction<T, U>>
extends AbstractTypeConvertingFunction<T, T, U> {

protected AbstractUniTypeFunction(BindableColumn<T> column) {
super(column);
}

@Override
public Optional<JDBCType> jdbcType() {
return column.jdbcType();
}

@Override
public Optional<String> typeHandler() {
return column.typeHandler();
}
}
11 changes: 3 additions & 8 deletions src/main/java/org/mybatis/dynamic/sql/select/function/Add.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright 2016-2018 the original author or authors.
* 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.
Expand All @@ -20,23 +20,18 @@
import org.mybatis.dynamic.sql.BasicColumn;
import org.mybatis.dynamic.sql.BindableColumn;

public class Add<T extends Number> extends AbstractMultipleColumnArithmeticFunction<T, Add<T>> {
public class Add<T extends Number> extends OperatorFunction<T> {

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

@Override
protected Add<T> copy() {
return new Add<>(column, secondColumn, subsequentColumns);
}

@Override
protected String operator() {
return "+"; //$NON-NLS-1$
}

public static <T extends Number> Add<T> of(BindableColumn<T> firstColumn, BasicColumn secondColumn,
List<BasicColumn> subsequentColumns) {
return new Add<>(firstColumn, secondColumn, subsequentColumns);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* 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.function;

import java.util.Arrays;
import java.util.List;

import org.mybatis.dynamic.sql.BasicColumn;
import org.mybatis.dynamic.sql.BindableColumn;

public class Concatenate<T> extends OperatorFunction<T> {

protected Concatenate(BindableColumn<T> firstColumn, BasicColumn secondColumn,
List<BasicColumn> subsequentColumns) {
super("||", firstColumn, secondColumn, subsequentColumns); //$NON-NLS-1$
}

@Override
protected Concatenate<T> copy() {
return new Concatenate<>(column, secondColumn, subsequentColumns);
}

public static <T> Concatenate<T> concatenate(BindableColumn<T> firstColumn, BasicColumn secondColumn,
BasicColumn... subsequentColumns) {
return new Concatenate<>(firstColumn, secondColumn, Arrays.asList(subsequentColumns));
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright 2016-2018 the original author or authors.
* 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.
Expand All @@ -20,23 +20,18 @@
import org.mybatis.dynamic.sql.BasicColumn;
import org.mybatis.dynamic.sql.BindableColumn;

public class Divide<T extends Number> extends AbstractMultipleColumnArithmeticFunction<T, Divide<T>> {
public class Divide<T extends Number> extends OperatorFunction<T> {

private Divide(BindableColumn<T> firstColumn, BasicColumn secondColumn,
List<BasicColumn> subsequentColumns) {
super(firstColumn, secondColumn, subsequentColumns);
super("/", firstColumn, secondColumn, subsequentColumns); //$NON-NLS-1$
}

@Override
protected Divide<T> copy() {
return new Divide<>(column, secondColumn, subsequentColumns);
}

@Override
protected String operator() {
return "/"; //$NON-NLS-1$
}

public static <T extends Number> Divide<T> of(BindableColumn<T> firstColumn, BasicColumn secondColumn,
List<BasicColumn> subsequentColumns) {
return new Divide<>(firstColumn, secondColumn, subsequentColumns);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright 2016-2018 the original author or authors.
* 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.
Expand All @@ -18,7 +18,7 @@
import org.mybatis.dynamic.sql.BindableColumn;
import org.mybatis.dynamic.sql.render.TableAliasCalculator;

public class Lower extends AbstractFunction<String, Lower> {
public class Lower extends AbstractUniTypeFunction<String, Lower> {

private Lower(BindableColumn<String> column) {
super(column);
Expand Down
Loading