Skip to content

Commit

Permalink
Add documentation for UpdateComponent terminal operations and Column …
Browse files Browse the repository at this point in the history
…extension functions
  • Loading branch information
Thijsiez committed Nov 27, 2024
1 parent 9b4191d commit 457edd1
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 60 deletions.
158 changes: 120 additions & 38 deletions src/main/kotlin/ch/icken/query/Column.kt
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,19 @@ class Column<Columns, Type : Any?>(internal val name: String) {
private fun <Columns> eq(name: String, value: Any?): Expression<Columns> =
if (value == null) IsNull(name) else EqualTo(name, value)
/**
* TODO
* Creates an [Expression][ch.icken.query.Expression] using the '=' operator.
*
* @param value the value to be compared with
* @return a new `Expression` instance
*/
@JvmName("eq")
infix fun <Columns, Type : Any> Column<Columns, Type>.eq(value: Type) = eq<Columns>(name, value)
/**
* TODO
* Creates an [Expression][ch.icken.query.Expression] using the '=' operator when `value` is not null,
* or using 'IS NULL' when `value` is null.
*
* @param value the value to be compared with
* @return a new `Expression` instance
*/
@JvmName("eqNullable")
infix fun <Columns, Type : Any> Column<Columns, Type?>.eq(value: Type?) = eq<Columns>(name, value)
Expand All @@ -53,64 +60,95 @@ infix fun <Columns, Type : Any> Column<Columns, Type?>.eq(value: Type?) = eq<Col
private fun <Columns> neq(name: String, value: Any?): Expression<Columns> =
if (value == null) IsNotNull(name) else NotEqualTo(name, value)
/**
* TODO
* Creates an [Expression][ch.icken.query.Expression] using the '!=' operator.
*
* @param value the value to be compared with
* @return a new `Expression` instance
*/
@JvmName("neq")
infix fun <Columns, Type : Any> Column<Columns, Type>.neq(value: Type) = neq<Columns>(name, value)
/**
* TODO
* Creates an [Expression][ch.icken.query.Expression] using the '!=' operator when `value` is not null,
* or using 'IS NOT NULL' when `value` is not null.
*
* @param value the value to be compared with
* @return a new `Expression` instance
*/
@JvmName("neqNullable")
infix fun <Columns, Type : Any> Column<Columns, Type?>.neq(value: Type?) = neq<Columns>(name, value)
//endregion
//region lt
private fun <Columns> lt(name: String, value: Any): Expression<Columns> = LessThan(name, value)
/**
* TODO
* Creates an [Expression][ch.icken.query.Expression] using the '<' operator.
*
* @param value the value to be compared with
* @return a new `Expression` instance
*/
@JvmName("lt")
infix fun <Columns, Type : Any> Column<Columns, Type>.lt(value: Type) = lt<Columns>(name, value)
/**
* TODO
* Creates an [Expression][ch.icken.query.Expression] using the '<' operator.
*
* @param value the value to be compared with
* @return a new `Expression` instance
*/
@JvmName("ltNullable")
infix fun <Columns, Type : Any> Column<Columns, Type?>.lt(value: Type) = lt<Columns>(name, value)
//endregion
//region gt
private fun <Columns> gt(name: String, value: Any): Expression<Columns> = GreaterThan(name, value)
/**
* TODO
* Creates an [Expression][ch.icken.query.Expression] using the '>' operator.
*
* @param value the value to be compared with
* @return a new `Expression` instance
*/
@JvmName("gt")
infix fun <Columns, Type : Any> Column<Columns, Type>.gt(value: Type) = gt<Columns>(name, value)
/**
* TODO
* Creates an [Expression][ch.icken.query.Expression] using the '>' operator.
*
* @param value the value to be compared with
* @return a new `Expression` instance
*/
@JvmName("gtNullable")
infix fun <Columns, Type : Any> Column<Columns, Type?>.gt(value: Type) = gt<Columns>(name, value)
//endregion
//region lte
private fun <Columns> lte(name: String, value: Any): Expression<Columns> = LessThanOrEqualTo(name, value)
/**
* TODO
* Creates an [Expression][ch.icken.query.Expression] using the '<=' operator.
*
* @param value the value to be compared with
* @return a new `Expression` instance
*/
@JvmName("lte")
infix fun <Columns, Type : Any> Column<Columns, Type>.lte(value: Type) = lte<Columns>(name, value)
/**
* TODO
* Creates an [Expression][ch.icken.query.Expression] using the '<=' operator.
*
* @param value the value to be compared with
* @return a new `Expression` instance
*/
@JvmName("lteNullable")
infix fun <Columns, Type : Any> Column<Columns, Type?>.lte(value: Type) = lte<Columns>(name, value)
//endregion
//region gte
private fun <Columns> gte(name: String, value: Any): Expression<Columns> = GreaterThanOrEqualTo(name, value)
/**
* TODO
* Creates an [Expression][ch.icken.query.Expression] using the '>=' operator.
*
* @param value the value to be compared with
* @return a new `Expression` instance
*/
@JvmName("gte")
infix fun <Columns, Type : Any> Column<Columns, Type>.gte(value: Type) = gte<Columns>(name, value)
/**
* TODO
* Creates an [Expression][ch.icken.query.Expression] using the '>=' operator.
*
* @param value the value to be compared with
* @return a new `Expression` instance
*/
@JvmName("gteNullable")
infix fun <Columns, Type : Any> Column<Columns, Type?>.gte(value: Type) = gte<Columns>(name, value)
Expand All @@ -119,63 +157,83 @@ infix fun <Columns, Type : Any> Column<Columns, Type?>.gte(value: Type) = gte<Co
//region in
private fun <Columns> `in`(name: String, values: Collection<Any>): Expression<Columns> = In(name, values)
/**
* TODO
* Creates an [Expression][ch.icken.query.Expression] using the 'IN' operator.
*
* @param values the values to be compared with
* @return a new `Expression` instance
*/
@JvmName("in")
infix fun <Columns, Type : Any> Column<Columns, Type>.`in`(values: Collection<Type>) = `in`<Columns>(name, values)
/**
* TODO
* Creates an [Expression][ch.icken.query.Expression] using the 'IN' operator.
*
* @param values the values to be compared with
* @return a new `Expression` instance
*/
@JvmName("inNullable")
infix fun <Columns, Type : Any> Column<Columns, Type?>.`in`(values: Collection<Type>) = `in`<Columns>(name, values)
//endregion
//region notIn
private fun <Columns> notIn(name: String, values: Collection<Any>): Expression<Columns> = NotIn(name, values)
/**
* TODO
* Creates an [Expression][ch.icken.query.Expression] using the 'NOT IN' operator.
*
* @param values the values to be compared with
* @return a new `Expression` instance
*/
@JvmName("notIn")
infix fun <Columns, Type : Any> Column<Columns, Type>.notIn(values: Collection<Type>) = notIn<Columns>(name, values)
/**
* TODO
* Creates an [Expression][ch.icken.query.Expression] using the 'NOT IN' operator.
*
* @param values the values to be compared with
* @return a new `Expression` instance
*/
@JvmName("notInNullable")
infix fun <Columns, Type : Any> Column<Columns, Type?>.notIn(values: Collection<Type>) = notIn<Columns>(name, values)
//endregion

//region like
private fun <Columns> like(name: String, expression: String?): Expression<Columns> =
if (expression == null) IsNull(name) else Like(name, expression)
private fun <Columns> like(name: String, pattern: String?): Expression<Columns> =
if (pattern == null) IsNull(name) else Like(name, pattern)
/**
* TODO
* Creates an [Expression][ch.icken.query.Expression] using the 'LIKE' operator.
*
* @param pattern the pattern to be matched
* @return a new `Expression` instance
*/
@JvmName("like")
infix fun <Columns> Column<Columns, String>.like(expression: String) = like<Columns>(name, expression)
infix fun <Columns> Column<Columns, String>.like(pattern: String) = like<Columns>(name, pattern)
/**
* TODO
* Creates an [Expression][ch.icken.query.Expression] using the 'LIKE' operator when `pattern` is not null,
* or using 'IS NULL' when `pattern` is null.
*
* @param pattern the pattern to be matched
* @return a new `Expression` instance
*/
@JvmName("likeNullable")
infix fun <Columns> Column<Columns, String?>.like(expression: String?) = like<Columns>(name, expression)
//TODO startsWith
//TODO contains
//TODO endsWith
infix fun <Columns> Column<Columns, String?>.like(pattern: String?) = like<Columns>(name, pattern)
//endregion
//region notLike
private fun <Columns> notLike(name: String, expression: String?): Expression<Columns> =
if (expression == null) IsNotNull(name) else NotLike(name, expression)
private fun <Columns> notLike(name: String, pattern: String?): Expression<Columns> =
if (pattern == null) IsNotNull(name) else NotLike(name, pattern)
/**
* TODO
* Creates an [Expression][ch.icken.query.Expression] using the 'NOT LIKE' operator.
*
* @param pattern the pattern to be matched
* @return a new `Expression` instance
*/
@JvmName("notLike")
infix fun <Columns> Column<Columns, String>.notLike(expression: String) = notLike<Columns>(name, expression)
infix fun <Columns> Column<Columns, String>.notLike(pattern: String) = notLike<Columns>(name, pattern)
/**
* TODO
* Creates an [Expression][ch.icken.query.Expression] using the 'NOT LIKE' operator when `pattern` is not null,
* or using 'IS NOT NULL' when `pattern` is not null.
*
* @param pattern the pattern to be matched
* @return a new `Expression` instance
*/
@JvmName("notLikeNullable")
infix fun <Columns> Column<Columns, String?>.notLike(expression: String?) = notLike<Columns>(name, expression)
//TODO notStartsWith
//TODO notContains
//TODO notEndsWith
infix fun <Columns> Column<Columns, String?>.notLike(pattern: String?) = notLike<Columns>(name, pattern)
//endregion

//region between
Expand All @@ -186,13 +244,25 @@ private fun <Columns> between(name: String, min: Any?, maxIncl: Any?): Expressio
else -> IsNull(name)
}
/**
* TODO
* Creates an [Expression][ch.icken.query.Expression] using the 'BETWEEN' operator.
*
* @param min the minimum value to be compared with
* @param maxIncl the maximum (inclusive) value to be compared with
* @return a new `Expression` instance
*/
@JvmName("between")
fun <Columns, Type : Any> Column<Columns, Type>.between(min: Type, maxIncl: Type) =
between<Columns>(name, min, maxIncl)
/**
* TODO
* Creates an [Expression][ch.icken.query.Expression] using exactly one of the following:
* - the 'BETWEEN' operator when both `min` and `maxIncl` are not null
* - the '>=' operator when `min` is not null and `maxIncl` is null
* - the '<=' operator when `min` is null and `maxIncl` is not null
* - 'IS NULL' when both `min` and `maxIncl` are null
*
* @param min the minimum value to be compared with
* @param maxIncl the maximum (inclusive) value to be compared with
* @return a new `Expression` instance
*/
@JvmName("betweenNullable")
fun <Columns, Type : Any> Column<Columns, Type?>.between(min: Type?, maxIncl: Type?) =
Expand All @@ -206,13 +276,25 @@ private fun <Columns> notBetween(name: String, min: Any?, maxIncl: Any?): Expres
else -> IsNotNull(name)
}
/**
* TODO
* Creates an [Expression][ch.icken.query.Expression] using the 'NOT BETWEEN' operator.
*
* @param min the minimum value to be compared with
* @param maxIncl the maximum (inclusive) value to be compared with
* @return a new `Expression` instance
*/
@JvmName("notBetween")
fun <Columns, Type : Any> Column<Columns, Type>.notBetween(min: Type, maxIncl: Type) =
notBetween<Columns>(name, min, maxIncl)
/**
* TODO
* Creates an [Expression][ch.icken.query.Expression] using exactly one of the following:
* - the 'NOT BETWEEN' operator when both `min` and `maxIncl` are not null
* - the '<' operator when `min` is not null and `maxIncl` is null
* - the '>' operator when `min` is null and `maxIncl` is not null
* - 'IS NOT NULL' when both `min` and `maxIncl` are null
*
* @param min the minimum value to be compared with
* @param maxIncl the maximum (inclusive) value to be compared with
* @return a new `Expression` instance
*/
@JvmName("notBetweenNullable")
fun <Columns, Type : Any> Column<Columns, Type?>.notBetween(min: Type?, maxIncl: Type?) =
Expand Down
31 changes: 14 additions & 17 deletions src/main/kotlin/ch/icken/query/Component.kt
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,8 @@ sealed class Component<Entity : PanacheEntityBase, Id : Any, Columns> private co
protected val expression: Expression<Columns>
) : Component<Entity, Id, Columns>(companion) {
//region Chaining operations
/**
* TODO
*/
fun and(expression: Expression<Columns>): QueryComponent<Entity, Id, Columns> =
LogicalQueryComponent.AndQueryComponent(companion, this, expression)
/**
* TODO
*/
fun or(expression: Expression<Columns>): QueryComponent<Entity, Id, Columns> =
LogicalQueryComponent.OrQueryComponent(companion, this, expression)
//endregion
Expand Down Expand Up @@ -223,16 +217,20 @@ sealed class Component<Entity : PanacheEntityBase, Id : Any, Columns> private co
private val setters: Array<out Columns.() -> SetterExpression>
) : UpdateComponent<Entity, Id, Columns>(companion) {
//region Chaining operations
/**
* TODO
*/
fun where(expression: Expression<Columns>): LogicalUpdateComponent<Entity, Id, Columns> =
LogicalUpdateComponent.WhereUpdateComponent(companion, this, expression)
//endregion

//region Terminal operations
/**
* TODO
* Updates all entities of this type.
*
* WARNING: this function updates ALL entities without a WHERE clause
*
* WARNING: this function requires a transaction to be active.
*
* @return the number of entities updated
* @see io.quarkus.hibernate.orm.panache.kotlin.PanacheCompanionBase.update
*/
fun executeWithoutWhere() = withCompiled { companion.update(component, parameters) }
//endregion
Expand Down Expand Up @@ -263,21 +261,20 @@ sealed class Component<Entity : PanacheEntityBase, Id : Any, Columns> private co
private val expression: Expression<Columns>
) : UpdateComponent<Entity, Id, Columns>(companion) {
//region Chaining operations
/**
* TODO
*/
fun and(expression: Expression<Columns>): LogicalUpdateComponent<Entity, Id, Columns> =
AndUpdateComponent(companion, this, expression)
/**
* TODO
*/
fun or(expression: Expression<Columns>): LogicalUpdateComponent<Entity, Id, Columns> =
OrUpdateComponent(companion, this, expression)
//endregion

//region Terminal operations
/**
* TODO
* Updates all entities matching the preceding query
*
* WARNING: this function requires a transaction to be active
*
* @return the number of entities updated
* @see io.quarkus.hibernate.orm.panache.kotlin.PanacheCompanionBase.update
*/
fun execute() = withCompiled { companion.update(component, parameters) }
//endregion
Expand Down
9 changes: 4 additions & 5 deletions src/main/kotlin/ch/icken/query/Expression.kt
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,10 @@ sealed class Expression<Columns> {
class NotIn<Columns> internal constructor(key: String, values: Collection<Any>) :
BooleanValueExpression<Columns>(key, "NOT IN", values)

class Like<Columns> internal constructor(key: String, expression: String) :
BooleanValueExpression<Columns>(key, "LIKE", expression)
class NotLike<Columns> internal constructor(key: String, expression: String) :
BooleanValueExpression<Columns>(key, "NOT LIKE", expression)

class Like<Columns> internal constructor(key: String, pattern: String) :
BooleanValueExpression<Columns>(key, "LIKE", pattern)
class NotLike<Columns> internal constructor(key: String, pattern: String) :
BooleanValueExpression<Columns>(key, "NOT LIKE", pattern)
}

sealed class BetweenExpression<Columns> private constructor(
Expand Down

0 comments on commit 457edd1

Please sign in to comment.