Skip to content

Commit

Permalink
scope(field-map): replace field maps by DefaultFieldMap or StrictFiel…
Browse files Browse the repository at this point in the history
…dMap instead of regular map
  • Loading branch information
magonxesp committed Jun 28, 2024
1 parent 8f3fbc9 commit b7b4499
Show file tree
Hide file tree
Showing 18 changed files with 122 additions and 43 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package io.github.magonxesp.criteria.domain

class RequiredFieldException(override val message: String? = null) : Exception(message)
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ package io.github.magonxesp.criteria.infrastructure

import io.github.magonxesp.criteria.domain.Filter
import io.github.magonxesp.criteria.domain.OrderBy
import io.github.magonxesp.criteria.infrastructure.map.FieldMap

abstract class Adapter(private val fieldMap: FieldMap) {
protected val Filter.mappedField
get() = fieldMap.mappedField(field)
get() = fieldMap[field]

protected val OrderBy.mappedField
get() = fieldMap.mappedField(field)
}
get() = fieldMap[field]
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package io.github.magonxesp.criteria.infrastructure.map

class DefaultFieldMap(override val map: Map<String, String> = mapOf()) : FieldMap()

fun fieldMapOf(vararg mapping: Pair<String, String>) = DefaultFieldMap(map = mapping.toMap())
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package io.github.magonxesp.criteria.infrastructure.map

abstract class FieldMap {
abstract val map: Map<String, String>
open operator fun get(index: String): String = map[index] ?: index
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package io.github.magonxesp.criteria.infrastructure.map

import io.github.magonxesp.criteria.domain.RequiredFieldException

class StrictFieldMap(override val map: Map<String, String>) : FieldMap() {
override fun get(index: String): String = map[index]
?: throw RequiredFieldException("The field $index is not present in field map")
}

fun strictFieldMapOf(vararg mapping: Pair<String, String>) = StrictFieldMap(map = mapping.toMap())
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package io.github.magonxesp.criteria.infrastructure.map

import io.kotest.core.spec.style.AnnotationSpec
import io.kotest.matchers.shouldBe

class DefaultFieldMapTest : AnnotationSpec() {
@Test
fun `it should map a field`() {
val map = fieldMapOf(
"author" to "author.name"
)

val mapped = map["author"]

mapped shouldBe "author.name"
}

@Test
fun `it should map a not existing field`() {
val map = fieldMapOf(
"author" to "author.name"
)

val mapped = map["title"]

mapped shouldBe "title"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package io.github.magonxesp.criteria.infrastructure.map

import io.github.magonxesp.criteria.domain.RequiredFieldException
import io.kotest.assertions.throwables.shouldThrow
import io.kotest.core.spec.style.AnnotationSpec
import io.kotest.matchers.shouldBe

class StrictFieldMapTest : AnnotationSpec() {
@Test
fun `it should map a field`() {
val map = strictFieldMapOf(
"author" to "author.name"
)

val mapped = map["author"]

mapped shouldBe "author.name"
}

@Test
fun `it should not map a not existing field`() {
val map = strictFieldMapOf(
"author" to "author.name"
)

shouldThrow<RequiredFieldException> {
map["title"]
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ package io.github.magonxesp.criteria.infrastructure.mongodb
import com.mongodb.client.model.Filters.and
import com.mongodb.kotlin.client.coroutine.FindFlow
import io.github.magonxesp.criteria.domain.Criteria
import io.github.magonxesp.criteria.infrastructure.FieldMap
import io.github.magonxesp.criteria.infrastructure.map.DefaultFieldMap
import io.github.magonxesp.criteria.infrastructure.map.FieldMap

class CriteriaMongoDbFindFlowAdapter(private val fieldMap: FieldMap = mapOf()) {
class CriteriaMongoDbFindFlowAdapter(private val fieldMap: FieldMap = DefaultFieldMap()) {
fun <T : Any> apply(criteria: Criteria, findFlow: FindFlow<T>) {
val filterMapper = FilterBsonAdapter(fieldMap)
val orderMapper = OrderByBsonAdapter(fieldMap)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@ import com.mongodb.client.model.Filters.`in`
import io.github.magonxesp.criteria.domain.Filter
import io.github.magonxesp.criteria.domain.FilterOperator
import io.github.magonxesp.criteria.infrastructure.Adapter
import io.github.magonxesp.criteria.infrastructure.FieldMap
import io.github.magonxesp.criteria.infrastructure.map.DefaultFieldMap
import io.github.magonxesp.criteria.infrastructure.map.FieldMap
import org.bson.conversions.Bson
import kotlinx.datetime.Instant

class FilterBsonAdapter(fieldMap: FieldMap = mapOf()) : Adapter(fieldMap) {
class FilterBsonAdapter(fieldMap: FieldMap) : Adapter(fieldMap) {
private fun Filter.numberBson(): Bson? {
if (value !is Number) {
return null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import com.mongodb.client.model.Sorts
import io.github.magonxesp.criteria.domain.Order
import io.github.magonxesp.criteria.domain.OrderBy
import io.github.magonxesp.criteria.infrastructure.Adapter
import io.github.magonxesp.criteria.infrastructure.FieldMap
import io.github.magonxesp.criteria.infrastructure.map.FieldMap
import org.bson.conversions.Bson

class OrderByBsonAdapter(fieldMap: FieldMap = mapOf()) : Adapter(fieldMap) {
class OrderByBsonAdapter(fieldMap: FieldMap) : Adapter(fieldMap) {
private fun OrderBy.toBson(): Bson =
if (order == Order.ASC) {
Sorts.ascending(mappedField)
Expand All @@ -16,4 +16,4 @@ class OrderByBsonAdapter(fieldMap: FieldMap = mapOf()) : Adapter(fieldMap) {
}

fun adapt(orderBy: List<OrderBy>): Bson = Sorts.orderBy(*orderBy.map { it.toBson() }.toTypedArray())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@ package io.github.magonxesp.criteria.infrastructure.jpa

import io.github.magonxesp.criteria.domain.Filter
import io.github.magonxesp.criteria.domain.FilterOperator
import io.github.magonxesp.criteria.infrastructure.FieldMap
import io.github.magonxesp.criteria.infrastructure.map.FieldMap
import jakarta.persistence.criteria.CriteriaBuilder
import jakarta.persistence.criteria.Predicate
import jakarta.persistence.criteria.Root

class FilterListJpaPredicateAdapter(
root: Root<*>,
builder: CriteriaBuilder,
fieldMap: FieldMap = mapOf(),
joinMap: JoinMap = mapOf()
builder: CriteriaBuilder,
fieldMap: FieldMap,
joinMap: JoinMap
) : JpaAdapter(root, builder, joinMap, fieldMap) {
private fun Any.toList(): List<Any> {
if (this is Collection<*>) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@ package io.github.magonxesp.criteria.infrastructure.jpa

import io.github.magonxesp.criteria.domain.Filter
import io.github.magonxesp.criteria.domain.FilterOperator
import io.github.magonxesp.criteria.infrastructure.FieldMap
import io.github.magonxesp.criteria.infrastructure.map.FieldMap
import jakarta.persistence.criteria.CriteriaBuilder
import jakarta.persistence.criteria.Path
import jakarta.persistence.criteria.Predicate
import jakarta.persistence.criteria.Root
import java.time.Instant

class FilterScalarPredicateAdapter(
root: Root<*>,
builder: CriteriaBuilder,
fieldMap: FieldMap = mapOf(),
joinMap: JoinMap = mapOf()
root: Root<*>,
builder: CriteriaBuilder,
fieldMap: FieldMap,
joinMap: JoinMap
) : JpaAdapter(root, builder, joinMap, fieldMap) {

fun numberPredicate(filter: Filter): Predicate? {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
package io.github.magonxesp.criteria.infrastructure.jpa

import io.github.magonxesp.criteria.domain.Filter
import io.github.magonxesp.criteria.infrastructure.FieldMap
import io.github.magonxesp.criteria.infrastructure.map.FieldMap
import jakarta.persistence.criteria.CriteriaBuilder
import jakarta.persistence.criteria.Predicate
import jakarta.persistence.criteria.Root

class FiltersJpaPredicateAdapter(
root: Root<*>,
builder: CriteriaBuilder,
fieldMap: FieldMap = mapOf(),
joinMap: JoinMap = mapOf()
builder: CriteriaBuilder,
fieldMap: FieldMap,
joinMap: JoinMap
) : JpaAdapter(root, builder, joinMap, fieldMap) {
private val scalarPredicates = FilterScalarPredicateAdapter(root, builder, fieldMap, joinMap)
private val listPredicates = FilterListJpaPredicateAdapter(root, builder, fieldMap, joinMap)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@ package io.github.magonxesp.criteria.infrastructure.jpa
import io.github.magonxesp.criteria.domain.Filter
import io.github.magonxesp.criteria.domain.OrderBy
import io.github.magonxesp.criteria.infrastructure.Adapter
import io.github.magonxesp.criteria.infrastructure.FieldMap
import io.github.magonxesp.criteria.infrastructure.map.FieldMap
import jakarta.persistence.criteria.CriteriaBuilder
import jakarta.persistence.criteria.From
import jakarta.persistence.criteria.Root

abstract class JpaAdapter(
protected val root: Root<*>,
protected val builder: CriteriaBuilder,
private val joinMap: JoinMap = mapOf(),
fieldMap: FieldMap = mapOf(),
protected val root: Root<*>,
protected val builder: CriteriaBuilder,
private val joinMap: JoinMap,
fieldMap: FieldMap,
) : Adapter(fieldMap) {
private fun String.stripJoinIdentifier() = replace(Regex("[a-zA-Z_]+\\."), "")
private fun String.stripJoinField() = replace(Regex("\\.[a-zA-Z_]+"), "")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
package io.github.magonxesp.criteria.infrastructure.jpa

import io.github.magonxesp.criteria.domain.OrderBy
import io.github.magonxesp.criteria.infrastructure.Adapter
import io.github.magonxesp.criteria.infrastructure.FieldMap
import io.github.magonxesp.criteria.infrastructure.map.FieldMap
import jakarta.persistence.criteria.*
import io.github.magonxesp.criteria.domain.Order as DomainOrder

class OrderByJpaOrderAdapter(
root: Root<*>,
builder: CriteriaBuilder,
fieldMap: FieldMap = mapOf(),
joinMap: JoinMap = mapOf()
fieldMap: FieldMap,
joinMap: JoinMap
) : JpaAdapter(root, builder, joinMap, fieldMap) {
private fun OrderBy.toOrder(): Order =
if (order == DomainOrder.ASC) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,19 @@ package io.github.magonxesp.criteria.infrastructure.spring

import io.github.magonxesp.criteria.domain.Criteria
import io.github.magonxesp.criteria.domain.PaginatedCollection
import io.github.magonxesp.criteria.infrastructure.FieldMap
import io.github.magonxesp.criteria.infrastructure.map.FieldMap
import io.github.magonxesp.criteria.infrastructure.jpa.FiltersJpaPredicateAdapter
import io.github.magonxesp.criteria.infrastructure.jpa.JoinMap
import io.github.magonxesp.criteria.infrastructure.jpa.OrderByJpaOrderAdapter
import io.github.magonxesp.criteria.infrastructure.map.DefaultFieldMap
import jakarta.persistence.criteria.Root
import org.springframework.data.domain.Page
import org.springframework.data.domain.PageRequest
import org.springframework.data.jpa.domain.Specification
import org.springframework.data.jpa.repository.JpaSpecificationExecutor

class CriteriaJPASpecificationAdapter(
private val fieldMap: FieldMap = mapOf(),
private val fieldMap: FieldMap = DefaultFieldMap(),
) {
fun <T> adapt(
criteria: Criteria,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package io.github.magonxesp.criteria.infrastructure
import io.github.magonxesp.criteria.*
import io.github.magonxesp.criteria.domain.FilterOperator
import io.github.magonxesp.criteria.domain.criteria
import io.github.magonxesp.criteria.infrastructure.map.fieldMapOf
import io.github.magonxesp.criteria.infrastructure.spring.CriteriaJPASpecificationAdapter
import io.kotest.matchers.collections.shouldContain
import io.kotest.matchers.collections.shouldContainAll
Expand All @@ -27,7 +28,7 @@ class CriteriaJPASpecificationAdapterTest : SpringBootTestCase() {
filter("authorName", author.name, FilterOperator.EQUALS)
}

val fieldMap = mapOf(
val fieldMap = fieldMapOf(
"authorName" to "author.name",
)

Expand Down Expand Up @@ -55,7 +56,7 @@ class CriteriaJPASpecificationAdapterTest : SpringBootTestCase() {
filter("bookGenre", genre.genre, FilterOperator.EQUALS)
}

val fieldMap = mapOf(
val fieldMap = fieldMapOf(
"bookGenre" to "genres.genre",
)

Expand Down

0 comments on commit b7b4499

Please sign in to comment.