All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.lightningkite.lightningdb.Condition.kt Maven / Gradle / Ivy

@file:SharedCode

package com.lightningkite.lightningdb

import com.lightningkite.khrysalis.*
import kotlinx.serialization.*
import kotlin.reflect.KProperty1

@Serializable(ConditionSerializer::class)
// Why is this class open instead of sealed?  See https://github.com/Kotlin/kotlinx.serialization/issues/1843
open class Condition protected constructor() {
    open override fun hashCode(): Int {
        fatalError()
    }

    open override fun equals(other: Any?): Boolean {
        fatalError()
    }

    open operator fun invoke(on: T): Boolean {
        fatalError()
    }

    infix fun and(other: Condition): Condition.And = Condition.And(listOf(this, other))
    infix fun or(other: Condition): Condition.Or = Condition.Or(listOf(this, other))
    operator fun not(): Condition.Not = Condition.Not(this)

    @Serializable(ConditionNeverSerializer::class)
    @SerialName("Never")
    class Never : Condition() {
        override fun invoke(on: T): Boolean = false
        override fun hashCode(): Int = 0

        @Suppress("UNCHECKED_CAST")
        override fun equals(other: Any?): Boolean = (other as? Condition.Never) != null
    }

    @Serializable(ConditionAlwaysSerializer::class)
    @SerialName("Always")
    class Always : Condition() {
        override fun invoke(on: T): Boolean = true
        override fun hashCode(): Int = 1

        @Suppress("UNCHECKED_CAST")
        override fun equals(other: Any?): Boolean = (other as? Condition.Always) != null
    }

    @Serializable(ConditionAndSerializer::class)
    @SerialName("And")
    data class And(val conditions: List>) : Condition() {
        override fun invoke(on: T): Boolean = conditions.all { it(on) }
    }

    @Serializable(ConditionOrSerializer::class)
    @SerialName("Or")
    data class Or(val conditions: List>) : Condition() {
        override fun invoke(on: T): Boolean = conditions.any { it(on) }
    }

    @Serializable(ConditionNotSerializer::class)
    @SerialName("Not")
    data class Not(val condition: Condition) : Condition() {
        override fun invoke(on: T): Boolean = !condition(on)
    }

    @Serializable(ConditionEqualSerializer::class)
    @SerialName("Equal")
    data class Equal(val value: T) : Condition() {
        override fun invoke(on: T): Boolean = on == value
    }

    @Serializable(ConditionNotEqualSerializer::class)
    @SerialName("NotEqual")
    data class NotEqual(val value: T) : Condition() {
        override fun invoke(on: T): Boolean = on != value
    }

    @Serializable(ConditionInsideSerializer::class)
    @SerialName("Inside")
    data class Inside(val values: List) : Condition() {
        override fun invoke(on: T): Boolean = values.contains(on)
    }

    @Serializable(ConditionNotInsideSerializer::class)
    @SerialName("NotInside")
    data class NotInside(val values: List) : Condition() {
        override fun invoke(on: T): Boolean = !values.contains(on)
    }

    @Serializable(ConditionGreaterThanSerializer::class)
    @SerialName("GreaterThan")
    data class GreaterThan>(val value: T) : Condition() {
        override fun invoke(on: T): Boolean = on > value
    }

    @Serializable(ConditionLessThanSerializer::class)
    @SerialName("LessThan")
    data class LessThan>(val value: T) : Condition() {
        override fun invoke(on: T): Boolean = on < value
    }

    @Serializable(ConditionGreaterThanOrEqualSerializer::class)
    @SerialName("GreaterThanOrEqual")
    data class GreaterThanOrEqual>(val value: T) : Condition() {
        override fun invoke(on: T): Boolean = on >= value
    }

    @Serializable(ConditionLessThanOrEqualSerializer::class)
    @SerialName("LessThanOrEqual")
    data class LessThanOrEqual>(val value: T) : Condition() {
        override fun invoke(on: T): Boolean = on <= value
    }

    @Serializable
    @SerialName("StringContains")
    data class StringContains(val value: String, val ignoreCase: Boolean = false) : Condition() {
        override fun invoke(on: String): Boolean = on.contains(value, ignoreCase)
    }

    @Serializable
    @SerialName("FullTextSearch")
    data class FullTextSearch(val value: String, val ignoreCase: Boolean = false) :
        Condition() {
        override fun invoke(on: T): Boolean {
            fatalError("Not Implemented locally")
        }
    }

    @Serializable
    @SerialName("RegexMatches")
    data class RegexMatches(val pattern: String, val ignoreCase: Boolean = false) : Condition() {
        @Transient
        val regex = Regex(pattern, if (ignoreCase) setOf(RegexOption.IGNORE_CASE) else setOf())
        override fun invoke(on: String): Boolean = regex.matches(on)
    }

    @Serializable(ConditionIntBitsClearSerializer::class)
    @SerialName("IntBitsClear")
    data class IntBitsClear(val mask: Int) : Condition() {
        override fun invoke(on: Int): Boolean = on and mask == 0
    }

    @Serializable(ConditionIntBitsSetSerializer::class)
    @SerialName("IntBitsSet")
    data class IntBitsSet(val mask: Int) : Condition() {
        override fun invoke(on: Int): Boolean = on and mask == mask
    }

    @Serializable(ConditionIntBitsAnyClearSerializer::class)
    @SerialName("IntBitsAnyClear")
    data class IntBitsAnyClear(val mask: Int) : Condition() {
        override fun invoke(on: Int): Boolean = on and mask < mask
    }

    @Serializable(ConditionIntBitsAnySetSerializer::class)
    @SerialName("IntBitsAnySet")
    data class IntBitsAnySet(val mask: Int) : Condition() {
        override fun invoke(on: Int): Boolean = on and mask > 0
    }

    @Serializable(ConditionListAllElementsSerializer::class)
    @SerialName("ListAllElements")
    data class ListAllElements(val condition: Condition) : Condition>() {
        override fun invoke(on: List): Boolean = on.all { condition(it) }
    }

    @Serializable(ConditionListAnyElementsSerializer::class)
    @SerialName("ListAnyElements")
    data class ListAnyElements(val condition: Condition) : Condition>() {
        override fun invoke(on: List): Boolean = on.any { condition(it) }
    }

    @Serializable(ConditionListSizesEqualsSerializer::class)
    @SerialName("ListSizesEquals")
    data class ListSizesEquals(val count: Int) : Condition>() {
        override fun invoke(on: List): Boolean = on.size == count
    }

    @Serializable(ConditionSetAllElementsSerializer::class)
    @SerialName("SetAllElements")
    data class SetAllElements(val condition: Condition) : Condition>() {
        override fun invoke(on: Set): Boolean = on.all { condition(it) }
    }

    @Serializable(ConditionSetAnyElementsSerializer::class)
    @SerialName("SetAnyElements")
    data class SetAnyElements(val condition: Condition) : Condition>() {
        override fun invoke(on: Set): Boolean = on.any { condition(it) }
    }

    @Serializable(ConditionSetSizesEqualsSerializer::class)
    @SerialName("SetSizesEquals")
    data class SetSizesEquals(val count: Int) : Condition>() {
        override fun invoke(on: Set): Boolean = on.size == count
    }

    @Serializable(ConditionExistsSerializer::class)
    @SerialName("Exists")
    data class Exists(val key: String) : Condition>() {
        override fun invoke(on: Map): Boolean = on.containsKey(key)
    }

    @Serializable
    @SerialName("OnKey")
    data class OnKey(val key: String, val condition: Condition) :
        Condition>() {
        override fun invoke(on: Map): Boolean = on.containsKey(key) && condition(on[key] as V)
    }

    data class OnField(
        val key: KProperty1,
        val condition: Condition,
    ) : Condition() {
        override fun invoke(on: K): Boolean = condition(key.get(on))
    }

    @Serializable(ConditionIfNotNullSerializer::class)
    @SerialName("IfNotNull")
    data class IfNotNull(val condition: Condition) : Condition() {
        override fun invoke(on: T?): Boolean = on != null && condition(on)
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy