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:
David Sansome 2010-10-17 17:50:20 +00:00
parent dd4afe9b06
commit 42e4c4a8db
7 changed files with 57 additions and 8 deletions

View File

@ -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>

View File

@ -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);

View File

@ -0,0 +1,4 @@
ALTER TABLE %allsongstables ADD COLUMN skipcount INTEGER NOT NULL DEFAULT 0;
UPDATE schema_version SET version=18;

View File

@ -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;

View File

@ -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_;

View File

@ -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
}

View File

@ -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_;