Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package ch.ergon.dope.resolvable.expression.type.function.token

import ch.ergon.dope.resolvable.expression.operator.FunctionOperator
import ch.ergon.dope.resolvable.expression.type.TypeExpression
import ch.ergon.dope.resolvable.expression.type.function.token.factory.ContainsTokenOptions
import ch.ergon.dope.resolvable.expression.type.toDopeType
import ch.ergon.dope.validtype.BooleanType
import ch.ergon.dope.validtype.StringType
import ch.ergon.dope.validtype.ValidType

data class ContainsTokenExpression(
val inputObject: TypeExpression<out ValidType>,
Comment thread
jansigi marked this conversation as resolved.
Outdated
Comment thread
jansigi marked this conversation as resolved.
Outdated
val tokenExpression: TypeExpression<StringType>,
val options: ContainsTokenOptions? = null,
) : FunctionOperator<BooleanType>

fun TypeExpression<out ValidType>.containsToken(
tokenExpression: TypeExpression<StringType>,
options: ContainsTokenOptions? = null,
) = ContainsTokenExpression(this, tokenExpression, options)

fun TypeExpression<out ValidType>.containsToken(
tokenExpression: String,
Comment thread
jansigi marked this conversation as resolved.
Outdated
options: ContainsTokenOptions? = null,
) = containsToken(tokenExpression.toDopeType(), options)
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package ch.ergon.dope.resolvable.expression.type.function.token

import ch.ergon.dope.resolvable.expression.operator.FunctionOperator
import ch.ergon.dope.resolvable.expression.type.TypeExpression
import ch.ergon.dope.resolvable.expression.type.function.token.factory.ContainsTokenOptions
import ch.ergon.dope.resolvable.expression.type.toDopeType
import ch.ergon.dope.validtype.BooleanType
import ch.ergon.dope.validtype.StringType
import ch.ergon.dope.validtype.ValidType

data class ContainsTokenLikeExpression(
val inputObject: TypeExpression<out ValidType>,
val tokenExpression: TypeExpression<StringType>,
Comment thread
jansigi marked this conversation as resolved.
Outdated
val options: ContainsTokenOptions? = null,
) : FunctionOperator<BooleanType>

fun TypeExpression<out ValidType>.containsTokenLike(
tokenExpression: TypeExpression<StringType>,
options: ContainsTokenOptions? = null,
) = ContainsTokenLikeExpression(this, tokenExpression, options)

fun TypeExpression<out ValidType>.containsTokenLike(
Comment thread
jansigi marked this conversation as resolved.
tokenExpression: String,
options: ContainsTokenOptions? = null,
) = containsTokenLike(tokenExpression.toDopeType(), options)
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package ch.ergon.dope.resolvable.expression.type.function.token

import ch.ergon.dope.resolvable.expression.operator.FunctionOperator
import ch.ergon.dope.resolvable.expression.type.TypeExpression
import ch.ergon.dope.resolvable.expression.type.function.token.factory.ContainsTokenOptions
import ch.ergon.dope.resolvable.expression.type.toDopeType
import ch.ergon.dope.validtype.BooleanType
import ch.ergon.dope.validtype.StringType
import ch.ergon.dope.validtype.ValidType

data class ContainsTokenRegexpExpression(
val inputObject: TypeExpression<out ValidType>,
val tokenExpression: TypeExpression<StringType>,
Comment thread
jansigi marked this conversation as resolved.
Outdated
val options: ContainsTokenOptions? = null,
) : FunctionOperator<BooleanType>

fun TypeExpression<out ValidType>.containsTokenRegexp(
tokenExpression: TypeExpression<StringType>,
options: ContainsTokenOptions? = null,
) = ContainsTokenRegexpExpression(this, tokenExpression, options)

fun TypeExpression<out ValidType>.containsTokenRegexp(
Comment thread
jansigi marked this conversation as resolved.
tokenExpression: String,
options: ContainsTokenOptions? = null,
) = containsTokenRegexp(tokenExpression.toDopeType(), options)
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package ch.ergon.dope.resolvable.expression.type.function.token

import ch.ergon.dope.resolvable.expression.operator.FunctionOperator
import ch.ergon.dope.resolvable.expression.type.TypeExpression
import ch.ergon.dope.resolvable.expression.type.function.token.factory.CustomTokenOptions
import ch.ergon.dope.resolvable.expression.type.toDopeType
import ch.ergon.dope.validtype.ArrayType
import ch.ergon.dope.validtype.StringType

data class TokensExpression(
val inString: TypeExpression<ArrayType<StringType>>,
val options: CustomTokenOptions? = null,
Comment thread
jansigi marked this conversation as resolved.
Outdated
) : FunctionOperator<ArrayType<StringType>>

fun TypeExpression<ArrayType<StringType>>.tokens(options: CustomTokenOptions? = null) = TokensExpression(this, options)
Comment thread
jansigi marked this conversation as resolved.
Outdated

fun List<String>.tokens(options: CustomTokenOptions? = null) = toDopeType().tokens(options)
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package ch.ergon.dope.resolvable.expression.type.function.token.factory
Comment thread
jansigi marked this conversation as resolved.
Outdated

import ch.ergon.dope.resolvable.Resolvable

data class ContainsTokenOptions(
val names: Boolean? = null,
val case: TokenCases? = null,
val specials: Boolean? = null,
val split: Boolean? = null,
val trim: Boolean? = null,
) : Resolvable

fun containsTokenOptions(
names: Boolean? = null,
case: TokenCases? = null,
specials: Boolean? = null,
split: Boolean? = null,
trim: Boolean? = null,
) = ContainsTokenOptions(names, case, specials, split, trim)
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package ch.ergon.dope.resolvable.expression.type.function.string.factory
package ch.ergon.dope.resolvable.expression.type.function.token.factory

import ch.ergon.dope.resolvable.Resolvable

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ import ch.ergon.dope.resolvable.expression.rowscope.windowdefinition.WindowDefin
import ch.ergon.dope.resolvable.expression.rowscope.windowdefinition.WindowFrameClause
import ch.ergon.dope.resolvable.expression.type.CaseClass
import ch.ergon.dope.resolvable.expression.type.ObjectEntryPrimitive
import ch.ergon.dope.resolvable.expression.type.function.string.factory.CustomTokenOptions
import ch.ergon.dope.resolvable.expression.type.function.token.factory.ContainsTokenOptions
import ch.ergon.dope.resolvable.expression.type.function.token.factory.CustomTokenOptions
import ch.ergon.dope.resolver.QueryResolver

interface AbstractCouchbaseResolver : QueryResolver<CouchbaseDopeQuery> {
Expand Down Expand Up @@ -88,6 +89,8 @@ class CouchbaseResolver(

is Asterisk -> resolve(resolvable)

is ContainsTokenOptions -> resolve(resolvable)

is CustomTokenOptions -> resolve(resolvable)

is HashOrNestedLoopHint -> resolve(resolvable)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import ch.ergon.dope.couchbase.util.formatFunctionQueryString
import ch.ergon.dope.merge
import ch.ergon.dope.orEmpty
import ch.ergon.dope.resolvable.expression.operator.FunctionOperator
import ch.ergon.dope.resolvable.expression.type.TypeExpression
import ch.ergon.dope.resolvable.expression.type.function.FunctionExpression
import ch.ergon.dope.resolvable.expression.type.function.array.ArrayFunctionExpression
import ch.ergon.dope.resolvable.expression.type.function.conditional.DecodeExpression
Expand All @@ -17,9 +18,15 @@ import ch.ergon.dope.resolvable.expression.type.function.search.ISearchFunctionE
import ch.ergon.dope.resolvable.expression.type.function.search.SearchDependencyFunctionExpression
import ch.ergon.dope.resolvable.expression.type.function.search.SearchFunctionType
import ch.ergon.dope.resolvable.expression.type.function.string.MaskExpression
import ch.ergon.dope.resolvable.expression.type.function.string.TokensExpression
import ch.ergon.dope.resolvable.expression.type.function.token.ContainsTokenExpression
import ch.ergon.dope.resolvable.expression.type.function.token.ContainsTokenLikeExpression
import ch.ergon.dope.resolvable.expression.type.function.token.ContainsTokenRegexpExpression
import ch.ergon.dope.resolvable.expression.type.function.token.TokensExpression
import ch.ergon.dope.resolvable.expression.type.function.token.factory.ContainsTokenOptions
import ch.ergon.dope.resolvable.expression.type.function.type.ToNumberExpression
import ch.ergon.dope.resolvable.expression.type.toDopeType
import ch.ergon.dope.validtype.StringType
import ch.ergon.dope.validtype.ValidType

interface FunctionOperatorResolver : AbstractCouchbaseResolver {
fun resolve(typeExpression: FunctionOperator<*>): CouchbaseDopeQuery = when (typeExpression) {
Expand Down Expand Up @@ -78,16 +85,37 @@ interface FunctionOperatorResolver : AbstractCouchbaseResolver {
}

is TokensExpression -> {
val inString = typeExpression.inStr.toDopeType().toDopeQuery(this)
val inStringDopeQuery = typeExpression.inString.toDopeQuery(this)
val optionsDopeQuery = typeExpression.options?.toDopeQuery(this).takeIf { !it?.queryString.isNullOrEmpty() }
val functionQueryString = formatFunctionQueryString(
"TOKENS",
inString.queryString,
inStringDopeQuery.queryString,
optionsDopeQuery?.queryString,
)
CouchbaseDopeQuery(functionQueryString, optionsDopeQuery?.parameters.orEmpty())
CouchbaseDopeQuery(functionQueryString, inStringDopeQuery.parameters.merge(optionsDopeQuery?.parameters))
}

is ContainsTokenExpression -> resolve(
"CONTAINS_TOKEN",
typeExpression.inputObject,
typeExpression.tokenExpression,
typeExpression.options,
)

is ContainsTokenLikeExpression -> resolve(
"CONTAINS_TOKEN_LIKE",
typeExpression.inputObject,
typeExpression.tokenExpression,
typeExpression.options,
)

is ContainsTokenRegexpExpression -> resolve(
"CONTAINS_TOKEN_REGEXP",
typeExpression.inputObject,
typeExpression.tokenExpression,
typeExpression.options,
)

is MaskExpression -> {
val inputStringDopeQuery = typeExpression.inStr.toDopeQuery(this)
val optionsString =
Expand Down Expand Up @@ -187,4 +215,25 @@ interface FunctionOperatorResolver : AbstractCouchbaseResolver {

else -> throw UnsupportedOperationException("Not supported: $typeExpression")
}

private fun resolve(
symbol: String,
inputObject: TypeExpression<out ValidType>,
tokenExpression: TypeExpression<StringType>,
options: ContainsTokenOptions?,
): CouchbaseDopeQuery {
val inputObjectDopeQuery = inputObject.toDopeQuery(this)
val tokenExpressionDopeQuery = tokenExpression.toDopeQuery(this)
val optionsDopeQuery = options?.toDopeQuery(this).takeIf { !it?.queryString.isNullOrEmpty() }
val functionQueryString = formatFunctionQueryString(
symbol,
inputObjectDopeQuery.queryString,
tokenExpressionDopeQuery.queryString,
optionsDopeQuery?.queryString,
)
return CouchbaseDopeQuery(
functionQueryString,
inputObjectDopeQuery.parameters.merge(tokenExpressionDopeQuery.parameters, optionsDopeQuery?.parameters),
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ import ch.ergon.dope.resolvable.expression.type.collection.SatisfiesExpression
import ch.ergon.dope.resolvable.expression.type.function.array.UnpackExpression
import ch.ergon.dope.resolvable.expression.type.function.date.DateComponentType
import ch.ergon.dope.resolvable.expression.type.function.date.DateUnitType
import ch.ergon.dope.resolvable.expression.type.function.string.factory.CustomTokenOptions
import ch.ergon.dope.resolvable.expression.type.function.token.factory.ContainsTokenOptions
import ch.ergon.dope.resolvable.expression.type.function.token.factory.CustomTokenOptions
import ch.ergon.dope.resolvable.expression.type.range.RangeIndexedLike
import ch.ergon.dope.resolvable.expression.type.range.RangeLike
import ch.ergon.dope.resolvable.expression.type.relational.BetweenExpression
Expand Down Expand Up @@ -380,4 +381,20 @@ interface TypeExpressionResolver : InfixOperatorResolver, FunctionOperatorResolv

return CouchbaseDopeQuery(queryString = queryString)
}

fun resolve(containsTokenOptions: ContainsTokenOptions): CouchbaseDopeQuery {
val options = listOfNotNull(
containsTokenOptions.names?.let { "names" to it },
containsTokenOptions.case?.let { "case" to "\"${it.queryString}\"" },
containsTokenOptions.specials?.let { "specials" to it },
containsTokenOptions.split?.let { "split" to it },
containsTokenOptions.trim?.let { "trim" to it },
)
val queryString = options
.joinToString(", ", "{", "}") { (key, value) -> "\"$key\": $value" }
.takeIf { options.isNotEmpty() }
.orEmpty()
Comment thread
jansigi marked this conversation as resolved.

return CouchbaseDopeQuery(queryString = queryString)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ import ch.ergon.dope.resolvable.expression.type.arithmetic.add
import ch.ergon.dope.resolvable.expression.type.function.string.concat
import ch.ergon.dope.resolvable.expression.type.function.string.concat2
import ch.ergon.dope.resolvable.expression.type.function.string.contains
import ch.ergon.dope.resolvable.expression.type.function.string.factory.TokenCases
import ch.ergon.dope.resolvable.expression.type.function.string.factory.customTokenOptions
import ch.ergon.dope.resolvable.expression.type.function.string.initCap
import ch.ergon.dope.resolvable.expression.type.function.string.length
import ch.ergon.dope.resolvable.expression.type.function.string.lower
Expand All @@ -38,11 +36,13 @@ import ch.ergon.dope.resolvable.expression.type.function.string.substring
import ch.ergon.dope.resolvable.expression.type.function.string.substring1
import ch.ergon.dope.resolvable.expression.type.function.string.suffixes
import ch.ergon.dope.resolvable.expression.type.function.string.title
import ch.ergon.dope.resolvable.expression.type.function.string.tokens
import ch.ergon.dope.resolvable.expression.type.function.string.trim
import ch.ergon.dope.resolvable.expression.type.function.string.upper
import ch.ergon.dope.resolvable.expression.type.function.string.urlDecode
import ch.ergon.dope.resolvable.expression.type.function.string.urlEncode
import ch.ergon.dope.resolvable.expression.type.function.token.factory.TokenCases
import ch.ergon.dope.resolvable.expression.type.function.token.factory.customTokenOptions
import ch.ergon.dope.resolvable.expression.type.function.token.tokens
import ch.ergon.dope.resolvable.expression.type.get
import ch.ergon.dope.resolvable.expression.type.logic.and
import ch.ergon.dope.resolvable.expression.type.relational.isEqualTo
Expand Down Expand Up @@ -85,9 +85,7 @@ class StringFunctionsTest : ResolverDependentTest {

val actual: String = QueryBuilder
.select(
"abc".toDopeType().concat("def".toDopeType(), "ghi".toDopeType(), someStringField()).alias(
"concat",
),
"abc".toDopeType().concat("def".toDopeType(), "ghi".toDopeType(), someStringField()).alias("concat"),
).build(CouchbaseResolver()).queryString

assertEquals(unifyString(expected), actual)
Expand Down Expand Up @@ -142,9 +140,7 @@ class StringFunctionsTest : ResolverDependentTest {
fun `should Support Concat2 One Argument`() {
val expected = "CONCAT2(\"-\", \"a\") AS `c2`"

val actual: String = "-".concat2("a".toDopeType()).alias(
"c2",
).toDopeQuery(resolver).queryString
val actual: String = "-".concat2("a".toDopeType()).alias("c2").toDopeQuery(resolver).queryString

assertEquals(unifyString(expected), actual)
}
Expand Down

This file was deleted.

Loading