- Fix HOME override that caused FVM to re-download 220MB Flutter SDK on every run; use XDG_DATA_HOME instead to isolate app data without touching HOME - Switch DB path from getApplicationDocumentsDirectory() to getApplicationSupportDirectory() so XDG_DATA_HOME isolation works and stale accounts don't leak between test runs - Replace fixed pump(5s/3s) waits with pumpUntil() polling at 200ms so tests stop waiting as soon as the UI is ready (23s of dead wait → 8s) - Add timing instrumentation (ts() in shell, _log()/Stopwatch in Dart) - Fix CI integration-ui job: was mixing subosito flutter with fvm flutter; now uses fvm consistently with actions/cache for ~/.fvm, ~/.pub-cache, and build/linux Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
93 lines
3.4 KiB
Dart
93 lines
3.4 KiB
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';
|
|
|
|
part 'database.g.dart';
|
|
|
|
// ── Tables ────────────────────────────────────────────────────────────────────
|
|
|
|
class Accounts extends Table {
|
|
TextColumn get id => text()();
|
|
TextColumn get displayName => text()();
|
|
TextColumn get email => text()();
|
|
TextColumn get imapHost => text()();
|
|
IntColumn get imapPort => integer()();
|
|
BoolColumn get imapSsl => boolean()();
|
|
TextColumn get smtpHost => text()();
|
|
IntColumn get smtpPort => integer()();
|
|
BoolColumn get smtpSsl => boolean()();
|
|
|
|
@override
|
|
Set<Column> get primaryKey => {id};
|
|
}
|
|
|
|
@DataClassName('MailboxRow')
|
|
class Mailboxes extends Table {
|
|
TextColumn get id => text()();
|
|
TextColumn get accountId =>
|
|
text().references(Accounts, #id, onDelete: KeyAction.cascade)();
|
|
TextColumn get path => text()();
|
|
TextColumn get name => text()();
|
|
IntColumn get unreadCount => integer().withDefault(const Constant(0))();
|
|
IntColumn get totalCount => integer().withDefault(const Constant(0))();
|
|
|
|
@override
|
|
Set<Column> get primaryKey => {id};
|
|
}
|
|
|
|
class Emails extends Table {
|
|
TextColumn get id => text()();
|
|
TextColumn get accountId =>
|
|
text().references(Accounts, #id, onDelete: KeyAction.cascade)();
|
|
TextColumn get mailboxPath => text()();
|
|
IntColumn get uid => integer()();
|
|
TextColumn get subject => text().nullable()();
|
|
DateTimeColumn get sentAt => dateTime().nullable()();
|
|
DateTimeColumn get receivedAt => dateTime()();
|
|
// JSON-encoded List<{name,email}>
|
|
TextColumn get fromJson => text().withDefault(const Constant('[]'))();
|
|
TextColumn get toAddresses => text().withDefault(const Constant('[]'))();
|
|
TextColumn get ccJson => text().withDefault(const Constant('[]'))();
|
|
TextColumn get preview => text().nullable()();
|
|
BoolColumn get isSeen => boolean().withDefault(const Constant(false))();
|
|
BoolColumn get isFlagged => boolean().withDefault(const Constant(false))();
|
|
BoolColumn get hasAttachment => boolean().withDefault(const Constant(false))();
|
|
|
|
@override
|
|
Set<Column> get primaryKey => {id};
|
|
}
|
|
|
|
class EmailBodies extends Table {
|
|
TextColumn get emailId =>
|
|
text().references(Emails, #id, onDelete: KeyAction.cascade)();
|
|
TextColumn get textBody => text().nullable()();
|
|
TextColumn get htmlBody => text().nullable()();
|
|
// JSON-encoded List<{filename,contentType,size}>
|
|
TextColumn get attachmentsJson =>
|
|
text().withDefault(const Constant('[]'))();
|
|
|
|
@override
|
|
Set<Column> get primaryKey => {emailId};
|
|
}
|
|
|
|
// ── Database ──────────────────────────────────────────────────────────────────
|
|
|
|
@DriftDatabase(tables: [Accounts, Mailboxes, Emails, EmailBodies])
|
|
class AppDatabase extends _$AppDatabase {
|
|
AppDatabase([QueryExecutor? executor]) : super(executor ?? _openConnection());
|
|
|
|
@override
|
|
int get schemaVersion => 1;
|
|
}
|
|
|
|
LazyDatabase _openConnection() {
|
|
return LazyDatabase(() async {
|
|
final dir = await getApplicationSupportDirectory();
|
|
final file = File(p.join(dir.path, 'sharedinbox.db'));
|
|
return NativeDatabase.createInBackground(file);
|
|
});
|
|
}
|