db/DatabasePrint: support descending sort
This commit is contained in:
parent
6246d36fe6
commit
7a55ab6acc
@ -1693,7 +1693,9 @@ OK
|
|||||||
|
|
||||||
<para>
|
<para>
|
||||||
<varname>sort</varname> sorts the result by the
|
<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
|
order is undefined. Only the first tag value will be
|
||||||
used, if multiple of the same type exist. To sort by
|
used, if multiple of the same type exist. To sort by
|
||||||
"Artist", "Album" or "AlbumArtist", you should specify
|
"Artist", "Album" or "AlbumArtist", you should specify
|
||||||
|
@ -68,8 +68,15 @@ handle_match(Client &client, Request args, Response &r, bool fold_case)
|
|||||||
window.SetAll();
|
window.SetAll();
|
||||||
|
|
||||||
TagType sort = TAG_NUM_OF_ITEM_TYPES;
|
TagType sort = TAG_NUM_OF_ITEM_TYPES;
|
||||||
|
bool descending = false;
|
||||||
if (args.size >= 2 && StringIsEqual(args[args.size - 2], "sort")) {
|
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)
|
if (sort == TAG_NUM_OF_ITEM_TYPES)
|
||||||
throw ProtocolError(ACK_ERROR_ARG, "Unknown sort tag");
|
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(),
|
db_selection_print(r, client.GetPartition(),
|
||||||
selection, true, false,
|
selection, true, false,
|
||||||
sort,
|
sort, descending,
|
||||||
window.start, window.end);
|
window.start, window.end);
|
||||||
return CommandResult::OK;
|
return CommandResult::OK;
|
||||||
}
|
}
|
||||||
|
@ -149,11 +149,16 @@ CompareNumeric(const char *a, const char *b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
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 *a_value = a.GetSortValue(type);
|
||||||
const char *b_value = b.GetSortValue(type);
|
const char *b_value = b.GetSortValue(type);
|
||||||
|
|
||||||
|
if (descending) {
|
||||||
|
using std::swap;
|
||||||
|
swap(a_value, b_value);
|
||||||
|
}
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case TAG_DISC:
|
case TAG_DISC:
|
||||||
case TAG_TRACK:
|
case TAG_TRACK:
|
||||||
@ -168,7 +173,7 @@ void
|
|||||||
db_selection_print(Response &r, Partition &partition,
|
db_selection_print(Response &r, Partition &partition,
|
||||||
const DatabaseSelection &selection,
|
const DatabaseSelection &selection,
|
||||||
bool full, bool base,
|
bool full, bool base,
|
||||||
TagType sort,
|
TagType sort, bool descending,
|
||||||
unsigned window_start, unsigned window_end)
|
unsigned window_start, unsigned window_end)
|
||||||
{
|
{
|
||||||
const Database &db = partition.GetDatabaseOrThrow();
|
const Database &db = partition.GetDatabaseOrThrow();
|
||||||
@ -216,8 +221,10 @@ db_selection_print(Response &r, Partition &partition,
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::stable_sort(songs.begin(), songs.end(),
|
std::stable_sort(songs.begin(), songs.end(),
|
||||||
[sort](const DetachedSong &a, const DetachedSong &b){
|
[sort, descending](const DetachedSong &a,
|
||||||
return CompareTags(sort, a.GetTag(),
|
const DetachedSong &b){
|
||||||
|
return CompareTags(sort, descending,
|
||||||
|
a.GetTag(),
|
||||||
b.GetTag());
|
b.GetTag());
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -242,7 +249,7 @@ db_selection_print(Response &r, Partition &partition,
|
|||||||
bool full, bool base)
|
bool full, bool base)
|
||||||
{
|
{
|
||||||
db_selection_print(r, partition, selection, full, 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());
|
0, std::numeric_limits<int>::max());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ void
|
|||||||
db_selection_print(Response &r, Partition &partition,
|
db_selection_print(Response &r, Partition &partition,
|
||||||
const DatabaseSelection &selection,
|
const DatabaseSelection &selection,
|
||||||
bool full, bool base,
|
bool full, bool base,
|
||||||
TagType sort,
|
TagType sort, bool descending,
|
||||||
unsigned window_start, unsigned window_end);
|
unsigned window_start, unsigned window_end);
|
||||||
|
|
||||||
void
|
void
|
||||||
|
Loading…
Reference in New Issue
Block a user