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-242: feature use index #49

Merged
merged 19 commits into from
Sep 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
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
7 changes: 4 additions & 3 deletions core/src/main/kotlin/ch/ergon/dope/QueryBuilder.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ import ch.ergon.dope.resolvable.clause.model.UpdateClause
import ch.ergon.dope.resolvable.expression.AsteriskExpression
import ch.ergon.dope.resolvable.expression.Expression
import ch.ergon.dope.resolvable.expression.SingleExpression
import ch.ergon.dope.resolvable.fromable.Bucket
import ch.ergon.dope.resolvable.fromable.Deletable
import ch.ergon.dope.resolvable.fromable.Fromable
import ch.ergon.dope.resolvable.fromable.Updatable

class QueryBuilder {
fun select(expression: Expression, vararg expressions: Expression) = SelectClause(expression, *expressions)
Expand All @@ -22,7 +23,7 @@ class QueryBuilder {

fun selectFrom(fromable: Fromable) = SelectClause(AsteriskExpression()).from(fromable)

fun deleteFrom(bucket: Bucket) = DeleteClause(bucket)
fun deleteFrom(deletable: Deletable) = DeleteClause(deletable)

fun update(bucket: Bucket) = UpdateClause(bucket)
fun update(updatable: Updatable) = UpdateClause(updatable)
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package ch.ergon.dope.resolvable

import ch.ergon.dope.DopeQuery

fun formatToQueryString(left: String, vararg right: String) =
"$left ${right.joinToString()}"

Expand All @@ -10,6 +12,7 @@ fun formatToQueryStringWithSeparator(symbol: String, separator: String, vararg a
"$symbol$separator${argument.joinToString(separator = ", ")}"

fun formatToQueryStringWithBrackets(left: String, symbol: String, right: String) = "($left $symbol $right)"

fun formatToQueryStringWithBrackets(symbol: String, vararg argument: String) =
"$symbol(${argument.joinToString(separator = ", ")})"

Expand All @@ -19,3 +22,12 @@ fun formatPathToQueryString(name: String, path: String) =
} else {
"`$path`.`$name`"
}

fun formatStringListToQueryStringWithBrackets(dopeQueries: List<String>, seperator: String = ", ", prefix: String = "(", postfix: String = ")") =
dopeQueries.joinToString(seperator, prefix, postfix)

fun formatListToQueryStringWithBrackets(dopeQueries: List<DopeQuery>, seperator: String = ", ", prefix: String = "(", postfix: String = ")") =
dopeQueries.joinToString(seperator, prefix, postfix) { it.queryString }

fun formatIndexToQueryString(indexName: String?, indexType: String?) =
listOfNotNull(indexName?.let { "`$it`" }, indexType).joinToString(separator = " ")
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,12 @@ 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.DeleteReturningClause
import ch.ergon.dope.resolvable.clause.model.DeleteUseKeys.Companion.DeleteUseKeysClause
import ch.ergon.dope.resolvable.clause.model.DeleteWhereClause
import ch.ergon.dope.resolvable.expression.TypeExpression
import ch.ergon.dope.resolvable.expression.unaliased.type.Field
import ch.ergon.dope.resolvable.expression.unaliased.type.toDopeType
import ch.ergon.dope.validtype.ArrayType
import ch.ergon.dope.validtype.BooleanType
import ch.ergon.dope.validtype.NumberType
import ch.ergon.dope.validtype.StringType
import ch.ergon.dope.validtype.ValidType

interface IDeleteReturningClause : Clause
Expand All @@ -30,15 +27,6 @@ interface IDeleteWhereClause : IDeleteLimitClause {
fun limit(number: Number) = limit(number.toDopeType())
}

interface IDeleteUseKeysClause : IDeleteWhereClause {
interface IDeleteClause : IDeleteWhereClause {
fun where(booleanExpression: TypeExpression<BooleanType>) = DeleteWhereClause(booleanExpression, this)
}

interface IDeleteClause : IDeleteUseKeysClause {
fun useKeys(key: TypeExpression<StringType>) = 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<ArrayType<StringType>>) = DeleteUseKeysClause(key, this)
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ 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.SelectUseKeys.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
Expand All @@ -22,6 +21,7 @@ import ch.ergon.dope.resolvable.expression.unaliased.type.toDopeType
import ch.ergon.dope.resolvable.fromable.AliasedSelectClause
import ch.ergon.dope.resolvable.fromable.Bucket
import ch.ergon.dope.resolvable.fromable.Fromable
import ch.ergon.dope.resolvable.fromable.Joinable
import ch.ergon.dope.validtype.ArrayType
import ch.ergon.dope.validtype.BooleanType
import ch.ergon.dope.validtype.NumberType
Expand Down Expand Up @@ -49,33 +49,26 @@ interface ISelectWhereClause : ISelectGroupByClause {
fun groupBy(field: Field<out ValidType>, vararg fields: Field<out ValidType>) = GroupByClause(field, *fields, parentClause = this)
}

interface ISelectUseKeysClause : ISelectWhereClause {
interface ISelectFromClause : ISelectWhereClause {
fun where(whereExpression: TypeExpression<BooleanType>) = SelectWhereClause(whereExpression, this)
}

interface ISelectFromClause : ISelectUseKeysClause {
fun useKeys(key: TypeExpression<StringType>) = 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<ArrayType<StringType>>) = SelectUseKeysClause(keys, this)
}

interface ISelectJoinClause : ISelectFromClause {
fun join(bucket: Bucket, onCondition: TypeExpression<BooleanType>) = StandardJoinClause(bucket, onCondition, this)
fun join(bucket: Bucket, onKeys: Field<out ValidType>) = StandardJoinClause(bucket, onKeys, this)
fun join(bucket: Bucket, onKey: Field<out ValidType>, forBucket: Bucket) = StandardJoinClause(bucket, onKey, forBucket, this)
fun join(joinable: Joinable, onCondition: TypeExpression<BooleanType>) = StandardJoinClause(joinable, onCondition, this)
fun join(joinable: Joinable, onKeys: Field<out ValidType>) = StandardJoinClause(joinable, onKeys, this)
fun join(joinable: Joinable, onKey: Field<out ValidType>, forBucket: Bucket) = StandardJoinClause(joinable, onKey, forBucket, this)

fun innerJoin(joinable: Joinable, onCondition: TypeExpression<BooleanType>) = InnerJoinClause(joinable, onCondition, this)
fun innerJoin(joinable: Joinable, onKeys: Field<out ValidType>) = InnerJoinClause(joinable, onKeys, this)
fun innerJoin(joinable: Joinable, onKey: Field<out ValidType>, forBucket: Bucket) = InnerJoinClause(joinable, onKey, forBucket, this)

fun innerJoin(bucket: Bucket, onCondition: TypeExpression<BooleanType>) = InnerJoinClause(bucket, onCondition, this)
fun innerJoin(bucket: Bucket, onKeys: Field<out ValidType>) = InnerJoinClause(bucket, onKeys, this)
fun innerJoin(bucket: Bucket, onKey: Field<out ValidType>, forBucket: Bucket) = InnerJoinClause(bucket, onKey, forBucket, this)
fun leftJoin(joinable: Joinable, onCondition: TypeExpression<BooleanType>) = LeftJoinClause(joinable, onCondition, this)
fun leftJoin(joinable: Joinable, onKeys: Field<out ValidType>) = LeftJoinClause(joinable, onKeys, this)
fun leftJoin(joinable: Joinable, onKey: Field<out ValidType>, forBucket: Bucket) = LeftJoinClause(joinable, onKey, forBucket, this)

fun leftJoin(bucket: Bucket, onCondition: TypeExpression<BooleanType>) = LeftJoinClause(bucket, onCondition, this)
fun leftJoin(bucket: Bucket, onKeys: Field<out ValidType>) = LeftJoinClause(bucket, onKeys, this)
fun leftJoin(bucket: Bucket, onKey: Field<out ValidType>, forBucket: Bucket) = LeftJoinClause(bucket, onKey, forBucket, this)
fun rightJoin(joinable: Joinable, onCondition: TypeExpression<BooleanType>) = RightJoinClause(joinable, onCondition, this)

fun rightJoin(bucket: Bucket, onCondition: TypeExpression<BooleanType>) = RightJoinClause(bucket, onCondition, this)
fun alias(alias: String) = AliasedSelectClause(alias, this)
}

interface ISelectUnnestClause : ISelectJoinClause {
Expand All @@ -85,6 +78,4 @@ interface ISelectUnnestClause : ISelectJoinClause {

interface ISelectClause : ISelectFromClause {
fun from(fromable: Fromable) = FromClause(fromable, this)

fun alias(alias: String) = AliasedSelectClause(alias, this)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,11 @@ import ch.ergon.dope.resolvable.clause.model.SetClause
import ch.ergon.dope.resolvable.clause.model.UnsetClause
import ch.ergon.dope.resolvable.clause.model.UpdateLimitClause
import ch.ergon.dope.resolvable.clause.model.UpdateReturningClause
import ch.ergon.dope.resolvable.clause.model.UpdateUseKeys.Companion.UpdateUseKeysClause
import ch.ergon.dope.resolvable.clause.model.UpdateWhereClause
import ch.ergon.dope.resolvable.clause.model.to
import ch.ergon.dope.resolvable.expression.TypeExpression
import ch.ergon.dope.resolvable.expression.unaliased.type.Field
import ch.ergon.dope.resolvable.expression.unaliased.type.toDopeType
import ch.ergon.dope.validtype.ArrayType
import ch.ergon.dope.validtype.BooleanType
import ch.ergon.dope.validtype.NumberType
import ch.ergon.dope.validtype.StringType
Expand All @@ -36,18 +34,9 @@ interface IUpdateSetClause : IUpdateUnsetClause {
fun unset(field: Field<out ValidType>) = UnsetClause(field, parentClause = this)
}

interface IUpdateUseKeysClause : IUpdateSetClause {
interface IUpdateClause : IUpdateSetClause {
fun <T : ValidType> set(field: Field<T>, value: TypeExpression<T>) = SetClause(field.to(value), parentClause = this)
fun set(field: Field<NumberType>, value: Number) = SetClause(field.to(value.toDopeType()), parentClause = this)
fun set(field: Field<StringType>, value: String) = SetClause(field.to(value.toDopeType()), parentClause = this)
fun set(field: Field<BooleanType>, value: Boolean) = SetClause(field.to(value.toDopeType()), parentClause = this)
}

interface IUpdateClause : IUpdateUseKeysClause {
fun useKeys(key: TypeExpression<StringType>) = UpdateUseKeysClause(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<ArrayType<StringType>>) = UpdateUseKeysClause(key, this)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@ import ch.ergon.dope.DopeQuery
import ch.ergon.dope.DopeQueryManager
import ch.ergon.dope.resolvable.clause.IDeleteClause
import ch.ergon.dope.resolvable.fromable.AliasedBucket
import ch.ergon.dope.resolvable.fromable.Bucket

class DeleteClause(private val bucket: Bucket) : IDeleteClause {
import ch.ergon.dope.resolvable.fromable.Deletable

class DeleteClause(private val deletable: Deletable) : IDeleteClause {
jansigi marked this conversation as resolved.
Show resolved Hide resolved
override fun toDopeQuery(manager: DopeQueryManager): DopeQuery {
val bucketDopeQuery = when (bucket) {
is AliasedBucket -> bucket.asBucketDefinition().toDopeQuery(manager)
else -> bucket.toDopeQuery(manager)
val bucketDopeQuery = when (deletable) {
is AliasedBucket -> deletable.asBucketDefinition().toDopeQuery(manager)
else -> deletable.toDopeQuery(manager)
}
return DopeQuery(
queryString = "DELETE FROM ${bucketDopeQuery.queryString}",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import ch.ergon.dope.resolvable.expression.TypeExpression
import ch.ergon.dope.resolvable.expression.unaliased.type.Field
import ch.ergon.dope.resolvable.fromable.AliasedBucket
import ch.ergon.dope.resolvable.fromable.Bucket
import ch.ergon.dope.resolvable.fromable.Joinable
import ch.ergon.dope.validtype.BooleanType
import ch.ergon.dope.validtype.ValidType

Expand All @@ -33,7 +34,7 @@ private enum class OnType {

sealed class SelectJoinClause : ISelectJoinClause {
private val joinType: JoinType
private val bucket: Bucket
private val joinable: Joinable
private val onCondition: TypeExpression<BooleanType>?
private val onKeys: Field<out ValidType>?
private val onKey: Field<out ValidType>?
Expand All @@ -43,13 +44,13 @@ sealed class SelectJoinClause : ISelectJoinClause {

constructor(
joinType: JoinType,
bucket: Bucket,
joinable: Joinable,
onCondition: TypeExpression<BooleanType>,
parentClause: ISelectFromClause,
) {
this.onType = ON
this.joinType = joinType
this.bucket = bucket
this.joinable = joinable
this.onCondition = onCondition
this.parentClause = parentClause
this.onKeys = null
Expand All @@ -59,13 +60,13 @@ sealed class SelectJoinClause : ISelectJoinClause {

constructor(
joinType: JoinType,
bucket: Bucket,
joinable: Joinable,
onKeys: Field<out ValidType>,
parentClause: ISelectFromClause,
) {
this.onType = ON_KEYS
this.joinType = joinType
this.bucket = bucket
this.joinable = joinable
this.onKeys = onKeys
this.parentClause = parentClause
this.onCondition = null
Expand All @@ -75,14 +76,14 @@ sealed class SelectJoinClause : ISelectJoinClause {

constructor(
joinType: JoinType,
bucket: Bucket,
joinable: Joinable,
onKey: Field<out ValidType>,
forBucket: Bucket,
parentClause: ISelectFromClause,
) {
this.onType = ON_KEY_FOR
this.joinType = joinType
this.bucket = bucket
this.joinable = joinable
this.onKey = onKey
this.forBucket = forBucket
this.parentClause = parentClause
Expand All @@ -92,12 +93,12 @@ sealed class SelectJoinClause : ISelectJoinClause {

override fun toDopeQuery(manager: DopeQueryManager): DopeQuery {
val parentDopeQuery = parentClause.toDopeQuery(manager)
val bucketDopeQuery = when (bucket) {
is AliasedBucket -> bucket.asBucketDefinition().toDopeQuery(manager)
else -> bucket.toDopeQuery(manager)
val joinableDopeQuery = when (joinable) {
is AliasedBucket -> joinable.asBucketDefinition().toDopeQuery(manager)
else -> joinable.toDopeQuery(manager)
}
val joinQueryString = "${parentDopeQuery.queryString} ${joinType.type} ${bucketDopeQuery.queryString}"
val joinParameters = parentDopeQuery.parameters + bucketDopeQuery.parameters
val joinQueryString = "${parentDopeQuery.queryString} ${joinType.type} ${joinableDopeQuery.queryString}"
val joinParameters = parentDopeQuery.parameters + joinableDopeQuery.parameters

return when (onType) {
ON -> {
Expand Down Expand Up @@ -130,37 +131,37 @@ sealed class SelectJoinClause : ISelectJoinClause {
}

class StandardJoinClause : SelectJoinClause {
constructor(bucket: Bucket, onCondition: TypeExpression<BooleanType>, parentClause: ISelectFromClause) :
super(JOIN, bucket, onCondition, parentClause)
constructor(joinable: Joinable, onCondition: TypeExpression<BooleanType>, parentClause: ISelectFromClause) :
super(JOIN, joinable, onCondition, parentClause)

constructor(bucket: Bucket, onKeys: Field<out ValidType>, parentClause: ISelectFromClause) :
super(JOIN, bucket, onKeys, parentClause)
constructor(joinable: Joinable, onKeys: Field<out ValidType>, parentClause: ISelectFromClause) :
super(JOIN, joinable, onKeys, parentClause)

constructor(bucket: Bucket, onKey: Field<out ValidType>, forBucket: Bucket, parentClause: ISelectFromClause) :
super(JOIN, bucket, onKey, forBucket, parentClause)
constructor(joinable: Joinable, onKey: Field<out ValidType>, forBucket: Bucket, parentClause: ISelectFromClause) :
super(JOIN, joinable, onKey, forBucket, parentClause)
}

class LeftJoinClause : SelectJoinClause {
constructor(bucket: Bucket, onCondition: TypeExpression<BooleanType>, parentClause: ISelectFromClause) :
super(LEFT_JOIN, bucket, onCondition, parentClause)
constructor(joinable: Joinable, onCondition: TypeExpression<BooleanType>, parentClause: ISelectFromClause) :
super(LEFT_JOIN, joinable, onCondition, parentClause)

constructor(bucket: Bucket, onKeys: Field<out ValidType>, parentClause: ISelectFromClause) :
super(LEFT_JOIN, bucket, onKeys, parentClause)
constructor(joinable: Joinable, onKeys: Field<out ValidType>, parentClause: ISelectFromClause) :
super(LEFT_JOIN, joinable, onKeys, parentClause)

constructor(bucket: Bucket, onKey: Field<out ValidType>, forBucket: Bucket, parentClause: ISelectFromClause) :
super(LEFT_JOIN, bucket, onKey, forBucket, parentClause)
constructor(joinable: Joinable, onKey: Field<out ValidType>, forBucket: Bucket, parentClause: ISelectFromClause) :
super(LEFT_JOIN, joinable, onKey, forBucket, parentClause)
}

class InnerJoinClause : SelectJoinClause {
constructor(bucket: Bucket, onCondition: TypeExpression<BooleanType>, parentClause: ISelectFromClause) :
super(INNER_JOIN, bucket, onCondition, parentClause)
constructor(joinable: Joinable, onCondition: TypeExpression<BooleanType>, parentClause: ISelectFromClause) :
super(INNER_JOIN, joinable, onCondition, parentClause)

constructor(bucket: Bucket, onKeys: Field<out ValidType>, parentClause: ISelectFromClause) :
super(INNER_JOIN, bucket, onKeys, parentClause)
constructor(joinable: Joinable, onKeys: Field<out ValidType>, parentClause: ISelectFromClause) :
super(INNER_JOIN, joinable, onKeys, parentClause)

constructor(bucket: Bucket, onKey: Field<out ValidType>, forBucket: Bucket, parentClause: ISelectFromClause) :
super(INNER_JOIN, bucket, onKey, forBucket, parentClause)
constructor(joinable: Joinable, onKey: Field<out ValidType>, forBucket: Bucket, parentClause: ISelectFromClause) :
super(INNER_JOIN, joinable, onKey, forBucket, parentClause)
}

class RightJoinClause(bucket: Bucket, onCondition: TypeExpression<BooleanType>, parentClause: ISelectFromClause) :
SelectJoinClause(RIGHT_JOIN, bucket, onCondition, parentClause)
class RightJoinClause(joinable: Joinable, onCondition: TypeExpression<BooleanType>, parentClause: ISelectFromClause) :
SelectJoinClause(RIGHT_JOIN, joinable, onCondition, parentClause)
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@ import ch.ergon.dope.DopeQuery
import ch.ergon.dope.DopeQueryManager
import ch.ergon.dope.resolvable.clause.IUpdateClause
import ch.ergon.dope.resolvable.fromable.AliasedBucket
import ch.ergon.dope.resolvable.fromable.Bucket
import ch.ergon.dope.resolvable.fromable.Updatable

class UpdateClause(private val bucket: Bucket) : IUpdateClause {
class UpdateClause(private val updatable: Updatable) : IUpdateClause {
override fun toDopeQuery(manager: DopeQueryManager): DopeQuery {
val resolvableDopeQuery = when (bucket) {
is AliasedBucket -> bucket.asBucketDefinition().toDopeQuery(manager)
else -> bucket.toDopeQuery(manager)
val updatableDopeQuery = when (updatable) {
is AliasedBucket -> updatable.asBucketDefinition().toDopeQuery(manager)
else -> updatable.toDopeQuery(manager)
}
return DopeQuery(
queryString = "UPDATE ${resolvableDopeQuery.queryString}",
parameters = resolvableDopeQuery.parameters,
queryString = "UPDATE ${updatableDopeQuery.queryString}",
parameters = updatableDopeQuery.parameters,
)
}
}
Loading
Loading