Let the database do the sorting (#7025)
This commit is contained in:
parent
4078b3475e
commit
5c6000155c
@ -18,7 +18,7 @@ import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.activity.MainActivity;
|
||||
import de.danoeh.antennapod.adapter.EpisodeItemListAdapter;
|
||||
import de.danoeh.antennapod.adapter.actionbutton.DeleteActionButton;
|
||||
import de.danoeh.antennapod.core.event.DownloadLogEvent;
|
||||
import de.danoeh.antennapod.event.DownloadLogEvent;
|
||||
import de.danoeh.antennapod.core.menuhandler.MenuItemUtils;
|
||||
import de.danoeh.antennapod.core.storage.DBReader;
|
||||
import de.danoeh.antennapod.core.util.FeedItemUtil;
|
||||
|
@ -13,7 +13,7 @@ import com.google.android.material.appbar.MaterialToolbar;
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.adapter.DownloadLogAdapter;
|
||||
import de.danoeh.antennapod.core.event.DownloadLogEvent;
|
||||
import de.danoeh.antennapod.event.DownloadLogEvent;
|
||||
import de.danoeh.antennapod.core.storage.DBReader;
|
||||
import de.danoeh.antennapod.core.storage.DBWriter;
|
||||
import de.danoeh.antennapod.databinding.DownloadLogFragmentBinding;
|
||||
|
@ -39,7 +39,7 @@ import java.util.concurrent.ExecutionException;
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.activity.MainActivity;
|
||||
import de.danoeh.antennapod.adapter.EpisodeItemListAdapter;
|
||||
import de.danoeh.antennapod.core.feed.FeedEvent;
|
||||
import de.danoeh.antennapod.event.FeedEvent;
|
||||
import de.danoeh.antennapod.core.menuhandler.MenuItemUtils;
|
||||
import de.danoeh.antennapod.core.storage.DBReader;
|
||||
import de.danoeh.antennapod.core.storage.DBWriter;
|
||||
|
@ -14,6 +14,7 @@ import de.danoeh.antennapod.core.storage.DBWriter;
|
||||
import de.danoeh.antennapod.event.playback.PlaybackHistoryEvent;
|
||||
import de.danoeh.antennapod.model.feed.FeedItem;
|
||||
import de.danoeh.antennapod.model.feed.FeedItemFilter;
|
||||
import de.danoeh.antennapod.model.feed.SortOrder;
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
import org.greenrobot.eventbus.ThreadMode;
|
||||
|
||||
@ -21,6 +22,7 @@ import java.util.List;
|
||||
|
||||
public class PlaybackHistoryFragment extends EpisodesListFragment {
|
||||
public static final String TAG = "PlaybackHistoryFragment";
|
||||
private static final FeedItemFilter FILTER_HISTORY = new FeedItemFilter(FeedItemFilter.IS_IN_HISTORY);
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
@ -90,17 +92,18 @@ public class PlaybackHistoryFragment extends EpisodesListFragment {
|
||||
@NonNull
|
||||
@Override
|
||||
protected List<FeedItem> loadData() {
|
||||
return DBReader.getPlaybackHistory(0, page * EPISODES_PER_PAGE);
|
||||
return DBReader.getEpisodes(0, page * EPISODES_PER_PAGE, FILTER_HISTORY, SortOrder.COMPLETION_DATE_NEW_OLD);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected List<FeedItem> loadMoreData(int page) {
|
||||
return DBReader.getPlaybackHistory((page - 1) * EPISODES_PER_PAGE, EPISODES_PER_PAGE);
|
||||
return DBReader.getEpisodes((page - 1) * EPISODES_PER_PAGE, EPISODES_PER_PAGE, FILTER_HISTORY,
|
||||
SortOrder.COMPLETION_DATE_NEW_OLD);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int loadTotalItemCount() {
|
||||
return (int) DBReader.getPlaybackHistoryLength();
|
||||
return DBReader.getTotalEpisodeCount(FILTER_HISTORY);
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ import androidx.recyclerview.widget.RecyclerView;
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.activity.MainActivity;
|
||||
import de.danoeh.antennapod.adapter.EpisodeItemListAdapter;
|
||||
import de.danoeh.antennapod.core.event.DownloadLogEvent;
|
||||
import de.danoeh.antennapod.event.DownloadLogEvent;
|
||||
import de.danoeh.antennapod.core.menuhandler.MenuItemUtils;
|
||||
import de.danoeh.antennapod.core.storage.DBReader;
|
||||
import de.danoeh.antennapod.event.FeedItemEvent;
|
||||
|
@ -16,8 +16,6 @@ import java.util.Map;
|
||||
|
||||
import de.danoeh.antennapod.core.util.FeedItemPermutors;
|
||||
import de.danoeh.antennapod.core.util.LongList;
|
||||
import de.danoeh.antennapod.core.util.comparator.DownloadResultComparator;
|
||||
import de.danoeh.antennapod.core.util.comparator.PlaybackCompletionDateComparator;
|
||||
import de.danoeh.antennapod.model.feed.Chapter;
|
||||
import de.danoeh.antennapod.model.feed.Feed;
|
||||
import de.danoeh.antennapod.model.feed.FeedItem;
|
||||
@ -341,57 +339,6 @@ public final class DBReader {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the playback history from the database. A FeedItem is in the playback history if playback of the correpsonding episode
|
||||
* has been completed at least once.
|
||||
*
|
||||
* @param limit The maximum number of items to return.
|
||||
*
|
||||
* @return The playback history. The FeedItems are sorted by their media's playbackCompletionDate in descending order.
|
||||
*/
|
||||
@NonNull
|
||||
public static List<FeedItem> getPlaybackHistory(int offset, int limit) {
|
||||
Log.d(TAG, "getPlaybackHistory() called");
|
||||
|
||||
PodDBAdapter adapter = PodDBAdapter.getInstance();
|
||||
adapter.open();
|
||||
|
||||
Cursor mediaCursor = null;
|
||||
Cursor itemCursor = null;
|
||||
try {
|
||||
mediaCursor = adapter.getCompletedMediaCursor(offset, limit);
|
||||
String[] itemIds = new String[mediaCursor.getCount()];
|
||||
for (int i = 0; i < itemIds.length && mediaCursor.moveToPosition(i); i++) {
|
||||
int index = mediaCursor.getColumnIndex(PodDBAdapter.KEY_FEEDITEM);
|
||||
itemIds[i] = Long.toString(mediaCursor.getLong(index));
|
||||
}
|
||||
itemCursor = adapter.getFeedItemCursor(itemIds);
|
||||
List<FeedItem> items = extractItemlistFromCursor(adapter, itemCursor);
|
||||
loadAdditionalFeedItemListData(items);
|
||||
Collections.sort(items, new PlaybackCompletionDateComparator());
|
||||
return items;
|
||||
} finally {
|
||||
if (mediaCursor != null) {
|
||||
mediaCursor.close();
|
||||
}
|
||||
if (itemCursor != null) {
|
||||
itemCursor.close();
|
||||
}
|
||||
adapter.close();
|
||||
}
|
||||
}
|
||||
|
||||
public static long getPlaybackHistoryLength() {
|
||||
PodDBAdapter adapter = PodDBAdapter.getInstance();
|
||||
adapter.open();
|
||||
|
||||
try {
|
||||
return adapter.getCompletedMediaLength();
|
||||
} finally {
|
||||
adapter.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the download log from the database.
|
||||
*
|
||||
@ -408,7 +355,6 @@ public final class DBReader {
|
||||
while (cursor.moveToNext()) {
|
||||
downloadLog.add(DownloadResultCursorMapper.convert(cursor));
|
||||
}
|
||||
Collections.sort(downloadLog, new DownloadResultComparator());
|
||||
return downloadLog;
|
||||
} finally {
|
||||
adapter.close();
|
||||
@ -432,7 +378,6 @@ public final class DBReader {
|
||||
while (cursor.moveToNext()) {
|
||||
downloadLog.add(DownloadResultCursorMapper.convert(cursor));
|
||||
}
|
||||
Collections.sort(downloadLog, new DownloadResultComparator());
|
||||
return downloadLog;
|
||||
} finally {
|
||||
adapter.close();
|
||||
@ -691,7 +636,6 @@ public final class DBReader {
|
||||
try (Cursor itemCursor = adapter.getFeedItemCursorByUrl(urls)) {
|
||||
List<FeedItem> items = extractItemlistFromCursor(adapter, itemCursor);
|
||||
loadAdditionalFeedItemListData(items);
|
||||
Collections.sort(items, new PlaybackCompletionDateComparator());
|
||||
return items;
|
||||
} finally {
|
||||
adapter.close();
|
||||
|
@ -12,7 +12,7 @@ import androidx.documentfile.provider.DocumentFile;
|
||||
|
||||
import com.google.common.util.concurrent.Futures;
|
||||
|
||||
import de.danoeh.antennapod.core.event.DownloadLogEvent;
|
||||
import de.danoeh.antennapod.event.DownloadLogEvent;
|
||||
import de.danoeh.antennapod.core.feed.LocalFeedUpdater;
|
||||
import de.danoeh.antennapod.net.download.serviceinterface.DownloadServiceInterface;
|
||||
import de.danoeh.antennapod.core.service.playback.PlaybackServiceInterface;
|
||||
@ -39,7 +39,7 @@ import de.danoeh.antennapod.event.MessageEvent;
|
||||
import de.danoeh.antennapod.event.playback.PlaybackHistoryEvent;
|
||||
import de.danoeh.antennapod.event.QueueEvent;
|
||||
import de.danoeh.antennapod.event.UnreadItemsUpdateEvent;
|
||||
import de.danoeh.antennapod.core.feed.FeedEvent;
|
||||
import de.danoeh.antennapod.event.FeedEvent;
|
||||
import de.danoeh.antennapod.storage.preferences.PlaybackPreferences;
|
||||
import de.danoeh.antennapod.storage.preferences.UserPreferences;
|
||||
import de.danoeh.antennapod.model.download.DownloadResult;
|
||||
|
@ -11,7 +11,6 @@ import de.danoeh.antennapod.core.feed.ChapterMerger;
|
||||
import de.danoeh.antennapod.model.feed.FeedMedia;
|
||||
import de.danoeh.antennapod.net.common.AntennapodHttpClient;
|
||||
import de.danoeh.antennapod.core.storage.DBReader;
|
||||
import de.danoeh.antennapod.core.util.comparator.ChapterStartTimeComparator;
|
||||
import de.danoeh.antennapod.parser.feed.PodcastIndexChapterParser;
|
||||
import de.danoeh.antennapod.parser.media.id3.ChapterReader;
|
||||
import de.danoeh.antennapod.parser.media.id3.ID3ReaderException;
|
||||
@ -30,6 +29,7 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -232,4 +232,11 @@ public class ChapterUtils {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static class ChapterStartTimeComparator implements Comparator<Chapter> {
|
||||
@Override
|
||||
public int compare(Chapter lhs, Chapter rhs) {
|
||||
return Long.compare(lhs.getStart(), rhs.getStart());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -78,6 +78,12 @@ public class FeedItemPermutors {
|
||||
case SIZE_LARGE_SMALL:
|
||||
comparator = (f1, f2) -> Long.compare(size(f2), size(f1));
|
||||
break;
|
||||
case COMPLETION_DATE_NEW_OLD:
|
||||
comparator = (f1, f2) -> f2.getMedia().getPlaybackCompletionDate()
|
||||
.compareTo(f1.getMedia().getPlaybackCompletionDate());
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Permutor not implemented");
|
||||
}
|
||||
|
||||
if (comparator != null) {
|
||||
|
@ -1,14 +0,0 @@
|
||||
package de.danoeh.antennapod.core.util.comparator;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
import de.danoeh.antennapod.model.feed.Chapter;
|
||||
|
||||
public class ChapterStartTimeComparator implements Comparator<Chapter> {
|
||||
|
||||
@Override
|
||||
public int compare(Chapter lhs, Chapter rhs) {
|
||||
return Long.compare(lhs.getStart(), rhs.getStart());
|
||||
}
|
||||
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
package de.danoeh.antennapod.core.util.comparator;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
import de.danoeh.antennapod.model.download.DownloadResult;
|
||||
|
||||
/** Compares the completion date of two DownloadResult objects. */
|
||||
public class DownloadResultComparator implements Comparator<DownloadResult> {
|
||||
|
||||
@Override
|
||||
public int compare(DownloadResult lhs, DownloadResult rhs) {
|
||||
return rhs.getCompletionDate().compareTo(lhs.getCompletionDate());
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
package de.danoeh.antennapod.core.util.comparator;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
import de.danoeh.antennapod.model.feed.FeedItem;
|
||||
|
||||
public class PlaybackCompletionDateComparator implements Comparator<FeedItem> {
|
||||
|
||||
public int compare(FeedItem lhs, FeedItem rhs) {
|
||||
if (lhs.getMedia() != null
|
||||
&& lhs.getMedia().getPlaybackCompletionDate() != null
|
||||
&& rhs.getMedia() != null
|
||||
&& rhs.getMedia().getPlaybackCompletionDate() != null) {
|
||||
return rhs.getMedia().getPlaybackCompletionDate()
|
||||
.compareTo(lhs.getMedia().getPlaybackCompletionDate());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
@ -320,7 +320,7 @@ public class DbReaderTest {
|
||||
}
|
||||
adapter.close();
|
||||
|
||||
long len = DBReader.getPlaybackHistoryLength();
|
||||
long len = DBReader.getTotalEpisodeCount(new FeedItemFilter(FeedItemFilter.IS_IN_HISTORY));
|
||||
assertEquals("Wrong size: ", (int) len, playedItems);
|
||||
}
|
||||
|
||||
@ -500,7 +500,8 @@ public class DbReaderTest {
|
||||
}
|
||||
adapter.close();
|
||||
|
||||
List<FeedItem> saved = DBReader.getPlaybackHistory(paramOffset, paramLimit);
|
||||
List<FeedItem> saved = DBReader.getEpisodes(paramOffset, paramLimit,
|
||||
new FeedItemFilter(FeedItemFilter.IS_IN_HISTORY), SortOrder.COMPLETION_DATE_NEW_OLD);
|
||||
assertNotNull(saved);
|
||||
assertEquals(String.format("Wrong size with offset %d and limit %d: ",
|
||||
paramOffset, paramLimit),
|
||||
|
@ -1,4 +1,4 @@
|
||||
package de.danoeh.antennapod.core.event;
|
||||
package de.danoeh.antennapod.event;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
@ -1,10 +1,7 @@
|
||||
package de.danoeh.antennapod.core.feed;
|
||||
package de.danoeh.antennapod.event;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
|
||||
public class FeedEvent {
|
||||
|
||||
public enum Action {
|
||||
@ -23,10 +20,6 @@ public class FeedEvent {
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
|
||||
.append("action", action)
|
||||
.append("feedId", feedId)
|
||||
.toString();
|
||||
return "FeedEvent{action=" + action + ", feedId=" + feedId + '}';
|
||||
}
|
||||
|
||||
}
|
@ -23,6 +23,7 @@ public class FeedItemFilter implements Serializable {
|
||||
public final boolean showNoMedia;
|
||||
public final boolean showIsFavorite;
|
||||
public final boolean showNotFavorite;
|
||||
public final boolean showInHistory;
|
||||
|
||||
public static final String PLAYED = "played";
|
||||
public static final String UNPLAYED = "unplayed";
|
||||
@ -37,6 +38,7 @@ public class FeedItemFilter implements Serializable {
|
||||
public static final String NOT_QUEUED = "not_queued";
|
||||
public static final String DOWNLOADED = "downloaded";
|
||||
public static final String NOT_DOWNLOADED = "not_downloaded";
|
||||
public static final String IS_IN_HISTORY = "is_in_history";
|
||||
|
||||
public static FeedItemFilter unfiltered() {
|
||||
return new FeedItemFilter("");
|
||||
@ -63,6 +65,7 @@ public class FeedItemFilter implements Serializable {
|
||||
showIsFavorite = hasProperty(IS_FAVORITE);
|
||||
showNotFavorite = hasProperty(NOT_FAVORITE);
|
||||
showNew = hasProperty(NEW);
|
||||
showInHistory = hasProperty(IS_IN_HISTORY);
|
||||
}
|
||||
|
||||
private boolean hasProperty(String property) {
|
||||
@ -106,6 +109,9 @@ public class FeedItemFilter implements Serializable {
|
||||
return false;
|
||||
} else if (showNotFavorite && item.isTagged(FeedItem.TAG_FAVORITE)) {
|
||||
return false;
|
||||
} else if (showInHistory && item.getMedia() != null
|
||||
&& item.getMedia().getPlaybackCompletionDate().getTime() == 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -26,7 +26,8 @@ public enum SortOrder {
|
||||
FEED_TITLE_Z_A(102, INTER_FEED),
|
||||
RANDOM(103, INTER_FEED),
|
||||
SMART_SHUFFLE_OLD_NEW(104, INTER_FEED),
|
||||
SMART_SHUFFLE_NEW_OLD(105, INTER_FEED);
|
||||
SMART_SHUFFLE_NEW_OLD(105, INTER_FEED),
|
||||
COMPLETION_DATE_NEW_OLD(106, INTER_FEED);
|
||||
|
||||
public enum Scope {
|
||||
INTRA_FEED, INTER_FEED
|
||||
|
@ -983,7 +983,7 @@ public class PodDBAdapter {
|
||||
public final Cursor getDownloadLog(final int feedFileType, final long feedFileId) {
|
||||
final String query = "SELECT * FROM " + TABLE_NAME_DOWNLOAD_LOG +
|
||||
" WHERE " + KEY_FEEDFILE + "=" + feedFileId + " AND " + KEY_FEEDFILETYPE + "=" + feedFileType
|
||||
+ " ORDER BY " + KEY_ID + " DESC";
|
||||
+ " ORDER BY " + KEY_COMPLETION_DATE + " DESC";
|
||||
return db.rawQuery(query, null);
|
||||
}
|
||||
|
||||
@ -1107,29 +1107,6 @@ public class PodDBAdapter {
|
||||
return "((" + SELECT_KEY_ITEM_ID + " * " + seed + ") % 46471)";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a cursor which contains feed media objects with a playback
|
||||
* completion date in ascending order.
|
||||
*
|
||||
* @param offset The row to start at.
|
||||
* @param limit The maximum row count of the returned cursor. Must be an
|
||||
* integer >= 0.
|
||||
* @throws IllegalArgumentException if limit < 0
|
||||
*/
|
||||
public final Cursor getCompletedMediaCursor(int offset, int limit) {
|
||||
if (limit < 0) {
|
||||
throw new IllegalArgumentException("Limit must be >= 0");
|
||||
}
|
||||
|
||||
return db.query(TABLE_NAME_FEED_MEDIA, null,
|
||||
KEY_PLAYBACK_COMPLETION_DATE + " > 0", null, null,
|
||||
null, String.format(Locale.US, "%s DESC LIMIT %d, %d", KEY_PLAYBACK_COMPLETION_DATE, offset, limit));
|
||||
}
|
||||
|
||||
public final long getCompletedMediaLength() {
|
||||
return DatabaseUtils.queryNumEntries(db, TABLE_NAME_FEED_MEDIA, KEY_PLAYBACK_COMPLETION_DATE + "> 0");
|
||||
}
|
||||
|
||||
public final Cursor getSingleFeedMediaCursor(long id) {
|
||||
final String query = "SELECT " + KEYS_FEED_MEDIA + " FROM " + TABLE_NAME_FEED_MEDIA
|
||||
+ " WHERE " + KEY_ID + "=" + id;
|
||||
@ -1168,7 +1145,8 @@ public class PodDBAdapter {
|
||||
urlsString.append(DatabaseUtils.sqlEscapeString(urls.get(i)));
|
||||
}
|
||||
final String query = SELECT_FEED_ITEMS_AND_MEDIA
|
||||
+ " WHERE " + KEY_DOWNLOAD_URL + " IN (" + urlsString + ")";
|
||||
+ " WHERE " + KEY_DOWNLOAD_URL + " IN (" + urlsString + ")"
|
||||
+ " ORDER BY " + KEY_PLAYBACK_COMPLETION_DATE + " DESC";
|
||||
return db.rawQuery(query, null);
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@ public class FeedItemFilterQuery {
|
||||
// The keys used within this method, but explicitly combined with their table
|
||||
String keyRead = PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + PodDBAdapter.KEY_READ;
|
||||
String keyPosition = PodDBAdapter.TABLE_NAME_FEED_MEDIA + "." + PodDBAdapter.KEY_POSITION;
|
||||
String keyCompletionDate = PodDBAdapter.TABLE_NAME_FEED_MEDIA + "." + PodDBAdapter.KEY_PLAYBACK_COMPLETION_DATE;
|
||||
String keyDownloaded = PodDBAdapter.TABLE_NAME_FEED_MEDIA + "." + PodDBAdapter.KEY_DOWNLOADED;
|
||||
String keyMediaId = PodDBAdapter.TABLE_NAME_FEED_MEDIA + "." + PodDBAdapter.KEY_ID;
|
||||
String keyItemId = PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + PodDBAdapter.KEY_ID;
|
||||
@ -62,6 +63,9 @@ public class FeedItemFilterQuery {
|
||||
} else if (filter.showNotFavorite) {
|
||||
statements.add(keyItemId + " NOT IN (SELECT " + keyFeedItem + " FROM " + tableFavorites + ") ");
|
||||
}
|
||||
if (filter.showInHistory) {
|
||||
statements.add(keyCompletionDate + " > 0 ");
|
||||
}
|
||||
|
||||
if (statements.isEmpty()) {
|
||||
return "";
|
||||
|
@ -31,6 +31,10 @@ public class FeedItemSortQuery {
|
||||
case SIZE_LARGE_SMALL:
|
||||
sortQuery = PodDBAdapter.TABLE_NAME_FEED_MEDIA + "." + PodDBAdapter.KEY_SIZE + " " + "DESC";
|
||||
break;
|
||||
case COMPLETION_DATE_NEW_OLD:
|
||||
sortQuery = PodDBAdapter.TABLE_NAME_FEED_MEDIA + "."
|
||||
+ PodDBAdapter.KEY_PLAYBACK_COMPLETION_DATE + " " + "DESC";
|
||||
break;
|
||||
default:
|
||||
sortQuery = "";
|
||||
break;
|
||||
|
Loading…
x
Reference in New Issue
Block a user