diff --git a/packages/postgrest/lib/src/postgrest_filter_builder.dart b/packages/postgrest/lib/src/postgrest_filter_builder.dart index 97798fe6a..b922903ba 100644 --- a/packages/postgrest/lib/src/postgrest_filter_builder.dart +++ b/packages/postgrest/lib/src/postgrest_filter_builder.dart @@ -476,6 +476,45 @@ class PostgrestFilterBuilder extends PostgrestTransformBuilder { return copyWithUrl(url); } + /// Finds all rows whose value in the stated [column] matches the supplied [pattern] using PostgreSQL regular expression (case sensitive). + /// + /// ```dart + /// await supabase + /// .from('users') + /// .select() + /// .matchRegex('username', '^sup.*'); + /// ``` + PostgrestFilterBuilder matchRegex(String column, String pattern) { + return copyWithUrl(appendSearchParams(column, 'match.$pattern')); + } + + /// Finds all rows whose value in the stated [column] matches the supplied [pattern] using PostgreSQL regular expression (case insensitive). + /// + /// ```dart + /// await supabase + /// .from('users') + /// .select() + /// .imatchRegex('username', '^SUP.*'); + /// ``` + PostgrestFilterBuilder imatchRegex(String column, String pattern) { + return copyWithUrl(appendSearchParams(column, 'imatch.$pattern')); + } + + /// Finds all rows whose value on the stated [column] is not equal to the specified [value], treating `NULL` as a comparable value. + /// + /// This is different from [neq] which treats `NULL` specially. + /// + /// ```dart + /// await supabase + /// .from('users') + /// .select() + /// .isDistinct('age', null); + /// ``` + // ignore: non_constant_identifier_names + PostgrestFilterBuilder isDistinct(String column, Object? value) { + return copyWithUrl(appendSearchParams(column, 'isdistinct.$value')); + } + @override PostgrestFilterBuilder setHeader(String key, String value) { return PostgrestFilterBuilder( diff --git a/packages/postgrest/test/filter_test.dart b/packages/postgrest/test/filter_test.dart index 606a3ac6f..49ac4c55a 100644 --- a/packages/postgrest/test/filter_test.dart +++ b/packages/postgrest/test/filter_test.dart @@ -477,6 +477,39 @@ void main() { expect(res[0]['username'], 'supabot'); }); + test('matchRegex - regex match (case sensitive)', () async { + final res = await postgrest + .from('users') + .select('username') + .matchRegex('username', '^supa.*'); + expect(res, isNotEmpty); + for (final item in res) { + expect((item['username'] as String).startsWith('supa'), true); + } + }); + + test('imatchRegex - regex match (case insensitive)', () async { + final res = await postgrest + .from('users') + .select('username') + .imatchRegex('username', '^SUPA.*'); + expect(res, isNotEmpty); + for (final item in res) { + expect( + (item['username'] as String).toLowerCase().startsWith('supa'), true); + } + }); + + test('isDistinct', () async { + final res = await postgrest + .from('users') + .select('username,status') + .isDistinct('status', 'ONLINE'); + expect(res, isNotEmpty); + for (final item in res) { + expect(item['status'] != 'ONLINE', true); + } + }); test('filter on rpc', () async { final List res = await postgrest.rpc('get_username_and_status', params: {'name_param': 'supabot'}).neq('status', 'ONLINE'); diff --git a/packages/supabase_flutter/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/supabase_flutter/example/android/gradle/wrapper/gradle-wrapper.properties index d5ce57cba..ae4378fe9 100644 --- a/packages/supabase_flutter/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/packages/supabase_flutter/example/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip \ No newline at end of file +distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-all.zip \ No newline at end of file diff --git a/packages/supabase_flutter/example/android/settings.gradle b/packages/supabase_flutter/example/android/settings.gradle index ed68c2f27..6c34fad02 100644 --- a/packages/supabase_flutter/example/android/settings.gradle +++ b/packages/supabase_flutter/example/android/settings.gradle @@ -18,7 +18,7 @@ pluginManagement { plugins { id "dev.flutter.flutter-plugin-loader" version "1.0.0" - id "com.android.application" version "8.6.0" apply false + id "com.android.application" version '8.13.1' apply false id "org.jetbrains.kotlin.android" version "2.1.20" apply false }