Skip to main content

DataFilter

DataFilter is a sealed interface describing data-querying logic independently from any specific database technology. The rationale is discussed here.

A DataFilter is either a Field operation, or a logical combination (And / Or) of other filters. Implementations like invirt-mongodb translate a DataFilter into native database constructs (e.g. DataFilter.mongoFilter()).

sealed interface DataFilter {
sealed class Field : DataFilter
data class Or(val filters: List<DataFilter>) : DataFilter
data class And(val filters: List<DataFilter>) : DataFilter
}

DataFilter.Field

The available field operations are:

OperationExample
Eq<Value>(field, value)User::name eq "John"
Ne<Value>(field, value)User::status ne Status.DELETED
Gt<Value>(field, value)User::age gt 18
Gte<Value>(field, value)User::age gte 18
Lt<Value>(field, value)Product::priceMinor lt 1000_00
Lte<Value>(field, value)Product::priceMinor lte 1000_00
Exists(field)User::email.exists()
DoesntExist(field)User::email.doesntExist()
WithinGeoBounds(field, GeoBoundingBox)User::location withinGeoBounds bbox

Filters can be constructed either by string field name or via KProperty references, using the companion factory methods on DataFilter or the infix/extension shortcuts:

// Companion factories
DataFilter.eq("name", "John")
DataFilter.lt("priceMinor", 1000_00)

// String extensions
"status" eq "PUBLISHED"
"priceMinor" gte 100

// KProperty extensions
Product::priceMinor lte 1000_00
User::email.exists()

DataFilter.And / DataFilter.Or

Logical combinations of filters. The framework provides factory functions and a flatten() helper that collapses single-element And / Or wrappers.

val filter = orDataFilter(
Product::status ne Status.PUBLISHED,
andDataFilter(
Product::status eq Status.PUBLISHED,
Product::priceMinor gte 200_000
)
)

// Same logical filter without redundant single-element wrappers
val simplified = filter.flatten()

In an Invirt application the most common way to build a filter is from query parameters via queryDataFilter, where the individual field filters are returned by lambdas and combined according to the QueryDataFilter.Operator.