diff options
-rw-r--r-- | doc/protocol.xml | 4 | ||||
-rw-r--r-- | src/command/DatabaseCommands.cxx | 11 | ||||
-rw-r--r-- | src/db/DatabasePrint.cxx | 17 | ||||
-rw-r--r-- | src/db/DatabasePrint.hxx | 2 |
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 |