summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/protocol.xml4
-rw-r--r--src/command/DatabaseCommands.cxx11
-rw-r--r--src/db/DatabasePrint.cxx17
-rw-r--r--src/db/DatabasePrint.hxx2
4 files changed, 25 insertions, 9 deletions
diff --git a/doc/protocol.xml b/doc/protocol.xml
index 1f0ab7eb9..480fbf90a 100644
--- a/doc/protocol.xml
+++ b/doc/protocol.xml
@@ -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
diff --git a/src/command/DatabaseCommands.cxx b/src/command/DatabaseCommands.cxx
index aad7d3a4c..a6e56dfc6 100644
--- a/src/command/DatabaseCommands.cxx
+++ b/src/command/DatabaseCommands.cxx
@@ -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;
}
diff --git a/src/db/DatabasePrint.cxx b/src/db/DatabasePrint.cxx
index fd8f72e18..a8f32aeb1 100644
--- a/src/db/DatabasePrint.cxx
+++ b/src/db/DatabasePrint.cxx
@@ -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());
}
diff --git a/src/db/DatabasePrint.hxx b/src/db/DatabasePrint.hxx
index e0a27674d..7612b9319 100644
--- a/src/db/DatabasePrint.hxx
+++ b/src/db/DatabasePrint.hxx
@@ -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