Skip to content

Commit

Permalink
feat: Apply suggested changes
Browse files Browse the repository at this point in the history
- Inherit from Function instead of Op
- Make both functions accept varargs
- Don't use an infix function for the expression builder

Signed-off-by: solonovamax <[email protected]>
  • Loading branch information
solonovamax committed Jan 9, 2025
1 parent 6bd5445 commit 8bd8a2a
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 44 deletions.
38 changes: 38 additions & 0 deletions exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/Function.kt
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,44 @@ class Random(
}
}

/**
* Represents an SQL operator that returns the greatest (maximum, largest
* value) of [expr1], [expr2], and [others].
*
* **Note:** The semantics of this function when applied to null values
* or values of multiple types depends on the vendor. Please check the
* documentation for your respective database.
*/
class Greatest<T>(
val expr1: Expression<in T>,
val expr2: Expression<in T>,
columnType: IColumnType<T & Any>,
vararg val others: Expression<in T>
) : Function<T>(columnType) {
override fun toQueryBuilder(queryBuilder: QueryBuilder): Unit = queryBuilder {
currentDialect.functionProvider.greatest(queryBuilder, expr1, expr2, *others)
}
}

/**
* Represents an SQL operator that returns the least (minimum, smallest
* value) of [expr1], [expr2], and [others].
*
* **Note:** The semantics of this function when applied to null values
* or values of multiple types depends on the vendor. Please check the
* documentation for your respective database.
*/
class Least<T>(
val expr1: Expression<in T>,
val expr2: Expression<in T>,
columnType: IColumnType<T & Any>,
vararg val others: Expression<in T>
) : Function<T>(columnType) {
override fun toQueryBuilder(queryBuilder: QueryBuilder): Unit = queryBuilder {
currentDialect.functionProvider.least(queryBuilder, expr1, expr2, *others)
}
}

// String Functions

/**
Expand Down
24 changes: 0 additions & 24 deletions exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/Op.kt
Original file line number Diff line number Diff line change
Expand Up @@ -299,30 +299,6 @@ class IsDistinctFromOp(
}
}

/**
* Represents an SQL operator that returns the greatest (maximum) of [expr1] and [expr2].
*/
class GreatestOp<T, S : T>(
val expr1: Expression<T>,
val expr2: Expression<S>,
) : Op<T>() {
override fun toQueryBuilder(queryBuilder: QueryBuilder): Unit = queryBuilder {
currentDialect.functionProvider.greatest(expr1, expr2, queryBuilder)
}
}

/**
* Represents an SQL operator that returns the least (minimum) of [expr1] and [expr2].
*/
class LeastOp<T, S : T>(
val expr1: Expression<T>,
val expr2: Expression<S>,
) : Op<T>() {
override fun toQueryBuilder(queryBuilder: QueryBuilder): Unit = queryBuilder {
currentDialect.functionProvider.least(expr1, expr2, queryBuilder)
}
}

// Mathematical Operators

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -580,24 +580,57 @@ interface ISqlExpressionBuilder {
): IsDistinctFromOp = IsDistinctFromOp(this, other)

/**
* The greatest (maximum) of this expression and [t].
* The greatest (maximum, largest value) of [expr1], [expr2], and [others].
*
* **Note:** The semantics of this function when applied to null values
* or values of multiple types depends on the vendor. Please check the
* documentation for your respective database.
*/
infix fun <T> ExpressionWithColumnType<T>.greatest(t: T): GreatestOp<T, T> = GreatestOp(this, wrap(t))
fun <T> greatest(
expr1: ExpressionWithColumnType<T>,
expr2: Expression<in T>,
vararg others: Expression<in T>,
): Greatest<T> = Greatest(expr1, expr2, expr1.columnType, *others)

/**
* The greatest (maximum) of this expression and [other].
* The greatest (maximum, largest value) of [literal], [expr1], and
* [others].
*
* **Note:** The semantics of this function when applied to null values
* or values of multiple types depends on the vendor. Please check the
* documentation for your respective database.
*/
infix fun <T, S : T> ExpressionWithColumnType<T>.greatest(other: Expression<S>): GreatestOp<T, S> = GreatestOp(this, other)
fun <T> greatest(
literal: T,
expr1: ExpressionWithColumnType<T>,
vararg others: Expression<in T>,
): Greatest<T> = Greatest(expr1.wrap(literal), expr1, expr1.columnType, *others)

/**
* The least (minimum) of this expression and [t].
* The least (minimum, smallest value) of [expr1], [expr2], and [others].
*
* **Note:** The semantics of this function when applied to null values
* or values of multiple types depends on the vendor. Please check the
* documentation for your respective database.
*/
infix fun <T> ExpressionWithColumnType<T>.least(t: T): LeastOp<T, T> = LeastOp(this, wrap(t))
fun <T> least(
expr1: ExpressionWithColumnType<T>,
expr2: Expression<in T>,
vararg others: Expression<in T>,
): Least<T> = Least(expr1, expr2, expr1.columnType, *others)

/**
* The least (minimum) of this expression and [other].
* The least (minimum, smallest value) of [literal], [expr1], and [others].
*
* **Note:** The semantics of this function when applied to null values
* or values of multiple types depends on the vendor. Please check the
* documentation for your respective database.
*/
infix fun <T, S : T> ExpressionWithColumnType<T>.least(other: Expression<S>): LeastOp<T, S> = LeastOp(this, other)
fun <T> least(
literal: T,
expr1: ExpressionWithColumnType<T>,
vararg others: Expression<in T>,
): Least<T> = Least(expr1.wrap(literal), expr1, expr1.columnType, *others)

// Mathematical Operators

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,23 +37,25 @@ abstract class FunctionProvider {
/**
* SQL function that returns the greatest (maximum) of two values.
*
* @param expr1 The first value.
* @param expr2 The second value.
* @param queryBuilder Query builder to append the SQL function to.
* @param expr The expressions to compare.
*/
open fun <T, S : T> greatest(expr1: Expression<T>, expr2: Expression<S>, queryBuilder: QueryBuilder): Unit = queryBuilder {
append("GREATEST(", expr1, ", ", expr2, ")")
open fun <T> greatest(queryBuilder: QueryBuilder, vararg expr: Expression<in T>): Unit = queryBuilder {
append("GREATEST(")
expr.appendTo { +it }
append(")")
}

/**
* SQL function that returns the least (minimum) of two values.
*
* @param expr1 The first value.
* @param expr2 The second value.
* @param queryBuilder Query builder to append the SQL function to.
* @param expr The expressions to compare.
*/
open fun <T, S : T> least(expr1: Expression<T>, expr2: Expression<S>, queryBuilder: QueryBuilder): Unit = queryBuilder {
append("LEAST(", expr1, ", ", expr2, ")")
open fun <T> least(queryBuilder: QueryBuilder, vararg expr: Expression<in T>): Unit = queryBuilder {
append("LEAST(")
expr.appendTo { +it }
append(")")
}

// String functions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,16 @@ internal object SQLiteDataTypeProvider : DataTypeProvider() {

@Suppress("TooManyFunctions")
internal object SQLiteFunctionProvider : FunctionProvider() {
override fun <T, S : T> greatest(expr1: Expression<T>, expr2: Expression<S>, queryBuilder: QueryBuilder) = queryBuilder {
append("MAX(", expr1, ", ", expr2, ")")
override fun <T> greatest(queryBuilder: QueryBuilder, vararg expr: Expression<in T>) = queryBuilder {
append("MAX(")
expr.appendTo { +it }
append(")")
}

override fun <T, S : T> least(expr1: Expression<T>, expr2: Expression<S>, queryBuilder: QueryBuilder) = queryBuilder {
append("MIN(", expr1, ", ", expr2, ")")
override fun <T> least(queryBuilder: QueryBuilder, vararg expr: Expression<in T>) = queryBuilder {
append("MIN(")
expr.appendTo { +it }
append(")")
}

override fun <T : String?> charLength(expr: Expression<T>, queryBuilder: QueryBuilder) = queryBuilder {
Expand Down

0 comments on commit 8bd8a2a

Please sign in to comment.