Skip to content
This repository was archived by the owner on May 13, 2023. It is now read-only.

fix/contains list #85

Merged
merged 13 commits into from
Aug 26, 2022
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## [1.0.0-dev.3]

- fix: maybeSingle [#84](https://github.com/supabase-community/postgrest-dart/pull/84)
- fix: `List` as value in any filter [#85](https://github.com/supabase-community/postgrest-dart/pull/85)

## [1.0.0-dev.2]

Expand Down
32 changes: 18 additions & 14 deletions lib/src/postgrest_filter_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ class PostgrestFilterBuilder extends PostgrestTransformBuilder {

/// Convert list filter to query params string
String _cleanFilterArray(List filter) {
if (filter is List<int> || filter is List<double> || filter is List<num>) {
if (filter.every((element) => element is num)) {
return filter.map((s) => '$s').join(',');
} else {
return filter.map((s) => '"$s"').join(',');
Expand All @@ -19,16 +19,15 @@ class PostgrestFilterBuilder extends PostgrestTransformBuilder {
/// ```
PostgrestFilterBuilder not(String column, String operator, dynamic value) {
if (value is List) {
if (operator == 'cs') {
// `cs` filter requires postgrest array type `{}`
if (operator == "in") {
appendSearchParams(
column,
'not.$operator.{${_cleanFilterArray(value)}}',
'not.$operator.(${_cleanFilterArray(value)})',
);
} else {
appendSearchParams(
column,
'not.$operator.(${_cleanFilterArray(value)})',
'not.$operator.{${_cleanFilterArray(value)}}',
);
}
} else {
Expand All @@ -55,7 +54,7 @@ class PostgrestFilterBuilder extends PostgrestTransformBuilder {
/// ```
PostgrestFilterBuilder eq(String column, dynamic value) {
if (value is List) {
appendSearchParams(column, 'eq.(${_cleanFilterArray(value)})');
appendSearchParams(column, 'eq.{${_cleanFilterArray(value)}}');
} else {
appendSearchParams(column, 'eq.$value');
}
Expand All @@ -69,7 +68,7 @@ class PostgrestFilterBuilder extends PostgrestTransformBuilder {
/// ```
PostgrestFilterBuilder neq(String column, dynamic value) {
if (value is List) {
appendSearchParams(column, 'neq.(${_cleanFilterArray(value)})');
appendSearchParams(column, 'neq.{${_cleanFilterArray(value)}}');
} else {
appendSearchParams(column, 'neq.$value');
}
Expand Down Expand Up @@ -171,7 +170,7 @@ class PostgrestFilterBuilder extends PostgrestTransformBuilder {
appendSearchParams(column, 'cs.$value');
} else if (value is List) {
// array
appendSearchParams(column, 'cs.(${_cleanFilterArray(value)})');
appendSearchParams(column, 'cs.{${_cleanFilterArray(value)}}');
} else {
// json
appendSearchParams(column, 'cs.${json.encode(value)}');
Expand All @@ -191,7 +190,7 @@ class PostgrestFilterBuilder extends PostgrestTransformBuilder {
appendSearchParams(column, 'cd.$value');
} else if (value is List) {
// array
appendSearchParams(column, 'cd.(${_cleanFilterArray(value)})');
appendSearchParams(column, 'cd.{${_cleanFilterArray(value)}}');
} else {
// json
appendSearchParams(column, 'cd.${json.encode(value)}');
Expand Down Expand Up @@ -261,7 +260,7 @@ class PostgrestFilterBuilder extends PostgrestTransformBuilder {
appendSearchParams(column, 'ov.$value');
} else if (value is List) {
// array
appendSearchParams(column, 'ov.(${_cleanFilterArray(value)})');
appendSearchParams(column, 'ov.{${_cleanFilterArray(value)}}');
}
return this;
}
Expand Down Expand Up @@ -301,11 +300,16 @@ class PostgrestFilterBuilder extends PostgrestTransformBuilder {
/// ```
PostgrestFilterBuilder filter(String column, String operator, dynamic value) {
if (value is List) {
if (operator == 'cs') {
// `cs` filter requires postgrest array type `{}`
appendSearchParams(column, '$operator.{${_cleanFilterArray(value)}}');
if (operator == "in") {
appendSearchParams(
column,
'$operator.(${_cleanFilterArray(value)})',
);
} else {
appendSearchParams(column, '$operator.(${_cleanFilterArray(value)})');
appendSearchParams(
column,
'$operator.{${_cleanFilterArray(value)}}',
);
}
} else {
appendSearchParams(column, '$operator.$value');
Expand Down
12 changes: 8 additions & 4 deletions test/basic_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,13 @@ void main() {
});

test('basic update', () async {
final res = await postgrest.from('messages').update(
{'channel_id': 2},
).select();
final res = await postgrest
.from('messages')
.update(
{'channel_id': 2},
)
.is_("data", null)
.select();
expect(res, [
{
'id': 1,
Expand Down Expand Up @@ -171,7 +175,7 @@ void main() {
test('basic delete', () async {
final res = await postgrest
.from('messages')
.delete(returning: ReturningOption.minimal)
.delete()
.eq('message', 'Supabase Launch Week is on fire')
.select();
expect(res, [
Expand Down
191 changes: 126 additions & 65 deletions test/filter_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -71,25 +71,49 @@ void main() {
}
});

test('eq', () async {
final res = await postgrest
.from('users')
.select('username')
.eq('username', 'supabot');

for (final item in res as List) {
expect((item as Map)['username'] == ('supabot'), true);
}
});

test('neq', () async {
final res = await postgrest
.from('users')
.select('username')
.neq('username', 'supabot');
for (final item in res as List) {
expect((item as Map)['username'] == ('supabot'), false);
}
group("eq", () {
test('eq string', () async {
final res = await postgrest
.from('users')
.select('username')
.eq('username', 'supabot');

for (final item in res as List) {
expect((item as Map)['username'] == ('supabot'), true);
}
});

test('eq list', () async {
final res = await postgrest
.from('users')
.select('username')
.eq('interests', ["basketball", "baseball"]);

for (final item in res as List) {
expect((item as Map)['username'] == ('supabot'), true);
}
});
});

group("neq", () {
test('neq string', () async {
final res = await postgrest
.from('users')
.select('username')
.neq('username', 'supabot');
for (final item in res as List) {
expect((item as Map)['username'] == ('supabot'), false);
}
});

test('neq list', () async {
final List res = await postgrest
.from('users')
.select('username')
.neq('interests', ["football"]);
final onlyNames = res.map((row) => row["username"]).toList();
expect(onlyNames, ["supabot", "awailas"]);
});
});

test('gt', () async {
Expand Down Expand Up @@ -160,24 +184,45 @@ void main() {
);
}
});
group("contains", () {
test('contains range', () async {
final res = await postgrest
.from('users')
.select('username')
.contains('age_range', '[1,2)');
expect(
((res as List)[0] as Map)['username'],
'supabot',
);
});

test('contains', () async {
final res = await postgrest
.from('users')
.select('username')
.contains('age_range', '[1,2)');
expect(
((res as List)[0] as Map)['username'],
'supabot',
);
});

test('containedBy', () async {
final res = await postgrest
.from('users')
.select('username')
.containedBy('age_range', '[1,2)');
expect(((res as List)[0] as Map)['username'], 'supabot');
test('contains list', () async {
final res = await postgrest
.from('users')
.select('username')
.contains('interests', ["basketball", "baseball"]);
expect(
((res as List)[0] as Map)['username'],
'supabot',
);
});
});
group("containedBy", () {
test('containedBy range', () async {
final res = await postgrest
.from('users')
.select('username')
.containedBy('age_range', '[0,3)');
expect(((res as List)[0] as Map)['username'], 'supabot');
});

test('containedBy list', () async {
final res = await postgrest
.from('users')
.select('username')
.containedBy('interests', ["basketball", "baseball", "xxxx"]);
expect(((res as List)[0] as Map)['username'], 'supabot');
});
});

test('rangeLt', () async {
Expand Down Expand Up @@ -226,15 +271,28 @@ void main() {
expect((res as List).length, 3);
});

test('overlaps', () async {
final res = await postgrest
.from('users')
.select('username')
.overlaps('age_range', '[2,25)');
expect(
((res as List)[0] as Map)['username'],
'dragarcia',
);
group("overlap", () {
test('overlaps range', () async {
final res = await postgrest
.from('users')
.select('username')
.overlaps('age_range', '[2,25)');
expect(
((res as List)[0] as Map)['username'],
'dragarcia',
);
});

test('overlaps list', () async {
final res = await postgrest
.from('users')
.select('username')
.overlaps('interests', ["basketball", "baseball"]);
expect(
((res as List)[0] as Map)['username'],
'supabot',
);
});
});

test('textSearch', () async {
Expand Down Expand Up @@ -287,26 +345,29 @@ void main() {
expect(((res as List)[0] as Map)['username'], 'supabot');
});

test('filter', () async {
final res = await postgrest
.from('users')
.select()
.filter('username', 'eq', 'supabot');
expect(((res as List)[0] as Map)['username'], 'supabot');
});

test('filter cs with List of values', () async {
final res = await postgrest
.from('users')
.select()
.filter('interests', 'cs', ['basketball']);
expect((res as List).length, 2);
for (final item in res) {
expect(
((item as Map)['interests'] as List).contains('basketball'),
true,
);
}
group("filter", () {
test('filter', () async {
final res = await postgrest
.from('users')
.select()
.filter('username', 'eq', 'supabot');
expect(((res as List)[0] as Map)['username'], 'supabot');
});

test('filter in with List of values', () async {
final res = await postgrest
.from('users')
.select()
.filter('username', 'in', ['supabot', 'kiwicopple']);
expect((res as List).length, 2);
for (final item in res) {
expect(
(item as Map)['username'] == 'supabot' ||
item['username'] == 'kiwicopple',
true,
);
}
});
});

test('match', () async {
Expand Down