diff --git a/.gitignore b/.gitignore index b8c2bac..1ab8bb9 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,7 @@ .vscode/ # Flutter/Dart/Pub related +**/*.g.dart **/doc/api/ .dart_tool/ pubspec.lock diff --git a/README.md b/README.md index a6030b3..170139d 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,13 @@ The classical music player and organizer. https://musicus.org +## Hacking + +You can use the following command to automatically update generated code while +working on Musicus: + +`flutter pub run build_runner watch` + ## License Musicus is free and open source software: you can redistribute it and/or modify diff --git a/lib/database.dart b/lib/database.dart new file mode 100644 index 0000000..9101386 --- /dev/null +++ b/lib/database.dart @@ -0,0 +1,40 @@ +import 'package:moor_flutter/moor_flutter.dart'; + +part 'database.g.dart'; + +@UseMoor( + include: { + 'database.moor', + }, +) +class Database extends _$Database { + Database(String fileName) + : super(FlutterQueryExecutor.inDatabaseFolder(path: fileName)); + + @override + int get schemaVersion => 0; + + Future updatePerson(Person person) async { + await into(persons).insert(person); + } + + Future updateInstrument(Instrument instrument) async { + await into(instruments).insert(instrument); + } + + Future updateWork(Work work, List instrumentIds) async { + await transaction(() async { + await into(works).insert(work); + + await (delete(instrumentations)..where((i) => i.work.equals(work.id))) + .go(); + + await into(instrumentations).insertAll(instrumentIds + .map((id) => Instrumentation( + work: work.id, + instrument: id, + )) + .toList()); + }); + } +} diff --git a/lib/database.moor b/lib/database.moor new file mode 100644 index 0000000..256e89d --- /dev/null +++ b/lib/database.moor @@ -0,0 +1,54 @@ +CREATE TABLE persons ( + id INTEGER NOT NULL PRIMARY KEY, + first_name TEXT NOT NULL, + last_name TEXT NOT NULL +); + +CREATE TABLE instruments ( + id INTEGER NOT NULL PRIMARY KEY, + name TEXT NOT NULL +); + +CREATE TABLE works ( + id INTEGER NOT NULL PRIMARY KEY, + composer INTEGER REFERENCES persons(id), + title TEXT NOT NULL, + part_of INTEGER REFERENCES works(id) ON DELETE CASCADE, + part_index INTEGER +); + +CREATE TABLE instrumentations ( + work INTEGER NOT NULL REFERENCES works(id) ON DELETE CASCADE, + instrument INTEGER NOT NULL REFERENCES instruments(id) ON DELETE CASCADE +); + +allPersons: +SELECT * FROM persons ORDER BY last_name; + +personById: +SELECT * FROM persons WHERE id = :id LIMIT 1; + +allInstruments: +SELECT * FROM instruments ORDER BY name; + +instrumentById: +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; + +instrumentsByWork: +SELECT instruments.* FROM instrumentations + JOIN instruments ON instrumentations.instrument=instruments.id + WHERE instrumentations.work = :workId;