-
Notifications
You must be signed in to change notification settings - Fork 619
Description
Hello community! I am working on a project that uses PostgreSQL and Neo4j reactively. I am making great progress with it and I have already finished the reactive part of PostgreSQL. However, when I got to the Neo4j part, I encountered some problems when trying to use the Criteria pattern. I am not sure how to use it correctly and I have not found something similar to Query Criteria in Spring Data Neo4j. I have been looking online but I have not found much information about it. I am looking for a way to use the Criteria pattern efficiently in order to move my project forward.
The following example is what I have implemented for the relational part, but I would like to find a solution for the Neo4j part as well. I am eagerly awaiting any advice you can provide me on how to use the Criteria pattern effectively in Neo4j.
interface CriteriaParser<Out : Any?> {
fun parse(criteria: Criteria): Out
}
import com.astrum.data.criteria.Criteria
import com.astrum.data.criteria.CriteriaParser
import com.astrum.data.expansion.columnName
import kotlin.reflect.KClass
import kotlin.reflect.full.memberProperties
import org.springframework.data.relational.core.query.Criteria as R2DBCCriteria
import org.springframework.data.relational.core.query.Criteria.CriteriaStep as R2DBCCriteriaStep
class R2DBCCriteriaParser<T : Any>(
clazz: KClass<T>
) : CriteriaParser<R2DBCCriteria> {
private val columnNames = clazz.memberProperties.associate { it.name to columnName(it) }
override fun parse(criteria: Criteria): R2DBCCriteria {
return when (criteria) {
is Criteria.Empty -> R2DBCCriteria.empty()
is Criteria.And -> parse(criteria)
is Criteria.Or -> parse(criteria)
is Criteria.Equals -> parse(criteria)
is Criteria.NotEquals -> parse(criteria)
is Criteria.Between -> parse(criteria)
is Criteria.NotBetween -> parse(criteria)
is Criteria.LessThan -> parse(criteria)
is Criteria.LessThanEquals -> parse(criteria)
is Criteria.GreaterThan -> parse(criteria)
is Criteria.GreaterThanEquals -> parse(criteria)
is Criteria.IsNull -> parse(criteria)
is Criteria.IsNotNull -> parse(criteria)
is Criteria.Like -> parse(criteria)
is Criteria.NotLike -> parse(criteria)
is Criteria.In -> parse(criteria)
is Criteria.NotIn -> parse(criteria)
is Criteria.IsTrue -> parse(criteria)
is Criteria.IsFalse -> parse(criteria)
else -> throw RuntimeException()
}
}
private fun parse(criteria: Criteria.And): R2DBCCriteria {
if (criteria.value.isEmpty()) {
return R2DBCCriteria.empty()
}
if (criteria.value.size == 1) {
return parse(criteria.value[0])
}
return criteria.value
.filter { it !is Criteria.Empty }
.map { parse(it) }
.reduce { acc, cur -> acc.and(cur) }
}
private fun parse(criteria: Criteria.Or): R2DBCCriteria {
if (criteria.value.isEmpty()) {
return R2DBCCriteria.empty()
}
if (criteria.value.size == 1) {
return parse(criteria.value[0])
}
return criteria.value
.filter { it !is Criteria.Empty }
.map { parse(it) }
.reduce { acc, cur -> acc.or(cur) }
}
private fun parse(criteria: Criteria.Equals): R2DBCCriteria {
if (criteria.value == null) {
return where(criteria.key).isNull
}
return where(criteria.key).`is`(criteria.value)
}
private fun parse(criteria: Criteria.NotEquals): R2DBCCriteria {
if (criteria.value == null) {
return where(criteria.key).isNotNull
}
return where(criteria.key).not(criteria.value)
}
private fun parse(criteria: Criteria.Between): R2DBCCriteria {
return where(criteria.key).between(criteria.value.start, criteria.value.endInclusive)
}
private fun parse(criteria: Criteria.NotBetween): R2DBCCriteria {
return where(criteria.key).notBetween(criteria.value.start, criteria.value.endInclusive)
}
private fun parse(criteria: Criteria.LessThan): R2DBCCriteria {
return where(criteria.key).lessThan(criteria.value)
}
private fun parse(criteria: Criteria.LessThanEquals): R2DBCCriteria {
return where(criteria.key).lessThanOrEquals(criteria.value)
}
private fun parse(criteria: Criteria.GreaterThan): R2DBCCriteria {
return where(criteria.key).greaterThan(criteria.value)
}
private fun parse(criteria: Criteria.GreaterThanEquals): R2DBCCriteria {
return where(criteria.key).greaterThanOrEquals(criteria.value)
}
private fun parse(criteria: Criteria.IsNull): R2DBCCriteria {
return where(criteria.key).isNull
}
private fun parse(criteria: Criteria.IsNotNull): R2DBCCriteria {
return where(criteria.key).isNotNull
}
private fun parse(criteria: Criteria.Like): R2DBCCriteria {
return where(criteria.key).like(criteria.value)
}
private fun parse(criteria: Criteria.NotLike): R2DBCCriteria {
return where(criteria.key).notLike(criteria.value)
}
private fun parse(criteria: Criteria.In): R2DBCCriteria {
return where(criteria.key).`in`(criteria.value)
}
private fun parse(criteria: Criteria.NotIn): R2DBCCriteria {
return where(criteria.key).notIn(criteria.value)
}
private fun parse(criteria: Criteria.IsTrue): R2DBCCriteria {
return where(criteria.key).isTrue
}
private fun parse(criteria: Criteria.IsFalse): R2DBCCriteria {
return where(criteria.key).isFalse
}
private fun where(key: String): R2DBCCriteriaStep {
return R2DBCCriteria.where(
columnNames[key] ?: throw IllegalArgumentException("$key is invalid}")
)
}
}