diff --git a/lib/database.dart b/lib/database.dart index 074f6f7..b15633a 100644 --- a/lib/database.dart +++ b/lib/database.dart @@ -7,6 +7,16 @@ part 'database.g.dart'; final _random = Random(DateTime.now().millisecondsSinceEpoch); int generateId() => _random.nextInt(0xFFFFFFFF); +class WorkModel { + final Work work; + final List instrumentIds; + + WorkModel({ + @required this.work, + @required this.instrumentIds, + }); +} + @UseMoor( include: { 'database.moor', @@ -19,6 +29,14 @@ class Database extends _$Database { @override int get schemaVersion => 1; + // TODO: Remove this once https://github.com/simolus3/moor/issues/453 is fixed. + Selectable worksByComposer(int id) { + return customSelectQuery( + 'SELECT DISTINCT A.* FROM works A, works B ON A.id = B.part_of WHERE A.composer = :id OR B.composer = :id', + variables: [Variable.withInt(id)], + readsFrom: {works}).map(_rowToWork); + } + Future updatePerson(Person person) async { await into(persons).insert(person); } @@ -27,19 +45,26 @@ class Database extends _$Database { await into(instruments).insert(instrument); } - Future updateWork(Work work, List instrumentIds) async { + Future updateWork(WorkModel model, List parts) async { await transaction(() async { - await into(works).insert(work); + final workId = model.work.id; + await (delete(works)..where((w) => w.id.equals(workId))).go(); + await (delete(works)..where((w) => w.partOf.equals(workId))).go(); - await (delete(instrumentations)..where((i) => i.work.equals(work.id))) - .go(); + Future insertWork(WorkModel model) async { + await into(works).insert(model.work); + await batch((b) => b.insertAll( + instrumentations, + model.instrumentIds + .map((id) => + Instrumentation(work: model.work.id, instrument: id)) + .toList())); + } - await into(instrumentations).insertAll(instrumentIds - .map((id) => Instrumentation( - work: work.id, - instrument: id, - )) - .toList()); + await insertWork(model); + for (final part in parts) { + await insertWork(part); + } }); } } diff --git a/lib/database.moor b/lib/database.moor index 256e89d..3193bb8 100644 --- a/lib/database.moor +++ b/lib/database.moor @@ -14,7 +14,8 @@ CREATE TABLE works ( composer INTEGER REFERENCES persons(id), title TEXT NOT NULL, part_of INTEGER REFERENCES works(id) ON DELETE CASCADE, - part_index INTEGER + part_index INTEGER, + part_level INTEGER ); CREATE TABLE instrumentations ( @@ -37,16 +38,13 @@ SELECT * FROM instruments WHERE id = :id LIMIT 1; workById: SELECT * FROM works WHERE id = :id LIMIT 1; -worksByComposer: -WITH RECURSIVE work_parts(id, part_of) AS ( - SELECT id, part_of FROM works WHERE composer = :composerId - UNION ALL - SELECT works.id, works.part_of FROM works - JOIN work_parts ON works.id = work_parts.part_of -) -SELECT works.* FROM works - JOIN work_parts ON works.id = work_parts.id - WHERE work_parts.part_of IS NULL; +workParts: +SELECT * FROM works WHERE part_of = :id ORDER BY part_index; + +-- TODO: Uncomment this once https://github.com/simolus3/moor/issues/453 is fixed. +-- worksByComposer(:id AS INTEGER): +-- SELECT DISTINCT A.* FROM works A, works B ON A.id = B.part_of +-- WHERE A.composer = :id OR B.composer = :id; instrumentsByWork: SELECT instruments.* FROM instrumentations