mirror of
https://github.com/clementine-player/Clementine
synced 2024-12-18 04:19:55 +01:00
Add a skipcount field to the database, and read the last played time into Song objects. (still not used in the GUI yet).
This commit is contained in:
parent
dd4afe9b06
commit
42e4c4a8db
@ -278,5 +278,6 @@
|
||||
<file>icons/22x22/rating.png</file>
|
||||
<file>icons/32x32/rating.png</file>
|
||||
<file>icons/48x48/rating.png</file>
|
||||
<file>schema/schema-18.sql</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
@ -45,7 +45,9 @@ CREATE TABLE device_%deviceid_songs (
|
||||
rating INTEGER,
|
||||
forced_compilation_on INTEGER NOT NULL DEFAULT 0,
|
||||
forced_compilation_off INTEGER NOT NULL DEFAULT 0,
|
||||
effective_compilation NOT NULL DEFAULT 0
|
||||
effective_compilation NOT NULL DEFAULT 0,
|
||||
|
||||
skipcount INTEGER NOT NULL DEFAULT 0
|
||||
);
|
||||
|
||||
CREATE INDEX idx_device_%deviceid_songs_album ON device_%deviceid_songs (album);
|
||||
|
4
data/schema/schema-18.sql
Normal file
4
data/schema/schema-18.sql
Normal file
@ -0,0 +1,4 @@
|
||||
ALTER TABLE %allsongstables ADD COLUMN skipcount INTEGER NOT NULL DEFAULT 0;
|
||||
|
||||
UPDATE schema_version SET version=18;
|
||||
|
@ -29,7 +29,8 @@
|
||||
#include <QVariant>
|
||||
|
||||
const char* Database::kDatabaseFilename = "clementine.db";
|
||||
const int Database::kSchemaVersion = 17;
|
||||
const int Database::kSchemaVersion = 18;
|
||||
const char* Database::kMagicAllSongsTables = "%allsongstables";
|
||||
|
||||
int Database::sNextConnectionId = 1;
|
||||
QMutex Database::sNextConnectionIdMutex;
|
||||
@ -447,12 +448,35 @@ void Database::ExecCommands(const QString &schema, QSqlDatabase &db) {
|
||||
// Run each command
|
||||
QStringList commands(schema.split(";\n\n"));
|
||||
foreach (const QString& command, commands) {
|
||||
QSqlQuery query(db.exec(command));
|
||||
if (CheckErrors(query.lastError()))
|
||||
qFatal("Unable to update music library database");
|
||||
// There are now lots of "songs" tables that need to have the same schema:
|
||||
// songs, magnatune_songs, and device_*_songs. We allow a magic value
|
||||
// in the schema files to update all songs tables at once.
|
||||
if (command.contains(kMagicAllSongsTables)) {
|
||||
foreach (const QString& table, SongsTables(db)) {
|
||||
qDebug() << "Updating" << table << "for" << kMagicAllSongsTables;
|
||||
QString new_command(command);
|
||||
new_command.replace(kMagicAllSongsTables, table);
|
||||
QSqlQuery query(db.exec(new_command));
|
||||
if (CheckErrors(query.lastError()))
|
||||
qFatal("Unable to update music library database");
|
||||
}
|
||||
} else {
|
||||
QSqlQuery query(db.exec(command));
|
||||
if (CheckErrors(query.lastError()))
|
||||
qFatal("Unable to update music library database");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QStringList Database::SongsTables(QSqlDatabase& db) const {
|
||||
QStringList ret;
|
||||
foreach (const QString& table, db.tables()) {
|
||||
if (table == "songs" || table.endsWith("_songs"))
|
||||
ret << table;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool Database::CheckErrors(const QSqlError& error) {
|
||||
if (error.isValid()) {
|
||||
qDebug() << error;
|
||||
|
@ -43,6 +43,7 @@ class Database : public QObject {
|
||||
|
||||
static const int kSchemaVersion;
|
||||
static const char* kDatabaseFilename;
|
||||
static const char* kMagicAllSongsTables;
|
||||
|
||||
void Stop() {}
|
||||
|
||||
@ -58,6 +59,7 @@ class Database : public QObject {
|
||||
|
||||
private:
|
||||
void UpdateDatabaseSchema(int version, QSqlDatabase& db);
|
||||
QStringList SongsTables(QSqlDatabase& db) const;
|
||||
|
||||
QString directory_;
|
||||
QMutex connect_mutex_;
|
||||
|
@ -89,7 +89,7 @@ const QStringList Song::kColumns = QStringList()
|
||||
<< "mtime" << "ctime" << "filesize" << "sampler" << "art_automatic"
|
||||
<< "art_manual" << "filetype" << "playcount" << "lastplayed" << "rating"
|
||||
<< "forced_compilation_on" << "forced_compilation_off"
|
||||
<< "effective_compilation";
|
||||
<< "effective_compilation" << "skipcount";
|
||||
|
||||
const QString Song::kColumnSpec = Song::kColumns.join(", ");
|
||||
const QString Song::kBindSpec = Prepend(":", Song::kColumns).join(", ");
|
||||
@ -151,6 +151,8 @@ Song::Private::Private()
|
||||
forced_compilation_off_(false),
|
||||
rating_(-1.0),
|
||||
playcount_(0),
|
||||
skipcount_(0),
|
||||
lastplayed_(-1),
|
||||
length_(-1),
|
||||
bitrate_(-1),
|
||||
samplerate_(-1),
|
||||
@ -459,7 +461,7 @@ void Song::InitFromQuery(const SqlRow& q, int col) {
|
||||
|
||||
d->filetype_ = FileType(q.value(col + 24).toInt());
|
||||
d->playcount_ = q.value(col + 25).isNull() ? 0 : q.value(col + 25).toInt();
|
||||
// lastplayed = 26
|
||||
d->lastplayed_ = toint(col + 26);
|
||||
d->rating_ = tofloat(col + 27);
|
||||
|
||||
d->forced_compilation_on_ = q.value(col + 28).toBool();
|
||||
@ -467,6 +469,8 @@ void Song::InitFromQuery(const SqlRow& q, int col) {
|
||||
|
||||
// effective_compilation = 30
|
||||
|
||||
d->skipcount_ = q.value(col + 31).isNull() ? 0 : q.value(col + 31).toInt();
|
||||
|
||||
#undef tostr
|
||||
#undef toint
|
||||
#undef tofloat
|
||||
@ -508,6 +512,8 @@ void Song::InitFromLastFM(const lastfm::Track& track) {
|
||||
d->filetype_ = track->type2 ? Type_Mpeg : Type_Mp4;
|
||||
d->rating_ = float(track->rating) / 100; // 100 = 20 * 5 stars
|
||||
d->playcount_ = track->playcount;
|
||||
d->skipcount_ = track->skipcount;
|
||||
d->lastplayed_ = track->time_played;
|
||||
|
||||
d->filename_ = QString::fromLocal8Bit(track->ipod_path);
|
||||
d->filename_.replace(':', '/');
|
||||
@ -538,6 +544,8 @@ void Song::InitFromLastFM(const lastfm::Track& track) {
|
||||
track->mediatype = 1; // Audio
|
||||
track->rating = d->rating_ * 100; // 100 = 20 * 5 stars
|
||||
track->playcount = d->playcount_;
|
||||
track->skipcount = d->skipcount_;
|
||||
track->time_played = d->lastplayed_;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -905,7 +913,7 @@ void Song::BindToQuery(QSqlQuery *query) const {
|
||||
|
||||
query->bindValue(":filetype", d->filetype_);
|
||||
query->bindValue(":playcount", d->playcount_);
|
||||
query->bindValue(":lastplayed", -1); // TODO
|
||||
query->bindValue(":lastplayed", intval(d->lastplayed_));
|
||||
query->bindValue(":rating", intval(d->rating_));
|
||||
|
||||
query->bindValue(":forced_compilation_on", d->forced_compilation_on_ ? 1 : 0);
|
||||
@ -913,6 +921,8 @@ void Song::BindToQuery(QSqlQuery *query) const {
|
||||
|
||||
query->bindValue(":effective_compilation", is_compilation() ? 1 : 0);
|
||||
|
||||
query->bindValue(":skipcount", d->skipcount_);
|
||||
|
||||
#undef intval
|
||||
#undef notnullintval
|
||||
}
|
||||
|
@ -159,6 +159,8 @@ class Song {
|
||||
}
|
||||
float rating() const { return d->rating_; }
|
||||
int playcount() const { return d->playcount_; }
|
||||
int skipcount() const { return d->skipcount_; }
|
||||
int lastplayed() const { return d->lastplayed_; }
|
||||
|
||||
int length() const { return d->length_; }
|
||||
int bitrate() const { return d->bitrate_; }
|
||||
@ -217,6 +219,8 @@ class Song {
|
||||
void set_forced_compilation_off(bool v) { d->forced_compilation_off_ = v; }
|
||||
void set_rating(float v) { d->rating_ = v; }
|
||||
void set_playcount(int v) { d->playcount_ = v; }
|
||||
void set_skipcount(int v) { d->skipcount_ = v; }
|
||||
void set_lastplayed(int v) { d->lastplayed_ = v; }
|
||||
|
||||
// Setters that should only be used by tests
|
||||
void set_filename(const QString& v) { d->filename_ = v; }
|
||||
@ -260,6 +264,8 @@ class Song {
|
||||
|
||||
float rating_;
|
||||
int playcount_;
|
||||
int skipcount_;
|
||||
int lastplayed_;
|
||||
|
||||
int length_;
|
||||
int bitrate_;
|
||||
|
Loading…
Reference in New Issue
Block a user