db/DatabasePrint: support sorting by "modified-since"

Closes #172
This commit is contained in:
Max Kellermann 2017-12-18 21:36:47 +01:00
parent 7a55ab6acc
commit 5582367d68
5 changed files with 40 additions and 11 deletions

View File

@ -1702,7 +1702,8 @@ OK
"ArtistSort", "AlbumSort" or "AlbumArtistSort" instead. "ArtistSort", "AlbumSort" or "AlbumArtistSort" instead.
These will automatically fall back to the former if These will automatically fall back to the former if
"*Sort" doesn't exist. "AlbumArtist" falls back to just "*Sort" doesn't exist. "AlbumArtist" falls back to just
"Artist". "Artist". The type "Last-Modified" can sort by file
modification time.
</para> </para>
<para> <para>

View File

@ -35,6 +35,11 @@
#define LOCATE_TAG_BASE_TYPE (TAG_NUM_OF_ITEM_TYPES + 1) #define LOCATE_TAG_BASE_TYPE (TAG_NUM_OF_ITEM_TYPES + 1)
#define LOCATE_TAG_MODIFIED_SINCE (TAG_NUM_OF_ITEM_TYPES + 2) #define LOCATE_TAG_MODIFIED_SINCE (TAG_NUM_OF_ITEM_TYPES + 2)
/**
* Special value for the db_selection_print() sort parameter.
*/
#define SORT_TAG_LAST_MODIFIED (TAG_NUM_OF_ITEM_TYPES + 3)
#define LOCATE_TAG_FILE_TYPE TAG_NUM_OF_ITEM_TYPES+10 #define LOCATE_TAG_FILE_TYPE TAG_NUM_OF_ITEM_TYPES+10
#define LOCATE_TAG_ANY_TYPE TAG_NUM_OF_ITEM_TYPES+20 #define LOCATE_TAG_ANY_TYPE TAG_NUM_OF_ITEM_TYPES+20

View File

@ -55,6 +55,19 @@ handle_lsinfo2(Client &client, const char *uri, Response &r)
return CommandResult::OK; return CommandResult::OK;
} }
static TagType
ParseSortTag(const char *s)
{
if (StringIsEqualIgnoreCase(s, "Last-Modified"))
return TagType(SORT_TAG_LAST_MODIFIED);
TagType tag = tag_name_parse_i(s);
if (tag == TAG_NUM_OF_ITEM_TYPES)
throw ProtocolError(ACK_ERROR_ARG, "Unknown sort tag");
return tag;
}
static CommandResult static CommandResult
handle_match(Client &client, Request args, Response &r, bool fold_case) handle_match(Client &client, Request args, Response &r, bool fold_case)
{ {
@ -76,9 +89,7 @@ handle_match(Client &client, Request args, Response &r, bool fold_case)
++s; ++s;
} }
sort = tag_name_parse_i(s); sort = ParseSortTag(s);
if (sort == TAG_NUM_OF_ITEM_TYPES)
throw ProtocolError(ACK_ERROR_ARG, "Unknown sort tag");
args.pop_back(); args.pop_back();
args.pop_back(); args.pop_back();

View File

@ -220,13 +220,21 @@ db_selection_print(Response &r, Partition &partition,
db.Visit(selection, d, collect_songs, p); db.Visit(selection, d, collect_songs, p);
} }
std::stable_sort(songs.begin(), songs.end(), if (sort == TagType(SORT_TAG_LAST_MODIFIED))
[sort, descending](const DetachedSong &a, std::stable_sort(songs.begin(), songs.end(),
const DetachedSong &b){ [descending](const DetachedSong &a, const DetachedSong &b){
return CompareTags(sort, descending, return descending
a.GetTag(), ? a.GetLastModified() > b.GetLastModified()
b.GetTag()); : a.GetLastModified() < b.GetLastModified();
}); });
else
std::stable_sort(songs.begin(), songs.end(),
[sort, descending](const DetachedSong &a,
const DetachedSong &b){
return CompareTags(sort, descending,
a.GetTag(),
b.GetTag());
});
if (window_end < songs.size()) if (window_end < songs.size())
songs.erase(std::next(songs.begin(), window_end), songs.erase(std::next(songs.begin(), window_end),

View File

@ -38,6 +38,10 @@ db_selection_print(Response &r, Partition &partition,
const DatabaseSelection &selection, const DatabaseSelection &selection,
bool full, bool base); bool full, bool base);
/**
* @param sort the sort tag; TAG_NUM_OF_ITEM_TYPES means don't sort;
* LOCATE_TAG_MODIFIED_SINCE means sort by file modification time
*/
void void
db_selection_print(Response &r, Partition &partition, db_selection_print(Response &r, Partition &partition,
const DatabaseSelection &selection, const DatabaseSelection &selection,