db/DatabasePrint: support sorting by "modified-since"

Closes #172
This commit is contained in:
Max Kellermann 2017-12-18 21:36:47 +01:00
parent 7a55ab6acc
commit 5582367d68
5 changed files with 40 additions and 11 deletions

View File

@ -1702,7 +1702,8 @@ OK
"ArtistSort", "AlbumSort" or "AlbumArtistSort" instead.
These will automatically fall back to the former if
"*Sort" doesn't exist. "AlbumArtist" falls back to just
"Artist".
"Artist". The type "Last-Modified" can sort by file
modification time.
</para>
<para>

View File

@ -35,6 +35,11 @@
#define LOCATE_TAG_BASE_TYPE (TAG_NUM_OF_ITEM_TYPES + 1)
#define LOCATE_TAG_MODIFIED_SINCE (TAG_NUM_OF_ITEM_TYPES + 2)
/**
* Special value for the db_selection_print() sort parameter.
*/
#define SORT_TAG_LAST_MODIFIED (TAG_NUM_OF_ITEM_TYPES + 3)
#define LOCATE_TAG_FILE_TYPE TAG_NUM_OF_ITEM_TYPES+10
#define LOCATE_TAG_ANY_TYPE TAG_NUM_OF_ITEM_TYPES+20

View File

@ -55,6 +55,19 @@ handle_lsinfo2(Client &client, const char *uri, Response &r)
return CommandResult::OK;
}
static TagType
ParseSortTag(const char *s)
{
if (StringIsEqualIgnoreCase(s, "Last-Modified"))
return TagType(SORT_TAG_LAST_MODIFIED);
TagType tag = tag_name_parse_i(s);
if (tag == TAG_NUM_OF_ITEM_TYPES)
throw ProtocolError(ACK_ERROR_ARG, "Unknown sort tag");
return tag;
}
static CommandResult
handle_match(Client &client, Request args, Response &r, bool fold_case)
{
@ -76,9 +89,7 @@ handle_match(Client &client, Request args, Response &r, bool fold_case)
++s;
}
sort = tag_name_parse_i(s);
if (sort == TAG_NUM_OF_ITEM_TYPES)
throw ProtocolError(ACK_ERROR_ARG, "Unknown sort tag");
sort = ParseSortTag(s);
args.pop_back();
args.pop_back();

View File

@ -220,13 +220,21 @@ db_selection_print(Response &r, Partition &partition,
db.Visit(selection, d, collect_songs, p);
}
std::stable_sort(songs.begin(), songs.end(),
[sort, descending](const DetachedSong &a,
const DetachedSong &b){
return CompareTags(sort, descending,
a.GetTag(),
b.GetTag());
});
if (sort == TagType(SORT_TAG_LAST_MODIFIED))
std::stable_sort(songs.begin(), songs.end(),
[descending](const DetachedSong &a, const DetachedSong &b){
return descending
? a.GetLastModified() > b.GetLastModified()
: a.GetLastModified() < b.GetLastModified();
});
else
std::stable_sort(songs.begin(), songs.end(),
[sort, descending](const DetachedSong &a,
const DetachedSong &b){
return CompareTags(sort, descending,
a.GetTag(),
b.GetTag());
});
if (window_end < songs.size())
songs.erase(std::next(songs.begin(), window_end),

View File

@ -38,6 +38,10 @@ db_selection_print(Response &r, Partition &partition,
const DatabaseSelection &selection,
bool full, bool base);
/**
* @param sort the sort tag; TAG_NUM_OF_ITEM_TYPES means don't sort;
* LOCATE_TAG_MODIFIED_SINCE means sort by file modification time
*/
void
db_selection_print(Response &r, Partition &partition,
const DatabaseSelection &selection,