Add artist_id, album_id and song id to songs

This commit is contained in:
Jonas Kvinge 2019-05-30 18:04:30 +02:00
parent 7609bc181e
commit 111712fd6d
7 changed files with 142 additions and 45 deletions

View File

@ -5,6 +5,7 @@
<file>schema/schema-2.sql</file>
<file>schema/schema-3.sql</file>
<file>schema/schema-4.sql</file>
<file>schema/schema-5.sql</file>
<file>schema/device-schema.sql</file>
<file>style/strawberry.css</file>
<file>html/playing-tooltip-plain.html</file>

View File

@ -27,6 +27,10 @@ CREATE TABLE device_%deviceid_songs (
comment TEXT NOT NULL,
lyrics TEXT NOT NULL,
artist_id INTEGER NOT NULL DEFAULT -1;
album_id INTEGER NOT NULL DEFAULT -1;
song_id INTEGER NOT NULL DEFAULT -1;
beginning INTEGER NOT NULL DEFAULT 0,
length INTEGER NOT NULL DEFAULT 0,
@ -38,9 +42,9 @@ CREATE TABLE device_%deviceid_songs (
directory_id INTEGER NOT NULL,
filename TEXT NOT NULL,
filetype INTEGER NOT NULL DEFAULT 0,
filesize INTEGER NOT NULL,
mtime INTEGER NOT NULL,
ctime INTEGER NOT NULL,
filesize INTEGER NOT NULL DEFAULT 0,
mtime INTEGER NOT NULL DEFAULT 0,
ctime INTEGER NOT NULL DEFAULT 0,
unavailable INTEGER DEFAULT 0,
playcount INTEGER NOT NULL DEFAULT 0,

31
data/schema/schema-5.sql Normal file
View File

@ -0,0 +1,31 @@
ALTER TABLE songs ADD COLUMN artist_id INTEGER NOT NULL DEFAULT -1;
ALTER TABLE songs ADD COLUMN album_id INTEGER NOT NULL DEFAULT -1;
ALTER TABLE songs ADD COLUMN song_id INTEGER NOT NULL DEFAULT -1;
ALTER TABLE tidal_artists_songs ADD COLUMN artist_id INTEGER NOT NULL DEFAULT -1;
ALTER TABLE tidal_artists_songs ADD COLUMN album_id INTEGER NOT NULL DEFAULT -1;
ALTER TABLE tidal_artists_songs ADD COLUMN song_id INTEGER NOT NULL DEFAULT -1;
ALTER TABLE tidal_albums_songs ADD COLUMN artist_id INTEGER NOT NULL DEFAULT -1;
ALTER TABLE tidal_albums_songs ADD COLUMN album_id INTEGER NOT NULL DEFAULT -1;
ALTER TABLE tidal_albums_songs ADD COLUMN song_id INTEGER NOT NULL DEFAULT -1;
ALTER TABLE tidal_songs ADD COLUMN artist_id INTEGER NOT NULL DEFAULT -1;
ALTER TABLE tidal_songs ADD COLUMN album_id INTEGER NOT NULL DEFAULT -1;
ALTER TABLE tidal_songs ADD COLUMN song_id INTEGER NOT NULL DEFAULT -1;
ALTER TABLE playlist_items ADD COLUMN artist_id INTEGER NOT NULL DEFAULT -1;
ALTER TABLE playlist_items ADD COLUMN album_id INTEGER NOT NULL DEFAULT -1;
ALTER TABLE playlist_items ADD COLUMN song_id INTEGER NOT NULL DEFAULT -1;
UPDATE schema_version SET version=5;

View File

@ -4,7 +4,7 @@ CREATE TABLE IF NOT EXISTS schema_version (
DELETE FROM schema_version;
INSERT INTO schema_version (version) VALUES (4);
INSERT INTO schema_version (version) VALUES (5);
CREATE TABLE IF NOT EXISTS directories (
path TEXT NOT NULL,
@ -35,6 +35,10 @@ CREATE TABLE IF NOT EXISTS songs (
comment TEXT NOT NULL,
lyrics TEXT NOT NULL,
artist_id INTEGER NOT NULL DEFAULT -1;
album_id INTEGER NOT NULL DEFAULT -1;
song_id INTEGER NOT NULL DEFAULT -1;
beginning INTEGER NOT NULL DEFAULT 0,
length INTEGER NOT NULL DEFAULT 0,
@ -88,6 +92,10 @@ CREATE TABLE IF NOT EXISTS tidal_artists_songs (
comment TEXT NOT NULL,
lyrics TEXT NOT NULL,
artist_id INTEGER NOT NULL DEFAULT -1;
album_id INTEGER NOT NULL DEFAULT -1;
song_id INTEGER NOT NULL DEFAULT -1;
beginning INTEGER NOT NULL DEFAULT 0,
length INTEGER NOT NULL DEFAULT 0,
@ -141,6 +149,10 @@ CREATE TABLE IF NOT EXISTS tidal_albums_songs (
comment TEXT NOT NULL,
lyrics TEXT NOT NULL,
artist_id INTEGER NOT NULL DEFAULT -1;
album_id INTEGER NOT NULL DEFAULT -1;
song_id INTEGER NOT NULL DEFAULT -1;
beginning INTEGER NOT NULL DEFAULT 0,
length INTEGER NOT NULL DEFAULT 0,
@ -194,6 +206,10 @@ CREATE TABLE IF NOT EXISTS tidal_songs (
comment TEXT NOT NULL,
lyrics TEXT NOT NULL,
artist_id INTEGER NOT NULL DEFAULT -1;
album_id INTEGER NOT NULL DEFAULT -1;
song_id INTEGER NOT NULL DEFAULT -1;
beginning INTEGER NOT NULL DEFAULT 0,
length INTEGER NOT NULL DEFAULT 0,
@ -263,6 +279,10 @@ CREATE TABLE IF NOT EXISTS playlist_items (
comment TEXT NOT NULL,
lyrics TEXT NOT NULL,
artist_id INTEGER NOT NULL DEFAULT -1;
album_id INTEGER NOT NULL DEFAULT -1;
song_id INTEGER NOT NULL DEFAULT -1;
beginning INTEGER NOT NULL DEFAULT 0,
length INTEGER NOT NULL DEFAULT 0,

View File

@ -52,7 +52,7 @@
#include "scopedtransaction.h"
const char *Database::kDatabaseFilename = "strawberry.db";
const int Database::kSchemaVersion = 4;
const int Database::kSchemaVersion = 5;
const char *Database::kMagicAllSongsTables = "%allsongstables";
int Database::sNextConnectionId = 1;

View File

@ -89,6 +89,10 @@ const QStringList Song::kColumns = QStringList() << "title"
<< "comment"
<< "lyrics"
<< "artist_id"
<< "album_id"
<< "song_id"
<< "beginning"
<< "length"
@ -155,7 +159,6 @@ struct Song::Private : public QSharedData {
bool valid_;
int id_;
int album_id_; // A unique album ID
QString title_;
QString album_;
@ -173,6 +176,10 @@ struct Song::Private : public QSharedData {
QString comment_;
QString lyrics_;
int artist_id_;
int album_id_;
int song_id_;
qint64 beginning_;
qint64 end_;
@ -215,15 +222,20 @@ struct Song::Private : public QSharedData {
Song::Private::Private(Song::Source source)
: valid_(false),
id_(-1),
album_id_(-1),
track_(-1),
disc_(-1),
year_(-1),
originalyear_(-1),
compilation_(false),
artist_id_(-1),
album_id_(-1),
song_id_(-1),
beginning_(0),
end_(-1),
bitrate_(-1),
samplerate_(-1),
bitdepth_(-1),
@ -261,60 +273,53 @@ Song &Song::operator=(const Song &other) {
bool Song::is_valid() const { return d->valid_; }
bool Song::is_unavailable() const { return d->unavailable_; }
int Song::id() const { return d->id_; }
int Song::artist_id() const { return d->artist_id_; }
int Song::album_id() const { return d->album_id_; }
int Song::song_id() const { return d->song_id_; }
const QString &Song::title() const { return d->title_; }
const QString &Song::album() const { return d->album_; }
const QString &Song::effective_album() const {
// This value is useful for singles, which are one-track albums on their own.
return d->album_.isEmpty() ? d->title_ : d->album_;
}
// This value is useful for singles, which are one-track albums on their own.
const QString &Song::effective_album() const { return d->album_.isEmpty() ? d->title_ : d->album_; }
const QString &Song::artist() const { return d->artist_; }
const QString &Song::albumartist() const { return d->albumartist_; }
const QString &Song::effective_albumartist() const { return d->albumartist_.isEmpty() ? d->artist_ : d->albumartist_; }
const QString &Song::playlist_albumartist() const { return is_compilation() ? d->albumartist_ : effective_albumartist(); }
const QString &Song::composer() const { return d->composer_; }
const QString &Song::performer() const { return d->performer_; }
const QString &Song::grouping() const { return d->grouping_; }
int Song::track() const { return d->track_; }
int Song::disc() const { return d->disc_; }
int Song::year() const { return d->year_; }
int Song::originalyear() const { return d->originalyear_; }
int Song::effective_originalyear() const {
return d->originalyear_ < 0 ? d->year_ : d->originalyear_;
}
int Song::effective_originalyear() const { return d->originalyear_ < 0 ? d->year_ : d->originalyear_; }
const QString &Song::genre() const { return d->genre_; }
bool Song::is_compilation() const { return (d->compilation_ || d->compilation_detected_ || d->compilation_on_) && ! d->compilation_off_; }
const QString &Song::composer() const { return d->composer_; }
const QString &Song::performer() const { return d->performer_; }
const QString &Song::grouping() const { return d->grouping_; }
const QString &Song::comment() const { return d->comment_; }
const QString &Song::lyrics() const { return d->lyrics_; }
bool Song::is_compilation() const {
return (d->compilation_ || d->compilation_detected_ || d->compilation_on_) && ! d->compilation_off_;
}
int Song::playcount() const { return d->playcount_; }
int Song::skipcount() const { return d->skipcount_; }
int Song::lastplayed() const { return d->lastplayed_; }
const QString &Song::cue_path() const { return d->cue_path_; }
bool Song::has_cue() const { return !d->cue_path_.isEmpty(); }
int Song::album_id() const { return d->album_id_; }
qint64 Song::beginning_nanosec() const { return d->beginning_; }
qint64 Song::end_nanosec() const { return d->end_; }
qint64 Song::length_nanosec() const { return d->end_ - d->beginning_; }
int Song::bitrate() const { return d->bitrate_; }
int Song::samplerate() const { return d->samplerate_; }
int Song::bitdepth() const { return d->bitdepth_; }
Song::Source Song::source() const { return d->source_; }
int Song::directory_id() const { return d->directory_id_; }
const QUrl &Song::url() const { return d->url_; }
const QString &Song::basefilename() const { return d->basefilename_; }
Song::FileType Song::filetype() const { return d->filetype_; }
int Song::filesize() const { return d->filesize_; }
uint Song::mtime() const { return d->mtime_; }
uint Song::ctime() const { return d->ctime_; }
int Song::filesize() const { return d->filesize_; }
Song::FileType Song::filetype() const { return d->filetype_; }
bool Song::is_stream() const { return d->source_ == Source_Stream || d->source_ == Source_Tidal; }
bool Song::is_cdda() const { return d->source_ == Source_CDDA; }
bool Song::is_collection_song() const {
return !is_cdda() && !is_stream() && id() != -1;
}
bool Song::is_metadata_good() const {
return !d->title_.isEmpty() && !d->album_.isEmpty() && !d->artist_.isEmpty() && !d->url_.isEmpty() && d->end_ > 0;
}
int Song::playcount() const { return d->playcount_; }
int Song::skipcount() const { return d->skipcount_; }
int Song::lastplayed() const { return d->lastplayed_; }
const QString &Song::art_automatic() const { return d->art_automatic_; }
const QString &Song::art_manual() const { return d->art_manual_; }
bool Song::has_manually_unset_cover() const { return d->art_manual_ == kManuallyUnsetCover; }
@ -322,12 +327,24 @@ void Song::manually_unset_cover() { d->art_manual_ = kManuallyUnsetCover; }
bool Song::has_embedded_cover() const { return d->art_automatic_ == kEmbeddedCover; }
void Song::set_embedded_cover() { d->art_automatic_ = kEmbeddedCover; }
const QImage &Song::image() const { return d->image_; }
const QString &Song::cue_path() const { return d->cue_path_; }
bool Song::has_cue() const { return !d->cue_path_.isEmpty(); }
bool Song::is_collection_song() const { return !is_cdda() && !is_stream() && id() != -1; }
bool Song::is_metadata_good() const { return !d->title_.isEmpty() && !d->album_.isEmpty() && !d->artist_.isEmpty() && !d->url_.isEmpty() && d->end_ > 0; }
bool Song::is_stream() const { return d->source_ == Source_Stream || d->source_ == Source_Tidal; }
bool Song::is_cdda() const { return d->source_ == Source_CDDA; }
const QString &Song::error() const { return d->error_; }
void Song::set_id(int id) { d->id_ = id; }
void Song::set_album_id(int v) { d->album_id_ = v; }
void Song::set_valid(bool v) { d->valid_ = v; }
void Song::set_artist_id(int v) { d->artist_id_ = v; }
void Song::set_album_id(int v) { d->album_id_ = v; }
void Song::set_song_id(int v) { d->song_id_ = v; }
void Song::set_title(const QString &v) { d->title_ = v; }
void Song::set_album(const QString &v) { d->album_ = v; }
void Song::set_artist(const QString &v) { d->artist_ = v; }
@ -674,6 +691,7 @@ void Song::ToProtobuf(pb::tagreader::SongMetadata *pb) const {
pb->set_suspicious_tags(d->suspicious_tags_);
pb->set_art_automatic(DataCommaSizeFromQString(d->art_automatic_));
pb->set_filetype(static_cast<pb::tagreader::SongMetadata_FileType>(d->filetype_));
}
#define tostr(n) (q.value(n).isNull() ? QString::null : q.value(n).toString())
@ -744,6 +762,16 @@ void Song::InitFromQuery(const SqlRow &q, bool reliable_metadata, int col) {
d->comment_ = tostr(x);
}
else if (Song::kColumns.value(i) == "artist_id") {
d->artist_id_ = toint(x);
}
else if (Song::kColumns.value(i) == "album_id") {
d->album_id_ = toint(x);
}
else if (Song::kColumns.value(i) == "song_id") {
d->song_id_ = toint(x);
}
else if (Song::kColumns.value(i) == "beginning") {
d->beginning_ = q.value(x).isNull() ? 0 : q.value(x).toLongLong();
}
@ -1093,6 +1121,10 @@ void Song::BindToQuery(QSqlQuery *query) const {
query->bindValue(":comment", strval(d->comment_));
query->bindValue(":lyrics", strval(d->lyrics_));
query->bindValue(":artist_id", intval(d->artist_id_));
query->bindValue(":album_id", intval(d->album_id_));
query->bindValue(":song_id", intval(d->song_id_));
query->bindValue(":beginning", d->beginning_);
query->bindValue(":length", intval(length_nanosec()));
@ -1221,17 +1253,20 @@ bool Song::IsMetadataEqual(const Song &other) const {
d->album_ == other.d->album_ &&
d->artist_ == other.d->artist_ &&
d->albumartist_ == other.d->albumartist_ &&
d->composer_ == other.d->composer_ &&
d->performer_ == other.d->performer_ &&
d->grouping_ == other.d->grouping_ &&
d->track_ == other.d->track_ &&
d->disc_ == other.d->disc_ &&
d->year_ == other.d->year_ &&
d->originalyear_ == other.d->originalyear_ &&
d->genre_ == other.d->genre_ &&
d->compilation_ == other.d->compilation_ &&
d->composer_ == other.d->composer_ &&
d->performer_ == other.d->performer_ &&
d->grouping_ == other.d->grouping_ &&
d->comment_ == other.d->comment_ &&
d->lyrics_ == other.d->lyrics_ &&
d->compilation_ == other.d->compilation_ &&
d->artist_id_ == other.d->artist_id_ &&
d->album_id_ == other.d->album_id_ &&
d->song_id_ == other.d->song_id_ &&
d->beginning_ == other.d->beginning_ &&
length_nanosec() == other.length_nanosec() &&
d->bitrate_ == other.d->bitrate_ &&

View File

@ -197,10 +197,9 @@ class Song {
const QString &comment() const;
const QString &lyrics() const;
int playcount() const;
int skipcount() const;
int lastplayed() const;
int artist_id() const;
int album_id() const;
int song_id() const;
qint64 beginning_nanosec() const;
qint64 end_nanosec() const;
@ -219,6 +218,10 @@ class Song {
uint mtime() const;
uint ctime() const;
int playcount() const;
int skipcount() const;
int lastplayed() const;
const QString &art_automatic() const;
const QString &art_manual() const;
@ -265,7 +268,6 @@ class Song {
bool IsEditable() const;
void set_id(int id);
void set_album_id(int v);
void set_valid(bool v);
void set_title(const QString &v);
@ -285,6 +287,10 @@ class Song {
void set_comment(const QString &v);
void set_lyrics(const QString &v);
void set_artist_id(int v);
void set_album_id(int v);
void set_song_id(int v);
void set_beginning_nanosec(qint64 v);
void set_end_nanosec(qint64 v);
void set_length_nanosec(qint64 v);