Commit 7a55ab6a authored by Max Kellermann's avatar Max Kellermann

db/DatabasePrint: support descending sort

parent 6246d36f
......@@ -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
......
......@@ -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;
}
......
......@@ -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());
}
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment