Skip to content

Commit

Permalink
New join syntax for Kotlin
Browse files Browse the repository at this point in the history
  • Loading branch information
jeffgbutler committed Aug 19, 2024
1 parent 3cd872b commit f888b83
Show file tree
Hide file tree
Showing 5 changed files with 192 additions and 115 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
*/
package org.mybatis.dynamic.sql.select.render;

import static org.mybatis.dynamic.sql.util.StringUtilities.spaceBefore;

import java.util.Objects;
import java.util.stream.Collectors;

Expand All @@ -26,6 +24,7 @@
import org.mybatis.dynamic.sql.select.join.JoinSpecification;
import org.mybatis.dynamic.sql.util.FragmentAndParameters;
import org.mybatis.dynamic.sql.util.FragmentCollector;
import org.mybatis.dynamic.sql.util.Messages;

public class JoinRenderer {
private final JoinModel joinModel;
Expand All @@ -46,22 +45,17 @@ public FragmentAndParameters render() {
}

private FragmentAndParameters renderJoinSpecification(JoinSpecification joinSpecification) {
FragmentAndParameters renderedTable = joinSpecification.table().accept(tableExpressionRenderer);
FragmentAndParameters renderedJoinSpecification = JoinSpecificationRenderer
FragmentCollector fc = new FragmentCollector();
fc.add(FragmentAndParameters.fromFragment(joinSpecification.joinType().type()));
fc.add(joinSpecification.table().accept(tableExpressionRenderer));
fc.add(JoinSpecificationRenderer
.withJoinSpecification(joinSpecification)
.withRenderingContext(renderingContext)
.build()
.render()
.orElseThrow(() -> new InvalidSqlException("Join Specifications Must Render")); // TODO

String fragment = joinSpecification.joinType().type()
+ spaceBefore(renderedTable.fragment())
+ spaceBefore(renderedJoinSpecification.fragment());
.orElseThrow(() -> new InvalidSqlException(Messages.getString("ERROR.46")))); //$NON-NLS-1$

return FragmentAndParameters.withFragment(fragment)
.withParameters(renderedTable.parameters())
.withParameters(renderedJoinSpecification.parameters())
.build();
return fc.toFragmentAndParameters(Collectors.joining(" ")); //$NON-NLS-1$
}

public static Builder withJoinModel(JoinModel joinModel) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,11 @@ class JoinCollector {
internal fun initialCriterion() = invalidIfNull(criteriaCollector.initialCriterion, "ERROR.22") //$NON-NLS-1$
internal fun subCriteria() = criteriaCollector.subCriteria

fun on (receiver: GroupingCriteriaReceiver) {
assertNull(criteriaCollector.initialCriterion, "ERROR.45") //$NON-NLS-1$
criteriaCollector.apply(receiver)
}

@Deprecated("Please replace with the \"on\" lambda expression", level = DeprecationLevel.WARNING)
fun <T> on(leftColumn: BindableColumn<T>): RightColumnCollector<T> = RightColumnCollector {
assertNull(criteriaCollector.initialCriterion, "ERROR.45") //$NON-NLS-1$
criteriaCollector.apply { leftColumn.invoke(it) }
}

@Deprecated("Please move the \"and\" expression into an \"on\" lambda", level = DeprecationLevel.WARNING)
fun <T> and(leftColumn: BindableColumn<T>): RightColumnCollector<T> = RightColumnCollector {
criteriaCollector.and { leftColumn.invoke(it) }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,19 @@ abstract class KotlinBaseBuilder<D : AbstractWhereStarter<*,*>> {
@Suppress("TooManyFunctions")
abstract class KotlinBaseJoiningBuilder<D : AbstractQueryExpressionDSL<*, *>> : KotlinBaseBuilder<D>() {

@Deprecated("Please use the new form with the \"on\" keyword outside the lambda")
fun join(table: SqlTable, joinCriteria: JoinReceiver): Unit =
applyToDsl(joinCriteria) { jc ->
join(table, jc.initialCriterion(), jc.subCriteria())
}

@Deprecated("Please use the new form with the \"on\" keyword outside the lambda")
fun join(table: SqlTable, alias: String, joinCriteria: JoinReceiver): Unit =
applyToDsl(joinCriteria) { jc ->
join(table, alias, jc.initialCriterion(), jc.subCriteria())
}

@Deprecated("Please use the new form with the \"on\" keyword outside the lambda")
fun join(
subQuery: KotlinQualifiedSubQueryBuilder.() -> Unit,
joinCriteria: JoinReceiver
Expand All @@ -82,16 +85,36 @@ abstract class KotlinBaseJoiningBuilder<D : AbstractQueryExpressionDSL<*, *>> :
join(sq, sq.correlationName, jc.initialCriterion(), jc.subCriteria())
}

fun join(table: SqlTable): JoinCriteriaGatherer =
JoinCriteriaGatherer {
getDsl().join(table, it.initialCriterion, it.subCriteria)
}

fun join(table: SqlTable, alias: String): JoinCriteriaGatherer =
JoinCriteriaGatherer {
getDsl().join(table, alias, it.initialCriterion, it.subCriteria)
}

fun join(
subQuery: KotlinQualifiedSubQueryBuilder.() -> Unit): JoinCriteriaGatherer =
JoinCriteriaGatherer {
val sq = KotlinQualifiedSubQueryBuilder().apply(subQuery)
getDsl().join(sq, sq.correlationName, it.initialCriterion, it.subCriteria)
}

@Deprecated("Please use the new form with the \"on\" keyword outside the lambda")
fun fullJoin(table: SqlTable, joinCriteria: JoinReceiver): Unit =
applyToDsl(joinCriteria) { jc ->
fullJoin(table, jc.initialCriterion(), jc.subCriteria())
}

@Deprecated("Please use the new form with the \"on\" keyword outside the lambda")
fun fullJoin(table: SqlTable, alias: String, joinCriteria: JoinReceiver): Unit =
applyToDsl(joinCriteria) { jc ->
fullJoin(table, alias, jc.initialCriterion(), jc.subCriteria())
}

@Deprecated("Please use the new form with the \"on\" keyword outside the lambda")
fun fullJoin(
subQuery: KotlinQualifiedSubQueryBuilder.() -> Unit,
joinCriteria: JoinReceiver
Expand All @@ -100,16 +123,36 @@ abstract class KotlinBaseJoiningBuilder<D : AbstractQueryExpressionDSL<*, *>> :
fullJoin(sq, sq.correlationName, jc.initialCriterion(), jc.subCriteria())
}

fun fullJoin(table: SqlTable): JoinCriteriaGatherer =
JoinCriteriaGatherer {
getDsl().fullJoin(table, it.initialCriterion, it.subCriteria)
}

fun fullJoin(table: SqlTable, alias: String): JoinCriteriaGatherer =
JoinCriteriaGatherer {
getDsl().fullJoin(table, alias, it.initialCriterion, it.subCriteria)
}

fun fullJoin(
subQuery: KotlinQualifiedSubQueryBuilder.() -> Unit): JoinCriteriaGatherer =
JoinCriteriaGatherer {
val sq = KotlinQualifiedSubQueryBuilder().apply(subQuery)
getDsl().fullJoin(sq, sq.correlationName, it.initialCriterion, it.subCriteria)
}

@Deprecated("Please use the new form with the \"on\" keyword outside the lambda")
fun leftJoin(table: SqlTable, joinCriteria: JoinReceiver): Unit =
applyToDsl(joinCriteria) { jc ->
leftJoin(table, jc.initialCriterion(), jc.subCriteria())
}

@Deprecated("Please use the new form with the \"on\" keyword outside the lambda")
fun leftJoin(table: SqlTable, alias: String, joinCriteria: JoinReceiver): Unit =
applyToDsl(joinCriteria) { jc ->
leftJoin(table, alias, jc.initialCriterion(), jc.subCriteria())
}

@Deprecated("Please use the new form with the \"on\" keyword outside the lambda")
fun leftJoin(
subQuery: KotlinQualifiedSubQueryBuilder.() -> Unit,
joinCriteria: JoinReceiver
Expand All @@ -118,16 +161,36 @@ abstract class KotlinBaseJoiningBuilder<D : AbstractQueryExpressionDSL<*, *>> :
leftJoin(sq, sq.correlationName, jc.initialCriterion(), jc.subCriteria())
}

fun leftJoin(table: SqlTable): JoinCriteriaGatherer =
JoinCriteriaGatherer {
getDsl().leftJoin(table, it.initialCriterion, it.subCriteria)
}

fun leftJoin(table: SqlTable, alias: String): JoinCriteriaGatherer =
JoinCriteriaGatherer {
getDsl().leftJoin(table, alias, it.initialCriterion, it.subCriteria)
}

fun leftJoin(
subQuery: KotlinQualifiedSubQueryBuilder.() -> Unit): JoinCriteriaGatherer =
JoinCriteriaGatherer {
val sq = KotlinQualifiedSubQueryBuilder().apply(subQuery)
getDsl().leftJoin(sq, sq.correlationName, it.initialCriterion, it.subCriteria)
}

@Deprecated("Please use the new form with the \"on\" keyword outside the lambda")
fun rightJoin(table: SqlTable, joinCriteria: JoinReceiver): Unit =
applyToDsl(joinCriteria) { jc ->
rightJoin(table, jc.initialCriterion(), jc.subCriteria())
}

@Deprecated("Please use the new form with the \"on\" keyword outside the lambda")
fun rightJoin(table: SqlTable, alias: String, joinCriteria: JoinReceiver): Unit =
applyToDsl(joinCriteria) { jc ->
rightJoin(table, alias, jc.initialCriterion(), jc.subCriteria())
}

@Deprecated("Please use the new form with the \"on\" keyword outside the lambda")
fun rightJoin(
subQuery: KotlinQualifiedSubQueryBuilder.() -> Unit,
joinCriteria: JoinReceiver
Expand All @@ -136,6 +199,23 @@ abstract class KotlinBaseJoiningBuilder<D : AbstractQueryExpressionDSL<*, *>> :
rightJoin(sq, sq.correlationName, jc.initialCriterion(), jc.subCriteria())
}

fun rightJoin(table: SqlTable): JoinCriteriaGatherer =
JoinCriteriaGatherer {
getDsl().rightJoin(table, it.initialCriterion, it.subCriteria)
}

fun rightJoin(table: SqlTable, alias: String): JoinCriteriaGatherer =
JoinCriteriaGatherer {
getDsl().rightJoin(table, alias, it.initialCriterion, it.subCriteria)
}

fun rightJoin(
subQuery: KotlinQualifiedSubQueryBuilder.() -> Unit): JoinCriteriaGatherer =
JoinCriteriaGatherer {
val sq = KotlinQualifiedSubQueryBuilder().apply(subQuery)
getDsl().rightJoin(sq, sq.correlationName, it.initialCriterion, it.subCriteria)
}

private fun applyToDsl(joinCriteria: JoinReceiver, applyJoin: D.(JoinCollector) -> Unit) {
getDsl().applyJoin(JoinCollector().apply(joinCriteria))
}
Expand All @@ -148,3 +228,11 @@ abstract class KotlinBaseJoiningBuilder<D : AbstractQueryExpressionDSL<*, *>> :
getDsl().applyJoin(KotlinQualifiedSubQueryBuilder().apply(subQuery), JoinCollector().apply(joinCriteria))
}
}

class JoinCriteriaGatherer(private val consumer: (GroupingCriteriaCollector) -> Unit) {
infix fun on (joinCriteria: GroupingCriteriaReceiver): Unit =
with(GroupingCriteriaCollector().apply(joinCriteria)) {
assertTrue(initialCriterion != null || subCriteria.isNotEmpty(), "ERROR.22") //$NON-NLS-1$
consumer.invoke(this)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,5 @@ ERROR.42=You cannot call `else` in a Kotlin case expression more than once
ERROR.43=A Kotlin cast expression must have one, and only one, `as` element
ERROR.44={0} conditions must contain at least one value
ERROR.45=You cannot call "on" in a Kotlin join expression more than once
ERROR.46=At least one join criterion must render
INTERNAL.ERROR=Internal Error {0}
Loading

0 comments on commit f888b83

Please sign in to comment.