diff --git a/core/src/main/kotlin/ch/ergon/dope/resolvable/clause/IDeleteClause.kt b/core/src/main/kotlin/ch/ergon/dope/resolvable/clause/IDeleteClause.kt index 0e7afce9..7df6c8b5 100644 --- a/core/src/main/kotlin/ch/ergon/dope/resolvable/clause/IDeleteClause.kt +++ b/core/src/main/kotlin/ch/ergon/dope/resolvable/clause/IDeleteClause.kt @@ -2,8 +2,7 @@ package ch.ergon.dope.resolvable.clause import ch.ergon.dope.resolvable.clause.model.DeleteLimitClause import ch.ergon.dope.resolvable.clause.model.DeleteOffsetClause -import ch.ergon.dope.resolvable.clause.model.DeleteUseKeysArrayClause -import ch.ergon.dope.resolvable.clause.model.DeleteUseKeysStringClause +import ch.ergon.dope.resolvable.clause.model.DeleteUseKeysClause.Companion.DeleteUseKeysClause import ch.ergon.dope.resolvable.clause.model.DeleteWhereClause import ch.ergon.dope.resolvable.clause.model.ReturningClause import ch.ergon.dope.resolvable.expression.TypeExpression @@ -36,9 +35,10 @@ interface IDeleteUseKeysClause : IDeleteWhereClause { } interface IDeleteClause : IDeleteUseKeysClause { - fun useKeys(key: TypeExpression) = DeleteUseKeysStringClause(key, this) + fun useKeys(key: TypeExpression) = DeleteUseKeysClause(key, this) + // JvmName annotation in interfaces is currently not supported. https://youtrack.jetbrains.com/issue/KT-20068 @Suppress("INAPPLICABLE_JVM_NAME") @JvmName("useKeysArray") - fun useKeys(key: TypeExpression>) = DeleteUseKeysArrayClause(key, this) + fun useKeys(key: TypeExpression>) = DeleteUseKeysClause(key, this) } diff --git a/core/src/main/kotlin/ch/ergon/dope/resolvable/clause/ISelectClause.kt b/core/src/main/kotlin/ch/ergon/dope/resolvable/clause/ISelectClause.kt index 79a3a0e8..ce3c40ea 100644 --- a/core/src/main/kotlin/ch/ergon/dope/resolvable/clause/ISelectClause.kt +++ b/core/src/main/kotlin/ch/ergon/dope/resolvable/clause/ISelectClause.kt @@ -11,8 +11,7 @@ import ch.ergon.dope.resolvable.clause.model.SelectLimitClause import ch.ergon.dope.resolvable.clause.model.SelectOffsetClause import ch.ergon.dope.resolvable.clause.model.SelectOrderByClause import ch.ergon.dope.resolvable.clause.model.SelectOrderByTypeClause -import ch.ergon.dope.resolvable.clause.model.SelectUseKeysArrayClause -import ch.ergon.dope.resolvable.clause.model.SelectUseKeysStringClause +import ch.ergon.dope.resolvable.clause.model.SelectUseKeysClause.Companion.SelectUseKeysClause import ch.ergon.dope.resolvable.clause.model.SelectWhereClause import ch.ergon.dope.resolvable.clause.model.StandardJoinClause import ch.ergon.dope.resolvable.clause.model.UnnestClause @@ -57,11 +56,12 @@ interface ISelectUseKeysClause : ISelectWhereClause { } interface ISelectFromClause : ISelectUseKeysClause { - fun useKeys(key: TypeExpression) = SelectUseKeysStringClause(key, this) + fun useKeys(key: TypeExpression) = SelectUseKeysClause(key, this) + // JvmName annotation in interfaces is currently not supported. https://youtrack.jetbrains.com/issue/KT-20068 @Suppress("INAPPLICABLE_JVM_NAME") @JvmName("useKeysArray") - fun useKeys(keys: TypeExpression>) = SelectUseKeysArrayClause(keys, this) + fun useKeys(keys: TypeExpression>) = SelectUseKeysClause(keys, this) } interface ISelectJoinClause : ISelectFromClause { diff --git a/core/src/main/kotlin/ch/ergon/dope/resolvable/clause/model/UseKeysClause.kt b/core/src/main/kotlin/ch/ergon/dope/resolvable/clause/model/UseKeysClause.kt index 73af56bd..dfc82318 100644 --- a/core/src/main/kotlin/ch/ergon/dope/resolvable/clause/model/UseKeysClause.kt +++ b/core/src/main/kotlin/ch/ergon/dope/resolvable/clause/model/UseKeysClause.kt @@ -13,13 +13,31 @@ import ch.ergon.dope.validtype.ValidType private const val USE_KEYS = "USE KEYS" -sealed class SelectUseKeysClause( - private val parentClause: ISelectFromClause, - private val keys: TypeExpression, -) : ISelectUseKeysClause { +class SelectUseKeysClause : ISelectUseKeysClause { + private lateinit var useKeys: TypeExpression + private lateinit var parentClause: ISelectFromClause + + companion object { + @JvmName("selectSingleUseKeysClauseConstructor") + fun SelectUseKeysClause(key: TypeExpression, parentClause: ISelectFromClause): SelectUseKeysClause { + val instance = SelectUseKeysClause() + instance.useKeys = key + instance.parentClause = parentClause + return instance + } + + @JvmName("selectMultipleUseKeysClauseConstructor") + fun SelectUseKeysClause(keys: TypeExpression>, parentClause: ISelectFromClause): SelectUseKeysClause { + val instance = SelectUseKeysClause() + instance.useKeys = keys + instance.parentClause = parentClause + return instance + } + } + override fun toDopeQuery(): DopeQuery { val parentDopeQuery = parentClause.toDopeQuery() - val keysDopeQuery = keys.toDopeQuery() + val keysDopeQuery = useKeys.toDopeQuery() return DopeQuery( queryString = formatToQueryStringWithSymbol(parentDopeQuery.queryString, USE_KEYS, keysDopeQuery.queryString), parameters = parentDopeQuery.parameters + keysDopeQuery.parameters, @@ -27,28 +45,34 @@ sealed class SelectUseKeysClause( } } -class SelectUseKeysStringClause(key: TypeExpression, parentClause: ISelectFromClause) : - SelectUseKeysClause(parentClause, key) +class DeleteUseKeysClause : IDeleteUseKeysClause { + private lateinit var useKeys: TypeExpression + private lateinit var parentClause: IDeleteClause -class SelectUseKeysArrayClause(keys: TypeExpression>, parentClause: ISelectFromClause) : - SelectUseKeysClause(parentClause, keys) + companion object { + @JvmName("deleteSingleUseKeysClauseConstructor") + fun DeleteUseKeysClause(key: TypeExpression, parentClause: IDeleteClause): DeleteUseKeysClause { + val instance = DeleteUseKeysClause() + instance.useKeys = key + instance.parentClause = parentClause + return instance + } + + @JvmName("deleteMultipleUseKeysClauseConstructor") + fun DeleteUseKeysClause(keys: TypeExpression>, parentClause: IDeleteClause): DeleteUseKeysClause { + val instance = DeleteUseKeysClause() + instance.useKeys = keys + instance.parentClause = parentClause + return instance + } + } -sealed class DeleteUseKeysClause( - private val parentClause: IDeleteClause, - private val keys: TypeExpression, -) : IDeleteUseKeysClause { override fun toDopeQuery(): DopeQuery { val parentDopeQuery = parentClause.toDopeQuery() - val keysDopeQuery = keys.toDopeQuery() + val keysDopeQuery = useKeys.toDopeQuery() return DopeQuery( queryString = formatToQueryStringWithSymbol(parentDopeQuery.queryString, USE_KEYS, keysDopeQuery.queryString), parameters = parentDopeQuery.parameters + keysDopeQuery.parameters, ) } } - -class DeleteUseKeysStringClause(key: TypeExpression, parentClause: IDeleteClause) : - DeleteUseKeysClause(parentClause, key) - -class DeleteUseKeysArrayClause(keys: TypeExpression>, parentClause: IDeleteClause) : - DeleteUseKeysClause(parentClause, keys) diff --git a/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/AbsoluteExpression.kt b/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/AbsoluteExpression.kt new file mode 100644 index 00000000..186e8afc --- /dev/null +++ b/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/AbsoluteExpression.kt @@ -0,0 +1,11 @@ +package ch.ergon.dope.resolvable.expression.unaliased.type.numeric + +import ch.ergon.dope.resolvable.expression.TypeExpression +import ch.ergon.dope.resolvable.expression.unaliased.type.toDopeType +import ch.ergon.dope.validtype.NumberType + +class AbsoluteExpression(value: TypeExpression) : NumberFunctionExpression("ABS", value) + +fun abs(value: TypeExpression) = AbsoluteExpression(value) + +fun abs(value: Number) = abs(value.toDopeType()) diff --git a/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/ArcCosineExpression.kt b/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/ArcCosineExpression.kt new file mode 100644 index 00000000..11ef3e18 --- /dev/null +++ b/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/ArcCosineExpression.kt @@ -0,0 +1,11 @@ +package ch.ergon.dope.resolvable.expression.unaliased.type.numeric + +import ch.ergon.dope.resolvable.expression.TypeExpression +import ch.ergon.dope.resolvable.expression.unaliased.type.toDopeType +import ch.ergon.dope.validtype.NumberType + +class ArcCosineExpression(value: TypeExpression) : NumberFunctionExpression("ACOS", value) + +fun acos(value: TypeExpression) = ArcCosineExpression(value) + +fun acos(value: Number) = acos(value.toDopeType()) diff --git a/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/ArcSineExpression.kt b/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/ArcSineExpression.kt new file mode 100644 index 00000000..9ff56a40 --- /dev/null +++ b/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/ArcSineExpression.kt @@ -0,0 +1,11 @@ +package ch.ergon.dope.resolvable.expression.unaliased.type.numeric + +import ch.ergon.dope.resolvable.expression.TypeExpression +import ch.ergon.dope.resolvable.expression.unaliased.type.toDopeType +import ch.ergon.dope.validtype.NumberType + +class ArcSineExpression(value: TypeExpression) : NumberFunctionExpression("ASIN", value) + +fun asin(value: TypeExpression) = ArcSineExpression(value) + +fun asin(value: Number) = asin(value.toDopeType()) diff --git a/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/ArcTangent2Expression.kt b/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/ArcTangent2Expression.kt new file mode 100644 index 00000000..3d57d49a --- /dev/null +++ b/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/ArcTangent2Expression.kt @@ -0,0 +1,16 @@ +package ch.ergon.dope.resolvable.expression.unaliased.type.numeric + +import ch.ergon.dope.resolvable.expression.TypeExpression +import ch.ergon.dope.resolvable.expression.unaliased.type.toDopeType +import ch.ergon.dope.validtype.NumberType + +class ArcTangent2Expression(divisor: TypeExpression, dividend: TypeExpression) : + NumberFunctionExpression("ATAN2", divisor, dividend) + +fun atan2(divisor: TypeExpression, dividend: TypeExpression) = ArcTangent2Expression(divisor, dividend) + +fun atan2(divisor: TypeExpression, dividend: Number) = atan2(divisor, dividend.toDopeType()) + +fun atan2(divisor: Number, dividend: TypeExpression) = atan2(divisor.toDopeType(), dividend) + +fun atan2(divisor: Number, dividend: Number) = atan2(divisor.toDopeType(), dividend.toDopeType()) diff --git a/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/ArcTangentExpression.kt b/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/ArcTangentExpression.kt new file mode 100644 index 00000000..229ca622 --- /dev/null +++ b/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/ArcTangentExpression.kt @@ -0,0 +1,11 @@ +package ch.ergon.dope.resolvable.expression.unaliased.type.numeric + +import ch.ergon.dope.resolvable.expression.TypeExpression +import ch.ergon.dope.resolvable.expression.unaliased.type.toDopeType +import ch.ergon.dope.validtype.NumberType + +class ArcTangentExpression(value: TypeExpression) : NumberFunctionExpression("ATAN", value) + +fun atan(value: TypeExpression) = ArcTangentExpression(value) + +fun atan(value: Number) = atan(value.toDopeType()) diff --git a/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/CeilingExpression.kt b/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/CeilingExpression.kt new file mode 100644 index 00000000..ab9f9d47 --- /dev/null +++ b/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/CeilingExpression.kt @@ -0,0 +1,11 @@ +package ch.ergon.dope.resolvable.expression.unaliased.type.numeric + +import ch.ergon.dope.resolvable.expression.TypeExpression +import ch.ergon.dope.resolvable.expression.unaliased.type.toDopeType +import ch.ergon.dope.validtype.NumberType + +class CeilingExpression(value: TypeExpression) : NumberFunctionExpression("CEIL", value) + +fun ceil(value: TypeExpression) = CeilingExpression(value) + +fun ceil(value: Number) = ceil(value.toDopeType()) diff --git a/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/CosineExpression.kt b/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/CosineExpression.kt new file mode 100644 index 00000000..46d80575 --- /dev/null +++ b/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/CosineExpression.kt @@ -0,0 +1,11 @@ +package ch.ergon.dope.resolvable.expression.unaliased.type.numeric + +import ch.ergon.dope.resolvable.expression.TypeExpression +import ch.ergon.dope.resolvable.expression.unaliased.type.toDopeType +import ch.ergon.dope.validtype.NumberType + +class CosineExpression(value: TypeExpression) : NumberFunctionExpression("COS", value) + +fun cos(value: TypeExpression) = CosineExpression(value) + +fun cos(value: Number) = cos(value.toDopeType()) diff --git a/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/DegreesExpression.kt b/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/DegreesExpression.kt new file mode 100644 index 00000000..f17ae6de --- /dev/null +++ b/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/DegreesExpression.kt @@ -0,0 +1,11 @@ +package ch.ergon.dope.resolvable.expression.unaliased.type.numeric + +import ch.ergon.dope.resolvable.expression.TypeExpression +import ch.ergon.dope.resolvable.expression.unaliased.type.toDopeType +import ch.ergon.dope.validtype.NumberType + +class DegreesExpression(value: TypeExpression) : NumberFunctionExpression("DEGREES", value) + +fun degrees(value: TypeExpression) = DegreesExpression(value) + +fun degrees(value: Number) = degrees(value.toDopeType()) diff --git a/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/EulerExpression.kt b/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/EulerExpression.kt new file mode 100644 index 00000000..2f297acc --- /dev/null +++ b/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/EulerExpression.kt @@ -0,0 +1,14 @@ +package ch.ergon.dope.resolvable.expression.unaliased.type.numeric + +import ch.ergon.dope.DopeQuery +import ch.ergon.dope.resolvable.expression.TypeExpression +import ch.ergon.dope.validtype.NumberType + +class EulerExpression : TypeExpression { + override fun toDopeQuery() = DopeQuery( + queryString = "E()", + parameters = emptyMap(), + ) +} + +fun e() = EulerExpression() diff --git a/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/ExponentExpression.kt b/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/ExponentExpression.kt new file mode 100644 index 00000000..ed4b8106 --- /dev/null +++ b/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/ExponentExpression.kt @@ -0,0 +1,11 @@ +package ch.ergon.dope.resolvable.expression.unaliased.type.numeric + +import ch.ergon.dope.resolvable.expression.TypeExpression +import ch.ergon.dope.resolvable.expression.unaliased.type.toDopeType +import ch.ergon.dope.validtype.NumberType + +class ExponentExpression(value: TypeExpression) : NumberFunctionExpression("EXP", value) + +fun exp(value: TypeExpression) = ExponentExpression(value) + +fun exp(value: Number) = exp(value.toDopeType()) diff --git a/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/FloorExpression.kt b/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/FloorExpression.kt new file mode 100644 index 00000000..7f1faafd --- /dev/null +++ b/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/FloorExpression.kt @@ -0,0 +1,11 @@ +package ch.ergon.dope.resolvable.expression.unaliased.type.numeric + +import ch.ergon.dope.resolvable.expression.TypeExpression +import ch.ergon.dope.resolvable.expression.unaliased.type.toDopeType +import ch.ergon.dope.validtype.NumberType + +class FloorExpression(value: TypeExpression) : NumberFunctionExpression("FLOOR", value) + +fun floor(value: TypeExpression) = FloorExpression(value) + +fun floor(value: Number) = floor(value.toDopeType()) diff --git a/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/LogExpression.kt b/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/LogExpression.kt new file mode 100644 index 00000000..fd8a7476 --- /dev/null +++ b/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/LogExpression.kt @@ -0,0 +1,11 @@ +package ch.ergon.dope.resolvable.expression.unaliased.type.numeric + +import ch.ergon.dope.resolvable.expression.TypeExpression +import ch.ergon.dope.resolvable.expression.unaliased.type.toDopeType +import ch.ergon.dope.validtype.NumberType + +class LogExpression(value: TypeExpression) : NumberFunctionExpression("LOG", value) + +fun log(value: TypeExpression) = LogExpression(value) + +fun log(value: Number) = log(value.toDopeType()) diff --git a/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/LogNaturalisExpression.kt b/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/LogNaturalisExpression.kt new file mode 100644 index 00000000..7a8af314 --- /dev/null +++ b/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/LogNaturalisExpression.kt @@ -0,0 +1,11 @@ +package ch.ergon.dope.resolvable.expression.unaliased.type.numeric + +import ch.ergon.dope.resolvable.expression.TypeExpression +import ch.ergon.dope.resolvable.expression.unaliased.type.toDopeType +import ch.ergon.dope.validtype.NumberType + +class LogNaturalisExpression(value: TypeExpression) : NumberFunctionExpression("LN", value) + +fun ln(value: TypeExpression) = LogNaturalisExpression(value) + +fun ln(value: Number) = ln(value.toDopeType()) diff --git a/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/NumberFunctionExpression.kt b/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/NumberFunctionExpression.kt new file mode 100644 index 00000000..d7b0b4e6 --- /dev/null +++ b/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/NumberFunctionExpression.kt @@ -0,0 +1,21 @@ +package ch.ergon.dope.resolvable.expression.unaliased.type.numeric + +import ch.ergon.dope.DopeQuery +import ch.ergon.dope.resolvable.expression.TypeExpression +import ch.ergon.dope.resolvable.operator.FunctionOperator +import ch.ergon.dope.validtype.NumberType + +sealed class NumberFunctionExpression( + private val symbol: String, + private val value: TypeExpression, + private val extraValue: TypeExpression? = null, +) : TypeExpression, FunctionOperator { + override fun toDopeQuery(): DopeQuery { + val valueDopeQuery = value.toDopeQuery() + val extraValueDopeQuery = extraValue?.toDopeQuery() + return DopeQuery( + queryString = toFunctionQueryString(symbol = symbol, valueDopeQuery, extra = extraValueDopeQuery), + parameters = valueDopeQuery.parameters + extraValueDopeQuery?.parameters.orEmpty(), + ) + } +} diff --git a/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/PiExpression.kt b/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/PiExpression.kt new file mode 100644 index 00000000..38ca0a6e --- /dev/null +++ b/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/PiExpression.kt @@ -0,0 +1,14 @@ +package ch.ergon.dope.resolvable.expression.unaliased.type.numeric + +import ch.ergon.dope.DopeQuery +import ch.ergon.dope.resolvable.expression.TypeExpression +import ch.ergon.dope.validtype.NumberType + +class PiExpression : TypeExpression { + override fun toDopeQuery() = DopeQuery( + queryString = "PI()", + parameters = emptyMap(), + ) +} + +fun pi() = PiExpression() diff --git a/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/PowerExpression.kt b/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/PowerExpression.kt new file mode 100644 index 00000000..24eb6fb8 --- /dev/null +++ b/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/PowerExpression.kt @@ -0,0 +1,16 @@ +package ch.ergon.dope.resolvable.expression.unaliased.type.numeric + +import ch.ergon.dope.resolvable.expression.TypeExpression +import ch.ergon.dope.resolvable.expression.unaliased.type.toDopeType +import ch.ergon.dope.validtype.NumberType + +class PowerExpression(base: TypeExpression, exponent: TypeExpression) : + NumberFunctionExpression("POWER", base, exponent) + +fun power(base: TypeExpression, exponent: TypeExpression) = PowerExpression(base, exponent) + +fun power(base: TypeExpression, exponent: Number) = power(base, exponent.toDopeType()) + +fun power(base: Number, exponent: TypeExpression) = power(base.toDopeType(), exponent) + +fun power(base: Number, exponent: Number) = power(base.toDopeType(), exponent.toDopeType()) diff --git a/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/RadiansExpression.kt b/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/RadiansExpression.kt new file mode 100644 index 00000000..534de909 --- /dev/null +++ b/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/RadiansExpression.kt @@ -0,0 +1,11 @@ +package ch.ergon.dope.resolvable.expression.unaliased.type.numeric + +import ch.ergon.dope.resolvable.expression.TypeExpression +import ch.ergon.dope.resolvable.expression.unaliased.type.toDopeType +import ch.ergon.dope.validtype.NumberType + +class RadiansExpression(value: TypeExpression) : NumberFunctionExpression("RADIANS", value) + +fun radians(value: TypeExpression) = RadiansExpression(value) + +fun radians(value: Number) = radians(value.toDopeType()) diff --git a/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/RandomExpression.kt b/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/RandomExpression.kt new file mode 100644 index 00000000..aecfe4b3 --- /dev/null +++ b/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/RandomExpression.kt @@ -0,0 +1,25 @@ +package ch.ergon.dope.resolvable.expression.unaliased.type.numeric + +import ch.ergon.dope.DopeQuery +import ch.ergon.dope.resolvable.expression.TypeExpression +import ch.ergon.dope.resolvable.expression.unaliased.type.toDopeType +import ch.ergon.dope.resolvable.operator.FunctionOperator +import ch.ergon.dope.validtype.NumberType + +class RandomExpression(private val value: TypeExpression? = null) : + TypeExpression, FunctionOperator { + override fun toDopeQuery() = + value?.let { + val valueDopeQuery = value.toDopeQuery() + DopeQuery( + queryString = toFunctionQueryString("RANDOM", valueDopeQuery.queryString), + parameters = valueDopeQuery.parameters, + ) + } ?: DopeQuery(queryString = "RANDOM()", parameters = emptyMap()) +} + +fun random() = RandomExpression() + +fun random(value: TypeExpression) = RandomExpression(value) + +fun random(value: Number) = random(value.toDopeType()) diff --git a/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/RoundExpression.kt b/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/RoundExpression.kt new file mode 100644 index 00000000..e5e2d408 --- /dev/null +++ b/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/RoundExpression.kt @@ -0,0 +1,20 @@ +package ch.ergon.dope.resolvable.expression.unaliased.type.numeric + +import ch.ergon.dope.resolvable.expression.TypeExpression +import ch.ergon.dope.resolvable.expression.unaliased.type.toDopeType +import ch.ergon.dope.validtype.NumberType + +class RoundExpression(value: TypeExpression, digits: TypeExpression? = null) : + NumberFunctionExpression("ROUND", value, digits) + +fun round(value: TypeExpression) = RoundExpression(value) + +fun round(value: Number) = round(value.toDopeType()) + +fun round(value: TypeExpression, digits: TypeExpression) = RoundExpression(value, digits) + +fun round(value: TypeExpression, digits: Number) = round(value, digits.toDopeType()) + +fun round(value: Number, digits: TypeExpression) = round(value.toDopeType(), digits) + +fun round(value: Number, digits: Number) = round(value.toDopeType(), digits.toDopeType()) diff --git a/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/SignExpression.kt b/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/SignExpression.kt new file mode 100644 index 00000000..b3c3618c --- /dev/null +++ b/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/SignExpression.kt @@ -0,0 +1,11 @@ +package ch.ergon.dope.resolvable.expression.unaliased.type.numeric + +import ch.ergon.dope.resolvable.expression.TypeExpression +import ch.ergon.dope.resolvable.expression.unaliased.type.toDopeType +import ch.ergon.dope.validtype.NumberType + +class SignExpression(value: TypeExpression) : NumberFunctionExpression("SIGN", value) + +fun sign(value: TypeExpression) = SignExpression(value) + +fun sign(value: Number) = sign(value.toDopeType()) diff --git a/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/SineExpression.kt b/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/SineExpression.kt new file mode 100644 index 00000000..cb531146 --- /dev/null +++ b/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/SineExpression.kt @@ -0,0 +1,11 @@ +package ch.ergon.dope.resolvable.expression.unaliased.type.numeric + +import ch.ergon.dope.resolvable.expression.TypeExpression +import ch.ergon.dope.resolvable.expression.unaliased.type.toDopeType +import ch.ergon.dope.validtype.NumberType + +class SineExpression(value: TypeExpression) : NumberFunctionExpression("SIN", value) + +fun sin(value: TypeExpression) = SineExpression(value) + +fun sin(value: Number) = sin(value.toDopeType()) diff --git a/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/SquareRootExpression.kt b/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/SquareRootExpression.kt new file mode 100644 index 00000000..104b94ee --- /dev/null +++ b/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/SquareRootExpression.kt @@ -0,0 +1,11 @@ +package ch.ergon.dope.resolvable.expression.unaliased.type.numeric + +import ch.ergon.dope.resolvable.expression.TypeExpression +import ch.ergon.dope.resolvable.expression.unaliased.type.toDopeType +import ch.ergon.dope.validtype.NumberType + +class SquareRootExpression(value: TypeExpression) : NumberFunctionExpression("SQRT", value) + +fun sqrt(value: TypeExpression) = SquareRootExpression(value) + +fun sqrt(value: Number) = sqrt(value.toDopeType()) diff --git a/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/TangentExpression.kt b/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/TangentExpression.kt new file mode 100644 index 00000000..70e4423b --- /dev/null +++ b/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/TangentExpression.kt @@ -0,0 +1,11 @@ +package ch.ergon.dope.resolvable.expression.unaliased.type.numeric + +import ch.ergon.dope.resolvable.expression.TypeExpression +import ch.ergon.dope.resolvable.expression.unaliased.type.toDopeType +import ch.ergon.dope.validtype.NumberType + +class TangentExpression(value: TypeExpression) : NumberFunctionExpression("TAN", value) + +fun tan(value: TypeExpression) = TangentExpression(value) + +fun tan(value: Number) = tan(value.toDopeType()) diff --git a/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/TruncationExpression.kt b/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/TruncationExpression.kt new file mode 100644 index 00000000..8db4188d --- /dev/null +++ b/core/src/main/kotlin/ch/ergon/dope/resolvable/expression/unaliased/type/numeric/TruncationExpression.kt @@ -0,0 +1,20 @@ +package ch.ergon.dope.resolvable.expression.unaliased.type.numeric + +import ch.ergon.dope.resolvable.expression.TypeExpression +import ch.ergon.dope.resolvable.expression.unaliased.type.toDopeType +import ch.ergon.dope.validtype.NumberType + +class TruncationExpression(value: TypeExpression, digits: TypeExpression? = null) : + NumberFunctionExpression("TRUNC", value, digits) + +fun trunc(value: TypeExpression) = TruncationExpression(value) + +fun trunc(value: Number) = trunc(value.toDopeType()) + +fun trunc(value: TypeExpression, digits: TypeExpression) = TruncationExpression(value, digits) + +fun trunc(value: TypeExpression, digits: Number) = trunc(value, digits.toDopeType()) + +fun trunc(value: Number, digits: TypeExpression) = trunc(value.toDopeType(), digits) + +fun trunc(value: Number, digits: Number) = trunc(value.toDopeType(), digits.toDopeType()) diff --git a/core/src/test/kotlin/ch/ergon/dope/buildTest/NumberFunctionsTest.kt b/core/src/test/kotlin/ch/ergon/dope/buildTest/NumberFunctionsTest.kt index b7b134cd..0f5e131c 100644 --- a/core/src/test/kotlin/ch/ergon/dope/buildTest/NumberFunctionsTest.kt +++ b/core/src/test/kotlin/ch/ergon/dope/buildTest/NumberFunctionsTest.kt @@ -1,19 +1,41 @@ package ch.ergon.dope.buildTest import ch.ergon.dope.QueryBuilder +import ch.ergon.dope.helper.someNumberField import ch.ergon.dope.resolvable.expression.alias +import ch.ergon.dope.resolvable.expression.unaliased.type.numeric.abs +import ch.ergon.dope.resolvable.expression.unaliased.type.numeric.acos +import ch.ergon.dope.resolvable.expression.unaliased.type.numeric.asin +import ch.ergon.dope.resolvable.expression.unaliased.type.numeric.atan +import ch.ergon.dope.resolvable.expression.unaliased.type.numeric.atan2 +import ch.ergon.dope.resolvable.expression.unaliased.type.numeric.ceil +import ch.ergon.dope.resolvable.expression.unaliased.type.numeric.cos +import ch.ergon.dope.resolvable.expression.unaliased.type.numeric.degrees +import ch.ergon.dope.resolvable.expression.unaliased.type.numeric.e +import ch.ergon.dope.resolvable.expression.unaliased.type.numeric.exp +import ch.ergon.dope.resolvable.expression.unaliased.type.numeric.floor +import ch.ergon.dope.resolvable.expression.unaliased.type.numeric.ln +import ch.ergon.dope.resolvable.expression.unaliased.type.numeric.log +import ch.ergon.dope.resolvable.expression.unaliased.type.numeric.pi +import ch.ergon.dope.resolvable.expression.unaliased.type.numeric.power +import ch.ergon.dope.resolvable.expression.unaliased.type.numeric.radians +import ch.ergon.dope.resolvable.expression.unaliased.type.numeric.random +import ch.ergon.dope.resolvable.expression.unaliased.type.numeric.round +import ch.ergon.dope.resolvable.expression.unaliased.type.numeric.sign +import ch.ergon.dope.resolvable.expression.unaliased.type.numeric.sin +import ch.ergon.dope.resolvable.expression.unaliased.type.numeric.sqrt +import ch.ergon.dope.resolvable.expression.unaliased.type.numeric.tan +import ch.ergon.dope.resolvable.expression.unaliased.type.numeric.trunc import ch.ergon.dope.resolvable.expression.unaliased.type.toDopeType import junit.framework.TestCase.assertEquals import kotlin.test.BeforeTest import kotlin.test.Test class NumberFunctionsTest { - private lateinit var builder: StringBuilder private lateinit var create: QueryBuilder @BeforeTest fun setup() { - builder = StringBuilder() create = QueryBuilder() } @@ -28,4 +50,517 @@ class NumberFunctionsTest { assertEquals(expected, actual) } + + @Test + fun `should support ABS expression`() { + val expected = "ABS(-1)" + + val actual = abs(-1).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support ABS expression with number field`() { + val expected = "ABS(`numberField`)" + + val actual = abs(someNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support ACOS expression`() { + val expected = "ACOS(-1)" + + val actual = acos(-1).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support ACOS expression with number field`() { + val expected = "ACOS(`numberField`)" + + val actual = acos(someNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support ASIN expression`() { + val expected = "ASIN(-1)" + + val actual = asin(-1).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support ASIN expression with number field`() { + val expected = "ASIN(`numberField`)" + + val actual = asin(someNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support ATAN expression`() { + val expected = "ATAN(-1)" + + val actual = atan(-1).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support ATAN expression with number field`() { + val expected = "ATAN(`numberField`)" + + val actual = atan(someNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support ATAN2 expression`() { + val expected = "ATAN2(1, 0.5)" + + val actual = atan2(1, 0.5).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support ATAN2 expression with number field as divisor`() { + val expected = "ATAN2(`numberField`, 0.5)" + + val actual = atan2(someNumberField(), 0.5).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support ATAN2 expression with number field as dividend`() { + val expected = "ATAN2(0.5, `numberField`)" + + val actual = atan2(0.5, someNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support ATAN2 expression with number field as divisor and dividend`() { + val expected = "ATAN2(`numberField`, `anotherNumberField`)" + + val actual = atan2(someNumberField(), someNumberField("anotherNumberField")).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support CEIL expression`() { + val expected = "CEIL(3.14)" + + val actual = ceil(3.14).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support CEIL expression with number field`() { + val expected = "CEIL(`numberField`)" + + val actual = ceil(someNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support COS expression`() { + val expected = "COS(-1)" + + val actual = cos(-1).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support COS expression with number field`() { + val expected = "COS(`numberField`)" + + val actual = cos(someNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support DEGREES expression`() { + val expected = "DEGREES(-1)" + + val actual = degrees(-1).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support DEGREES expression with number field`() { + val expected = "DEGREES(`numberField`)" + + val actual = degrees(someNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support E (euler) expression`() { + val expected = "E()" + + val actual = e().toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support EXP expression`() { + val expected = "EXP(-1)" + + val actual = exp(-1).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support EXP expression with number field`() { + val expected = "EXP(`numberField`)" + + val actual = exp(someNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support LN expression`() { + val expected = "LN(1)" + + val actual = ln(1).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support LN expression with number field`() { + val expected = "LN(`numberField`)" + + val actual = ln(someNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support LOG expression`() { + val expected = "LOG(1)" + + val actual = log(1).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support LOG expression with number field`() { + val expected = "LOG(`numberField`)" + + val actual = log(someNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support FLOOR expression`() { + val expected = "FLOOR(3.14)" + + val actual = floor(3.14).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support FLOOR expression with number field`() { + val expected = "FLOOR(`numberField`)" + + val actual = floor(someNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support PI expression`() { + val expected = "PI()" + + val actual = pi().toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support POWER expression`() { + val expected = "POWER(2, 3)" + + val actual = power(2, 3).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support POWER expression with base as number field`() { + val expected = "POWER(`numberField`, 3)" + + val actual = power(someNumberField(), 3).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support POWER expression with exponent as number field`() { + val expected = "POWER(3.14, `numberField`)" + + val actual = power(3.14, someNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support POWER expression with base and exponent as number fields`() { + val expected = "POWER(`numberField`, `anotherNumberField`)" + + val actual = power(someNumberField(), someNumberField("anotherNumberField")).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support RADIANS expression`() { + val expected = "RADIANS(180)" + + val actual = radians(180).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support RADIANS expression with number field`() { + val expected = "RADIANS(`numberField`)" + + val actual = radians(someNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support RANDOM expression`() { + val expected = "RANDOM()" + + val actual = random().toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support RANDOM expression with seed`() { + val expected = "RANDOM(1)" + + val actual = random(1).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support RANDOM expression with number field as seed`() { + val expected = "RANDOM(`numberField`)" + + val actual = random(someNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support ROUND expression`() { + val expected = "ROUND(3.14)" + + val actual = round(3.14).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support ROUND expression with number field`() { + val expected = "ROUND(`numberField`)" + + val actual = round(someNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support ROUND expression with digits`() { + val expected = "ROUND(3.14, 1)" + + val actual = round(3.14, 1).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support ROUND expression with number field and digits`() { + val expected = "ROUND(`numberField`, 1)" + + val actual = round(someNumberField(), 1).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support ROUND expression with digits as number field`() { + val expected = "ROUND(3.14, `numberField`)" + + val actual = round(3.14, someNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support ROUND expression with number field and digits as number fields`() { + val expected = "ROUND(`numberField`, `anotherNumberField`)" + + val actual = round(someNumberField(), someNumberField("anotherNumberField")).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support SIGN expression`() { + val expected = "SIGN(-1)" + + val actual = sign(-1).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support SIGN expression with number field`() { + val expected = "SIGN(`numberField`)" + + val actual = sign(someNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support SIN expression`() { + val expected = "SIN(3.14)" + + val actual = sin(3.14).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support SIN expression with number field`() { + val expected = "SIN(`numberField`)" + + val actual = sin(someNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support SQRT expression`() { + val expected = "SQRT(16)" + + val actual = sqrt(16).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support SQRT expression with number field`() { + val expected = "SQRT(`numberField`)" + + val actual = sqrt(someNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support TAN expression`() { + val expected = "TAN(3.14)" + + val actual = tan(3.14).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support TAN expression with number field`() { + val expected = "TAN(`numberField`)" + + val actual = tan(someNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support TRUNC expression`() { + val expected = "TRUNC(3.14)" + + val actual = trunc(3.14).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support TRUNC expression with number field`() { + val expected = "TRUNC(`numberField`)" + + val actual = trunc(someNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support TRUNC expression with digits`() { + val expected = "TRUNC(3.14, 1)" + + val actual = trunc(3.14, 1).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support TRUNC expression with number field and digits`() { + val expected = "TRUNC(`numberField`, 1)" + + val actual = trunc(someNumberField(), 1).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support TRUNC expression with digits as number field`() { + val expected = "TRUNC(3.14, `numberField`)" + + val actual = trunc(3.14, someNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support TRUNC expression with number field and digits as number fields`() { + val expected = "TRUNC(`numberField`, `anotherNumberField`)" + + val actual = trunc(someNumberField(), someNumberField("anotherNumberField")).toDopeQuery().queryString + + assertEquals(expected, actual) + } } diff --git a/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/Absolute.kt b/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/Absolute.kt new file mode 100644 index 00000000..47c1c007 --- /dev/null +++ b/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/Absolute.kt @@ -0,0 +1,7 @@ +package ch.ergon.dope.extension.type.numberfunction + +import ch.ergon.dope.resolvable.expression.unaliased.type.numeric.abs +import ch.ergon.dope.toDopeType +import com.schwarz.crystalapi.schema.CMField + +fun abs(field: CMField) = abs(field.toDopeType()) diff --git a/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/ArcCosine.kt b/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/ArcCosine.kt new file mode 100644 index 00000000..5c251cc1 --- /dev/null +++ b/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/ArcCosine.kt @@ -0,0 +1,7 @@ +package ch.ergon.dope.extension.type.numberfunction + +import ch.ergon.dope.resolvable.expression.unaliased.type.numeric.acos +import ch.ergon.dope.toDopeType +import com.schwarz.crystalapi.schema.CMField + +fun acos(field: CMField) = acos(field.toDopeType()) diff --git a/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/ArcSine.kt b/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/ArcSine.kt new file mode 100644 index 00000000..f9b119e4 --- /dev/null +++ b/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/ArcSine.kt @@ -0,0 +1,7 @@ +package ch.ergon.dope.extension.type.numberfunction + +import ch.ergon.dope.resolvable.expression.unaliased.type.numeric.asin +import ch.ergon.dope.toDopeType +import com.schwarz.crystalapi.schema.CMField + +fun asin(field: CMField) = asin(field.toDopeType()) diff --git a/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/ArcTangent.kt b/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/ArcTangent.kt new file mode 100644 index 00000000..a9300bcd --- /dev/null +++ b/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/ArcTangent.kt @@ -0,0 +1,7 @@ +package ch.ergon.dope.extension.type.numberfunction + +import ch.ergon.dope.resolvable.expression.unaliased.type.numeric.atan +import ch.ergon.dope.toDopeType +import com.schwarz.crystalapi.schema.CMField + +fun atan(field: CMField) = atan(field.toDopeType()) diff --git a/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/ArcTangent2.kt b/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/ArcTangent2.kt new file mode 100644 index 00000000..7ca717a7 --- /dev/null +++ b/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/ArcTangent2.kt @@ -0,0 +1,17 @@ +package ch.ergon.dope.extension.type.numberfunction + +import ch.ergon.dope.resolvable.expression.TypeExpression +import ch.ergon.dope.resolvable.expression.unaliased.type.numeric.atan2 +import ch.ergon.dope.toDopeType +import ch.ergon.dope.validtype.NumberType +import com.schwarz.crystalapi.schema.CMField + +fun atan2(divisor: CMField, dividend: CMField) = atan2(divisor.toDopeType(), dividend.toDopeType()) + +fun atan2(divisor: CMField, dividend: TypeExpression) = atan2(divisor.toDopeType(), dividend) + +fun atan2(divisor: CMField, dividend: Number) = atan2(divisor.toDopeType(), dividend) + +fun atan2(divisor: TypeExpression, dividend: CMField) = atan2(divisor, dividend.toDopeType()) + +fun atan2(divisor: Number, dividend: CMField) = atan2(divisor, dividend.toDopeType()) diff --git a/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/Ceiling.kt b/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/Ceiling.kt new file mode 100644 index 00000000..6282eac3 --- /dev/null +++ b/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/Ceiling.kt @@ -0,0 +1,7 @@ +package ch.ergon.dope.extension.type.numberfunction + +import ch.ergon.dope.resolvable.expression.unaliased.type.numeric.ceil +import ch.ergon.dope.toDopeType +import com.schwarz.crystalapi.schema.CMField + +fun ceil(field: CMField) = ceil(field.toDopeType()) diff --git a/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/Cosine.kt b/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/Cosine.kt new file mode 100644 index 00000000..037cacba --- /dev/null +++ b/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/Cosine.kt @@ -0,0 +1,7 @@ +package ch.ergon.dope.extension.type.numberfunction + +import ch.ergon.dope.resolvable.expression.unaliased.type.numeric.cos +import ch.ergon.dope.toDopeType +import com.schwarz.crystalapi.schema.CMField + +fun cos(field: CMField) = cos(field.toDopeType()) diff --git a/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/Degrees.kt b/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/Degrees.kt new file mode 100644 index 00000000..40acf7e4 --- /dev/null +++ b/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/Degrees.kt @@ -0,0 +1,7 @@ +package ch.ergon.dope.extension.type.numberfunction + +import ch.ergon.dope.resolvable.expression.unaliased.type.numeric.degrees +import ch.ergon.dope.toDopeType +import com.schwarz.crystalapi.schema.CMField + +fun degrees(field: CMField) = degrees(field.toDopeType()) diff --git a/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/Exponent.kt b/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/Exponent.kt new file mode 100644 index 00000000..c9438982 --- /dev/null +++ b/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/Exponent.kt @@ -0,0 +1,7 @@ +package ch.ergon.dope.extension.type.numberfunction + +import ch.ergon.dope.resolvable.expression.unaliased.type.numeric.exp +import ch.ergon.dope.toDopeType +import com.schwarz.crystalapi.schema.CMField + +fun exp(field: CMField) = exp(field.toDopeType()) diff --git a/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/Floor.kt b/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/Floor.kt new file mode 100644 index 00000000..5ac92966 --- /dev/null +++ b/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/Floor.kt @@ -0,0 +1,7 @@ +package ch.ergon.dope.extension.type.numberfunction + +import ch.ergon.dope.resolvable.expression.unaliased.type.numeric.floor +import ch.ergon.dope.toDopeType +import com.schwarz.crystalapi.schema.CMField + +fun floor(field: CMField) = floor(field.toDopeType()) diff --git a/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/Log.kt b/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/Log.kt new file mode 100644 index 00000000..5435ed8d --- /dev/null +++ b/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/Log.kt @@ -0,0 +1,7 @@ +package ch.ergon.dope.extension.type.numberfunction + +import ch.ergon.dope.resolvable.expression.unaliased.type.numeric.log +import ch.ergon.dope.toDopeType +import com.schwarz.crystalapi.schema.CMField + +fun log(field: CMField) = log(field.toDopeType()) diff --git a/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/LogNaturalis.kt b/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/LogNaturalis.kt new file mode 100644 index 00000000..542f239a --- /dev/null +++ b/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/LogNaturalis.kt @@ -0,0 +1,7 @@ +package ch.ergon.dope.extension.type.numberfunction + +import ch.ergon.dope.resolvable.expression.unaliased.type.numeric.ln +import ch.ergon.dope.toDopeType +import com.schwarz.crystalapi.schema.CMField + +fun ln(field: CMField) = ln(field.toDopeType()) diff --git a/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/Power.kt b/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/Power.kt new file mode 100644 index 00000000..1a893494 --- /dev/null +++ b/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/Power.kt @@ -0,0 +1,17 @@ +package ch.ergon.dope.extension.type.numberfunction + +import ch.ergon.dope.resolvable.expression.TypeExpression +import ch.ergon.dope.resolvable.expression.unaliased.type.numeric.power +import ch.ergon.dope.toDopeType +import ch.ergon.dope.validtype.NumberType +import com.schwarz.crystalapi.schema.CMField + +fun power(base: CMField, exponent: CMField) = power(base.toDopeType(), exponent.toDopeType()) + +fun power(base: CMField, exponent: TypeExpression) = power(base.toDopeType(), exponent) + +fun power(base: CMField, exponent: Number) = power(base.toDopeType(), exponent) + +fun power(base: TypeExpression, exponent: CMField) = power(base, exponent.toDopeType()) + +fun power(base: Number, exponent: CMField) = power(base, exponent.toDopeType()) diff --git a/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/Radians.kt b/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/Radians.kt new file mode 100644 index 00000000..76888040 --- /dev/null +++ b/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/Radians.kt @@ -0,0 +1,7 @@ +package ch.ergon.dope.extension.type.numberfunction + +import ch.ergon.dope.resolvable.expression.unaliased.type.numeric.radians +import ch.ergon.dope.toDopeType +import com.schwarz.crystalapi.schema.CMField + +fun radians(field: CMField) = radians(field.toDopeType()) diff --git a/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/Random.kt b/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/Random.kt new file mode 100644 index 00000000..57fe3853 --- /dev/null +++ b/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/Random.kt @@ -0,0 +1,7 @@ +package ch.ergon.dope.extension.type.numberfunction + +import ch.ergon.dope.resolvable.expression.unaliased.type.numeric.random +import ch.ergon.dope.toDopeType +import com.schwarz.crystalapi.schema.CMField + +fun random(field: CMField) = random(field.toDopeType()) diff --git a/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/Round.kt b/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/Round.kt new file mode 100644 index 00000000..24e32d90 --- /dev/null +++ b/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/Round.kt @@ -0,0 +1,19 @@ +package ch.ergon.dope.extension.type.numberfunction + +import ch.ergon.dope.resolvable.expression.TypeExpression +import ch.ergon.dope.resolvable.expression.unaliased.type.numeric.round +import ch.ergon.dope.toDopeType +import ch.ergon.dope.validtype.NumberType +import com.schwarz.crystalapi.schema.CMField + +fun round(field: CMField) = round(field.toDopeType()) + +fun round(field: CMField, digits: CMField) = round(field.toDopeType(), digits.toDopeType()) + +fun round(field: CMField, digits: TypeExpression) = round(field.toDopeType(), digits) + +fun round(field: CMField, digits: Number) = round(field.toDopeType(), digits) + +fun round(value: TypeExpression, digits: CMField) = round(value, digits.toDopeType()) + +fun round(value: Number, digits: CMField) = round(value, digits.toDopeType()) diff --git a/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/Sign.kt b/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/Sign.kt new file mode 100644 index 00000000..17cd7b94 --- /dev/null +++ b/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/Sign.kt @@ -0,0 +1,7 @@ +package ch.ergon.dope.extension.type.numberfunction + +import ch.ergon.dope.resolvable.expression.unaliased.type.numeric.sign +import ch.ergon.dope.toDopeType +import com.schwarz.crystalapi.schema.CMField + +fun sign(field: CMField) = sign(field.toDopeType()) diff --git a/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/Sine.kt b/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/Sine.kt new file mode 100644 index 00000000..f94ae0a0 --- /dev/null +++ b/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/Sine.kt @@ -0,0 +1,7 @@ +package ch.ergon.dope.extension.type.numberfunction + +import ch.ergon.dope.resolvable.expression.unaliased.type.numeric.sin +import ch.ergon.dope.toDopeType +import com.schwarz.crystalapi.schema.CMField + +fun sin(field: CMField) = sin(field.toDopeType()) diff --git a/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/SquareRoot.kt b/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/SquareRoot.kt new file mode 100644 index 00000000..ce77ef52 --- /dev/null +++ b/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/SquareRoot.kt @@ -0,0 +1,7 @@ +package ch.ergon.dope.extension.type.numberfunction + +import ch.ergon.dope.resolvable.expression.unaliased.type.numeric.sqrt +import ch.ergon.dope.toDopeType +import com.schwarz.crystalapi.schema.CMField + +fun sqrt(field: CMField) = sqrt(field.toDopeType()) diff --git a/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/Tangent.kt b/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/Tangent.kt new file mode 100644 index 00000000..2c7206ff --- /dev/null +++ b/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/Tangent.kt @@ -0,0 +1,7 @@ +package ch.ergon.dope.extension.type.numberfunction + +import ch.ergon.dope.resolvable.expression.unaliased.type.numeric.tan +import ch.ergon.dope.toDopeType +import com.schwarz.crystalapi.schema.CMField + +fun tan(field: CMField) = tan(field.toDopeType()) diff --git a/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/Truncation.kt b/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/Truncation.kt new file mode 100644 index 00000000..2647db48 --- /dev/null +++ b/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/numberfunction/Truncation.kt @@ -0,0 +1,19 @@ +package ch.ergon.dope.extension.type.numberfunction + +import ch.ergon.dope.resolvable.expression.TypeExpression +import ch.ergon.dope.resolvable.expression.unaliased.type.numeric.trunc +import ch.ergon.dope.toDopeType +import ch.ergon.dope.validtype.NumberType +import com.schwarz.crystalapi.schema.CMField + +fun trunc(field: CMField) = trunc(field.toDopeType()) + +fun trunc(field: CMField, digits: CMField) = trunc(field.toDopeType(), digits.toDopeType()) + +fun trunc(field: CMField, digits: TypeExpression) = trunc(field.toDopeType(), digits) + +fun trunc(field: CMField, digits: Number) = trunc(field.toDopeType(), digits) + +fun trunc(value: TypeExpression, digits: CMField) = trunc(value, digits.toDopeType()) + +fun trunc(value: Number, digits: CMField) = trunc(value, digits.toDopeType()) diff --git a/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/relational/NotLike.kt b/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/relational/NotLike.kt new file mode 100644 index 00000000..c7f06810 --- /dev/null +++ b/crystal-map-connector/src/main/kotlin/ch/ergon/dope/extension/type/relational/NotLike.kt @@ -0,0 +1,25 @@ +package ch.ergon.dope.extension.type.relational + +import ch.ergon.dope.resolvable.expression.TypeExpression +import ch.ergon.dope.resolvable.expression.unaliased.type.Field +import ch.ergon.dope.resolvable.expression.unaliased.type.relational.NotLikeExpression +import ch.ergon.dope.resolvable.expression.unaliased.type.relational.isNotLike +import ch.ergon.dope.resolvable.expression.unaliased.type.toDopeType +import ch.ergon.dope.toDopeType +import ch.ergon.dope.validtype.StringType +import ch.ergon.dope.validtype.ValidType +import com.schwarz.crystalapi.schema.CMField + +fun Field.isNotLike(right: CMField): NotLikeExpression = isNotLike(right.toDopeType()) + +@JvmName("isNotLikeNumber") +fun CMField.isNotLike(right: String): NotLikeExpression = toDopeType().isNotLike(right.toDopeType()) + +@JvmName("isNotLikeString") +fun CMField.isNotLike(right: String): NotLikeExpression = toDopeType().isNotLike(right.toDopeType()) + +@JvmName("isNotLikeString") +fun CMField.isNotLike(right: TypeExpression): NotLikeExpression = toDopeType().isNotLike(right) + +@JvmName("isNotLikeBoolean") +fun CMField.isNotLike(right: String): NotLikeExpression = toDopeType().isNotLike(right.toDopeType()) diff --git a/crystal-map-connector/src/test/kotlin/ch/ergon/dope/extensions/type/numeric/NumberFunctionTest.kt b/crystal-map-connector/src/test/kotlin/ch/ergon/dope/extensions/type/numeric/NumberFunctionTest.kt new file mode 100644 index 00000000..ba3b1786 --- /dev/null +++ b/crystal-map-connector/src/test/kotlin/ch/ergon/dope/extensions/type/numeric/NumberFunctionTest.kt @@ -0,0 +1,380 @@ +package ch.ergon.dope.extensions.type.numeric + +import ch.ergon.dope.extension.type.numberfunction.abs +import ch.ergon.dope.extension.type.numberfunction.acos +import ch.ergon.dope.extension.type.numberfunction.asin +import ch.ergon.dope.extension.type.numberfunction.atan +import ch.ergon.dope.extension.type.numberfunction.atan2 +import ch.ergon.dope.extension.type.numberfunction.ceil +import ch.ergon.dope.extension.type.numberfunction.cos +import ch.ergon.dope.extension.type.numberfunction.degrees +import ch.ergon.dope.extension.type.numberfunction.exp +import ch.ergon.dope.extension.type.numberfunction.floor +import ch.ergon.dope.extension.type.numberfunction.ln +import ch.ergon.dope.extension.type.numberfunction.log +import ch.ergon.dope.extension.type.numberfunction.power +import ch.ergon.dope.extension.type.numberfunction.radians +import ch.ergon.dope.extension.type.numberfunction.random +import ch.ergon.dope.extension.type.numberfunction.round +import ch.ergon.dope.extension.type.numberfunction.sign +import ch.ergon.dope.extension.type.numberfunction.sin +import ch.ergon.dope.extension.type.numberfunction.sqrt +import ch.ergon.dope.extension.type.numberfunction.tan +import ch.ergon.dope.extension.type.numberfunction.trunc +import ch.ergon.dope.helper.someCMNumberField +import ch.ergon.dope.resolvable.expression.unaliased.type.toDopeType +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test + +class NumberFunctionTest { + @Test + fun `should support ABS number function with number CMField`() { + val expected = "ABS(`someNumberField`)" + + val actual = abs(someCMNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support ACOS number function with number CMField`() { + val expected = "ACOS(`someNumberField`)" + + val actual = acos(someCMNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support ASIN number function with number CMField`() { + val expected = "ASIN(`someNumberField`)" + + val actual = asin(someCMNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support ATAN number function with number CMField`() { + val expected = "ATAN(`someNumberField`)" + + val actual = atan(someCMNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support ATAN2 number function with divisor and dividend as number CMField`() { + val expected = "ATAN2(`someNumberField`, `anotherNumberField`)" + + val actual = atan2(someCMNumberField(), someCMNumberField("anotherNumberField")).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support ATAN2 number function with divisor as number CMField and dividend as TypeExpression`() { + val expected = "ATAN2(`someNumberField`, 1)" + + val actual = atan2(someCMNumberField(), 1.toDopeType()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support ATAN2 number function with divisor as number CMField and dividend as Number`() { + val expected = "ATAN2(`someNumberField`, 1)" + + val actual = atan2(someCMNumberField(), 1).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support ATAN2 number function with divisor as TypeExpression and dividend as number CMField`() { + val expected = "ATAN2(1, `someNumberField`)" + + val actual = atan2(1.toDopeType(), someCMNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support ATAN2 number function with divisor as Number and dividend as number CMField`() { + val expected = "ATAN2(1, `someNumberField`)" + + val actual = atan2(1, someCMNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support CEIL number function with number CMField`() { + val expected = "CEIL(`someNumberField`)" + + val actual = ceil(someCMNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support COS number function with number CMField`() { + val expected = "COS(`someNumberField`)" + + val actual = cos(someCMNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support DEGREES number function with number CMField`() { + val expected = "DEGREES(`someNumberField`)" + + val actual = degrees(someCMNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support EXP number function with number CMField`() { + val expected = "EXP(`someNumberField`)" + + val actual = exp(someCMNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support LN number function with number CMField`() { + val expected = "LN(`someNumberField`)" + + val actual = ln(someCMNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support LOG number function with number CMField`() { + val expected = "LOG(`someNumberField`)" + + val actual = log(someCMNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support FLOOR number function with number CMField`() { + val expected = "FLOOR(`someNumberField`)" + + val actual = floor(someCMNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support POWER number function with base and exponent as number CMField`() { + val expected = "POWER(`someNumberField`, `anotherNumberField`)" + + val actual = power(someCMNumberField(), someCMNumberField("anotherNumberField")).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support POWER number function with base as number CMField and exponent as TypeExpression`() { + val expected = "POWER(`someNumberField`, 1)" + + val actual = power(someCMNumberField(), 1.toDopeType()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support POWER number function with base as number CMField and exponent as Number`() { + val expected = "POWER(`someNumberField`, 1)" + + val actual = power(someCMNumberField(), 1).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support POWER number function with base as TypeExpression and exponent as number CMField`() { + val expected = "POWER(1, `someNumberField`)" + + val actual = power(1.toDopeType(), someCMNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support POWER number function with base as Number and exponent as number CMField`() { + val expected = "POWER(1, `someNumberField`)" + + val actual = power(1, someCMNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support RADIANS number function with number CMField`() { + val expected = "RADIANS(`someNumberField`)" + + val actual = radians(someCMNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support RANDOM number function with number CMField`() { + val expected = "RANDOM(`someNumberField`)" + + val actual = random(someCMNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support ROUND number function with number CMField`() { + val expected = "ROUND(`someNumberField`)" + + val actual = round(someCMNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support ROUND number function with value and digits as number CMField`() { + val expected = "ROUND(`someNumberField`, `anotherNumberField`)" + + val actual = round(someCMNumberField(), someCMNumberField("anotherNumberField")).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support ROUND number function with value as number CMField and digits as TypeExpression`() { + val expected = "ROUND(`someNumberField`, 1)" + + val actual = round(someCMNumberField(), 1.toDopeType()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support ROUND number function with value as number CMField and digits as Number`() { + val expected = "ROUND(`someNumberField`, 1)" + + val actual = round(someCMNumberField(), 1).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support ROUND number function with value as TypeExpression and digits as number CMField`() { + val expected = "ROUND(1, `someNumberField`)" + + val actual = round(1.toDopeType(), someCMNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support ROUND number function with value as Number and digits as number CMField`() { + val expected = "ROUND(1, `someNumberField`)" + + val actual = round(1, someCMNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support SIGN number function with number CMField`() { + val expected = "SIGN(`someNumberField`)" + + val actual = sign(someCMNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support SIN number function with number CMField`() { + val expected = "SIN(`someNumberField`)" + + val actual = sin(someCMNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support SQRT number function with number CMField`() { + val expected = "SQRT(`someNumberField`)" + + val actual = sqrt(someCMNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support TAN number function with number CMField`() { + val expected = "TAN(`someNumberField`)" + + val actual = tan(someCMNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support TRUNC number function with number CMField`() { + val expected = "TRUNC(`someNumberField`)" + + val actual = trunc(someCMNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support TRUNC number function with value and digits as number CMField`() { + val expected = "TRUNC(`someNumberField`, `anotherNumberField`)" + + val actual = trunc(someCMNumberField(), someCMNumberField("anotherNumberField")).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support TRUNC number function with value as number CMField and digits as TypeExpression`() { + val expected = "TRUNC(`someNumberField`, 1)" + + val actual = trunc(someCMNumberField(), 1.toDopeType()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support TRUNC number function with value as number CMField and digits as Number`() { + val expected = "TRUNC(`someNumberField`, 1)" + + val actual = trunc(someCMNumberField(), 1).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support TRUNC number function with value as TypeExpression and digits as number CMField`() { + val expected = "TRUNC(1, `someNumberField`)" + + val actual = trunc(1.toDopeType(), someCMNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } + + @Test + fun `should support TRUNC number function with value as Number and digits as number CMField`() { + val expected = "TRUNC(1, `someNumberField`)" + + val actual = trunc(1, someCMNumberField()).toDopeQuery().queryString + + assertEquals(expected, actual) + } +}