mirror of
https://github.com/owntone/owntone-server.git
synced 2024-12-28 08:05:56 -05:00
Support for skip_count and time_skipped file metadata
This commit is contained in:
parent
5ee0b69d39
commit
fde0a28142
@ -820,7 +820,8 @@ curl -X GET "http://localhost:3689/api/library/playlists/1/tracks"
|
|||||||
"disc_number": 1,
|
"disc_number": 1,
|
||||||
"length_ms": 223085,
|
"length_ms": 223085,
|
||||||
"play_count": 2,
|
"play_count": 2,
|
||||||
"last_time_played": "2018-02-23T10:31:20Z",
|
"skip_count": 1,
|
||||||
|
"time_played": "2018-02-23T10:31:20Z",
|
||||||
"media_kind": "music",
|
"media_kind": "music",
|
||||||
"data_kind": "file",
|
"data_kind": "file",
|
||||||
"path": "/music/srv/Heinrich/Solange wir tanzen/01 Solange wir tanzen.mp3",
|
"path": "/music/srv/Heinrich/Solange wir tanzen/01 Solange wir tanzen.mp3",
|
||||||
|
@ -36,12 +36,14 @@ Where valid field-names (with their types) are:
|
|||||||
* `data_kind` (enumeration)
|
* `data_kind` (enumeration)
|
||||||
* `media_kind` (enumeration)
|
* `media_kind` (enumeration)
|
||||||
* `play_count` (integer)
|
* `play_count` (integer)
|
||||||
|
* `skip_count` (integer)
|
||||||
* `rating` (integer)
|
* `rating` (integer)
|
||||||
* `year` (integer)
|
* `year` (integer)
|
||||||
* `compilation` (integer)
|
* `compilation` (integer)
|
||||||
* `time_added` (date)
|
* `time_added` (date)
|
||||||
* `time_modified` (date)
|
* `time_modified` (date)
|
||||||
* `time_played` (date)
|
* `time_played` (date)
|
||||||
|
* `time_skipped` (date)
|
||||||
|
|
||||||
Valid operators include:
|
Valid operators include:
|
||||||
* `is`, `includes`, `starts with` (string)
|
* `is`, `includes`, `starts with` (string)
|
||||||
|
@ -85,6 +85,7 @@ STRTAG : 'artist'
|
|||||||
;
|
;
|
||||||
|
|
||||||
INTTAG : 'play_count'
|
INTTAG : 'play_count'
|
||||||
|
| 'skip_count'
|
||||||
| 'rating'
|
| 'rating'
|
||||||
| 'year'
|
| 'year'
|
||||||
| 'compilation'
|
| 'compilation'
|
||||||
@ -93,6 +94,7 @@ INTTAG : 'play_count'
|
|||||||
DATETAG : 'time_added'
|
DATETAG : 'time_added'
|
||||||
| 'time_modified'
|
| 'time_modified'
|
||||||
| 'time_played'
|
| 'time_played'
|
||||||
|
| 'time_skipped'
|
||||||
;
|
;
|
||||||
|
|
||||||
ENUMTAG : 'data_kind'
|
ENUMTAG : 'data_kind'
|
||||||
|
@ -27,6 +27,7 @@ struct dmap_query_field_map;
|
|||||||
"daap.songdataurl", "f.url", 0
|
"daap.songdataurl", "f.url", 0
|
||||||
"daap.songdateadded", "f.time_added", 1
|
"daap.songdateadded", "f.time_added", 1
|
||||||
"daap.songdatemodified", "f.time_modified", 1
|
"daap.songdatemodified", "f.time_modified", 1
|
||||||
|
"daap.songlastskipdate", "f.time_skipped", 1
|
||||||
"daap.songdatereleased", "f.date_released", 1
|
"daap.songdatereleased", "f.date_released", 1
|
||||||
"daap.songdescription", "f.description", 0
|
"daap.songdescription", "f.description", 0
|
||||||
"daap.songdisccount", "f.total_discs", 1
|
"daap.songdisccount", "f.total_discs", 1
|
||||||
@ -40,6 +41,7 @@ struct dmap_query_field_map;
|
|||||||
"daap.songtrackcount", "f.total_tracks", 1
|
"daap.songtrackcount", "f.total_tracks", 1
|
||||||
"daap.songtracknumber", "f.track", 1
|
"daap.songtracknumber", "f.track", 1
|
||||||
"daap.songuserplaycount", "f.play_count", 1
|
"daap.songuserplaycount", "f.play_count", 1
|
||||||
|
"daap.songuserskipcount", "f.skip_count", 1
|
||||||
"daap.songyear", "f.year", 1
|
"daap.songyear", "f.year", 1
|
||||||
"com.apple.itunes.mediakind", "f.media_kind", 1
|
"com.apple.itunes.mediakind", "f.media_kind", 1
|
||||||
"com.apple.itunes.extended-media-kind", "f.media_kind", 1
|
"com.apple.itunes.extended-media-kind", "f.media_kind", 1
|
||||||
|
123
src/db.c
123
src/db.c
@ -158,6 +158,8 @@ static const struct col_type_map mfi_cols_map[] =
|
|||||||
{ mfi_offsetof(virtual_path), DB_TYPE_STRING },
|
{ mfi_offsetof(virtual_path), DB_TYPE_STRING },
|
||||||
{ mfi_offsetof(directory_id), DB_TYPE_INT },
|
{ mfi_offsetof(directory_id), DB_TYPE_INT },
|
||||||
{ mfi_offsetof(date_released), DB_TYPE_INT },
|
{ mfi_offsetof(date_released), DB_TYPE_INT },
|
||||||
|
{ mfi_offsetof(skip_count), DB_TYPE_INT },
|
||||||
|
{ mfi_offsetof(time_skipped), DB_TYPE_INT },
|
||||||
};
|
};
|
||||||
|
|
||||||
/* This list must be kept in sync with
|
/* This list must be kept in sync with
|
||||||
@ -250,6 +252,8 @@ static const ssize_t dbmfi_cols_map[] =
|
|||||||
dbmfi_offsetof(virtual_path),
|
dbmfi_offsetof(virtual_path),
|
||||||
dbmfi_offsetof(directory_id),
|
dbmfi_offsetof(directory_id),
|
||||||
dbmfi_offsetof(date_released),
|
dbmfi_offsetof(date_released),
|
||||||
|
dbmfi_offsetof(skip_count),
|
||||||
|
dbmfi_offsetof(time_skipped),
|
||||||
};
|
};
|
||||||
|
|
||||||
/* This list must be kept in sync with
|
/* This list must be kept in sync with
|
||||||
@ -2344,6 +2348,24 @@ db_file_inc_playcount(int id)
|
|||||||
#undef Q_TMPL
|
#undef Q_TMPL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
db_file_inc_skipcount(int id)
|
||||||
|
{
|
||||||
|
#define Q_TMPL "UPDATE files SET skip_count = skip_count + 1, time_skipped = %" PRIi64 " WHERE id = %d;"
|
||||||
|
char *query;
|
||||||
|
|
||||||
|
query = sqlite3_mprintf(Q_TMPL, (int64_t)time(NULL), id);
|
||||||
|
if (!query)
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_DB, "Out of memory for query string\n");
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
db_query_run(query, 1, 0);
|
||||||
|
#undef Q_TMPL
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
db_file_ping(int id)
|
db_file_ping(int id)
|
||||||
{
|
{
|
||||||
@ -2751,23 +2773,35 @@ db_file_fetch_byvirtualpath(const char *virtual_path)
|
|||||||
int
|
int
|
||||||
db_file_add(struct media_file_info *mfi)
|
db_file_add(struct media_file_info *mfi)
|
||||||
{
|
{
|
||||||
#define Q_TMPL "INSERT INTO files (id, path, fname, title, artist, album, genre, comment, type, composer," \
|
#define Q_TMPL "INSERT INTO files (" \
|
||||||
" orchestra, conductor, grouping, url, bitrate, samplerate, song_length, file_size, year, track," \
|
" id, path, fname, title, artist, album, genre, comment, type," \
|
||||||
" total_tracks, disc, total_discs, bpm, compilation, artwork, rating, play_count, seek, data_kind, item_kind," \
|
" composer, orchestra, conductor, grouping, url, bitrate," \
|
||||||
" description, time_added, time_modified, time_played, db_timestamp, disabled, sample_count," \
|
" samplerate, song_length, file_size, year, track," \
|
||||||
" codectype, idx, has_video, contentrating, bits_per_sample, album_artist," \
|
" total_tracks, disc, total_discs, bpm, compilation, artwork," \
|
||||||
" media_kind, tv_series_name, tv_episode_num_str, tv_network_name, tv_episode_sort, tv_season_num, " \
|
" rating, play_count, seek, data_kind, item_kind, description," \
|
||||||
" songartistid, songalbumid, " \
|
" time_added, time_modified, time_played, db_timestamp," \
|
||||||
" title_sort, artist_sort, album_sort, composer_sort, album_artist_sort, virtual_path," \
|
" disabled, sample_count, codectype, idx, has_video," \
|
||||||
" directory_id, date_released) " \
|
" contentrating, bits_per_sample, album_artist, media_kind," \
|
||||||
" VALUES (NULL, '%q', '%q', TRIM(%Q), TRIM(%Q), TRIM(%Q), TRIM(%Q), TRIM(%Q), %Q, TRIM(%Q)," \
|
" tv_series_name, tv_episode_num_str, tv_network_name," \
|
||||||
" TRIM(%Q), TRIM(%Q), TRIM(%Q), %Q, %d, %d, %d, %" PRIi64 ", %d, %d," \
|
" tv_episode_sort, tv_season_num, songartistid, songalbumid," \
|
||||||
" %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d," \
|
" title_sort, artist_sort, album_sort, composer_sort," \
|
||||||
" %Q, %" PRIi64 ", %" PRIi64 ", %" PRIi64 ", %" PRIi64 ", %d, %" PRIi64 "," \
|
" album_artist_sort, virtual_path, directory_id, date_released,"\
|
||||||
" %Q, %d, %d, %d, %d, TRIM(%Q)," \
|
" skip_count, time_skipped" \
|
||||||
" %d, TRIM(%Q), TRIM(%Q), TRIM(%Q), %d, %d," \
|
") VALUES (" \
|
||||||
" daap_songalbumid(LOWER(TRIM(%Q)), ''), daap_songalbumid(LOWER(TRIM(%Q)), LOWER(TRIM(%Q))), " \
|
" NULL, '%q', '%q', TRIM(%Q), TRIM(%Q), TRIM(%Q), TRIM(%Q), TRIM(%Q), %Q," \
|
||||||
" TRIM(%Q), TRIM(%Q), TRIM(%Q), TRIM(%Q), TRIM(%Q), TRIM(%Q), %d, %d);"
|
" TRIM(%Q), TRIM(%Q), TRIM(%Q), TRIM(%Q), %Q, %d," \
|
||||||
|
" %d, %d, %" PRIi64 ", %d, %d," \
|
||||||
|
" %d, %d, %d, %d, %d, %d," \
|
||||||
|
" %d, %d, %d, %d, %d, %Q," \
|
||||||
|
" %" PRIi64 ", %" PRIi64 ", %" PRIi64 ", %" PRIi64 "," \
|
||||||
|
" %d, %" PRIi64 ", %Q, %d, %d," \
|
||||||
|
" %d, %d, TRIM(%Q), %d," \
|
||||||
|
" TRIM(%Q), TRIM(%Q), TRIM(%Q)," \
|
||||||
|
" %d, %d, daap_songalbumid(LOWER(TRIM(%Q)), ''), daap_songalbumid(LOWER(TRIM(%Q)), LOWER(TRIM(%Q)))," \
|
||||||
|
" TRIM(%Q), TRIM(%Q), TRIM(%Q), TRIM(%Q)," \
|
||||||
|
" TRIM(%Q), TRIM(%Q), %d, %d," \
|
||||||
|
" %d, %" PRIi64 "" \
|
||||||
|
");"
|
||||||
|
|
||||||
char *query;
|
char *query;
|
||||||
char *errmsg;
|
char *errmsg;
|
||||||
@ -2789,20 +2823,19 @@ db_file_add(struct media_file_info *mfi)
|
|||||||
mfi->time_modified = mfi->db_timestamp;
|
mfi->time_modified = mfi->db_timestamp;
|
||||||
|
|
||||||
query = sqlite3_mprintf(Q_TMPL,
|
query = sqlite3_mprintf(Q_TMPL,
|
||||||
STR(mfi->path), STR(mfi->fname), mfi->title, mfi->artist, mfi->album,
|
STR(mfi->path), STR(mfi->fname), mfi->title, mfi->artist, mfi->album, mfi->genre, mfi->comment, mfi->type,
|
||||||
mfi->genre, mfi->comment, mfi->type, mfi->composer,
|
mfi->composer, mfi->orchestra, mfi->conductor, mfi->grouping, mfi->url, mfi->bitrate,
|
||||||
mfi->orchestra, mfi->conductor, mfi->grouping, mfi->url, mfi->bitrate,
|
mfi->samplerate, mfi->song_length, mfi->file_size, mfi->year, mfi->track,
|
||||||
mfi->samplerate, mfi->song_length, mfi->file_size, mfi->year, mfi->track,
|
mfi->total_tracks, mfi->disc, mfi->total_discs, mfi->bpm, mfi->compilation, mfi->artwork,
|
||||||
mfi->total_tracks, mfi->disc, mfi->total_discs, mfi->bpm, mfi->compilation, mfi->artwork,
|
mfi->rating, mfi->play_count, mfi->seek, mfi->data_kind, mfi->item_kind, mfi->description,
|
||||||
mfi->rating, mfi->play_count, mfi->seek, mfi->data_kind, mfi->item_kind,
|
(int64_t)mfi->time_added, (int64_t)mfi->time_modified, (int64_t)mfi->time_played, (int64_t)mfi->db_timestamp,
|
||||||
mfi->description, (int64_t)mfi->time_added, (int64_t)mfi->time_modified,
|
mfi->disabled, mfi->sample_count, mfi->codectype, mfi->index, mfi->has_video,
|
||||||
(int64_t)mfi->time_played, (int64_t)mfi->db_timestamp, mfi->disabled, mfi->sample_count,
|
mfi->contentrating, mfi->bits_per_sample, mfi->album_artist, mfi->media_kind,
|
||||||
mfi->codectype, mfi->index, mfi->has_video,
|
mfi->tv_series_name, mfi->tv_episode_num_str, mfi->tv_network_name,
|
||||||
mfi->contentrating, mfi->bits_per_sample, mfi->album_artist,
|
mfi->tv_episode_sort, mfi->tv_season_num, mfi->album_artist, mfi->album_artist, mfi->album,
|
||||||
mfi->media_kind, mfi->tv_series_name, mfi->tv_episode_num_str,
|
mfi->title_sort, mfi->artist_sort, mfi->album_sort, mfi->composer_sort,
|
||||||
mfi->tv_network_name, mfi->tv_episode_sort, mfi->tv_season_num,
|
mfi->album_artist_sort, mfi->virtual_path, mfi->directory_id, mfi->date_released,
|
||||||
mfi->album_artist, mfi->album_artist, mfi->album, mfi->title_sort, mfi->artist_sort, mfi->album_sort,
|
mfi->skip_count, mfi->time_skipped);
|
||||||
mfi->composer_sort, mfi->album_artist_sort, mfi->virtual_path, mfi->directory_id, mfi->date_released);
|
|
||||||
|
|
||||||
if (!query)
|
if (!query)
|
||||||
{
|
{
|
||||||
@ -2835,19 +2868,19 @@ int
|
|||||||
db_file_update(struct media_file_info *mfi)
|
db_file_update(struct media_file_info *mfi)
|
||||||
{
|
{
|
||||||
#define Q_TMPL "UPDATE files SET path = '%q', fname = '%q', title = TRIM(%Q), artist = TRIM(%Q), album = TRIM(%Q), genre = TRIM(%Q)," \
|
#define Q_TMPL "UPDATE files SET path = '%q', fname = '%q', title = TRIM(%Q), artist = TRIM(%Q), album = TRIM(%Q), genre = TRIM(%Q)," \
|
||||||
" comment = TRIM(%Q), type = %Q, composer = TRIM(%Q), orchestra = TRIM(%Q), conductor = TRIM(%Q), grouping = TRIM(%Q)," \
|
" comment = TRIM(%Q), type = %Q, composer = TRIM(%Q), orchestra = TRIM(%Q), conductor = TRIM(%Q), grouping = TRIM(%Q)," \
|
||||||
" url = %Q, bitrate = %d, samplerate = %d, song_length = %d, file_size = %" PRIi64 "," \
|
" url = %Q, bitrate = %d, samplerate = %d, song_length = %d, file_size = %" PRIi64 "," \
|
||||||
" year = %d, track = %d, total_tracks = %d, disc = %d, total_discs = %d, bpm = %d," \
|
" year = %d, track = %d, total_tracks = %d, disc = %d, total_discs = %d, bpm = %d," \
|
||||||
" compilation = %d, artwork = %d, rating = %d, seek = %d, data_kind = %d, item_kind = %d," \
|
" compilation = %d, artwork = %d, rating = %d, seek = %d, data_kind = %d, item_kind = %d," \
|
||||||
" description = %Q, time_modified = %" PRIi64 "," \
|
" description = %Q, time_modified = %" PRIi64 "," \
|
||||||
" db_timestamp = %" PRIi64 ", disabled = %" PRIi64 ", sample_count = %" PRIi64 "," \
|
" db_timestamp = %" PRIi64 ", disabled = %" PRIi64 ", sample_count = %" PRIi64 "," \
|
||||||
" codectype = %Q, idx = %d, has_video = %d," \
|
" codectype = %Q, idx = %d, has_video = %d," \
|
||||||
" bits_per_sample = %d, album_artist = TRIM(%Q)," \
|
" bits_per_sample = %d, album_artist = TRIM(%Q)," \
|
||||||
" media_kind = %d, tv_series_name = TRIM(%Q), tv_episode_num_str = TRIM(%Q)," \
|
" media_kind = %d, tv_series_name = TRIM(%Q), tv_episode_num_str = TRIM(%Q)," \
|
||||||
" tv_network_name = TRIM(%Q), tv_episode_sort = %d, tv_season_num = %d," \
|
" tv_network_name = TRIM(%Q), tv_episode_sort = %d, tv_season_num = %d," \
|
||||||
" songartistid = daap_songalbumid(LOWER(TRIM(%Q)), ''), songalbumid = daap_songalbumid(LOWER(TRIM(%Q)), LOWER(TRIM(%Q)))," \
|
" songartistid = daap_songalbumid(LOWER(TRIM(%Q)), ''), songalbumid = daap_songalbumid(LOWER(TRIM(%Q)), LOWER(TRIM(%Q)))," \
|
||||||
" title_sort = TRIM(%Q), artist_sort = TRIM(%Q), album_sort = TRIM(%Q), composer_sort = TRIM(%Q), album_artist_sort = TRIM(%Q)," \
|
" title_sort = TRIM(%Q), artist_sort = TRIM(%Q), album_sort = TRIM(%Q), composer_sort = TRIM(%Q), album_artist_sort = TRIM(%Q)," \
|
||||||
" virtual_path = TRIM(%Q), directory_id = %d, date_released = %d" \
|
" virtual_path = TRIM(%Q), directory_id = %d, date_released = %d, skip_count = %d, time_skipped = %" PRIi64 "" \
|
||||||
" WHERE id = %d;"
|
" WHERE id = %d;"
|
||||||
|
|
||||||
char *query;
|
char *query;
|
||||||
@ -2880,7 +2913,7 @@ db_file_update(struct media_file_info *mfi)
|
|||||||
mfi->album_artist, mfi->album_artist, mfi->album,
|
mfi->album_artist, mfi->album_artist, mfi->album,
|
||||||
mfi->title_sort, mfi->artist_sort, mfi->album_sort,
|
mfi->title_sort, mfi->artist_sort, mfi->album_sort,
|
||||||
mfi->composer_sort, mfi->album_artist_sort,
|
mfi->composer_sort, mfi->album_artist_sort,
|
||||||
mfi->virtual_path, mfi->directory_id, mfi->date_released,
|
mfi->virtual_path, mfi->directory_id, mfi->date_released, mfi->skip_count, mfi->time_skipped,
|
||||||
mfi->id);
|
mfi->id);
|
||||||
|
|
||||||
if (!query)
|
if (!query)
|
||||||
|
8
src/db.h
8
src/db.h
@ -219,6 +219,9 @@ struct media_file_info {
|
|||||||
|
|
||||||
uint32_t directory_id; /* Id of directory */
|
uint32_t directory_id; /* Id of directory */
|
||||||
uint32_t date_released;
|
uint32_t date_released;
|
||||||
|
|
||||||
|
uint32_t skip_count;
|
||||||
|
uint32_t time_skipped;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define mfi_offsetof(field) offsetof(struct media_file_info, field)
|
#define mfi_offsetof(field) offsetof(struct media_file_info, field)
|
||||||
@ -363,6 +366,8 @@ struct db_media_file_info {
|
|||||||
char *virtual_path;
|
char *virtual_path;
|
||||||
char *directory_id;
|
char *directory_id;
|
||||||
char *date_released;
|
char *date_released;
|
||||||
|
char *skip_count;
|
||||||
|
char *time_skipped;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define dbmfi_offsetof(field) offsetof(struct db_media_file_info, field)
|
#define dbmfi_offsetof(field) offsetof(struct db_media_file_info, field)
|
||||||
@ -557,6 +562,9 @@ db_files_get_count(void);
|
|||||||
void
|
void
|
||||||
db_file_inc_playcount(int id);
|
db_file_inc_playcount(int id);
|
||||||
|
|
||||||
|
void
|
||||||
|
db_file_inc_skipcount(int id);
|
||||||
|
|
||||||
void
|
void
|
||||||
db_file_ping(int id);
|
db_file_ping(int id);
|
||||||
|
|
||||||
|
@ -93,7 +93,9 @@
|
|||||||
" album_artist_sort VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
" album_artist_sort VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
||||||
" virtual_path VARCHAR(4096) DEFAULT NULL," \
|
" virtual_path VARCHAR(4096) DEFAULT NULL," \
|
||||||
" directory_id INTEGER DEFAULT 0," \
|
" directory_id INTEGER DEFAULT 0," \
|
||||||
" date_released INTEGER DEFAULT 0" \
|
" date_released INTEGER DEFAULT 0," \
|
||||||
|
" skip_count INTEGER DEFAULT 0," \
|
||||||
|
" time_skipped INTEGER DEFAULT 0" \
|
||||||
");"
|
");"
|
||||||
|
|
||||||
#define T_PL \
|
#define T_PL \
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
* is a major upgrade. In other words minor version upgrades permit downgrading
|
* is a major upgrade. In other words minor version upgrades permit downgrading
|
||||||
* forked-daapd after the database was upgraded. */
|
* forked-daapd after the database was upgraded. */
|
||||||
#define SCHEMA_VERSION_MAJOR 19
|
#define SCHEMA_VERSION_MAJOR 19
|
||||||
#define SCHEMA_VERSION_MINOR 8
|
#define SCHEMA_VERSION_MINOR 9
|
||||||
|
|
||||||
int
|
int
|
||||||
db_init_indices(sqlite3 *hdl);
|
db_init_indices(sqlite3 *hdl);
|
||||||
|
@ -1651,6 +1651,23 @@ static const struct db_upgrade_query db_upgrade_v1908_queries[] =
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define U_V1909_ALTER_FILES_ADD_SKIP_COUNT \
|
||||||
|
"ALTER TABLE files ADD COLUMN skip_count INTEGER DEFAULT 0;"
|
||||||
|
#define U_V1909_ALTER_FILES_ADD_TIME_SKIPPED \
|
||||||
|
"ALTER TABLE files ADD COLUMN time_skipped INTEGER DEFAULT 0;"
|
||||||
|
|
||||||
|
#define U_V1909_SCVER_MINOR \
|
||||||
|
"UPDATE admin SET value = '09' WHERE key = 'schema_version_minor';"
|
||||||
|
|
||||||
|
static const struct db_upgrade_query db_upgrade_v1909_queries[] =
|
||||||
|
{
|
||||||
|
{ U_V1909_ALTER_FILES_ADD_SKIP_COUNT, "alter table files add column skip_count" },
|
||||||
|
{ U_V1909_ALTER_FILES_ADD_TIME_SKIPPED, "alter table files add column time_skipped" },
|
||||||
|
|
||||||
|
{ U_V1909_SCVER_MINOR, "set schema_version_minor to 09" },
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
db_upgrade(sqlite3 *hdl, int db_ver)
|
db_upgrade(sqlite3 *hdl, int db_ver)
|
||||||
{
|
{
|
||||||
@ -1663,7 +1680,7 @@ db_upgrade(sqlite3 *hdl, int db_ver)
|
|||||||
switch (db_ver)
|
switch (db_ver)
|
||||||
{
|
{
|
||||||
case 1000:
|
case 1000:
|
||||||
ret = db_generic_upgrade(hdl, db_upgrade_v11_queries, sizeof(db_upgrade_v11_queries) / sizeof(db_upgrade_v11_queries[0]));
|
ret = db_generic_upgrade(hdl, db_upgrade_v11_queries, ARRAY_SIZE(db_upgrade_v11_queries));
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -1678,14 +1695,14 @@ db_upgrade(sqlite3 *hdl, int db_ver)
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ret = db_generic_upgrade(hdl, db_upgrade_v12_queries, sizeof(db_upgrade_v12_queries) / sizeof(db_upgrade_v12_queries[0]));
|
ret = db_generic_upgrade(hdl, db_upgrade_v12_queries, ARRAY_SIZE(db_upgrade_v12_queries));
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
|
|
||||||
case 1200:
|
case 1200:
|
||||||
ret = db_generic_upgrade(hdl, db_upgrade_v13_queries, sizeof(db_upgrade_v13_queries) / sizeof(db_upgrade_v13_queries[0]));
|
ret = db_generic_upgrade(hdl, db_upgrade_v13_queries, ARRAY_SIZE(db_upgrade_v13_queries));
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -1696,7 +1713,7 @@ db_upgrade(sqlite3 *hdl, int db_ver)
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ret = db_generic_upgrade(hdl, db_upgrade_v14_queries, sizeof(db_upgrade_v14_queries) / sizeof(db_upgrade_v14_queries[0]));
|
ret = db_generic_upgrade(hdl, db_upgrade_v14_queries, ARRAY_SIZE(db_upgrade_v14_queries));
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -1707,21 +1724,21 @@ db_upgrade(sqlite3 *hdl, int db_ver)
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ret = db_generic_upgrade(hdl, db_upgrade_v15_queries, sizeof(db_upgrade_v15_queries) / sizeof(db_upgrade_v15_queries[0]));
|
ret = db_generic_upgrade(hdl, db_upgrade_v15_queries, ARRAY_SIZE(db_upgrade_v15_queries));
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
|
|
||||||
case 1500:
|
case 1500:
|
||||||
ret = db_generic_upgrade(hdl, db_upgrade_v1501_queries, sizeof(db_upgrade_v1501_queries) / sizeof(db_upgrade_v1501_queries[0]));
|
ret = db_generic_upgrade(hdl, db_upgrade_v1501_queries, ARRAY_SIZE(db_upgrade_v1501_queries));
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
|
|
||||||
case 1501:
|
case 1501:
|
||||||
ret = db_generic_upgrade(hdl, db_upgrade_v16_queries, sizeof(db_upgrade_v16_queries) / sizeof(db_upgrade_v16_queries[0]));
|
ret = db_generic_upgrade(hdl, db_upgrade_v16_queries, ARRAY_SIZE(db_upgrade_v16_queries));
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -1732,28 +1749,28 @@ db_upgrade(sqlite3 *hdl, int db_ver)
|
|||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
|
|
||||||
case 1600:
|
case 1600:
|
||||||
ret = db_generic_upgrade(hdl, db_upgrade_v17_queries, sizeof(db_upgrade_v17_queries) / sizeof(db_upgrade_v17_queries[0]));
|
ret = db_generic_upgrade(hdl, db_upgrade_v17_queries, ARRAY_SIZE(db_upgrade_v17_queries));
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
|
|
||||||
case 1700:
|
case 1700:
|
||||||
ret = db_generic_upgrade(hdl, db_upgrade_v18_queries, sizeof(db_upgrade_v18_queries) / sizeof(db_upgrade_v18_queries[0]));
|
ret = db_generic_upgrade(hdl, db_upgrade_v18_queries, ARRAY_SIZE(db_upgrade_v18_queries));
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
|
|
||||||
case 1800:
|
case 1800:
|
||||||
ret = db_generic_upgrade(hdl, db_upgrade_v1801_queries, sizeof(db_upgrade_v1801_queries) / sizeof(db_upgrade_v1801_queries[0]));
|
ret = db_generic_upgrade(hdl, db_upgrade_v1801_queries, ARRAY_SIZE(db_upgrade_v1801_queries));
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
|
|
||||||
case 1801:
|
case 1801:
|
||||||
ret = db_generic_upgrade(hdl, db_upgrade_v1900_queries, sizeof(db_upgrade_v1900_queries) / sizeof(db_upgrade_v1900_queries[0]));
|
ret = db_generic_upgrade(hdl, db_upgrade_v1900_queries, ARRAY_SIZE(db_upgrade_v1900_queries));
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -1764,49 +1781,49 @@ db_upgrade(sqlite3 *hdl, int db_ver)
|
|||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
|
|
||||||
case 1900:
|
case 1900:
|
||||||
ret = db_generic_upgrade(hdl, db_upgrade_v1901_queries, sizeof(db_upgrade_v1901_queries) / sizeof(db_upgrade_v1901_queries[0]));
|
ret = db_generic_upgrade(hdl, db_upgrade_v1901_queries, ARRAY_SIZE(db_upgrade_v1901_queries));
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
|
|
||||||
case 1901:
|
case 1901:
|
||||||
ret = db_generic_upgrade(hdl, db_upgrade_v1902_queries, sizeof(db_upgrade_v1902_queries) / sizeof(db_upgrade_v1902_queries[0]));
|
ret = db_generic_upgrade(hdl, db_upgrade_v1902_queries, ARRAY_SIZE(db_upgrade_v1902_queries));
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
|
|
||||||
case 1902:
|
case 1902:
|
||||||
ret = db_generic_upgrade(hdl, db_upgrade_v1903_queries, sizeof(db_upgrade_v1903_queries) / sizeof(db_upgrade_v1903_queries[0]));
|
ret = db_generic_upgrade(hdl, db_upgrade_v1903_queries, ARRAY_SIZE(db_upgrade_v1903_queries));
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
|
|
||||||
case 1903:
|
case 1903:
|
||||||
ret = db_generic_upgrade(hdl, db_upgrade_v1904_queries, sizeof(db_upgrade_v1904_queries) / sizeof(db_upgrade_v1904_queries[0]));
|
ret = db_generic_upgrade(hdl, db_upgrade_v1904_queries, ARRAY_SIZE(db_upgrade_v1904_queries));
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
|
|
||||||
case 1904:
|
case 1904:
|
||||||
ret = db_generic_upgrade(hdl, db_upgrade_v1905_queries, sizeof(db_upgrade_v1905_queries) / sizeof(db_upgrade_v1905_queries[0]));
|
ret = db_generic_upgrade(hdl, db_upgrade_v1905_queries, ARRAY_SIZE(db_upgrade_v1905_queries));
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
|
|
||||||
case 1905:
|
case 1905:
|
||||||
ret = db_generic_upgrade(hdl, db_upgrade_V1906_queries, sizeof(db_upgrade_V1906_queries) / sizeof(db_upgrade_V1906_queries[0]));
|
ret = db_generic_upgrade(hdl, db_upgrade_V1906_queries, ARRAY_SIZE(db_upgrade_V1906_queries));
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
|
|
||||||
case 1906:
|
case 1906:
|
||||||
ret = db_generic_upgrade(hdl, db_upgrade_V1907_queries, sizeof(db_upgrade_V1907_queries) / sizeof(db_upgrade_V1907_queries[0]));
|
ret = db_generic_upgrade(hdl, db_upgrade_V1907_queries, ARRAY_SIZE(db_upgrade_V1907_queries));
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -1817,6 +1834,13 @@ db_upgrade(sqlite3 *hdl, int db_ver)
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
|
||||||
|
case 1908:
|
||||||
|
ret = db_generic_upgrade(hdl, db_upgrade_v1909_queries, ARRAY_SIZE(db_upgrade_v1909_queries));
|
||||||
|
if (ret < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -85,7 +85,10 @@ static const struct dmap_field_map dfm_dmap_aseq = { -1,
|
|||||||
static const struct dmap_field_map dfm_dmap_asfm = { dbmfi_offsetof(type), -1, -1 };
|
static const struct dmap_field_map dfm_dmap_asfm = { dbmfi_offsetof(type), -1, -1 };
|
||||||
static const struct dmap_field_map dfm_dmap_asgn = { dbmfi_offsetof(genre), -1, -1 };
|
static const struct dmap_field_map dfm_dmap_asgn = { dbmfi_offsetof(genre), -1, -1 };
|
||||||
static const struct dmap_field_map dfm_dmap_ashp = { dbmfi_offsetof(play_count), -1, -1 };
|
static const struct dmap_field_map dfm_dmap_ashp = { dbmfi_offsetof(play_count), -1, -1 };
|
||||||
|
static const struct dmap_field_map dfm_dmap_askd = { dbmfi_offsetof(time_skipped), -1, -1 };
|
||||||
|
static const struct dmap_field_map dfm_dmap_askp = { dbmfi_offsetof(skip_count), -1, -1 };
|
||||||
static const struct dmap_field_map dfm_dmap_aspc = { dbmfi_offsetof(play_count), -1, -1 };
|
static const struct dmap_field_map dfm_dmap_aspc = { dbmfi_offsetof(play_count), -1, -1 };
|
||||||
|
static const struct dmap_field_map dfm_dmap_aspl = { dbmfi_offsetof(time_played), -1, -1 };
|
||||||
static const struct dmap_field_map dfm_dmap_assp = { -1, -1, -1 };
|
static const struct dmap_field_map dfm_dmap_assp = { -1, -1, -1 };
|
||||||
static const struct dmap_field_map dfm_dmap_assr = { dbmfi_offsetof(samplerate), -1, -1 };
|
static const struct dmap_field_map dfm_dmap_assr = { dbmfi_offsetof(samplerate), -1, -1 };
|
||||||
static const struct dmap_field_map dfm_dmap_asst = { -1, -1, -1 };
|
static const struct dmap_field_map dfm_dmap_asst = { -1, -1, -1 };
|
||||||
@ -207,9 +210,12 @@ struct dmap_field;
|
|||||||
"daap.songformat", "asfm", &dfm_dmap_asfm, DMAP_TYPE_STRING
|
"daap.songformat", "asfm", &dfm_dmap_asfm, DMAP_TYPE_STRING
|
||||||
"daap.songgenre", "asgn", &dfm_dmap_asgn, DMAP_TYPE_STRING
|
"daap.songgenre", "asgn", &dfm_dmap_asgn, DMAP_TYPE_STRING
|
||||||
"daap.songhasbeenplayed", "ashp", &dfm_dmap_ashp, DMAP_TYPE_UBYTE
|
"daap.songhasbeenplayed", "ashp", &dfm_dmap_ashp, DMAP_TYPE_UBYTE
|
||||||
|
"daap.songlastskipdate", "askd", &dfm_dmap_askd, DMAP_TYPE_DATE
|
||||||
|
"daap.songuserskipcount", "askp", &dfm_dmap_askp, DMAP_TYPE_UINT
|
||||||
"daap.songkeywords", "asky", &dfm_dmap_asky, DMAP_TYPE_STRING
|
"daap.songkeywords", "asky", &dfm_dmap_asky, DMAP_TYPE_STRING
|
||||||
"daap.songlongcontentdescription", "aslc", &dfm_dmap_aslc, DMAP_TYPE_STRING
|
"daap.songlongcontentdescription", "aslc", &dfm_dmap_aslc, DMAP_TYPE_STRING
|
||||||
"daap.songuserplaycount", "aspc", &dfm_dmap_aspc, DMAP_TYPE_UINT
|
"daap.songuserplaycount", "aspc", &dfm_dmap_aspc, DMAP_TYPE_UINT
|
||||||
|
"daap.songdateplayed", "aspl", &dfm_dmap_aspl, DMAP_TYPE_DATE
|
||||||
"daap.songrelativevolume", "asrv", &dfm_dmap_asrv, DMAP_TYPE_BYTE
|
"daap.songrelativevolume", "asrv", &dfm_dmap_asrv, DMAP_TYPE_BYTE
|
||||||
"daap.sortartist", "assa", &dfm_dmap_assa, DMAP_TYPE_STRING
|
"daap.sortartist", "assa", &dfm_dmap_assa, DMAP_TYPE_STRING
|
||||||
"daap.sortcomposer", "assc", &dfm_dmap_assc, DMAP_TYPE_STRING
|
"daap.sortcomposer", "assc", &dfm_dmap_assc, DMAP_TYPE_STRING
|
||||||
|
@ -186,7 +186,9 @@ track_to_json(struct db_media_file_info *dbmfi)
|
|||||||
safe_json_add_int_from_string(item, "length_ms", dbmfi->song_length);
|
safe_json_add_int_from_string(item, "length_ms", dbmfi->song_length);
|
||||||
|
|
||||||
safe_json_add_int_from_string(item, "play_count", dbmfi->play_count);
|
safe_json_add_int_from_string(item, "play_count", dbmfi->play_count);
|
||||||
|
safe_json_add_int_from_string(item, "skip_count", dbmfi->skip_count);
|
||||||
safe_json_add_time_from_string(item, "time_played", dbmfi->time_played, true);
|
safe_json_add_time_from_string(item, "time_played", dbmfi->time_played, true);
|
||||||
|
safe_json_add_time_from_string(item, "time_skipped", dbmfi->time_skipped, true);
|
||||||
safe_json_add_time_from_string(item, "time_added", dbmfi->time_added, true);
|
safe_json_add_time_from_string(item, "time_added", dbmfi->time_added, true);
|
||||||
safe_json_add_time_from_string(item, "date_released", dbmfi->date_released, false);
|
safe_json_add_time_from_string(item, "date_released", dbmfi->date_released, false);
|
||||||
safe_json_add_int_from_string(item, "seek_ms", dbmfi->seek);
|
safe_json_add_int_from_string(item, "seek_ms", dbmfi->seek);
|
||||||
|
@ -98,12 +98,14 @@ static const struct field_map rsp_fields[] =
|
|||||||
{ "compilation", dbmfi_offsetof(compilation), F_DETAILED | F_FULL },
|
{ "compilation", dbmfi_offsetof(compilation), F_DETAILED | F_FULL },
|
||||||
{ "rating", dbmfi_offsetof(rating), F_DETAILED | F_FULL },
|
{ "rating", dbmfi_offsetof(rating), F_DETAILED | F_FULL },
|
||||||
{ "play_count", dbmfi_offsetof(play_count), F_DETAILED | F_FULL },
|
{ "play_count", dbmfi_offsetof(play_count), F_DETAILED | F_FULL },
|
||||||
|
{ "skip_count", dbmfi_offsetof(skip_count), F_DETAILED | F_FULL },
|
||||||
{ "data_kind", dbmfi_offsetof(data_kind), F_DETAILED },
|
{ "data_kind", dbmfi_offsetof(data_kind), F_DETAILED },
|
||||||
{ "item_kind", dbmfi_offsetof(item_kind), F_DETAILED },
|
{ "item_kind", dbmfi_offsetof(item_kind), F_DETAILED },
|
||||||
{ "description", dbmfi_offsetof(description), F_DETAILED | F_FULL },
|
{ "description", dbmfi_offsetof(description), F_DETAILED | F_FULL },
|
||||||
{ "time_added", dbmfi_offsetof(time_added), F_DETAILED | F_FULL },
|
{ "time_added", dbmfi_offsetof(time_added), F_DETAILED | F_FULL },
|
||||||
{ "time_modified", dbmfi_offsetof(time_modified), F_DETAILED | F_FULL },
|
{ "time_modified", dbmfi_offsetof(time_modified), F_DETAILED | F_FULL },
|
||||||
{ "time_played", dbmfi_offsetof(time_played), F_DETAILED | F_FULL },
|
{ "time_played", dbmfi_offsetof(time_played), F_DETAILED | F_FULL },
|
||||||
|
{ "time_skipped", dbmfi_offsetof(time_skipped), F_DETAILED | F_FULL },
|
||||||
{ "db_timestamp", dbmfi_offsetof(db_timestamp), F_DETAILED },
|
{ "db_timestamp", dbmfi_offsetof(db_timestamp), F_DETAILED },
|
||||||
{ "disabled", dbmfi_offsetof(disabled), F_ALWAYS },
|
{ "disabled", dbmfi_offsetof(disabled), F_ALWAYS },
|
||||||
{ "sample_count", dbmfi_offsetof(sample_count), F_DETAILED },
|
{ "sample_count", dbmfi_offsetof(sample_count), F_DETAILED },
|
||||||
|
@ -128,6 +128,8 @@ static struct metadata_map md_map[] =
|
|||||||
{ "Date Added", PLIST_DATE, mfi_offsetof(time_added) },
|
{ "Date Added", PLIST_DATE, mfi_offsetof(time_added) },
|
||||||
{ "Play Date", PLIST_UINT, mfi_offsetof(time_played) },
|
{ "Play Date", PLIST_UINT, mfi_offsetof(time_played) },
|
||||||
{ "Play Count", PLIST_UINT, mfi_offsetof(play_count) },
|
{ "Play Count", PLIST_UINT, mfi_offsetof(play_count) },
|
||||||
|
{ "Skip Count", PLIST_UINT, mfi_offsetof(skip_count) },
|
||||||
|
{ "Skip Date", PLIST_DATE, mfi_offsetof(time_skipped) },
|
||||||
{ NULL, 0, 0 }
|
{ NULL, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
18
src/player.c
18
src/player.c
@ -352,6 +352,14 @@ playcount_inc_cb(void *arg)
|
|||||||
db_file_inc_playcount(*id);
|
db_file_inc_playcount(*id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
skipcount_inc_cb(void *arg)
|
||||||
|
{
|
||||||
|
int *id = arg;
|
||||||
|
|
||||||
|
db_file_inc_skipcount(*id);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef LASTFM
|
#ifdef LASTFM
|
||||||
// Callback from the worker thread (async operation as it may block)
|
// Callback from the worker thread (async operation as it may block)
|
||||||
static void
|
static void
|
||||||
@ -2219,6 +2227,7 @@ playback_next_bh(void *arg, int *retval)
|
|||||||
{
|
{
|
||||||
struct player_source *ps;
|
struct player_source *ps;
|
||||||
int ret;
|
int ret;
|
||||||
|
int id;
|
||||||
uint32_t item_id;
|
uint32_t item_id;
|
||||||
|
|
||||||
// The upper half is playback_pause, therefor the current playing item is
|
// The upper half is playback_pause, therefor the current playing item is
|
||||||
@ -2230,11 +2239,16 @@ playback_next_bh(void *arg, int *retval)
|
|||||||
return COMMAND_END;
|
return COMMAND_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
item_id = cur_streaming->item_id;
|
||||||
|
|
||||||
// Only add to history if playback started
|
// Only add to history if playback started
|
||||||
if (cur_streaming->output_start > cur_streaming->stream_start)
|
if (cur_streaming->output_start > cur_streaming->stream_start)
|
||||||
history_add(cur_streaming->id, cur_streaming->item_id);
|
{
|
||||||
|
history_add(cur_streaming->id, item_id);
|
||||||
|
|
||||||
item_id = cur_streaming->item_id;
|
id = (int)cur_streaming->id;
|
||||||
|
worker_execute(skipcount_inc_cb, &id, sizeof(int), 5);
|
||||||
|
}
|
||||||
|
|
||||||
ps = source_next();
|
ps = source_next();
|
||||||
if (!ps)
|
if (!ps)
|
||||||
|
@ -36,12 +36,14 @@ struct rsp_query_field_map;
|
|||||||
"compilation", RSP_TYPE_INT
|
"compilation", RSP_TYPE_INT
|
||||||
"rating", RSP_TYPE_INT
|
"rating", RSP_TYPE_INT
|
||||||
"play_count", RSP_TYPE_INT
|
"play_count", RSP_TYPE_INT
|
||||||
|
"skip_count", RSP_TYPE_INT
|
||||||
"data_kind", RSP_TYPE_INT
|
"data_kind", RSP_TYPE_INT
|
||||||
"item_kind", RSP_TYPE_INT
|
"item_kind", RSP_TYPE_INT
|
||||||
"description", RSP_TYPE_STRING
|
"description", RSP_TYPE_STRING
|
||||||
"time_added", RSP_TYPE_DATE
|
"time_added", RSP_TYPE_DATE
|
||||||
"time_modified", RSP_TYPE_DATE
|
"time_modified", RSP_TYPE_DATE
|
||||||
"time_played", RSP_TYPE_DATE
|
"time_played", RSP_TYPE_DATE
|
||||||
|
"time_skipped", RSP_TYPE_DATE
|
||||||
"db_timestamp", RSP_TYPE_DATE
|
"db_timestamp", RSP_TYPE_DATE
|
||||||
"sample_count", RSP_TYPE_INT
|
"sample_count", RSP_TYPE_INT
|
||||||
"codectype", RSP_TYPE_STRING
|
"codectype", RSP_TYPE_STRING
|
||||||
|
Loading…
Reference in New Issue
Block a user