✍️
Flutter【Supabase】 DB取得 日付絞り込み 、フィルター独自定義(extensionFilterDay() を自作)
概要
SupabaseのFlutterのSDKを利用して、DBからデータを取得する際に、日付指定して絞り込みたかった。
[以上,以下](.lt(), .gt())を使い、を利用すれば実現できる。
が、ちょっと手間なので、日付絞り込みを、Extensionで独自拡張して対応しました。
対応後の実装( extensionFilterDay()を自作)
final todayDate = DateTime.now().toUtc() // 当日のDateTimeを作成
final res = await Supabase.instance.client
.from("my_table") // テーブル名
.select() // GET
.extensionFilterDay("created_at", todayDate) // 日時で絞る
もともとの処理
final todayDate = DateTime.now().toUtc() // 当日のDateTimeを作成
final nextDayDate = dayDateUTC.add(Duration(days: 1)); // 次の日のDateTimeを作成
// "yyyy-MM-dd"の文字列に変換
final outputFormat = DateFormat('yyyy-MM-dd');
final startDateString = outputFormat.format(startDayDate);
final nextDateString = outputFormat.format(nextDayDate);
final res = await Supabase.instance.client
.from("my_table") // テーブル名
.select() // GET
.gte("created_at", startDateString) // 日時で絞る(greater than or equal, '<=')
.lt("created_at", nextDateString) // 日時で絞る(less than, '>')
- 冗長な箇所
- 2つのFilterの指定が必要。( '<=' , と '>' の演算子)
- 引数に文字列変換が必要(Datetime -> 'yyyy-MM-dd'形式のString)
extensionで独自拡張を作成
日付にまつわる絞り込み処理を、下記2つ定義してExtensionを作成する
- 1, 日付を1日指定して絞り込む処理(.extensionFilterDay(date))
- 2, 日付を期間で指定して絞り込む処理(.extensionFilterDateRange(start, end))
// SupabaseのFilterの独自拡張を定義
extension PostgrestFilterBuilderExtensions on PostgrestFilterBuilder {
// 「指定した日付(UTC)で絞り込む」拡張処理
// ex)
// - 'created_at'を、現在の日付(UTC)で、絞りこむ例
// .select()
// .extensionFilterDay('created_at', DateTime.now().toUtc())
PostgrestFilterBuilder extensionFilterDay(String columnCreatedAt,
DateTime dayDateUTC) {
final startDayDate = dayDateUTC;
final nextDayDate = dayDateUTC.add(Duration(days: 1)); // add one day
// cast [DateTime] to ['yyy-MM-dd' String].
// ---
final outputFormat = DateFormat('yyyy-MM-dd');
final startDateString = outputFormat.format(startDayDate);
final nextDateString = outputFormat.format(nextDayDate);
print(
"add date Filter: [ $startDateString <= ] && [ > $nextDateString ] ");
// ---
// add filter ( startDayDate <= 'targetDay' && 'targetDay' > nextDayDate )
return this
.gte(
columnCreatedAt, startDateString) // filter by day(greater than or equal, '<=')
.lt(columnCreatedAt, nextDateString); // filter by day(less than, '>')
}
// 「指定した日付(UTC)のレンジで絞り込む」拡張処理
// NOTE: the parameter 'endDayDateUTC' is '>=', so it is contained date.
// ex)
// - 'created_at'を、日付(UTC)で、絞りこむ例
//
// final twoDaysBefore = DateTime.now().toUtc().add(Duration(days: -2))
// final twoDaysAfter = DateTime.now().toUtc().add(Duration(days: 2))
//
// .select()
// .extensionFilterDayRange('created_at', twoDaysBefore, twoDaysAfter)
PostgrestFilterBuilder extensionFilterDateRange(String columnCreatedAt, DateTime startDayDateUTC, DateTime endDayDateUTC) {
// cast [DateTime] to ['yyy-MM-dd' String].
// ---
final outputFormat = DateFormat('yyyy-MM-dd');
final startDateString = outputFormat.format(startDayDateUTC);
final endDateString = outputFormat.format(endDayDateUTC);
print("add date Filter: [ $startDateString <= ] && [ >= $endDateString ] " );
// ---
// add filter ( startDayDate <= 'targetDay' && 'targetDay' => nextDayDate )
return this
.gte(columnCreatedAt, startDateString) // filter by day(greater than or equal, '<=')
.lte(columnCreatedAt, endDateString); // filter by day(less than or equal, '>=')
}
}
// ex)1日の日付で絞る実装
final todayDate = DateTime.now().toUtc() // 当日のDateTimeを作成
final res = await Supabase.instance.client
.from("myTable") // テーブル名
.select() // GET
.extensionFilterDay("created_at", todayDate) // 日時で絞る
// ex)期間で絞る実装
final todayDate = DateTime.now().toUtc() // 当日のDateTimeを作成
final oneWeekLaterDayDate = dayDateUTC.add(Duration(days: 7)); // add one day
final res = await Supabase.instance.client
.from("myTable") // テーブル名
.select() // GET
.extensionFilterDayRange("created_at", todayDate, oneWeekLaterDayDate) // 日時を期間で絞る
所感
個人的には、FirebaseのDB(Firestore)と比べると、SupabaseのDBの方がデータ操作ををサクサク実装できるので嬉しい😀
FirebaseFirestoreだと、NoSQLだったりするので、Firebase導入プロジェクトでも、DBだけは「Supabase」で対応、というような両方利用するパターンを採用してみた。
将来的に、DBの移行作業があったとしても、Firestoreより、Supabaseの方が多く人にとってやりやすいのではないかな、とも思いました。
その他
適用されたフィルターを、Debug時にPrintして確認したかったが、それようの機能?がなさそう?
調べきれてないかもですが。。。
// イメージ
final res = await Supabase.instance.client
.from("awesome_table") // テーブル名
.select() // GET
.order("awesome_column1") // ソート
.order("awesome_column2") // ソート
.limit(100) // 最大取得件数を指定
.debugPrint() // <- これつけると、「Debug」時に、↑の設定をログはいてくれるイメージ
// ↓の debugフラグを試したが、期待した設定のログ出力はなかった。。
/// ↓ debugのコメント定義
/// If [debug] is set to `true`, debug logs will be printed in debug console.
await Supabase.initialize(
url: Env.supabaseUrl,
anonKey: Env.supabaseApiKey,
debug: true, // <- これつけたけど、↑のような細かな条件は出力されないみたい
);
Discussion