/// Expects a field to be equal to a given [value]. Predicate equals(T value) => new Predicate._(PredicateType.equals, value); /// Expects at least one of the given [predicates] to be true. Predicate anyOf(Iterable> predicates) => new MultiPredicate._(PredicateType.any, predicates); /// Expects a field to be contained within a set of [values]. Predicate isIn(Iterable values) => new Predicate._(PredicateType.isIn, null, values); /// Expects a field to be `null`. Predicate isNull() => equals(null); /// Expects a given [predicate] to not be true. Predicate not(Predicate predicate) => new MultiPredicate._(PredicateType.negate, [predicate]); /// Expects a field to be not be `null`. Predicate notNull() => not(isNull()); /// Expects a field to be less than a given [value]. Predicate lessThan(T value) => new Predicate._(PredicateType.less, value); /// Expects a field to be less than or equal to a given [value]. Predicate lessThanOrEqual(T value) => lessThan(value) | equals(value); /// Expects a field to be greater than a given [value]. Predicate greaterThan(T value) => new Predicate._(PredicateType.greater, value); /// Expects a field to be greater than or equal to a given [value]. Predicate greaterThanOrEqual(T value) => greaterThan(value) | equals(value); /// A generic query class. /// /// Angel services can translate these into driver-specific queries. /// This allows the Angel ORM to be flexible and support multiple platforms. class Query { final Map _fields = {}; final Map _sort = {}; /// Each field in a query is actually a [Predicate], and therefore acts as a contract /// with the underlying service. Map get fields => new Map.unmodifiable(_fields); /// The sorting order applied to this query. Map get sorting => new Map.unmodifiable(_sort); /// Sets the [Predicate] assigned to the given [key]. void operator []=(String key, Predicate value) => _fields[key] = value; /// Gets the [Predicate] assigned to the given [key]. Predicate operator [](String key) => _fields[key]; /// Sort output by the given [key]. void sortBy(String key, [SortType type = SortType.descending]) => _sort[key] = type; } /// A mechanism used to express an expectation about some object ([target]). class Predicate { /// The type of expectation we are declaring. final PredicateType type; /// The single argument of this target. final T target; final Iterable args; Predicate._(this.type, this.target, [this.args]); Predicate operator &(Predicate other) => and(other); Predicate operator |(Predicate other) => or(other); Predicate and(Predicate other) { return new MultiPredicate._(PredicateType.and, [this, other]); } Predicate or(Predicate other) { return new MultiPredicate._(PredicateType.or, [this, other]); } } /// An advanced [Predicate] that performs an operation of multiple other predicates. class MultiPredicate extends Predicate { final Iterable> targets; MultiPredicate._(PredicateType type, this.targets) : super._(type, null); /// Use [targets] instead. @deprecated T get target => throw new UnsupportedError( 'IterablePredicate has no `target`. Use `targets` instead.'); } /// The various types of predicate. enum PredicateType { equals, any, isIn, negate, and, or, less, greater, } /// The various modes of sorting. enum SortType { ascending, descending }