Skip to content

Commit ad31e7a

Browse files
authored
Merge pull request #1141 from appwrite/cursor/add-new-query-methods-and-tests-870c
Add new query methods and tests
2 parents 4af563f + 9479069 commit ad31e7a

File tree

31 files changed

+1156
-0
lines changed

31 files changed

+1156
-0
lines changed

templates/android/library/src/main/java/io/package/Query.kt.twig

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,84 @@ class Query(
192192
*/
193193
fun contains(attribute: String, value: Any) = Query("contains", attribute, parseValue(value)).toJson()
194194

195+
/**
196+
* Filter resources where attribute does not contain the specified value.
197+
*
198+
* @param attribute The attribute to filter on.
199+
* @param value The value to compare against.
200+
* @returns The query string.
201+
*/
202+
fun notContains(attribute: String, value: Any) = Query("notContains", attribute, parseValue(value)).toJson()
203+
204+
/**
205+
* Filter resources by searching attribute for value (inverse of search).
206+
*
207+
* @param attribute The attribute to filter on.
208+
* @param value The search value to match against.
209+
* @returns The query string.
210+
*/
211+
fun notSearch(attribute: String, value: String) = Query("notSearch", attribute, listOf(value)).toJson()
212+
213+
/**
214+
* Filter resources where attribute is not between start and end (exclusive).
215+
*
216+
* @param attribute The attribute to filter on.
217+
* @param start The start value of the range.
218+
* @param end The end value of the range.
219+
* @returns The query string.
220+
*/
221+
fun notBetween(attribute: String, start: Any, end: Any) = Query("notBetween", attribute, listOf(start, end)).toJson()
222+
223+
/**
224+
* Filter resources where attribute does not start with value.
225+
*
226+
* @param attribute The attribute to filter on.
227+
* @param value The value to compare against.
228+
* @returns The query string.
229+
*/
230+
fun notStartsWith(attribute: String, value: String) = Query("notStartsWith", attribute, listOf(value)).toJson()
231+
232+
/**
233+
* Filter resources where attribute does not end with value.
234+
*
235+
* @param attribute The attribute to filter on.
236+
* @param value The value to compare against.
237+
* @returns The query string.
238+
*/
239+
fun notEndsWith(attribute: String, value: String) = Query("notEndsWith", attribute, listOf(value)).toJson()
240+
241+
/**
242+
* Filter resources where document was created before date.
243+
*
244+
* @param value The date value to compare against.
245+
* @returns The query string.
246+
*/
247+
fun createdBefore(value: String) = Query("createdBefore", null, listOf(value)).toJson()
248+
249+
/**
250+
* Filter resources where document was created after date.
251+
*
252+
* @param value The date value to compare against.
253+
* @returns The query string.
254+
*/
255+
fun createdAfter(value: String) = Query("createdAfter", null, listOf(value)).toJson()
256+
257+
/**
258+
* Filter resources where document was updated before date.
259+
*
260+
* @param value The date value to compare against.
261+
* @returns The query string.
262+
*/
263+
fun updatedBefore(value: String) = Query("updatedBefore", null, listOf(value)).toJson()
264+
265+
/**
266+
* Filter resources where document was updated after date.
267+
*
268+
* @param value The date value to compare against.
269+
* @returns The query string.
270+
*/
271+
fun updatedAfter(value: String) = Query("updatedAfter", null, listOf(value)).toJson()
272+
195273
/**
196274
* Combine multiple queries using logical OR operator.
197275
*

templates/dart/lib/query.dart.twig

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,39 @@ class Query {
8383
static String contains(String attribute, dynamic value) =>
8484
Query._('contains', attribute, value).toString();
8585

86+
/// Filter resources where [attribute] does not contain [value]
87+
/// [value] can be a single value or a list.
88+
static String notContains(String attribute, dynamic value) =>
89+
Query._('notContains', attribute, value).toString();
90+
91+
/// Filter resources by searching [attribute] for [value] (inverse of search).
92+
static String notSearch(String attribute, String value) =>
93+
Query._('notSearch', attribute, value).toString();
94+
95+
/// Filter resources where [attribute] is not between [start] and [end] (exclusive).
96+
static String notBetween(String attribute, dynamic start, dynamic end) =>
97+
Query._('notBetween', attribute, [start, end]).toString();
98+
99+
/// Filter resources where [attribute] does not start with [value].
100+
static String notStartsWith(String attribute, String value) =>
101+
Query._('notStartsWith', attribute, value).toString();
102+
103+
/// Filter resources where [attribute] does not end with [value].
104+
static String notEndsWith(String attribute, String value) =>
105+
Query._('notEndsWith', attribute, value).toString();
106+
107+
/// Filter resources where document was created before [value].
108+
static String createdBefore(String value) => Query._('createdBefore', null, value).toString();
109+
110+
/// Filter resources where document was created after [value].
111+
static String createdAfter(String value) => Query._('createdAfter', null, value).toString();
112+
113+
/// Filter resources where document was updated before [value].
114+
static String updatedBefore(String value) => Query._('updatedBefore', null, value).toString();
115+
116+
/// Filter resources where document was updated after [value].
117+
static String updatedAfter(String value) => Query._('updatedAfter', null, value).toString();
118+
86119
static String or(List<String> queries) =>
87120
Query._('or', null, queries.map((query) => jsonDecode(query)).toList()).toString();
88121

templates/dart/test/query_test.dart.twig

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,5 +211,84 @@ void main() {
211211
expect(query['values'], 1);
212212
expect(query['method'], 'offset');
213213
});
214+
215+
test('returns notContains', () {
216+
final query = Query.notContains('attr', 'value').toJson();
217+
expect(query['attribute'], 'attr');
218+
expect(query['values'], ['value']);
219+
expect(query['method'], 'notContains');
220+
});
221+
222+
test('returns notSearch', () {
223+
final query = Query.notSearch('attr', 'keyword1 keyword2').toJson();
224+
expect(query['attribute'], 'attr');
225+
expect(query['values'], ['keyword1 keyword2']);
226+
expect(query['method'], 'notSearch');
227+
});
228+
229+
group('notBetween()', () {
230+
test('with integers', () {
231+
final query = Query.notBetween('attr', 1, 2).toJson();
232+
expect(query['attribute'], 'attr');
233+
expect(query['values'], [1, 2]);
234+
expect(query['method'], 'notBetween');
235+
});
236+
237+
test('with doubles', () {
238+
final query = Query.notBetween('attr', 1.0, 2.0).toJson();
239+
expect(query['attribute'], 'attr');
240+
expect(query['values'], [1.0, 2.0]);
241+
expect(query['method'], 'notBetween');
242+
});
243+
244+
test('with strings', () {
245+
final query = Query.notBetween('attr', 'a', 'z').toJson();
246+
expect(query['attribute'], 'attr');
247+
expect(query['values'], ['a', 'z']);
248+
expect(query['method'], 'notBetween');
249+
});
250+
});
251+
252+
test('returns notStartsWith', () {
253+
final query = Query.notStartsWith('attr', 'prefix').toJson();
254+
expect(query['attribute'], 'attr');
255+
expect(query['values'], ['prefix']);
256+
expect(query['method'], 'notStartsWith');
257+
});
258+
259+
test('returns notEndsWith', () {
260+
final query = Query.notEndsWith('attr', 'suffix').toJson();
261+
expect(query['attribute'], 'attr');
262+
expect(query['values'], ['suffix']);
263+
expect(query['method'], 'notEndsWith');
264+
});
265+
266+
test('returns createdBefore', () {
267+
final query = Query.createdBefore('2023-01-01').toJson();
268+
expect(query['attribute'], null);
269+
expect(query['values'], '2023-01-01');
270+
expect(query['method'], 'createdBefore');
271+
});
272+
273+
test('returns createdAfter', () {
274+
final query = Query.createdAfter('2023-01-01').toJson();
275+
expect(query['attribute'], null);
276+
expect(query['values'], '2023-01-01');
277+
expect(query['method'], 'createdAfter');
278+
});
279+
280+
test('returns updatedBefore', () {
281+
final query = Query.updatedBefore('2023-01-01').toJson();
282+
expect(query['attribute'], null);
283+
expect(query['values'], '2023-01-01');
284+
expect(query['method'], 'updatedBefore');
285+
});
286+
287+
test('returns updatedAfter', () {
288+
final query = Query.updatedAfter('2023-01-01').toJson();
289+
expect(query['attribute'], null);
290+
expect(query['values'], '2023-01-01');
291+
expect(query['method'], 'updatedAfter');
292+
});
214293
}
215294

templates/deno/src/query.ts.twig

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,104 @@ export class Query {
9393
static offset = (offset: number): string =>
9494
new Query("offset", undefined, offset).toString();
9595

96+
/**
97+
* Filter resources where attribute contains the specified value.
98+
*
99+
* @param {string} attribute
100+
* @param {string | string[]} value
101+
* @returns {string}
102+
*/
96103
static contains = (attribute: string, value: string | string[]): string =>
97104
new Query("contains", attribute, value).toString();
98105

106+
/**
107+
* Filter resources where attribute does not contain the specified value.
108+
*
109+
* @param {string} attribute
110+
* @param {string | string[]} value
111+
* @returns {string}
112+
*/
113+
static notContains = (attribute: string, value: string | string[]): string =>
114+
new Query("notContains", attribute, value).toString();
115+
116+
/**
117+
* Filter resources by searching attribute for value (inverse of search).
118+
* A fulltext index on attribute is required for this query to work.
119+
*
120+
* @param {string} attribute
121+
* @param {string} value
122+
* @returns {string}
123+
*/
124+
static notSearch = (attribute: string, value: string): string =>
125+
new Query("notSearch", attribute, value).toString();
126+
127+
/**
128+
* Filter resources where attribute is not between start and end (exclusive).
129+
*
130+
* @param {string} attribute
131+
* @param {string | number} start
132+
* @param {string | number} end
133+
* @returns {string}
134+
*/
135+
static notBetween = (attribute: string, start: string | number, end: string | number): string =>
136+
new Query("notBetween", attribute, [start, end] as QueryTypesList).toString();
137+
138+
/**
139+
* Filter resources where attribute does not start with value.
140+
*
141+
* @param {string} attribute
142+
* @param {string} value
143+
* @returns {string}
144+
*/
145+
static notStartsWith = (attribute: string, value: string): string =>
146+
new Query("notStartsWith", attribute, value).toString();
147+
148+
/**
149+
* Filter resources where attribute does not end with value.
150+
*
151+
* @param {string} attribute
152+
* @param {string} value
153+
* @returns {string}
154+
*/
155+
static notEndsWith = (attribute: string, value: string): string =>
156+
new Query("notEndsWith", attribute, value).toString();
157+
158+
/**
159+
* Filter resources where document was created before date.
160+
*
161+
* @param {string} value
162+
* @returns {string}
163+
*/
164+
static createdBefore = (value: string): string =>
165+
new Query("createdBefore", undefined, value).toString();
166+
167+
/**
168+
* Filter resources where document was created after date.
169+
*
170+
* @param {string} value
171+
* @returns {string}
172+
*/
173+
static createdAfter = (value: string): string =>
174+
new Query("createdAfter", undefined, value).toString();
175+
176+
/**
177+
* Filter resources where document was updated before date.
178+
*
179+
* @param {string} value
180+
* @returns {string}
181+
*/
182+
static updatedBefore = (value: string): string =>
183+
new Query("updatedBefore", undefined, value).toString();
184+
185+
/**
186+
* Filter resources where document was updated after date.
187+
*
188+
* @param {string} value
189+
* @returns {string}
190+
*/
191+
static updatedAfter = (value: string): string =>
192+
new Query("updatedAfter", undefined, value).toString();
193+
99194
static or = (queries: string[]) =>
100195
new Query("or", undefined, queries.map((query) => JSON.parse(query))).toString();
101196

templates/deno/test/query.test.ts.twig

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,4 +172,59 @@ describe('Query', () => {
172172
Query.offset(1).toString(),
173173
`{"method":"offset","values":[1]}`,
174174
));
175+
176+
test('notContains', () => assertEquals(
177+
Query.notContains('attr', 'value').toString(),
178+
`{"method":"notContains","attribute":"attr","values":["value"]}`,
179+
));
180+
181+
test('notSearch', () => assertEquals(
182+
Query.notSearch('attr', 'keyword1 keyword2').toString(),
183+
'{"method":"notSearch","attribute":"attr","values":["keyword1 keyword2"]}',
184+
));
185+
186+
describe('notBetween', () => {
187+
test('with integers', () => assertEquals(
188+
Query.notBetween('attr', 1, 2).toString(),
189+
`{"method":"notBetween","attribute":"attr","values":[1,2]}`,
190+
));
191+
test('with doubles', () => assertEquals(
192+
Query.notBetween('attr', 1.2, 2.2).toString(),
193+
`{"method":"notBetween","attribute":"attr","values":[1.2,2.2]}`,
194+
));
195+
test('with strings', () => assertEquals(
196+
Query.notBetween('attr', "a", "z").toString(),
197+
`{"method":"notBetween","attribute":"attr","values":["a","z"]}`,
198+
));
199+
});
200+
201+
test('notStartsWith', () => assertEquals(
202+
Query.notStartsWith('attr', 'prefix').toString(),
203+
`{"method":"notStartsWith","attribute":"attr","values":["prefix"]}`,
204+
));
205+
206+
test('notEndsWith', () => assertEquals(
207+
Query.notEndsWith('attr', 'suffix').toString(),
208+
`{"method":"notEndsWith","attribute":"attr","values":["suffix"]}`,
209+
));
210+
211+
test('createdBefore', () => assertEquals(
212+
Query.createdBefore('2023-01-01').toString(),
213+
`{"method":"createdBefore","values":["2023-01-01"]}`,
214+
));
215+
216+
test('createdAfter', () => assertEquals(
217+
Query.createdAfter('2023-01-01').toString(),
218+
`{"method":"createdAfter","values":["2023-01-01"]}`,
219+
));
220+
221+
test('updatedBefore', () => assertEquals(
222+
Query.updatedBefore('2023-01-01').toString(),
223+
`{"method":"updatedBefore","values":["2023-01-01"]}`,
224+
));
225+
226+
test('updatedAfter', () => assertEquals(
227+
Query.updatedAfter('2023-01-01').toString(),
228+
`{"method":"updatedAfter","values":["2023-01-01"]}`,
229+
));
175230
})

0 commit comments

Comments
 (0)