Skip to content

Commit fd86450

Browse files
SaadArdatiBirjuVachhani
authored andcommitted
Saad Query Filters #1
1 parent ef17290 commit fd86450

File tree

9 files changed

+419
-36
lines changed

9 files changed

+419
-36
lines changed

lib/src/api/mixins.dart

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1123,3 +1123,41 @@ mixin ConditionsMixin {
11231123
/// List of conditions that are applied to this node.
11241124
List<BaseCondition> conditions = [];
11251125
}
1126+
1127+
/// A mixin that adds the ability to filter a collection of data
1128+
/// on a node.
1129+
mixin QueryableMixin on BaseNode {
1130+
/// List of where() operations to be applied to the query.
1131+
List<WhereQueryFilter> whereFilters = [];
1132+
1133+
/// List of orderBy() operations to be applied to the query.
1134+
List<OrderByQueryFilter> orderByOperations = [];
1135+
1136+
/// Whether to use cloud database.
1137+
late bool useCloudDatabase;
1138+
1139+
/// The path of the collection to query.
1140+
late String? collectionPath;
1141+
1142+
/// A limit integer to specify the number of documents to be returned.
1143+
late int limit;
1144+
1145+
/// Whether the query operation is going to be restrictive.
1146+
/// This pertains to Firestore's indexing rules.
1147+
bool get restrictedIndexing => useCloudDatabase;
1148+
1149+
/// Sets the properties of this mixin.
1150+
void setQueryableMixin({
1151+
required List<WhereQueryFilter> whereOperations,
1152+
required List<OrderByQueryFilter> orderByOperations,
1153+
required bool useCloudDatabase,
1154+
required String? collectionPath,
1155+
required int limit,
1156+
}) {
1157+
this.whereFilters = whereOperations;
1158+
this.orderByOperations = orderByOperations;
1159+
this.useCloudDatabase = useCloudDatabase;
1160+
this.collectionPath = collectionPath;
1161+
this.limit = limit;
1162+
}
1163+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import 'package:codelessly_json_annotation/codelessly_json_annotation.dart';
2+
import 'package:equatable/equatable.dart';
3+
4+
import 'query_filter.dart';
5+
6+
part 'order_by_query_filter.g.dart';
7+
8+
/// Enum representing the Firestore order by operations.
9+
enum OrderByQuerySortOrder {
10+
/// Represents an ascending order operation.
11+
ascending('asc', 'In Ascending Order'),
12+
13+
/// Represents a descending order operation.
14+
descending('desc', 'In Descending Order');
15+
16+
/// The operation name.
17+
final String value;
18+
19+
/// The human-readable name of the operation.
20+
final String label;
21+
22+
const OrderByQuerySortOrder(this.value, this.label);
23+
}
24+
25+
/// Represents the order-by operation in Firestore.
26+
@JsonSerializable()
27+
class OrderByQueryFilter extends QueryFilter with EquatableMixin {
28+
/// The order-by operation to perform.
29+
final OrderByQuerySortOrder sortOrder;
30+
31+
/// Creates a new [OrderByQueryFilter] instance, given a [field] and an
32+
/// [sortOrder].
33+
const OrderByQueryFilter({
34+
required super.field,
35+
this.sortOrder = OrderByQuerySortOrder.ascending,
36+
});
37+
38+
/// Creates a copy of this [OrderByQueryFilter] instance with the given
39+
/// parameters.
40+
OrderByQueryFilter copyWith({
41+
String? field,
42+
OrderByQuerySortOrder? operator,
43+
}) {
44+
return OrderByQueryFilter(
45+
field: field ?? this.field,
46+
sortOrder: operator ?? this.sortOrder,
47+
);
48+
}
49+
50+
/// Converts a JSON object to a [OrderByQueryFilter] instance.
51+
factory OrderByQueryFilter.fromJson(Map<String, dynamic> json) =>
52+
_$OrderByQueryFilterFromJson(json);
53+
54+
/// Converts this [OrderByQueryFilter] instance to a JSON object.
55+
Map<String, dynamic> toJson() => _$OrderByQueryFilterToJson(this);
56+
57+
@override
58+
List<Object?> get props => [field, sortOrder];
59+
}

lib/src/api/models/cloud_database_queries/order_by_query_filter.g.dart

Lines changed: 42 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import 'order_by_query_filter.dart';
2+
import 'where_query_filter.dart';
3+
4+
/// An abstract class that represents common firestore operations.
5+
abstract class QueryFilter {
6+
7+
/// The name of the field to target.
8+
final String field;
9+
10+
/// Creates a new [QueryFilter] instance.
11+
const QueryFilter({required this.field});
12+
13+
/// A convenience getter that returns true if this [QueryFilter] is a
14+
/// [WhereQueryFilter].
15+
bool get isWhereFilter => this is WhereQueryFilter;
16+
17+
/// A convenience getter that returns true if this [QueryFilter] is an
18+
/// [OrderByQueryFilter].
19+
bool get isOrderByFilter => this is OrderByQueryFilter;
20+
}
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
import 'package:codelessly_json_annotation/codelessly_json_annotation.dart';
2+
import 'package:equatable/equatable.dart';
3+
4+
import 'query_filter.dart';
5+
6+
part 'where_query_filter.g.dart';
7+
8+
/// Enum representing the Firestore where operation.
9+
///
10+
/// Reference: https://firebase.google.com/docs/firestore/query-data/queries?hl=en
11+
///
12+
/// Cloud Firestore supports the following comparison operators:
13+
/// < less than
14+
/// <= less than or equal to
15+
/// == equal to
16+
/// > greater than
17+
/// >= greater than or equal to
18+
/// != not equal to
19+
/// array-contains
20+
/// array-contains-any
21+
/// in
22+
/// not-in
23+
enum WhereQueryOperator {
24+
/// Compares two values and returns true if they are equal.
25+
equal('Equal To', '=='),
26+
27+
/// Checks if two values are not equal.
28+
notEqual('Not Equal To', '!='),
29+
30+
/// Compares two values and returns true if the first is less than the second.
31+
lessThan('Less Than', '<'),
32+
33+
/// Compares two values and returns true if the first is less than or equal
34+
/// to the second.
35+
lessThanOrEqual('Less Than Or Equal To', '<='),
36+
37+
/// Compares two values and returns true if the first is greater than the
38+
/// second.
39+
greaterThan('Greater Than', '>'),
40+
41+
/// Compares two values and returns true if the first is greater than or equal
42+
/// to the second.
43+
greaterThanOrEqual('Greater Than Or Equal To', '>='),
44+
45+
/// Checks if an array contains a value.
46+
arrayContains('Array Contains', 'array-contains'),
47+
48+
/// Checks if an array contains any of the values in a given array.
49+
arrayContainsAny('Array Contains Any', 'array-contains-any'),
50+
51+
/// Checks if a value is in a given array.
52+
inArray('In Array', 'in'),
53+
54+
/// Checks if a value is not in a given array.
55+
notInArray('Not In Array', 'not-in');
56+
57+
/// The human-readable name of the operation.
58+
final String label;
59+
60+
/// The operator to use in the query.
61+
final String operator;
62+
63+
const WhereQueryOperator(this.label, this.operator);
64+
65+
/// Returns true if this operation is a range operation.
66+
bool get isRangeOperator =>
67+
this == WhereQueryOperator.greaterThan ||
68+
this == WhereQueryOperator.greaterThanOrEqual ||
69+
this == WhereQueryOperator.lessThan ||
70+
this == WhereQueryOperator.lessThanOrEqual;
71+
72+
/// Returns true if this operation is an inequality operation.
73+
bool get isInequalityOperator =>
74+
isRangeOperator ||
75+
this == WhereQueryOperator.notEqual ||
76+
this == WhereQueryOperator.notInArray;
77+
78+
/// Returns true if this operation is an equality operation.
79+
bool get isEqualityOperator =>
80+
this == WhereQueryOperator.equal ||
81+
this == WhereQueryOperator.arrayContains ||
82+
this == WhereQueryOperator.inArray;
83+
84+
/// Returns a set of all range operators.
85+
static Set<WhereQueryOperator> get rangeOperators => {
86+
WhereQueryOperator.greaterThan,
87+
WhereQueryOperator.greaterThanOrEqual,
88+
WhereQueryOperator.lessThan,
89+
WhereQueryOperator.lessThanOrEqual,
90+
};
91+
92+
/// Returns a set of all inequality operators.
93+
static Set<WhereQueryOperator> get inequalityOperators => {
94+
...rangeOperators,
95+
WhereQueryOperator.notEqual,
96+
WhereQueryOperator.notInArray,
97+
};
98+
99+
/// Returns a set of all equality operators.
100+
static Set<WhereQueryOperator> get equalityOperators => {
101+
WhereQueryOperator.equal,
102+
WhereQueryOperator.arrayContains,
103+
WhereQueryOperator.inArray,
104+
};
105+
106+
/// Returns true if the given [operators] iterable contains any equality
107+
/// operator.
108+
static bool hasEqualityOperator(Iterable<WhereQueryOperator> operators) {
109+
return operators.any((operator) => operator.isEqualityOperator);
110+
}
111+
112+
/// Returns true if the given [operators] iterable contains any inequality
113+
/// operator.
114+
static bool hasInequalityOperator(Iterable<WhereQueryOperator> operators) {
115+
return operators.any((operator) => operator.isInequalityOperator);
116+
}
117+
}
118+
119+
/// Represents the where operation in Codelessly Cloud Database.
120+
///
121+
/// Takes three parameters: a field to filter on, a comparison operator, and a value.
122+
///
123+
/// Reference: https://firebase.google.com/docs/firestore/query-data/queries?hl=en
124+
@JsonSerializable()
125+
class WhereQueryFilter extends QueryFilter with EquatableMixin {
126+
/// The where operation to perform.
127+
final WhereQueryOperator operator;
128+
129+
/// The value to compare against.
130+
final dynamic value;
131+
132+
/// Creates a new [WhereQueryFilter] instance, given a [field], an [operator],
133+
/// and a [value].
134+
const WhereQueryFilter({
135+
required super.field,
136+
required this.operator,
137+
required this.value,
138+
});
139+
140+
/// Creates a copy of this [WhereQueryFilter] instance, given a [field], an
141+
/// [operator], and a [value].
142+
WhereQueryFilter copyWith({
143+
String? field,
144+
WhereQueryOperator? operator,
145+
dynamic value,
146+
}) =>
147+
WhereQueryFilter(
148+
field: field ?? this.field,
149+
operator: operator ?? this.operator,
150+
value: value ?? this.value,
151+
);
152+
153+
/// Converts a JSON object to a [WhereQueryFilter] instance.
154+
factory WhereQueryFilter.fromJson(Map<String, dynamic> json) =>
155+
_$WhereQueryFilterFromJson(json);
156+
157+
/// Converts this [WhereQueryFilter] instance to a JSON object.
158+
Map<String, dynamic> toJson() => _$WhereQueryFilterToJson(this);
159+
160+
@override
161+
List<Object?> get props => [field, operator, value];
162+
}

lib/src/api/models/cloud_database_queries/where_query_filter.g.dart

Lines changed: 46 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/src/api/models/models.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,6 @@ export 'vec.dart';
6666
export 'visual_density.dart';
6767
export 'webview_models.dart';
6868
export 'grid_delegate_type.dart';
69+
export 'cloud_database_queries/query_filter.dart';
70+
export 'cloud_database_queries/where_query_filter.dart';
71+
export 'cloud_database_queries/order_by_query_filter.dart';

0 commit comments

Comments
 (0)