diff --git a/client/build.yaml b/client/build.yaml new file mode 100644 index 0000000..5c3643e --- /dev/null +++ b/client/build.yaml @@ -0,0 +1,7 @@ +targets: + $default: + builders: + moor_generator: + options: + generate_connect_constructor: true + use_column_name_as_json_key_when_defined_in_moor_file: false \ No newline at end of file diff --git a/client/lib/musicus_client.dart b/client/lib/musicus_client.dart index 8084f4d..6bcd252 100644 --- a/client/lib/musicus_client.dart +++ b/client/lib/musicus_client.dart @@ -1 +1,3 @@ -export 'src/client.dart'; \ No newline at end of file +export 'src/client.dart'; +export 'src/database.dart'; +export 'src/info.dart'; \ No newline at end of file diff --git a/client/lib/src/client.dart b/client/lib/src/client.dart index c4a9ca0..b10cc3b 100644 --- a/client/lib/src/client.dart +++ b/client/lib/src/client.dart @@ -3,7 +3,9 @@ import 'dart:io'; import 'package:http/http.dart' as http; import 'package:meta/meta.dart'; -import 'package:musicus_database/musicus_database.dart'; + +import 'database.dart'; +import 'info.dart'; /// Credentials for a Musicus account. class MusicusAccountCredentials { diff --git a/client/lib/src/database.dart b/client/lib/src/database.dart new file mode 100644 index 0000000..69e100d --- /dev/null +++ b/client/lib/src/database.dart @@ -0,0 +1,351 @@ +import 'dart:math'; + +import 'package:moor/moor.dart'; +import 'package:musicus_client/musicus_client.dart'; + +import 'info.dart'; + +part 'database.g.dart'; + +final _random = Random(DateTime.now().millisecondsSinceEpoch); + +/// Generate a random ID suitable for use as primary key. +int generateId() => _random.nextInt(0xFFFFFFFF); + +/// The database for storing all metadata for the music library. +/// +/// This also handles synchronization with a Musicus server. +@UseMoor(include: {'database.moor'}) +class MusicusClientDatabase extends _$MusicusClientDatabase { + /// The number of items contained in one result page. + static const pageSize = 50; + + /// The client to use for synchronization. + /// + /// This may be null indicating that everything should be kept local. + final MusicusClient client; + + @override + int get schemaVersion => 1; + + @override + MigrationStrategy get migration => MigrationStrategy( + beforeOpen: (details) async { + await customStatement('PRAGMA foreign_keys = ON'); + }, + ); + + MusicusClientDatabase({ + @required QueryExecutor executor, + this.client, + }) : super(executor); + + MusicusClientDatabase.connect({ + @required DatabaseConnection connection, + this.client, + }) : super.connect(connection); + + /// Get all available persons. + /// + /// This will return a list of [pageSize] persons. You can get another page + /// using the [page] parameter. If a non empty [search] string is provided, + /// the persons will get filtered based on that string. + Future> getPersons([int page, String search]) async { + final offset = page != null ? page * pageSize : 0; + List result; + + if (search == null || search.isEmpty) { + result = await allPersons(pageSize, offset).get(); + } else { + result = await searchPersons('$search%', pageSize, offset).get(); + } + + return result; + } + + /// Add [person] or replace an existing person with the same ID. + Future updatePerson(Person person) async { + await into(persons).insert( + person, + mode: InsertMode.insertOrReplace, + ); + } + + /// Delete the person by [id]. + Future deletePerson(int id) async { + await (delete(persons)..where((p) => p.id.equals(id))).go(); + } + + /// Get all available instruments. + /// + /// This will return a list of [pageSize] instruments. You can get another + /// page using the [page] parameter. If a non empty [search] string is + /// provided, the instruments will get filtered based on that string. + Future> getInstruments([int page, String search]) async { + final offset = page != null ? page * pageSize : 0; + List result; + + if (search == null || search.isEmpty) { + result = await allInstruments(pageSize, offset).get(); + } else { + result = await searchInstruments('$search%', pageSize, offset).get(); + } + + return result; + } + + /// Add [instrument] or replace an existing one with the same ID. + Future updateInstrument(Instrument instrument) async { + await into(instruments).insert( + instrument, + mode: InsertMode.insertOrReplace, + ); + } + + /// Delete the instrument by [id]. + Future deleteInstrument(int id) async { + await (delete(instruments)..where((i) => i.id.equals(id))).go(); + } + + /// Retrieve more information on an already queried work. + Future getWorkInfo(Work work) async { + final id = work.id; + + final composers = await partComposersByWork(id).get(); + composers.insert(0, await personById(work.composer).getSingle()); + final instruments = await instrumentsByWork(id).get(); + + final List parts = []; + for (final part in await partsByWork(id).get()) { + parts.add(PartInfo( + part: part, + composer: part.composer != null + ? await personById(part.composer).getSingle() + : null, + instruments: await instrumentsByWorkPart(part.id).get(), + )); + } + + final List sections = []; + for (final section in await sectionsByWork(id).get()) { + sections.add(section); + } + + return WorkInfo( + work: work, + instruments: instruments, + composers: composers, + parts: parts, + sections: sections, + ); + } + + /// Get all available information on a work. + Future getWork(int id) async { + final work = await workById(id).getSingle(); + return await getWorkInfo(work); + } + + /// Get information on all works written by the person with ID [personId]. + /// + /// This will return a list of [pageSize] results. You can get another page + /// using the [page] parameter. If a non empty [search] string is provided, + /// the works will be filtered using that string. + Future> getWorks(int personId, + [int page, String search]) async { + final offset = page != null ? page * pageSize : 0; + List works; + + if (search == null || search.isEmpty) { + works = await worksByComposer(personId, pageSize, offset).get(); + } else { + works = + await searchWorksByComposer(personId, '$search%', pageSize, offset) + .get(); + } + + final List result = []; + for (final work in works) { + result.add(await getWorkInfo(work)); + } + + return result; + } + + /// Add or replace a work and its associated data. + /// + /// This will explicitly update all associated composers and instruments, even + /// if they have already existed before. + Future updateWork(WorkInfo workInfo) async { + await transaction(() async { + final workId = workInfo.work.id; + + // Delete old work data first. The parts, sections and instrumentations + // will be deleted automatically due to their foreign key constraints. + await deleteWork(workId); + + // This will also include the composers of the work's parts. + for (final person in workInfo.composers) { + await updatePerson(person); + } + + await into(works).insert(workInfo.work); + + // At the moment, this will also update all provided instruments, even if + // they were already there previously. + for (final instrument in workInfo.instruments) { + await updateInstrument(instrument); + await into(instrumentations).insert(Instrumentation( + work: workId, + instrument: instrument.id, + )); + } + + for (final partInfo in workInfo.parts) { + final part = partInfo.part; + + await into(workParts).insert(part); + + for (final instrument in workInfo.instruments) { + await updateInstrument(instrument); + await into(partInstrumentations).insert(PartInstrumentation( + workPart: part.id, + instrument: instrument.id, + )); + } + } + + for (final section in workInfo.sections) { + await into(workSections).insert(section); + } + }); + } + + /// Delete the work by [id]. + Future deleteWork(int id) async { + // The parts and instrumentations will be deleted automatically due to + // their foreign key constraints. + await (delete(works)..where((w) => w.id.equals(id))).go(); + } + + /// Get all available ensembles. + /// + /// This will return a list of [pageSize] ensembles. You can get another page + /// using the [page] parameter. If a non empty [search] string is provided, + /// the ensembles will get filtered based on that string. + Future> getEnsembles([int page, String search]) async { + final offset = page != null ? page * pageSize : 0; + List result; + + if (search == null || search.isEmpty) { + result = await allEnsembles(pageSize, offset).get(); + } else { + result = await searchEnsembles('$search%', pageSize, offset).get(); + } + + return result; + } + + /// Add [ensemble] or replace an existing one with the same ID. + Future updateEnsemble(Ensemble ensemble) async { + await into(ensembles).insert( + ensemble, + mode: InsertMode.insertOrReplace, + ); + } + + /// Delete the ensemble by [id]. + Future deleteEnsemble(int id) async { + await (delete(ensembles)..where((e) => e.id.equals(id))).go(); + } + + /// Add or replace a recording and its associated data. + /// + /// This will explicitly also update all assoicated persons and instruments. + Future updateRecording(RecordingInfo recordingInfo) async { + await transaction(() async { + final recordingId = recordingInfo.recording.id; + + // Delete the old recording first. This will also delete the performances + // due to their foreign key constraint. + await deleteRecording(recordingId); + + await into(recordings).insert(recordingInfo.recording); + + for (final performance in recordingInfo.performances) { + if (performance.person != null) { + await updatePerson(performance.person); + } + + if (performance.ensemble != null) { + await updateEnsemble(performance.ensemble); + } + + if (performance.role != null) { + await updateInstrument(performance.role); + } + + await into(performances).insert(Performance( + recording: recordingId, + person: performance.person?.id, + ensemble: performance.ensemble?.id, + role: performance.role?.id, + )); + } + }); + } + + /// Retreive more information on an already queried recording. + Future getRecordingInfo(Recording recording) async { + final id = recording.id; + + final List performances = []; + for (final performance in await performancesByRecording(id).get()) { + performances.add(PerformanceInfo( + person: performance.person != null + ? await personById(performance.person).getSingle() + : null, + ensemble: performance.ensemble != null + ? await ensembleById(performance.ensemble).getSingle() + : null, + role: performance.role != null + ? await instrumentById(performance.role).getSingle() + : null, + )); + } + + return RecordingInfo( + recording: recording, + performances: performances, + ); + } + + /// Get all available information on a recording. + Future getRecording(int id) async { + final recording = await recordingById(id).getSingle(); + return await getRecordingInfo(recording); + } + + /// Delete a recording by [id]. + Future deleteRecording(int id) async { + // This will also delete the performances due to their foreign key + // constraint. + await (delete(recordings)..where((r) => r.id.equals(id))).go(); + } + + /// Get information on all recordings of the work with ID [workId]. + /// + /// This will return a list of [pageSize] recordings. You can get the other + /// pages using the [page] parameter. + Future> getRecordings(int workId, [int page]) async { + final offset = page != null ? page * pageSize : 0; + final recordings = await recordingsByWork(workId, pageSize, offset).get(); + + final List result = []; + for (final recording in recordings) { + result.add(await getRecordingInfo(recording)); + } + + return result; + } +} diff --git a/client/lib/src/database.moor b/client/lib/src/database.moor new file mode 100644 index 0000000..3544348 --- /dev/null +++ b/client/lib/src/database.moor @@ -0,0 +1,149 @@ +CREATE TABLE persons ( + id INTEGER NOT NULL PRIMARY KEY, + first_name TEXT NOT NULL, + last_name TEXT NOT NULL, + sync BOOLEAN NOT NULL DEFAULT FALSE, + synced BOOLEAN NOT NULL DEFAULT FALSE +); + +-- This represents real instruments as well as other roles that can be played +-- in a recording. +CREATE TABLE instruments ( + id INTEGER NOT NULL PRIMARY KEY, + name TEXT NOT NULL, + sync BOOLEAN NOT NULL DEFAULT FALSE, + synced BOOLEAN NOT NULL DEFAULT FALSE +); + +CREATE TABLE works ( + id INTEGER NOT NULL PRIMARY KEY, + composer INTEGER REFERENCES persons(id) ON DELETE SET NULL, + title TEXT NOT NULL, + sync BOOLEAN NOT NULL DEFAULT FALSE, + synced BOOLEAN NOT NULL DEFAULT FALSE +); + +CREATE TABLE instrumentations ( + work INTEGER NOT NULL REFERENCES works(id) ON DELETE CASCADE, + instrument INTEGER NOT NULL REFERENCES instruments(id) ON DELETE CASCADE +); + +CREATE TABLE work_parts ( + id INTEGER NOT NULL PRIMARY KEY, + composer INTEGER REFERENCES persons(id) ON DELETE SET NULL, + title TEXT NOT NULL, + part_of INTEGER NOT NULL REFERENCES works(id) ON DELETE CASCADE, + part_index INTEGER NOT NULL +); + +CREATE TABLE part_instrumentations ( + work_part INTEGER NOT NULL REFERENCES works(id) ON DELETE CASCADE, + instrument INTEGER NOT NULL REFERENCES instruments(id) ON DELETE CASCADE +); + +CREATE TABLE work_sections ( + id INTEGER NOT NULL PRIMARY KEY, + work INTEGER NOT NULL REFERENCES works(id) ON DELETE CASCADE, + title TEXT NOT NULL, + before_part_index INTEGER NOT NULL +); + +CREATE TABLE ensembles ( + id INTEGER NOT NULL PRIMARY KEY, + name TEXT NOT NULL, + sync BOOLEAN NOT NULL DEFAULT FALSE, + synced BOOLEAN NOT NULL DEFAULT FALSE +); + +CREATE TABLE recordings ( + id INTEGER NOT NULL PRIMARY KEY, + work INTEGER REFERENCES works(id) ON DELETE SET NULL, + comment TEXT NOT NULL, + sync BOOLEAN NOT NULL DEFAULT FALSE, + synced BOOLEAN NOT NULL DEFAULT FALSE +); + +CREATE TABLE performances ( + recording INTEGER NOT NULL REFERENCES recordings(id) ON DELETE CASCADE, + person INTEGER REFERENCES persons(id) ON DELETE CASCADE, + ensemble INTEGER REFERENCES ensembles(id) ON DELETE CASCADE, + role INTEGER REFERENCES instruments(id) ON DELETE SET NULL +); + +allPersons: +SELECT * FROM persons ORDER BY last_name, first_name + LIMIT :limit OFFSET :offset; + +searchPersons: +SELECT * FROM persons WHERE last_name LIKE :search + ORDER BY last_name, first_name LIMIT :limit OFFSET :offset; + +personById: +SELECT * FROM persons WHERE id = :id LIMIT 1; + +allInstruments: +SELECT * FROM instruments ORDER BY name LIMIT :limit OFFSET :offset; + +searchInstruments: +SELECT * FROM instruments WHERE name LIKE :search ORDER BY name + LIMIT :limit OFFSET :offset; + +instrumentById: +SELECT * FROM instruments WHERE id = :id LIMIT 1; + +workById: +SELECT * FROM works WHERE id = :id LIMIT 1; + +partsByWork: +SELECT * FROM work_parts WHERE part_of = :id ORDER BY part_index; + +sectionsByWork: +SELECT * FROM work_sections WHERE work = :id ORDER BY before_part_index; + +worksByComposer: +SELECT DISTINCT works.* FROM works + JOIN work_parts ON work_parts.part_of = works.id + WHERE works.composer = :id OR work_parts.composer = :id + ORDER BY works.title LIMIT :limit OFFSET :offset; + +searchWorksByComposer: +SELECT DISTINCT works.* FROM works + JOIN work_parts ON work_parts.part_of = works.id + WHERE (works.composer = :id OR work_parts.composer = :id) + AND works.title LIKE :search + ORDER BY works.title LIMIT :limit OFFSET :offset; + +partComposersByWork: +SELECT DISTINCT persons.* FROM persons + JOIN work_parts ON work_parts.composer = persons.id + WHERE work_parts.part_of = :id; + +instrumentsByWork: +SELECT instruments.* FROM instrumentations + JOIN instruments ON instrumentations.instrument = instruments.id + WHERE instrumentations.work = :workId; + +instrumentsByWorkPart: +SELECT instruments.* FROM part_instrumentations + JOIN instruments ON part_instrumentations.instrument = instruments.id + WHERE part_instrumentations.work_part = :id; + +allEnsembles: +SELECT * FROM ensembles ORDER BY name LIMIT :limit OFFSET :offset; + +searchEnsembles: +SELECT * FROM ensembles WHERE name LIKE :search ORDER BY name + LIMIT :limit OFFSET :offset; + +ensembleById: +SELECT * FROM ensembles WHERE id = :id LIMIT 1; + +recordingById: +SELECT * FROM recordings WHERE id = :id; + +recordingsByWork: +SELECT * FROM recordings WHERE work = :id ORDER BY id + LIMIT :limit OFFSET :offset; + +performancesByRecording: +SELECT * FROM performances WHERE recording = :id; \ No newline at end of file diff --git a/client/lib/src/info.dart b/client/lib/src/info.dart new file mode 100644 index 0000000..d337b3d --- /dev/null +++ b/client/lib/src/info.dart @@ -0,0 +1,157 @@ +import 'database.dart'; + +/// A bundle of all available information on a work part. +class PartInfo { + /// The work part itself. + final WorkPart part; + + /// A list of instruments. + /// + /// This will include the instruments, that are specific to this part. + final List instruments; + + /// The composer of this part. + /// + /// This is null, if this part doesn't have a specific composer. + final Person composer; + + PartInfo({ + this.part, + this.instruments, + this.composer, + }); + + factory PartInfo.fromJson(Map json) => PartInfo( + part: WorkPart.fromJson(json['part']), + instruments: json['instruments'] + .map((j) => Instrument.fromJson(j)) + .toList(), + composer: + json['composer'] != null ? Person.fromJson(json['composer']) : null, + ); + + Map toJson() => { + 'part': part.toJson(), + 'instruments': instruments.map((i) => i.toJson()).toList(), + 'composers': composer?.toJson(), + }; +} + +/// A bundle information on a work. +/// +/// This includes all available information except for recordings of this work. +class WorkInfo { + /// The work itself. + final Work work; + + /// A list of instruments. + /// + /// This will not the include the instruments, that are specific to the work + /// parts. + final List instruments; + + /// A list of persons, which will include all part composers. + final List composers; + + /// All available information on the work parts. + final List parts; + + /// The sections of this work. + final List sections; + + WorkInfo({ + this.work, + this.instruments, + this.composers, + this.parts, + this.sections, + }); + + factory WorkInfo.fromJson(Map json) => WorkInfo( + work: Work.fromJson(json['work']), + instruments: json['instruments'] + .map((j) => Instrument.fromJson(j)) + .toList(), + composers: + json['composers'].map((j) => Person.fromJson(j)).toList(), + parts: + json['parts'].map((j) => PartInfo.fromJson(j)).toList(), + sections: json['sections'] + .map((j) => WorkSection.fromJson(j)) + .toList(), + ); + + Map toJson() => { + 'work': work.toJson(), + 'instruments': instruments.map((i) => i.toJson()).toList(), + 'composers': composers.map((c) => c.toJson()).toList(), + 'parts': parts.map((c) => c.toJson()).toList(), + 'sections': sections.map((s) => s.toJson()).toList(), + }; +} + +/// All available information on a performance within a recording. +class PerformanceInfo { + /// The performing person. + /// + /// This will be null, if this is an ensemble. + final Person person; + + /// The performing ensemble. + /// + /// This will be null, if this is a person. + final Ensemble ensemble; + + /// The instrument/role or null. + final Instrument role; + + PerformanceInfo({ + this.person, + this.ensemble, + this.role, + }); + + factory PerformanceInfo.fromJson(Map json) => + PerformanceInfo( + person: json['person'] != null ? Person.fromJson(json['person']) : null, + ensemble: json['ensemble'] != null + ? Ensemble.fromJson(json['ensemble']) + : null, + role: json['role'] != null ? Instrument.fromJson(json['role']) : null, + ); + + Map toJson() => { + 'person': person?.toJson(), + 'ensemble': ensemble?.toJson(), + 'role': role?.toJson(), + }; +} + +/// All available information on a recording. +/// +/// This doesn't include the recorded work, because probably it's already +/// available. +class RecordingInfo { + /// The recording itself. + final Recording recording; + + /// Information on the performances within this recording. + final List performances; + + RecordingInfo({ + this.recording, + this.performances, + }); + + factory RecordingInfo.fromJson(Map json) => RecordingInfo( + recording: Recording.fromJson(json['recording']), + performances: json['performances'] + .map((j) => PerformanceInfo.fromJson(j)) + .toList(), + ); + + Map toJson() => { + 'recording': recording.toJson(), + 'performances': performances.map((p) => p.toJson()).toList(), + }; +} diff --git a/client/pubspec.yaml b/client/pubspec.yaml index 4d6bda6..39279ff 100644 --- a/client/pubspec.yaml +++ b/client/pubspec.yaml @@ -3,10 +3,13 @@ description: Client library for the Musicus server. version: 0.0.1 environment: - sdk: ">=2.3.0 <3.0.0" + sdk: ">=2.6.0 <3.0.0" dependencies: http: meta: - musicus_database: - path: ../database \ No newline at end of file + moor: + +dev_dependencies: + build_runner: + moor_generator: \ No newline at end of file diff --git a/common/lib/src/backend.dart b/common/lib/src/backend.dart index 3bda8e0..225b5ec 100644 --- a/common/lib/src/backend.dart +++ b/common/lib/src/backend.dart @@ -7,7 +7,6 @@ import 'package:moor/isolate.dart'; import 'package:moor/moor.dart'; import 'package:moor_ffi/moor_ffi.dart'; import 'package:musicus_client/musicus_client.dart'; -import 'package:musicus_database/musicus_database.dart'; import 'library.dart'; import 'platform.dart'; @@ -97,7 +96,7 @@ class MusicusBackendState extends State { /// prevent all access to the backend. MusicusBackendStatus status = MusicusBackendStatus.loading; - Database db; + MusicusClientDatabase db; MusicusPlayback playback; MusicusSettings settings; MusicusClient client; @@ -122,7 +121,7 @@ class MusicusBackendState extends State { } final moorIsolate = MoorIsolate.fromConnectPort(moorPort); - db = Database.connect(await moorIsolate.connect()); + db = MusicusClientDatabase.connect(connection: await moorIsolate.connect()); playback = widget.playback; await playback.setup(); diff --git a/common/lib/src/editors/ensemble.dart b/common/lib/src/editors/ensemble.dart index c45f36b..3a0b2d7 100644 --- a/common/lib/src/editors/ensemble.dart +++ b/common/lib/src/editors/ensemble.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:musicus_database/musicus_database.dart'; +import 'package:musicus_client/musicus_client.dart'; import '../backend.dart'; diff --git a/common/lib/src/editors/instrument.dart b/common/lib/src/editors/instrument.dart index 2c08da1..5c057c8 100644 --- a/common/lib/src/editors/instrument.dart +++ b/common/lib/src/editors/instrument.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:musicus_database/musicus_database.dart'; +import 'package:musicus_client/musicus_client.dart'; import '../backend.dart'; diff --git a/common/lib/src/editors/performance.dart b/common/lib/src/editors/performance.dart index 1ebd39b..d5fd906 100644 --- a/common/lib/src/editors/performance.dart +++ b/common/lib/src/editors/performance.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:musicus_database/musicus_database.dart'; +import 'package:musicus_client/musicus_client.dart'; import '../selectors/ensemble.dart'; import '../selectors/instruments.dart'; diff --git a/common/lib/src/editors/person.dart b/common/lib/src/editors/person.dart index ae4b2ed..0b8a993 100644 --- a/common/lib/src/editors/person.dart +++ b/common/lib/src/editors/person.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:musicus_database/musicus_database.dart'; +import 'package:musicus_client/musicus_client.dart'; import '../backend.dart'; diff --git a/common/lib/src/editors/recording.dart b/common/lib/src/editors/recording.dart index c01b74b..73065ee 100644 --- a/common/lib/src/editors/recording.dart +++ b/common/lib/src/editors/recording.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:musicus_database/musicus_database.dart'; +import 'package:musicus_client/musicus_client.dart'; import '../backend.dart'; import '../editors/performance.dart'; diff --git a/common/lib/src/editors/tracks.dart b/common/lib/src/editors/tracks.dart index 5d084b9..462d0af 100644 --- a/common/lib/src/editors/tracks.dart +++ b/common/lib/src/editors/tracks.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:musicus_database/musicus_database.dart'; +import 'package:musicus_client/musicus_client.dart'; import '../backend.dart'; import '../library.dart'; diff --git a/common/lib/src/editors/work.dart b/common/lib/src/editors/work.dart index f139d70..8160c30 100644 --- a/common/lib/src/editors/work.dart +++ b/common/lib/src/editors/work.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:musicus_database/musicus_database.dart'; +import 'package:musicus_client/musicus_client.dart'; import '../backend.dart'; import '../selectors/instruments.dart'; diff --git a/common/lib/src/selectors/ensemble.dart b/common/lib/src/selectors/ensemble.dart index 068ef29..a24024d 100644 --- a/common/lib/src/selectors/ensemble.dart +++ b/common/lib/src/selectors/ensemble.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:musicus_database/musicus_database.dart'; +import 'package:musicus_client/musicus_client.dart'; import '../editors/ensemble.dart'; import '../widgets/lists.dart'; diff --git a/common/lib/src/selectors/instruments.dart b/common/lib/src/selectors/instruments.dart index adb7fb6..e348226 100644 --- a/common/lib/src/selectors/instruments.dart +++ b/common/lib/src/selectors/instruments.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:musicus_database/musicus_database.dart'; +import 'package:musicus_client/musicus_client.dart'; import '../backend.dart'; import '../editors/instrument.dart'; diff --git a/common/lib/src/selectors/person.dart b/common/lib/src/selectors/person.dart index 8fd1a17..31ed4ef 100644 --- a/common/lib/src/selectors/person.dart +++ b/common/lib/src/selectors/person.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:musicus_database/musicus_database.dart'; +import 'package:musicus_client/musicus_client.dart'; import '../editors/person.dart'; import '../widgets/lists.dart'; diff --git a/common/lib/src/selectors/recording.dart b/common/lib/src/selectors/recording.dart index 16bdd18..cf97ea6 100644 --- a/common/lib/src/selectors/recording.dart +++ b/common/lib/src/selectors/recording.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:musicus_database/musicus_database.dart'; +import 'package:musicus_client/musicus_client.dart'; import '../editors/recording.dart'; import '../widgets/lists.dart'; diff --git a/common/lib/src/selectors/work.dart b/common/lib/src/selectors/work.dart index 364f4f6..a3a52dc 100644 --- a/common/lib/src/selectors/work.dart +++ b/common/lib/src/selectors/work.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:musicus_database/musicus_database.dart'; +import 'package:musicus_client/musicus_client.dart'; import '../editors/work.dart'; import '../widgets/lists.dart'; diff --git a/common/lib/src/widgets/lists.dart b/common/lib/src/widgets/lists.dart index 306b698..52a4689 100644 --- a/common/lib/src/widgets/lists.dart +++ b/common/lib/src/widgets/lists.dart @@ -1,7 +1,7 @@ import 'dart:async'; import 'package:flutter/material.dart'; -import 'package:musicus_database/musicus_database.dart'; +import 'package:musicus_client/musicus_client.dart'; import '../backend.dart'; import '../widgets/texts.dart'; diff --git a/common/lib/src/widgets/recording_tile.dart b/common/lib/src/widgets/recording_tile.dart index 257f38f..697a86f 100644 --- a/common/lib/src/widgets/recording_tile.dart +++ b/common/lib/src/widgets/recording_tile.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:musicus_database/musicus_database.dart'; +import 'package:musicus_client/musicus_client.dart'; import 'texts.dart'; diff --git a/common/lib/src/widgets/texts.dart b/common/lib/src/widgets/texts.dart index 5e63abc..0db58dc 100644 --- a/common/lib/src/widgets/texts.dart +++ b/common/lib/src/widgets/texts.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:musicus_database/musicus_database.dart'; +import 'package:musicus_client/musicus_client.dart'; /// A widget showing information on a list of performances. class PerformancesText extends StatelessWidget { diff --git a/common/pubspec.yaml b/common/pubspec.yaml index 18b9545..da3b035 100644 --- a/common/pubspec.yaml +++ b/common/pubspec.yaml @@ -13,6 +13,4 @@ dependencies: moor_ffi: musicus_client: path: ../client - musicus_database: - path: ../database rxdart: \ No newline at end of file diff --git a/mobile/lib/playback.dart b/mobile/lib/playback.dart index f257eea..51fec66 100644 --- a/mobile/lib/playback.dart +++ b/mobile/lib/playback.dart @@ -5,7 +5,7 @@ import 'dart:ui'; import 'package:audio_service/audio_service.dart'; import 'package:moor/isolate.dart'; -import 'package:musicus_database/musicus_database.dart'; +import 'package:musicus_client/musicus_client.dart'; import 'package:musicus_common/musicus_common.dart'; import 'package:musicus_player/musicus_player.dart'; @@ -281,7 +281,7 @@ class _PlaybackService extends BackgroundAudioTask { final _loading = Completer(); final List _playlist = []; - Database db; + MusicusClientDatabase db; MusicusPlayer _player; int _currentTrack = 0; bool _playing = false; @@ -306,7 +306,7 @@ class _PlaybackService extends BackgroundAudioTask { Future _load() async { final moorPort = IsolateNameServer.lookupPortByName('moor'); final moorIsolate = MoorIsolate.fromConnectPort(moorPort); - db = Database.connect(await moorIsolate.connect()); + db = MusicusClientDatabase.connect(connection: await moorIsolate.connect()); _loading.complete(); } diff --git a/mobile/lib/screens/home.dart b/mobile/lib/screens/home.dart index 07269a6..29ffdd3 100644 --- a/mobile/lib/screens/home.dart +++ b/mobile/lib/screens/home.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; +import 'package:musicus_client/musicus_client.dart'; import 'package:musicus_common/musicus_common.dart'; -import 'package:musicus_database/musicus_database.dart'; import '../icons.dart'; diff --git a/mobile/lib/screens/person.dart b/mobile/lib/screens/person.dart index 930ba34..503739b 100644 --- a/mobile/lib/screens/person.dart +++ b/mobile/lib/screens/person.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; +import 'package:musicus_client/musicus_client.dart'; import 'package:musicus_common/musicus_common.dart'; -import 'package:musicus_database/musicus_database.dart'; import 'work.dart'; diff --git a/mobile/lib/screens/program.dart b/mobile/lib/screens/program.dart index 9a3d170..046d392 100644 --- a/mobile/lib/screens/program.dart +++ b/mobile/lib/screens/program.dart @@ -1,8 +1,8 @@ import 'dart:async'; import 'package:flutter/material.dart'; +import 'package:musicus_client/musicus_client.dart'; import 'package:musicus_common/musicus_common.dart'; -import 'package:musicus_database/musicus_database.dart'; import '../widgets/play_pause_button.dart'; diff --git a/mobile/lib/screens/work.dart b/mobile/lib/screens/work.dart index 666d1e7..4f977ac 100644 --- a/mobile/lib/screens/work.dart +++ b/mobile/lib/screens/work.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; +import 'package:musicus_client/musicus_client.dart'; import 'package:musicus_common/musicus_common.dart'; -import 'package:musicus_database/musicus_database.dart'; class WorkScreen extends StatelessWidget { final WorkInfo workInfo; diff --git a/mobile/lib/widgets/player_bar.dart b/mobile/lib/widgets/player_bar.dart index 055c9fc..5083f0a 100644 --- a/mobile/lib/widgets/player_bar.dart +++ b/mobile/lib/widgets/player_bar.dart @@ -1,8 +1,8 @@ import 'dart:async'; import 'package:flutter/material.dart'; +import 'package:musicus_client/musicus_client.dart'; import 'package:musicus_common/musicus_common.dart'; -import 'package:musicus_database/musicus_database.dart'; import '../screens/program.dart'; diff --git a/mobile/pubspec.yaml b/mobile/pubspec.yaml index 80891f5..e68c7ef 100644 --- a/mobile/pubspec.yaml +++ b/mobile/pubspec.yaml @@ -20,8 +20,6 @@ dependencies: path: ../client musicus_common: path: ../common - musicus_database: - path: ../database musicus_player: path: ../player path: