🍃

flutterでdriftとfreezeを使う時にやったこと

2023/01/05に公開

はじめに

動作環境は以下のとおり

drift:2.4.0
freezed:2.2.0

一応動いてるけどこれで合ってるのか分からないので誰か教えてください

データクラスをカスタマイズしたいとき

以下に書いてある通りアノテーション@UseRowClassをつけてデータクラスを自作する
https://drift.simonbinder.eu/docs/advanced-features/custom_row_classes/

part 'user.g.dart';

(User)
class Users extends Table {
  IntColumn get id => integer().autoIncrement()();
  TextColumn get name => text()();
  DateTimeColumn get birthday => dateTime()();
}

class User {
  final int id;
  final String name;
  final DateTime birthday;
  final int age;

  User(
      {required this.id,
      required this.name,
      required this.birthday,
      this.age = 0}); // requiredにするとエラーになるのでデフォルト値を設定する

  void method() {
    print('$name($age才)');
  }
}

データクラスをfreezedしたいとき

@UseRowClassで自作のデータクラスを指定して、データクラスに@freezedをつける
なぜか@JsonKeyが被ってエラーになるのでdriftの方をアクセス不可にする

import 'package:drift/drift.dart' hide JsonKey;

part 'user.g.dart';
part 'user.freezed.dart';

(User)
class Users extends Table {
  IntColumn get id => integer().autoIncrement()();
  TextColumn get name => text()();
  DateTimeColumn get birthday => dateTime()();
}


class User with _$User {
  const factory User({
    required int id,
    required String name,
    required DateTime birthday,
  }) = _User;
}

データクラスをカスタマイズかつfreezedしたいとき

以下のAdding getters and methods to our modelsのところに書いてある
https://pub.dev/documentation/freezed/latest/
自作のデータクラスにプライベートのコンストラクタを作る

part 'user.g.dart';
part 'user.freezed.dart';

(User)
class Users extends Table {
  IntColumn get id => integer().autoIncrement()();
  TextColumn get name => text()();
  DateTimeColumn get birthday => dateTime()();
}


class User with _$User {
  const User._(); // これがプライベートコンストラクタらしい
  const factory User({
    required int id,
    required String name,
    required DateTime birthday,
    (0) int age, // requiredの代わりにデフォルト値を設定する
  }) = _User;

  void method() {
    print('$name($age才)');
  }
}

おまけ

ブラウザでデバッグする場合driftがうまく動かなかかったので
スマホとブラウザでデータベースを切り替えたいとき

index.html
<head>
  ...
  <script defer src="sql-wasm.js"></script>
  ...
</head>
main.dart
import 'package:myproject/db_connect.dart'
    if (dart.library.html) 'package:myproject/db_connect_web.dart';
db_connect.dart
import 'dart:io';
import 'package:drift/drift.dart';
import 'package:drift/native.dart';
import 'package:path/path.dart' as p;
import 'package:path_provider/path_provider.dart';

LazyDatabase openConnection() {
  return LazyDatabase(() async {
    final dir = await getApplicationSupportDirectory();
    final file = File(p.join(dir.path, 'db.sqlite'));
    return NativeDatabase(file);
  });
}
db_connect_web.dart
import 'package:drift/drift.dart';
import 'package:drift/web.dart';

LazyDatabase openConnection() {
  return LazyDatabase(() async {
    return WebDatabase("app");
  });
}

参考は以下
https://drift.simonbinder.eu/web/
https://github.com/rodydavis/moor_shared

Discussion