Skip to content

Commit

Permalink
runtime-join: Simplify API with direct usage of Fields
Browse files Browse the repository at this point in the history
  • Loading branch information
minborg committed Feb 20, 2018
1 parent 71e24da commit 2839dd3
Show file tree
Hide file tree
Showing 17 changed files with 517 additions and 691 deletions.
Expand Up @@ -14,7 +14,6 @@
import com.speedment.runtime.field.trait.HasComparableOperators; import com.speedment.runtime.field.trait.HasComparableOperators;
import com.speedment.runtime.join.trait.HasDefaultBuild; import com.speedment.runtime.join.trait.HasDefaultBuild;
import com.speedment.runtime.join.trait.HasJoins; import com.speedment.runtime.join.trait.HasJoins;
import com.speedment.runtime.join.trait.HasOn;
import com.speedment.runtime.join.trait.HasOnPredicates; import com.speedment.runtime.join.trait.HasOnPredicates;
import com.speedment.runtime.join.trait.HasWhere; import com.speedment.runtime.join.trait.HasWhere;
import java.util.function.BiFunction; import java.util.function.BiFunction;
Expand Down Expand Up @@ -60,30 +59,22 @@ interface JoinBuilder1<T1> extends
HasWhere<T1, JoinBuilder1<T1>> { HasWhere<T1, JoinBuilder1<T1>> {


@Override @Override
<T2> AfterJoin<T1, T2> innerJoin(TableIdentifier<T2> joinedTable); <T2> AfterJoin<T1, T2> innerJoinOn(HasComparableOperators<T2, ?> joinedField);


@Override @Override
<T2> AfterJoin<T1, T2> leftJoin(TableIdentifier<T2> joinedTable); <T2> AfterJoin<T1, T2> leftJoinOn(HasComparableOperators<T2, ?> joinedField);


@Override @Override
<T2> AfterJoin<T1, T2> rightJoin(TableIdentifier<T2> joinedTable); <T2> AfterJoin<T1, T2> rightJoinOn(HasComparableOperators<T2, ?> joinedField);


@Override @Override
<T2> AfterJoin<T1, T2> fullOuterJoin(TableIdentifier<T2> joinedTable); <T2> AfterJoin<T1, T2> fullOuterJoinOn(HasComparableOperators<T2, ?> joinedField);


@Override @Override
<T2> JoinBuilder2<T1, T2> crossJoin(TableIdentifier<T2> joinedTable); <T2> JoinBuilder2<T1, T2> crossJoin(TableIdentifier<T2> joinedTable);


interface AfterJoin<T1, T2> extends interface AfterJoin<T1, T2> extends
HasOn<Object> /*HasOn<T1> */ { HasOnPredicates<JoinBuilder2<T1, T2>> {

@Override
<V extends Comparable<? super V>, FIELD extends HasComparableOperators<? extends Object, V>> AfterOn<T1, T2, V>
on(FIELD originalField); // Must be T1

interface AfterOn<T1, T2, V extends Comparable<? super V>> extends
HasOnPredicates<V, T2, JoinBuilder2<T1, T2>> {
}


} }


Expand All @@ -93,19 +84,19 @@ interface JoinBuilder2<T1, T2> extends
HasDefaultBuild<Tuple2<T1, T2>> { HasDefaultBuild<Tuple2<T1, T2>> {


@Override @Override
<T3> AfterJoin<T1, T2, T3> innerJoin(TableIdentifier<T3> joinedTable); <T3> AfterJoin<T1, T2, T3> innerJoinOn(HasComparableOperators<T3, ?> joinedField);


@Override @Override
<T3> AfterJoin<T1, T2, T3> leftJoin(TableIdentifier<T3> joinedTable); <T3> AfterJoin<T1, T2, T3> leftJoinOn(HasComparableOperators<T3, ?> joinedField);


@Override @Override
<T3> AfterJoin<T1, T2, T3> rightJoin(TableIdentifier<T3> joinedTable); <T3> AfterJoin<T1, T2, T3> rightJoinOn(HasComparableOperators<T3, ?> joinedField);


@Override @Override
<T4> AfterJoin<T1, T2, T4> fullOuterJoin(TableIdentifier<T4> joinedTable); <T3> AfterJoin<T1, T2, T3> fullOuterJoinOn(HasComparableOperators<T3, ?> joinedField);


@Override @Override
<T4> JoinBuilder3<T1, T2, T4> crossJoin(TableIdentifier<T4> joinedTable); <T3> JoinBuilder3<T1, T2, T3> crossJoin(TableIdentifier<T3> joinedTable);


@Override @Override
default Join<Tuple2<T1, T2>> build() { default Join<Tuple2<T1, T2>> build() {
Expand All @@ -129,15 +120,7 @@ default Join<Tuple2<T1, T2>> build() {
<T> Join<T> build(BiFunction<T1, T2, T> constructor); <T> Join<T> build(BiFunction<T1, T2, T> constructor);


interface AfterJoin<T1, T2, T3> extends interface AfterJoin<T1, T2, T3> extends
HasOn<Object> { HasOnPredicates<JoinBuilder3<T1, T2, T3>> {

@Override
<V extends Comparable<? super V>, FIELD extends HasComparableOperators<? extends Object, V>> AfterOn<T1, T2, T3, V>
on(FIELD originalField); // Enforce dynamic type later in operation parameter

interface AfterOn<T1, T2, T3, V extends Comparable<? super V>> extends
HasOnPredicates<V, T3, JoinBuilder3<T1, T2, T3>> {
}


} }


Expand All @@ -147,16 +130,16 @@ interface JoinBuilder3<T1, T2, T3> extends
HasDefaultBuild<Tuple3<T1, T2, T3>> { HasDefaultBuild<Tuple3<T1, T2, T3>> {


@Override @Override
<T4> AfterJoin<T1, T2, T3, T4> innerJoin(TableIdentifier<T4> joinedTable); <T4> AfterJoin<T1, T2, T3, T4> innerJoinOn(HasComparableOperators<T4, ?> joinedField);


@Override @Override
<T4> AfterJoin<T1, T2, T3, T4> leftJoin(TableIdentifier<T4> joinedTable); <T4> AfterJoin<T1, T2, T3, T4> leftJoinOn(HasComparableOperators<T4, ?> joinedField);


@Override @Override
<T4> AfterJoin<T1, T2, T3, T4> rightJoin(TableIdentifier<T4> joinedTable); <T4> AfterJoin<T1, T2, T3, T4> rightJoinOn(HasComparableOperators<T4, ?> joinedField);


@Override @Override
<T4> AfterJoin<T1, T2, T3, T4> fullOuterJoin(TableIdentifier<T4> joinedTable); <T4> AfterJoin<T1, T2, T3, T4> fullOuterJoinOn(HasComparableOperators<T4, ?> joinedField);


@Override @Override
<T4> JoinBuilder4<T1, T2, T3, T4> crossJoin(TableIdentifier<T4> joinedTable); <T4> JoinBuilder4<T1, T2, T3, T4> crossJoin(TableIdentifier<T4> joinedTable);
Expand All @@ -183,15 +166,7 @@ default Join<Tuple3<T1, T2, T3>> build() {
<T> Join<T> build(TriFunction<T1, T2, T3, T> constructor); <T> Join<T> build(TriFunction<T1, T2, T3, T> constructor);


interface AfterJoin<T1, T2, T3, T4> extends interface AfterJoin<T1, T2, T3, T4> extends
HasOn<Object> { HasOnPredicates<JoinBuilder4<T1, T2, T3, T4>> {

@Override
<V extends Comparable<? super V>, FIELD extends HasComparableOperators<? extends Object, V>> AfterOn<T1, T2, T3, T4, V>
on(FIELD originalField);

interface AfterOn<T1, T2, T3, T4, V extends Comparable<? super V>> extends
HasOnPredicates<V, T4, JoinBuilder4<T1, T2, T3, T4>> {
}


} }


Expand All @@ -201,16 +176,16 @@ interface JoinBuilder4<T1, T2, T3, T4> extends
HasDefaultBuild<Tuple4<T1, T2, T3, T4>> { HasDefaultBuild<Tuple4<T1, T2, T3, T4>> {


@Override @Override
<T5> AfterJoin<T1, T2, T3, T4, T5> innerJoin(TableIdentifier<T5> joinedTable); <T5> AfterJoin<T1, T2, T3, T4, T5> innerJoinOn(HasComparableOperators<T5, ?> joinedField);


@Override @Override
<T5> AfterJoin<T1, T2, T3, T4, T5> leftJoin(TableIdentifier<T5> joinedTable); <T5> AfterJoin<T1, T2, T3, T4, T5> leftJoinOn(HasComparableOperators<T5, ?> joinedField);


@Override @Override
<T5> AfterJoin<T1, T2, T3, T4, T5> rightJoin(TableIdentifier<T5> joinedTable); <T5> AfterJoin<T1, T2, T3, T4, T5> rightJoinOn(HasComparableOperators<T5, ?> joinedField);


@Override @Override
<T5> AfterJoin<T1, T2, T3, T4, T5> fullOuterJoin(TableIdentifier<T5> joinedTable); <T5> AfterJoin<T1, T2, T3, T4, T5> fullOuterJoinOn(HasComparableOperators<T5, ?> joinedField);


@Override @Override
<T5> JoinBuilder5<T1, T2, T3, T4, T5> crossJoin(TableIdentifier<T5> joinedTable); <T5> JoinBuilder5<T1, T2, T3, T4, T5> crossJoin(TableIdentifier<T5> joinedTable);
Expand Down Expand Up @@ -241,15 +216,7 @@ default Join<Tuple4<T1, T2, T3, T4>> build() {
<T> Join<T> build(QuadFunction<T1, T2, T3, T4, T> constructor); <T> Join<T> build(QuadFunction<T1, T2, T3, T4, T> constructor);


interface AfterJoin<T1, T2, T3, T4, T5> extends interface AfterJoin<T1, T2, T3, T4, T5> extends
HasOn<Object> { HasOnPredicates<JoinBuilder5<T1, T2, T3, T4, T5>> {

@Override
<V extends Comparable<? super V>, FIELD extends HasComparableOperators<? extends Object, V>> AfterOn<T1, T2, T3, T4, T5, V>
on(FIELD originalField);

interface AfterOn<T1, T2, T3, T4, T5, V extends Comparable<? super V>> extends
HasOnPredicates<V, T5, JoinBuilder5<T1, T2, T3, T4, T5>> {
}


} }


Expand All @@ -259,16 +226,16 @@ interface JoinBuilder5<T1, T2, T3, T4, T5> extends
HasDefaultBuild<Tuple5<T1, T2, T3, T4, T5>> { HasDefaultBuild<Tuple5<T1, T2, T3, T4, T5>> {


@Override @Override
<T6> AfterJoin<T1, T2, T3, T4, T5, T6> innerJoin(TableIdentifier<T6> joinedTable); <T6> AfterJoin<T1, T2, T3, T4, T5, T6> innerJoinOn(HasComparableOperators<T6, ?> joinedField);


@Override @Override
<T6> AfterJoin<T1, T2, T3, T4, T5, T6> leftJoin(TableIdentifier<T6> joinedTable); <T6> AfterJoin<T1, T2, T3, T4, T5, T6> leftJoinOn(HasComparableOperators<T6, ?> joinedField);


@Override @Override
<T6> AfterJoin<T1, T2, T3, T4, T5, T6> rightJoin(TableIdentifier<T6> joinedTable); <T6> AfterJoin<T1, T2, T3, T4, T5, T6> rightJoinOn(HasComparableOperators<T6, ?> joinedField);


@Override @Override
<T6> AfterJoin<T1, T2, T3, T4, T5, T6> fullOuterJoin(TableIdentifier<T6> joinedTable); <T6> AfterJoin<T1, T2, T3, T4, T5, T6> fullOuterJoinOn(HasComparableOperators<T6, ?> joinedField);


@Override @Override
<T6> JoinBuilder6<T1, T2, T3, T4, T5, T6> crossJoin(TableIdentifier<T6> joinedTable); <T6> JoinBuilder6<T1, T2, T3, T4, T5, T6> crossJoin(TableIdentifier<T6> joinedTable);
Expand Down Expand Up @@ -300,15 +267,7 @@ default Join<Tuple5<T1, T2, T3, T4, T5>> build() {
<T> Join<T> build(Function5<T1, T2, T3, T4, T5, T> constructor); <T> Join<T> build(Function5<T1, T2, T3, T4, T5, T> constructor);


interface AfterJoin<T1, T2, T3, T4, T5, T6> extends interface AfterJoin<T1, T2, T3, T4, T5, T6> extends
HasOn<Object> { HasOnPredicates<JoinBuilder6<T1, T2, T3, T4, T5, T6>> {

@Override
<V extends Comparable<? super V>, FIELD extends HasComparableOperators<? extends Object, V>> AfterOn<T1, T2, T3, T4, T5, T6, V>
on(FIELD originalField);

interface AfterOn<T1, T2, T3, T4, T5, T6, V extends Comparable<? super V>> extends
HasOnPredicates<V, T6, JoinBuilder6<T1, T2, T3, T4, T5, T6>> {
}


} }


Expand Down
Expand Up @@ -5,6 +5,7 @@
import com.speedment.runtime.join.JoinStreamSupplierComponent; import com.speedment.runtime.join.JoinStreamSupplierComponent;
import com.speedment.runtime.join.stage.JoinType; import com.speedment.runtime.join.stage.JoinType;
import com.speedment.runtime.join.stage.Stage; import com.speedment.runtime.join.stage.Stage;
import com.speedment.runtime.join.trait.HasWhere;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
Expand All @@ -15,31 +16,43 @@
import static java.util.stream.Collectors.joining; import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList; import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toSet; import static java.util.stream.Collectors.toSet;
import java.util.stream.IntStream;


/** /**
* *
* @author Per Minborg * @author Per Minborg
*/ */
abstract class AbstractJoinBuilder<T> { abstract class AbstractJoinBuilder<T, SELF> implements HasWhere<T, SELF> {


private final JoinStreamSupplierComponent streamSupplier; private final JoinStreamSupplierComponent streamSupplier;
private final List<StageBean<?>> stageBeans; private final List<StageBean<?>> stageBeans;
private final StageBean<T> stageBean; private final StageBean<T> stageBean;


AbstractJoinBuilder(JoinStreamSupplierComponent streamSupplier, TableIdentifier<T> initialTable) { AbstractJoinBuilder(
final JoinStreamSupplierComponent streamSupplier,
final TableIdentifier<T> initialTable
) {
this.streamSupplier = requireNonNull(streamSupplier); this.streamSupplier = requireNonNull(streamSupplier);
this.stageBeans = new ArrayList<>(); this.stageBeans = new ArrayList<>();
this.stageBean = AbstractJoinBuilder.this.addStageBeanOf(requireNonNull(initialTable)); this.stageBean = AbstractJoinBuilder.this.addStageBeanOf(requireNonNull(initialTable));
} }


AbstractJoinBuilder(AbstractJoinBuilder<?> previous, StageBean<T> stageBean) { AbstractJoinBuilder(
final AbstractJoinBuilder<?, ?> previous,
final StageBean<T> stageBean
) {
requireNonNull(previous); requireNonNull(previous);
this.streamSupplier = previous.streamSuppler(); this.streamSupplier = previous.streamSuppler();
this.stageBeans = previous.stageBeans(); this.stageBeans = previous.stageBeans();
this.stageBean = requireNonNull(stageBean); this.stageBean = requireNonNull(stageBean);
} }


@Override
@SuppressWarnings("unchecked")
public SELF where(Predicate<? super T> predicate) {
addPredicate(predicate);
return (SELF) this;
}

<T> StageBean<T> addStageBeanOf(TableIdentifier<T> table) { <T> StageBean<T> addStageBeanOf(TableIdentifier<T> table) {
return addStageBeanHelper(new StageBean<>(table)); return addStageBeanHelper(new StageBean<>(table));
} }
Expand All @@ -48,6 +61,10 @@ <T> StageBean<T> addStageBeanOf(TableIdentifier<T> table, JoinType joinType) {
return addStageBeanHelper(new StageBean<>(table, joinType)); return addStageBeanHelper(new StageBean<>(table, joinType));
} }


<T> StageBean<T> addStageBeanOf(JoinType joinType, HasComparableOperators<T, ?> field) {
return addStageBeanHelper(new StageBean<>(joinType, field));
}

<T> StageBean<T> addStageBeanHelper(final StageBean<T> stageBean) { <T> StageBean<T> addStageBeanHelper(final StageBean<T> stageBean) {
requireNonNull(stageBean); requireNonNull(stageBean);
stageBeans.add((StageBean<?>) stageBean); stageBeans.add((StageBean<?>) stageBean);
Expand Down Expand Up @@ -95,9 +112,9 @@ void assertFieldsAreInJoinTables() throws IllegalStateException {


for (int i = 1; i < stageBeans.size(); i++) { for (int i = 1; i < stageBeans.size(); i++) {
final StageBean<?> sb = stageBeans.get(i); final StageBean<?> sb = stageBeans.get(i);
assertFieldIn(tableIdentifiers, sb.getOtherTableField(), i); assertFieldIn(tableIdentifiers, sb.getField(), i);
assertFieldIn(tableIdentifiers, sb.getFirstField(), i); assertFieldIn(tableIdentifiers, sb.getForeignFirstField(), i);
assertFieldIn(tableIdentifiers, sb.getSecondField(), i); assertFieldIn(tableIdentifiers, sb.getForeignSecondField(), i);
} }
} }


Expand Down
@@ -0,0 +1,104 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.speedment.runtime.join.internal.component.join;

import com.speedment.runtime.field.predicate.Inclusion;
import com.speedment.runtime.field.trait.HasComparableOperators;
import com.speedment.runtime.join.stage.OperatorType;
import com.speedment.runtime.join.trait.HasOnPredicates;
import static java.util.Objects.requireNonNull;
import java.util.function.BiFunction;

/**
*
* @author Per Minborg
*/
class BaseAfterJoin<T, R> implements HasOnPredicates<R> {

private final AbstractJoinBuilder<?, ?> currentBuilderStage;
private final StageBean<T> stageBean;
private final BiFunction<AbstractJoinBuilder<?, ?>, StageBean<T>, R> constructor;

BaseAfterJoin(
final AbstractJoinBuilder<?, ?> currentBuilderStage,
final StageBean<T> stageBean,
final BiFunction<AbstractJoinBuilder<?, ?>, StageBean<T>, R> constructor
) {
this.currentBuilderStage = requireNonNull(currentBuilderStage);
this.stageBean = requireNonNull(stageBean);
this.constructor = requireNonNull(constructor);
}

@Override
public R equal(HasComparableOperators<?, ?> joinedField) {
return operation(OperatorType.EQUAL, joinedField);
}

@Override
public R notEqual(HasComparableOperators<?, ?> joinedField) {
return operation(OperatorType.NOT_EQUAL, joinedField);
}

@Override
public R lessThan(HasComparableOperators<?, ?> joinedField) {
return operation(OperatorType.LESS_THAN, joinedField);
}

@Override
public R lessOrEqual(HasComparableOperators<?, ?> joinedField) {
return operation(OperatorType.LESS_OR_EQUAL, joinedField);
}

@Override
public R greaterThan(HasComparableOperators<?, ?> joinedField) {
return operation(OperatorType.GREATER_THAN, joinedField);
}

@Override
public R greaterOrEqual(HasComparableOperators<?, ?> joinedField) {
return operation(OperatorType.GREATER_OR_EQUAL, joinedField);
}

@Override
public <ENTITY> R between(HasComparableOperators<ENTITY, ?> joinedFieldFrom, HasComparableOperators<ENTITY, ?> joinedFieldTo) {
return between(joinedFieldFrom, joinedFieldTo, Inclusion.START_INCLUSIVE_END_EXCLUSIVE);
}

@Override
public <ENTITY> R between(HasComparableOperators<ENTITY, ?> joinedFieldFrom, HasComparableOperators<ENTITY, ?> joinedFieldTo, Inclusion inclusion) {
return operation(OperatorType.BETWEEN, joinedFieldFrom, joinedFieldTo, inclusion);
}

@Override
public <ENTITY> R notBetween(HasComparableOperators<ENTITY, ?> joinedFieldFrom, HasComparableOperators<ENTITY, ?> joinedFieldTo) {
return notBetween(joinedFieldFrom, joinedFieldTo, Inclusion.START_INCLUSIVE_END_EXCLUSIVE);
}

@Override
public <ENTITY> R notBetween(HasComparableOperators<ENTITY, ?> joinedFieldFrom, HasComparableOperators<ENTITY, ?> joinedFieldTo, Inclusion inclusion) {
return operation(OperatorType.NOT_BETWEEN, joinedFieldFrom, joinedFieldTo, inclusion);
}

private R operation(OperatorType operatorType, HasComparableOperators<?, ?> joinedField) {
stageBean.setOperatorType(operatorType);
stageBean.setForeignFirstField(joinedField);
return constructor.apply(currentBuilderStage, stageBean);
}

private <ENTITY> R operation(
final OperatorType operatorType,
final HasComparableOperators<ENTITY, ?> joinedFieldFrom,
final HasComparableOperators<ENTITY, ?> joinedFieldTo,
final Inclusion inclusion
) {
stageBean.setOperatorType(operatorType);
stageBean.setForeignFirstField(joinedFieldFrom);
stageBean.setForeignSecondField(joinedFieldTo);
stageBean.setForeignInclusion(inclusion);
return constructor.apply(currentBuilderStage, stageBean);
}

}

0 comments on commit 2839dd3

Please sign in to comment.