db/DatabasePrint: support descending sort

This commit is contained in:
Max Kellermann 2017-12-18 21:50:14 +01:00
parent 6246d36fe6
commit 7a55ab6acc
4 changed files with 25 additions and 9 deletions

View File

@ -1693,7 +1693,9 @@ OK
<para>
<varname>sort</varname> sorts the result by the
specified tag. Without <varname>sort</varname>, the
specified tag. The sort is descending if the tag is
prefixed with a minus ('-').
Without <varname>sort</varname>, the
order is undefined. Only the first tag value will be
used, if multiple of the same type exist. To sort by
"Artist", "Album" or "AlbumArtist", you should specify

View File

@ -68,8 +68,15 @@ handle_match(Client &client, Request args, Response &r, bool fold_case)
window.SetAll();
TagType sort = TAG_NUM_OF_ITEM_TYPES;
bool descending = false;
if (args.size >= 2 && StringIsEqual(args[args.size - 2], "sort")) {
sort = tag_name_parse_i(args.back());
const char *s = args.back();
if (*s == '-') {
descending = true;
++s;
}
sort = tag_name_parse_i(s);
if (sort == TAG_NUM_OF_ITEM_TYPES)
throw ProtocolError(ACK_ERROR_ARG, "Unknown sort tag");
@ -87,7 +94,7 @@ handle_match(Client &client, Request args, Response &r, bool fold_case)
db_selection_print(r, client.GetPartition(),
selection, true, false,
sort,
sort, descending,
window.start, window.end);
return CommandResult::OK;
}

View File

@ -149,11 +149,16 @@ CompareNumeric(const char *a, const char *b)
}
static bool
CompareTags(TagType type, const Tag &a, const Tag &b)
CompareTags(TagType type, bool descending, const Tag &a, const Tag &b)
{
const char *a_value = a.GetSortValue(type);
const char *b_value = b.GetSortValue(type);
if (descending) {
using std::swap;
swap(a_value, b_value);
}
switch (type) {
case TAG_DISC:
case TAG_TRACK:
@ -168,7 +173,7 @@ void
db_selection_print(Response &r, Partition &partition,
const DatabaseSelection &selection,
bool full, bool base,
TagType sort,
TagType sort, bool descending,
unsigned window_start, unsigned window_end)
{
const Database &db = partition.GetDatabaseOrThrow();
@ -216,8 +221,10 @@ db_selection_print(Response &r, Partition &partition,
}
std::stable_sort(songs.begin(), songs.end(),
[sort](const DetachedSong &a, const DetachedSong &b){
return CompareTags(sort, a.GetTag(),
[sort, descending](const DetachedSong &a,
const DetachedSong &b){
return CompareTags(sort, descending,
a.GetTag(),
b.GetTag());
});
@ -242,7 +249,7 @@ db_selection_print(Response &r, Partition &partition,
bool full, bool base)
{
db_selection_print(r, partition, selection, full, base,
TAG_NUM_OF_ITEM_TYPES,
TAG_NUM_OF_ITEM_TYPES, false,
0, std::numeric_limits<int>::max());
}

View File

@ -42,7 +42,7 @@ void
db_selection_print(Response &r, Partition &partition,
const DatabaseSelection &selection,
bool full, bool base,
TagType sort,
TagType sort, bool descending,
unsigned window_start, unsigned window_end);
void