2018-05-04 03:51:17 +00:00
|
|
|
/// Expects a field to be equal to a given [value].
|
|
|
|
Predicate<T> equals<T>(T value) =>
|
|
|
|
new Predicate<T>._(PredicateType.equals, value);
|
2017-06-18 04:19:05 +00:00
|
|
|
|
2018-05-04 03:51:17 +00:00
|
|
|
/// Expects at least one of the given [predicates] to be true.
|
|
|
|
Predicate<T> anyOf<T>(Iterable<Predicate<T>> predicates) =>
|
|
|
|
new MultiPredicate<T>._(PredicateType.any, predicates);
|
2017-06-24 21:21:32 +00:00
|
|
|
|
2018-05-04 03:51:17 +00:00
|
|
|
/// Expects a field to be contained within a set of [values].
|
|
|
|
Predicate<T> isIn<T>(Iterable<T> values) => new Predicate<T>._(PredicateType.isIn, null, values);
|
2017-07-14 22:04:58 +00:00
|
|
|
|
2018-05-04 03:51:17 +00:00
|
|
|
/// Expects a field to be `null`.
|
|
|
|
Predicate<T> isNull<T>() => equals(null);
|
2017-07-14 22:04:58 +00:00
|
|
|
|
2018-05-04 03:51:17 +00:00
|
|
|
/// Expects a given [predicate] to not be true.
|
|
|
|
Predicate<T> not<T>(Predicate<T> predicate) =>
|
|
|
|
new MultiPredicate<T>._(PredicateType.negate, [predicate]);
|
2017-07-14 22:04:58 +00:00
|
|
|
|
2018-05-04 03:51:17 +00:00
|
|
|
/// Expects a field to be not be `null`.
|
|
|
|
Predicate<T> notNull<T>() => not(isNull());
|
2017-06-18 04:19:05 +00:00
|
|
|
|
2018-05-04 03:51:17 +00:00
|
|
|
/// Expects a field to be less than a given [value].
|
|
|
|
Predicate<T> lessThan<T>(T value) =>
|
|
|
|
new Predicate<T>._(PredicateType.less, value);
|
2017-06-18 04:19:05 +00:00
|
|
|
|
2018-05-04 03:51:17 +00:00
|
|
|
/// Expects a field to be less than or equal to a given [value].
|
|
|
|
Predicate<T> lessThanOrEqual<T>(T value) => lessThan(value) | equals(value);
|
2017-06-18 04:19:05 +00:00
|
|
|
|
2018-05-04 03:51:17 +00:00
|
|
|
/// Expects a field to be greater than a given [value].
|
|
|
|
Predicate<T> greaterThan<T>(T value) =>
|
|
|
|
new Predicate<T>._(PredicateType.greater, value);
|
2017-06-18 04:19:05 +00:00
|
|
|
|
2018-05-04 03:51:17 +00:00
|
|
|
/// Expects a field to be greater than or equal to a given [value].
|
|
|
|
Predicate<T> greaterThanOrEqual<T>(T value) =>
|
|
|
|
greaterThan(value) | equals(value);
|
2017-06-18 04:19:05 +00:00
|
|
|
|
2018-05-04 03:51:17 +00:00
|
|
|
/// 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<String, Predicate> _fields = {};
|
|
|
|
final Map<String, SortType> _sort = {};
|
2017-06-18 04:19:05 +00:00
|
|
|
|
2018-05-04 03:51:17 +00:00
|
|
|
/// Each field in a query is actually a [Predicate], and therefore acts as a contract
|
|
|
|
/// with the underlying service.
|
|
|
|
Map<String, Predicate> get fields =>
|
|
|
|
new Map<String, Predicate>.unmodifiable(_fields);
|
2017-06-18 04:19:05 +00:00
|
|
|
|
2018-05-04 03:51:17 +00:00
|
|
|
/// The sorting order applied to this query.
|
|
|
|
Map<String, SortType> get sorting =>
|
|
|
|
new Map<String, SortType>.unmodifiable(_sort);
|
2017-06-18 04:19:05 +00:00
|
|
|
|
2018-05-04 03:51:17 +00:00
|
|
|
/// Sets the [Predicate] assigned to the given [key].
|
|
|
|
void operator []=(String key, Predicate value) => _fields[key] = value;
|
2017-06-18 04:19:05 +00:00
|
|
|
|
2018-05-04 03:51:17 +00:00
|
|
|
/// Gets the [Predicate] assigned to the given [key].
|
|
|
|
Predicate operator [](String key) => _fields[key];
|
2017-07-14 22:04:58 +00:00
|
|
|
|
2018-05-04 03:51:17 +00:00
|
|
|
/// Sort output by the given [key].
|
|
|
|
void sortBy(String key, [SortType type = SortType.descending]) =>
|
|
|
|
_sort[key] = type;
|
2017-06-18 04:19:05 +00:00
|
|
|
}
|
|
|
|
|
2018-05-04 03:51:17 +00:00
|
|
|
/// A mechanism used to express an expectation about some object ([target]).
|
|
|
|
class Predicate<T> {
|
|
|
|
/// The type of expectation we are declaring.
|
|
|
|
final PredicateType type;
|
2017-06-18 04:19:05 +00:00
|
|
|
|
2018-05-04 03:51:17 +00:00
|
|
|
/// The single argument of this target.
|
|
|
|
final T target;
|
|
|
|
final Iterable<T> args;
|
2017-06-18 04:19:05 +00:00
|
|
|
|
2018-05-04 03:51:17 +00:00
|
|
|
Predicate._(this.type, this.target, [this.args]);
|
2017-06-18 04:19:05 +00:00
|
|
|
|
2018-05-04 03:51:17 +00:00
|
|
|
Predicate<T> operator &(Predicate<T> other) => and(other);
|
2017-07-14 22:04:58 +00:00
|
|
|
|
2018-05-04 03:51:17 +00:00
|
|
|
Predicate<T> operator |(Predicate<T> other) => or(other);
|
2017-07-14 22:04:58 +00:00
|
|
|
|
2018-05-04 03:51:17 +00:00
|
|
|
Predicate<T> and(Predicate<T> other) {
|
|
|
|
return new MultiPredicate._(PredicateType.and, [this, other]);
|
2017-07-14 22:04:58 +00:00
|
|
|
}
|
|
|
|
|
2018-05-04 03:51:17 +00:00
|
|
|
Predicate<T> or(Predicate<T> other) {
|
|
|
|
return new MultiPredicate._(PredicateType.or, [this, other]);
|
2017-07-14 22:04:58 +00:00
|
|
|
}
|
2017-06-18 04:19:05 +00:00
|
|
|
}
|
|
|
|
|
2018-05-04 03:51:17 +00:00
|
|
|
/// An advanced [Predicate] that performs an operation of multiple other predicates.
|
|
|
|
class MultiPredicate<T> extends Predicate<T> {
|
|
|
|
final Iterable<Predicate<T>> targets;
|
2017-07-14 22:04:58 +00:00
|
|
|
|
2018-05-04 03:51:17 +00:00
|
|
|
MultiPredicate._(PredicateType type, this.targets) : super._(type, null);
|
2017-07-14 22:04:58 +00:00
|
|
|
|
2018-05-04 03:51:17 +00:00
|
|
|
/// Use [targets] instead.
|
|
|
|
@deprecated
|
|
|
|
T get target => throw new UnsupportedError(
|
|
|
|
'IterablePredicate has no `target`. Use `targets` instead.');
|
2017-06-18 04:19:05 +00:00
|
|
|
}
|
|
|
|
|
2018-05-04 03:51:17 +00:00
|
|
|
/// The various types of predicate.
|
|
|
|
enum PredicateType {
|
|
|
|
equals,
|
|
|
|
any,
|
|
|
|
isIn,
|
|
|
|
negate,
|
|
|
|
and,
|
|
|
|
or,
|
|
|
|
less,
|
|
|
|
greater,
|
2017-06-18 04:19:05 +00:00
|
|
|
}
|
2018-05-04 03:51:17 +00:00
|
|
|
|
|
|
|
/// The various modes of sorting.
|
|
|
|
enum SortType { ascending, descending }
|