import 'dart:math'; import 'package:moor/moor.dart'; part 'database.g.dart'; final _random = Random(DateTime.now().millisecondsSinceEpoch); int generateId() => _random.nextInt(0xFFFFFFFF); class WorkPartData { final Work work; final List instrumentIds; WorkPartData({ this.work, this.instrumentIds, }); factory WorkPartData.fromJson(Map json) => WorkPartData( work: Work.fromJson(json['work']), instrumentIds: List.from(json['instrumentIds']), ); Map toJson() => { 'work': work.toJson(), 'instrumentIds': instrumentIds, }; } class WorkData { final WorkPartData data; final List partData; WorkData({ this.data, this.partData, }); factory WorkData.fromJson(Map json) => WorkData( data: WorkPartData.fromJson(json['data']), partData: json['partData'] .map((j) => WorkPartData.fromJson(j)) .toList(), ); Map toJson() => { 'data': data.toJson(), 'partData': partData.map((d) => d.toJson()).toList(), }; } class RecordingData { final Recording recording; final List performances; RecordingData({ this.recording, this.performances, }); factory RecordingData.fromJson(Map json) => RecordingData( recording: Recording.fromJson(json['recording']), performances: json['performances'] .map((j) => Performance.fromJson(j)) .toList(), ); Map toJson() => { 'recording': recording.toJson(), 'performances': performances.map((p) => p.toJson()).toList(), }; } @UseMoor( include: { 'database.moor', }, ) class Database extends _$Database { Database(QueryExecutor queryExecutor) : super(queryExecutor); Database.connect(DatabaseConnection connection) : super.connect(connection); @override int get schemaVersion => 1; @override MigrationStrategy get migration => MigrationStrategy( beforeOpen: (details) async { await customStatement('PRAGMA foreign_keys = ON'); }, ); Future updatePerson(Person person) async { await into(persons).insert(person, orReplace: true); } Future updateInstrument(Instrument instrument) async { await into(instruments).insert(instrument, orReplace: true); } Future updateWork(WorkData data) async { await transaction(() async { final workId = data.data.work.id; await (delete(works)..where((w) => w.id.equals(workId))).go(); await (delete(works)..where((w) => w.partOf.equals(workId))).go(); Future insertWork(WorkPartData partData) async { await into(works).insert(partData.work); await batch((b) => b.insertAll( instrumentations, partData.instrumentIds .map((id) => Instrumentation(work: partData.work.id, instrument: id)) .toList())); } await insertWork(data.data); for (final partData in data.partData) { await insertWork(partData); } }); } Future updateEnsemble(Ensemble ensemble) async { await into(ensembles).insert(ensemble, orReplace: true); } Future updateRecording(RecordingData data) async { await transaction(() async { await (delete(performances) ..where((p) => p.recording.equals(data.recording.id))) .go(); await into(recordings).insert(data.recording, orReplace: true); for (final performance in data.performances) { await into(performances).insert(performance); } }); } }