Skip to content
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

DOPE-228: added Between and NotBetween comparison and extension functions #36

Merged
merged 5 commits into from
Jul 10, 2024
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
martinagallati-ergon marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package ch.ergon.dope.resolvable.expression.unaliased.type.relational

import ch.ergon.dope.DopeQuery
import ch.ergon.dope.resolvable.expression.TypeExpression
import ch.ergon.dope.validtype.BooleanType
import ch.ergon.dope.validtype.ComparableType

class BetweenExpression<T : ComparableType>(
private val expression: TypeExpression<T>,
private val start: TypeExpression<T>,
private val end: TypeExpression<T>,
) : TypeExpression<BooleanType> {
override fun toDopeQuery(): DopeQuery {
val expressionDopeQuery = expression.toDopeQuery()
val startDopeQuery = start.toDopeQuery()
val endDopeQuery = end.toDopeQuery()
return DopeQuery(
queryString = "${expressionDopeQuery.queryString} BETWEEN ${startDopeQuery.queryString} AND ${endDopeQuery.queryString}",
parameters = expressionDopeQuery.parameters + startDopeQuery.parameters + endDopeQuery.parameters,
)
}
}

fun <T : ComparableType> TypeExpression<T>.between(start: TypeExpression<T>, end: TypeExpression<T>) =
BetweenExpression(this, start, end)
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package ch.ergon.dope.resolvable.expression.unaliased.type.relational

import ch.ergon.dope.DopeQuery
import ch.ergon.dope.resolvable.expression.TypeExpression
import ch.ergon.dope.validtype.BooleanType
import ch.ergon.dope.validtype.ComparableType

class NotBetweenExpression<T : ComparableType>(
private val expression: TypeExpression<T>,
private val start: TypeExpression<T>,
private val end: TypeExpression<T>,
) : TypeExpression<BooleanType> {
override fun toDopeQuery(): DopeQuery {
val expressionDopeQuery = expression.toDopeQuery()
val startDopeQuery = start.toDopeQuery()
val endDopeQuery = end.toDopeQuery()
return DopeQuery(
queryString = "${expressionDopeQuery.queryString} NOT BETWEEN ${startDopeQuery.queryString} AND ${endDopeQuery.queryString}",
parameters = expressionDopeQuery.parameters + startDopeQuery.parameters + endDopeQuery.parameters,
)
}
}

fun <T : ComparableType> TypeExpression<T>.notBetween(start: TypeExpression<T>, end: TypeExpression<T>) =
NotBetweenExpression(this, start, end)
martinagallati-ergon marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package ch.ergon.dope.operators.comparison

import ch.ergon.dope.DopeQuery
import ch.ergon.dope.helper.someNumberField
import ch.ergon.dope.resolvable.expression.unaliased.type.ParameterManager
import ch.ergon.dope.resolvable.expression.unaliased.type.asParameter
import ch.ergon.dope.resolvable.expression.unaliased.type.relational.BetweenExpression
import ch.ergon.dope.resolvable.expression.unaliased.type.relational.between
import ch.ergon.dope.resolvable.expression.unaliased.type.toDopeType
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test

class BetweenExpressionTest {
@BeforeEach
fun reset() {
ParameterManager.resetCounter()
}

@Test
fun `should support BETWEEN expression`() {
val expected = DopeQuery(
queryString = "`numberField` BETWEEN 1 AND 10",
emptyMap(),
)
val underTest = BetweenExpression(someNumberField(), 1.toDopeType(), 10.toDopeType())

val actual = underTest.toDopeQuery()

assertEquals(expected, actual)
}

@Test
fun `should support BETWEEN expression with parameter`() {
val parameterValue = 5
val expected = DopeQuery(
queryString = "$1 BETWEEN 1 AND 10",
mapOf("$1" to parameterValue),
)
val underTest = BetweenExpression(parameterValue.asParameter(), 1.toDopeType(), 10.toDopeType())

val actual = underTest.toDopeQuery()

assertEquals(expected, actual)
}

@Test
fun `should support BETWEEN expression with first and second parameter`() {
val parameterValue = 5
val parameterValue2 = 1
val expected = DopeQuery(
queryString = "$1 BETWEEN $2 AND 10",
mapOf("$1" to parameterValue, "$2" to parameterValue2),
)
val underTest = BetweenExpression(parameterValue.asParameter(), parameterValue2.asParameter(), 10.toDopeType())

val actual = underTest.toDopeQuery()

assertEquals(expected, actual)
}

@Test
fun `should support BETWEEN expression with all parameters`() {
val parameterValue = 5
val parameterValue2 = 1
val parameterValue3 = 10
val expected = DopeQuery(
queryString = "$1 BETWEEN $2 AND $3",
mapOf("$1" to parameterValue, "$2" to parameterValue2, "$3" to parameterValue3),
)
val underTest = BetweenExpression(parameterValue.asParameter(), parameterValue2.asParameter(), parameterValue3.asParameter())

val actual = underTest.toDopeQuery()

assertEquals(expected, actual)
}

@Test
fun `should support BETWEEN extension`() {
val expression = someNumberField()
val start = 1.toDopeType()
val end = 10.toDopeType()
val expected = BetweenExpression(expression, start, end)

val actual = expression.between(start, end)

assertEquals(expected.toDopeQuery(), actual.toDopeQuery())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package ch.ergon.dope.operators.comparison

import ch.ergon.dope.DopeQuery
import ch.ergon.dope.helper.someNumberField
import ch.ergon.dope.resolvable.expression.unaliased.type.ParameterManager
import ch.ergon.dope.resolvable.expression.unaliased.type.asParameter
import ch.ergon.dope.resolvable.expression.unaliased.type.relational.NotBetweenExpression
import ch.ergon.dope.resolvable.expression.unaliased.type.relational.notBetween
import ch.ergon.dope.resolvable.expression.unaliased.type.toDopeType
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test

class NotBetweenExpressionTest {
@BeforeEach
fun reset() {
ParameterManager.resetCounter()
}

@Test
fun `should support NOT BETWEEN expression`() {
val expected = DopeQuery(
queryString = "`numberField` NOT BETWEEN 1 AND 10",
emptyMap(),
)
val underTest = NotBetweenExpression(someNumberField(), 1.toDopeType(), 10.toDopeType())

val actual = underTest.toDopeQuery()

assertEquals(expected, actual)
}

@Test
fun `should support NOT BETWEEN expression with parameter`() {
val parameterValue = 5
val expected = DopeQuery(
queryString = "$1 NOT BETWEEN 1 AND 10",
mapOf("$1" to parameterValue),
)
val underTest = NotBetweenExpression(parameterValue.asParameter(), 1.toDopeType(), 10.toDopeType())

val actual = underTest.toDopeQuery()

assertEquals(expected, actual)
}

@Test
fun `should support NOT BETWEEN expression with first and second parameter`() {
val parameterValue = 5
val parameterValue2 = 1
val expected = DopeQuery(
queryString = "$1 NOT BETWEEN $2 AND 10",
mapOf("$1" to parameterValue, "$2" to parameterValue2),
)
val underTest = NotBetweenExpression(parameterValue.asParameter(), parameterValue2.asParameter(), 10.toDopeType())

val actual = underTest.toDopeQuery()

assertEquals(expected, actual)
}

@Test
fun `should support NOT BETWEEN expression with all parameters`() {
val parameterValue = 5
val parameterValue2 = 1
val parameterValue3 = 10
val expected = DopeQuery(
queryString = "$1 NOT BETWEEN $2 AND $3",
mapOf("$1" to parameterValue, "$2" to parameterValue2, "$3" to parameterValue3),
)
val underTest = NotBetweenExpression(parameterValue.asParameter(), parameterValue2.asParameter(), parameterValue3.asParameter())

val actual = underTest.toDopeQuery()

assertEquals(expected, actual)
}

@Test
fun `should support NOT BETWEEN extension`() {
val expression = someNumberField()
val start = 1.toDopeType()
val end = 10.toDopeType()
val expected = NotBetweenExpression(expression, start, end)

val actual = expression.notBetween(start, end)

assertEquals(expected.toDopeQuery(), actual.toDopeQuery())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package ch.ergon.dope.extension.type.relational

import ch.ergon.dope.resolvable.expression.TypeExpression
import ch.ergon.dope.resolvable.expression.unaliased.type.relational.BetweenExpression
import ch.ergon.dope.resolvable.expression.unaliased.type.relational.between
import ch.ergon.dope.toDopeType
import ch.ergon.dope.validtype.NumberType
import ch.ergon.dope.validtype.StringType
import com.schwarz.crystalapi.schema.CMField

@JvmName("betweenNumber")
fun CMField<out Number>.between(start: CMField<out Number>, end: CMField<out Number>): BetweenExpression<NumberType> =
toDopeType().between(start.toDopeType(), end.toDopeType())

@JvmName("betweenNumber")
fun CMField<out Number>.between(start: CMField<out Number>, end: TypeExpression<NumberType>): BetweenExpression<NumberType> =
toDopeType().between(start.toDopeType(), end)

@JvmName("betweenNumber")
fun CMField<out Number>.between(start: TypeExpression<NumberType>, end: CMField<out Number>): BetweenExpression<NumberType> =
toDopeType().between(start, end.toDopeType())

@JvmName("betweenNumber")
fun CMField<out Number>.between(start: TypeExpression<NumberType>, end: TypeExpression<NumberType>): BetweenExpression<NumberType> =
toDopeType().between(start, end)

@JvmName("betweenNumber")
fun TypeExpression<NumberType>.between(start: CMField<out Number>, end: CMField<out Number>): BetweenExpression<NumberType> =
this.between(start.toDopeType(), end.toDopeType())

@JvmName("betweenNumber")
fun TypeExpression<NumberType>.between(start: CMField<out Number>, end: TypeExpression<NumberType>): BetweenExpression<NumberType> =
this.between(start.toDopeType(), end)

@JvmName("betweenNumber")
fun TypeExpression<NumberType>.between(start: TypeExpression<NumberType>, end: CMField<out Number>): BetweenExpression<NumberType> =
this.between(start, end.toDopeType())

@JvmName("betweenString")
fun CMField<String>.between(start: CMField<String>, end: CMField<String>): BetweenExpression<StringType> =
toDopeType().between(start.toDopeType(), end.toDopeType())

@JvmName("betweenString")
fun CMField<String>.between(start: CMField<String>, end: TypeExpression<StringType>): BetweenExpression<StringType> =
toDopeType().between(start.toDopeType(), end)

@JvmName("betweenString")
fun CMField<String>.between(start: TypeExpression<StringType>, end: CMField<String>): BetweenExpression<StringType> =
toDopeType().between(start, end.toDopeType())

@JvmName("betweenString")
fun CMField<String>.between(start: TypeExpression<StringType>, end: TypeExpression<StringType>): BetweenExpression<StringType> =
toDopeType().between(start, end)

@JvmName("betweenString")
fun TypeExpression<StringType>.between(start: CMField<String>, end: CMField<String>): BetweenExpression<StringType> =
this.between(start.toDopeType(), end.toDopeType())

@JvmName("betweenString")
fun TypeExpression<StringType>.between(start: CMField<String>, end: TypeExpression<StringType>): BetweenExpression<StringType> =
this.between(start.toDopeType(), end)

@JvmName("betweenString")
fun TypeExpression<StringType>.between(start: TypeExpression<StringType>, end: CMField<String>): BetweenExpression<StringType> =
this.between(start, end.toDopeType())
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package ch.ergon.dope.extension.type.relational

import ch.ergon.dope.resolvable.expression.TypeExpression
import ch.ergon.dope.resolvable.expression.unaliased.type.relational.NotBetweenExpression
import ch.ergon.dope.resolvable.expression.unaliased.type.relational.notBetween
import ch.ergon.dope.toDopeType
import ch.ergon.dope.validtype.NumberType
import ch.ergon.dope.validtype.StringType
import com.schwarz.crystalapi.schema.CMField

@JvmName("betweenNumber")
fun CMField<out Number>.notBetween(start: CMField<out Number>, end: CMField<out Number>): NotBetweenExpression<NumberType> =
toDopeType().notBetween(start.toDopeType(), end.toDopeType())

@JvmName("betweenNumber")
fun CMField<out Number>.notBetween(start: CMField<out Number>, end: TypeExpression<NumberType>): NotBetweenExpression<NumberType> =
toDopeType().notBetween(start.toDopeType(), end)

@JvmName("betweenNumber")
fun CMField<out Number>.notBetween(start: TypeExpression<NumberType>, end: CMField<out Number>): NotBetweenExpression<NumberType> =
toDopeType().notBetween(start, end.toDopeType())

@JvmName("betweenNumber")
fun CMField<out Number>.notBetween(start: TypeExpression<NumberType>, end: TypeExpression<NumberType>): NotBetweenExpression<NumberType> =
toDopeType().notBetween(start, end)

@JvmName("betweenNumber")
fun TypeExpression<NumberType>.notBetween(start: CMField<out Number>, end: CMField<out Number>): NotBetweenExpression<NumberType> =
this.notBetween(start.toDopeType(), end.toDopeType())

@JvmName("betweenNumber")
fun TypeExpression<NumberType>.notBetween(start: CMField<out Number>, end: TypeExpression<NumberType>): NotBetweenExpression<NumberType> =
this.notBetween(start.toDopeType(), end)

@JvmName("betweenNumber")
fun TypeExpression<NumberType>.notBetween(start: TypeExpression<NumberType>, end: CMField<out Number>): NotBetweenExpression<NumberType> =
this.notBetween(start, end.toDopeType())

@JvmName("betweenString")
fun CMField<String>.notBetween(start: CMField<String>, end: CMField<String>): NotBetweenExpression<StringType> =
toDopeType().notBetween(start.toDopeType(), end.toDopeType())

@JvmName("betweenString")
fun CMField<String>.notBetween(start: CMField<String>, end: TypeExpression<StringType>): NotBetweenExpression<StringType> =
toDopeType().notBetween(start.toDopeType(), end)

@JvmName("betweenString")
fun CMField<String>.notBetween(start: TypeExpression<StringType>, end: CMField<String>): NotBetweenExpression<StringType> =
toDopeType().notBetween(start, end.toDopeType())

@JvmName("betweenString")
fun CMField<String>.notBetween(start: TypeExpression<StringType>, end: TypeExpression<StringType>): NotBetweenExpression<StringType> =
toDopeType().notBetween(start, end)

@JvmName("betweenString")
fun TypeExpression<StringType>.notBetween(start: CMField<String>, end: CMField<String>): NotBetweenExpression<StringType> =
this.notBetween(start.toDopeType(), end.toDopeType())

@JvmName("betweenString")
fun TypeExpression<StringType>.notBetween(start: CMField<String>, end: TypeExpression<StringType>): NotBetweenExpression<StringType> =
this.notBetween(start.toDopeType(), end)

@JvmName("betweenString")
fun TypeExpression<StringType>.notBetween(start: TypeExpression<StringType>, end: CMField<String>): NotBetweenExpression<StringType> =
this.notBetween(start, end.toDopeType())
Loading