Skip to content

Commit

Permalink
feat(query): Add Condition expansion function to improve ease of use (
Browse files Browse the repository at this point in the history
  • Loading branch information
Ahoo-Wang authored Feb 29, 2024
1 parent 91aa074 commit 816ccf3
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 24 deletions.
31 changes: 26 additions & 5 deletions wow-api/src/main/kotlin/me/ahoo/wow/api/query/Query.kt
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,31 @@ data class Condition(
val children: List<Condition> = emptyList()
) {
companion object {
val EMPTY = Condition("", Operator.EMPTY, "")
val EMPTY_VALUE = Any()
const val EMPTY_VALUE = ""
val EMPTY = Condition(EMPTY_VALUE, Operator.EMPTY, EMPTY_VALUE)

fun and(vararg conditions: Condition) = Condition(EMPTY_VALUE, Operator.AND, children = conditions.toList())
fun and(conditions: List<Condition>) = Condition(EMPTY_VALUE, Operator.AND, children = conditions)
fun or(vararg conditions: Condition) = Condition(EMPTY_VALUE, Operator.OR, children = conditions.toList())
fun or(conditions: List<Condition>) = Condition(EMPTY_VALUE, Operator.OR, children = conditions)
fun empty() = EMPTY
fun eq(field: String, value: Any) = Condition(field, Operator.EQ, value)
fun ne(field: String, value: Any) = Condition(field, Operator.NE, value)
fun gt(field: String, value: Any) = Condition(field, Operator.GT, value)
fun lt(field: String, value: Any) = Condition(field, Operator.LT, value)
fun gte(field: String, value: Any) = Condition(field, Operator.GTE, value)
fun lte(field: String, value: Any) = Condition(field, Operator.LTE, value)
fun like(field: String, value: Any) = Condition(field, Operator.LIKE, value)

@Suppress("FunctionNaming")
fun `in`(field: String, value: List<Any>) = Condition(field, Operator.IN, value)
fun notIn(field: String, value: List<Any>) = Condition(field, Operator.NOT_IN, value)
fun <V> between(field: String, start: V, end: V) = Condition(field, Operator.BETWEEN, listOf(start, end))
fun all(field: String, value: List<Any>) = Condition(field, Operator.ALL, value)
fun startsWith(field: String, value: Any) = Condition(field, Operator.STATS_WITH, value)
fun elemMatch(field: String, value: Condition) = Condition(field, Operator.ELEM_MATCH, children = listOf(value))
fun isNull(field: String) = Condition(field, Operator.NULL)
fun notNull(field: String) = Condition(field, Operator.NOT_NULL)
}
}

Expand All @@ -56,9 +79,7 @@ data class Sort(val field: String, val direction: Direction) {

data class Pagination(val index: Int, val size: Int) {
companion object {
const val DEFAULT_PAGE_INDEX = 1
const val DEFAULT_PAGE_SIZE = 10
val DEFAULT_PAGINATION = Pagination(DEFAULT_PAGE_INDEX, DEFAULT_PAGE_SIZE)
val DEFAULT_PAGINATION = Pagination(1, 10)
fun offset(index: Int, size: Int) = (index - 1) * size
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class MongoSnapshotRepository(private val database: MongoDatabase) : SnapshotRep
val snapshotCollectionName = aggregateId.toSnapshotCollectionName()
return database.getCollection(snapshotCollectionName)
.find(Filters.eq(Documents.ID_FIELD, aggregateId.id))
.limit(1)
.first()
.toMono()
.map {
Expand All @@ -49,6 +50,7 @@ class MongoSnapshotRepository(private val database: MongoDatabase) : SnapshotRep
return database.getCollection(snapshotCollectionName)
.find(Filters.eq(Documents.ID_FIELD, aggregateId.id))
.projection(Document(MessageRecords.VERSION, 1))
.limit(1)
.first()
.toMono()
.map {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class MongoSnapshotQueryService(private val collection: MongoCollection<Document
override fun <S : Any> single(tenantId: String, condition: Condition): Mono<Snapshot<S>> {
val filter = condition.toMongoFilter().withTenantId(tenantId)
return collection.find(filter)
.limit(1)
.first()
.toMono()
.toSnapshot()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,33 +60,33 @@ class MongoFilterConverterTest {
fun toMongoFilterParameters(): Stream<Arguments> {
return Stream.of(
Arguments.of(Condition.EMPTY, Filters.empty()),
Arguments.of(Condition("id", Operator.EQ, "id"), Filters.eq("id", "id")),
Arguments.of(Condition("id", Operator.NE, "id"), Filters.ne("id", "id")),
Arguments.of(Condition("id", Operator.GT, 1), Filters.gt("id", 1)),
Arguments.of(Condition("id", Operator.LT, 1), Filters.lt("id", 1)),
Arguments.of(Condition("id", Operator.GTE, 1), Filters.gte("id", 1)),
Arguments.of(Condition("id", Operator.LTE, 1), Filters.lte("id", 1)),
Arguments.of(Condition("id", Operator.LIKE, "value"), Filters.regex("id", "value")),
Arguments.of(Condition("id", Operator.IN, listOf("value")), Filters.`in`("id", listOf("value"))),
Arguments.of(Condition("id", Operator.NOT_IN, listOf("value")), Filters.nin("id", listOf("value"))),
Arguments.of(Condition.eq("id", "id"), Filters.eq("id", "id")),
Arguments.of(Condition.ne("id", "id"), Filters.ne("id", "id")),
Arguments.of(Condition.gt("id", 1), Filters.gt("id", 1)),
Arguments.of(Condition.lt("id", 1), Filters.lt("id", 1)),
Arguments.of(Condition.gte("id", 1), Filters.gte("id", 1)),
Arguments.of(Condition.lte("id", 1), Filters.lte("id", 1)),
Arguments.of(Condition.like("id", "value"), Filters.regex("id", "value")),
Arguments.of(Condition.`in`("id", listOf("value")), Filters.`in`("id", listOf("value"))),
Arguments.of(Condition.notIn("id", listOf("value")), Filters.nin("id", listOf("value"))),
Arguments.of(
Condition("id", Operator.BETWEEN, listOf(1, 2)),
Condition.between("id", 1, 2),
Filters.and(Filters.gte("id", 1), Filters.lte("id", 2))
),
Arguments.of(Condition("id", Operator.ALL, listOf("value")), Filters.all("id", listOf("value"))),
Arguments.of(Condition("id", Operator.NULL, ""), Filters.eq("id", null)),
Arguments.of(Condition("id", Operator.NOT_NULL, ""), Filters.ne("id", null)),
Arguments.of(Condition.all("id", listOf("value")), Filters.all("id", listOf("value"))),
Arguments.of(Condition.isNull("id"), Filters.eq("id", null)),
Arguments.of(Condition.notNull("id"), Filters.ne("id", null)),
Arguments.of(
Condition("id", Operator.ELEM_MATCH, children = listOf(Condition("id", Operator.EQ, "id"))),
Condition.elemMatch("id", Condition("id", Operator.EQ, "id")),
Filters.elemMatch("id", Filters.eq("id", "id"))
),
Arguments.of(Condition("id", Operator.STATS_WITH, "value"), Filters.regex("id", "^value")),
Arguments.of(Condition.startsWith("id", "value"), Filters.regex("id", "^value")),
Arguments.of(
Condition("", Operator.AND, children = listOf(Condition("id", Operator.EQ, "id"))),
Condition.and(listOf(Condition("id", Operator.EQ, "id"))),
Filters.and(Filters.eq("id", "id"))
),
Arguments.of(
Condition("", Operator.OR, children = listOf(Condition("id", Operator.EQ, "id"))),
Condition.or(listOf(Condition("id", Operator.EQ, "id"))),
Filters.or(Filters.eq("id", "id"))
),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class ArchiveAggregateIdRouteSpec(
override val summary: String
get() = "Archive AggregateId"
override val appendPathSuffix: String
get() = "event/aggregate_id"
get() = "event/aggregateId"
override val responses: ApiResponses
get() = ApiResponses().withRequestTimeout()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class PagedQuerySnapshotRouteSpec(
get() = Https.Method.POST

override val appendPathSuffix: String
get() = "snapshot/pagedQuery"
get() = "snapshot/pagination"

override val summary: String
get() = "Paged Query snapshot"
Expand Down

0 comments on commit 816ccf3

Please sign in to comment.