From 613a9896e91200c3d4e8744173e48c445003469f Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Wed, 3 Apr 2024 22:21:42 +0200 Subject: Remember column indices between different list items (#7051) This is way faster than searching for the column index again for every item. --- .../antennapod/storage/database/DBReader.java | 155 ++++++++------------- .../storage/database/mapper/ChapterCursor.java | 41 ++++++ .../database/mapper/ChapterCursorMapper.java | 32 ----- .../database/mapper/DownloadResultCursor.java | 52 +++++++ .../mapper/DownloadResultCursorMapper.java | 35 ----- .../storage/database/mapper/FeedCursor.java | 92 ++++++++++++ .../storage/database/mapper/FeedCursorMapper.java | 70 ---------- .../storage/database/mapper/FeedItemCursor.java | 71 ++++++++++ .../database/mapper/FeedItemCursorMapper.java | 48 ------- .../storage/database/mapper/FeedMediaCursor.java | 81 +++++++++++ .../database/mapper/FeedMediaCursorMapper.java | 67 --------- .../database/mapper/FeedPreferencesCursor.java | 85 +++++++++++ .../mapper/FeedPreferencesCursorMapper.java | 82 ----------- .../database/mapper/FeedCursorMapperTest.java | 5 +- 14 files changed, 485 insertions(+), 431 deletions(-) create mode 100644 storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/ChapterCursor.java delete mode 100644 storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/ChapterCursorMapper.java create mode 100644 storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/DownloadResultCursor.java delete mode 100644 storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/DownloadResultCursorMapper.java create mode 100644 storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/FeedCursor.java delete mode 100644 storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/FeedCursorMapper.java create mode 100644 storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/FeedItemCursor.java delete mode 100644 storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/FeedItemCursorMapper.java create mode 100644 storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/FeedMediaCursor.java delete mode 100644 storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/FeedMediaCursorMapper.java create mode 100644 storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/FeedPreferencesCursor.java delete mode 100644 storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/FeedPreferencesCursorMapper.java diff --git a/storage/database/src/main/java/de/danoeh/antennapod/storage/database/DBReader.java b/storage/database/src/main/java/de/danoeh/antennapod/storage/database/DBReader.java index f0239d8f5..41bb75b8b 100644 --- a/storage/database/src/main/java/de/danoeh/antennapod/storage/database/DBReader.java +++ b/storage/database/src/main/java/de/danoeh/antennapod/storage/database/DBReader.java @@ -25,12 +25,11 @@ import de.danoeh.antennapod.model.feed.FeedPreferences; import de.danoeh.antennapod.model.feed.SortOrder; import de.danoeh.antennapod.model.feed.SubscriptionsFilter; import de.danoeh.antennapod.model.download.DownloadResult; -import de.danoeh.antennapod.storage.database.mapper.ChapterCursorMapper; -import de.danoeh.antennapod.storage.database.mapper.DownloadResultCursorMapper; -import de.danoeh.antennapod.storage.database.mapper.FeedCursorMapper; -import de.danoeh.antennapod.storage.database.mapper.FeedItemCursorMapper; -import de.danoeh.antennapod.storage.database.mapper.FeedMediaCursorMapper; -import de.danoeh.antennapod.storage.database.mapper.FeedPreferencesCursorMapper; +import de.danoeh.antennapod.storage.database.mapper.ChapterCursor; +import de.danoeh.antennapod.storage.database.mapper.DownloadResultCursor; +import de.danoeh.antennapod.storage.database.mapper.FeedCursor; +import de.danoeh.antennapod.storage.database.mapper.FeedItemCursor; +import de.danoeh.antennapod.storage.database.mapper.FeedMediaCursor; /** * Provides methods for reading data from the AntennaPod database. @@ -72,11 +71,10 @@ public final class DBReader { @NonNull private static List getFeedList(PodDBAdapter adapter) { - try (Cursor cursor = adapter.getAllFeedsCursor()) { + try (FeedCursor cursor = new FeedCursor(adapter.getAllFeedsCursor())) { List feeds = new ArrayList<>(cursor.getCount()); while (cursor.moveToNext()) { - Feed feed = extractFeedFromCursorRow(cursor); - feeds.add(feed); + feeds.add(cursor.getFeed()); } return feeds; } @@ -173,8 +171,8 @@ public final class DBReader { PodDBAdapter adapter = PodDBAdapter.getInstance(); adapter.open(); - try (Cursor cursor = adapter.getItemsOfFeedCursor(feed, filter)) { - List items = extractItemlistFromCursor(adapter, cursor); + try (FeedItemCursor cursor = new FeedItemCursor(adapter.getItemsOfFeedCursor(feed, filter))) { + List items = extractItemlistFromCursor(cursor); FeedItemPermutors.getPermutor(sortOrder).reorder(items); feed.setItems(items); for (FeedItem item : items) { @@ -186,45 +184,20 @@ public final class DBReader { } } - public static List extractItemlistFromCursor(Cursor itemlistCursor) { - Log.d(TAG, "extractItemlistFromCursor() called with: " + "itemlistCursor = [" + itemlistCursor + "]"); - PodDBAdapter adapter = PodDBAdapter.getInstance(); - adapter.open(); - try { - return extractItemlistFromCursor(adapter, itemlistCursor); - } finally { - adapter.close(); - } - } - @NonNull - private static List extractItemlistFromCursor(PodDBAdapter adapter, Cursor cursor) { + private static List extractItemlistFromCursor(FeedItemCursor cursor) { List result = new ArrayList<>(cursor.getCount()); - if (cursor.moveToFirst()) { - int indexMediaId = cursor.getColumnIndexOrThrow(PodDBAdapter.SELECT_KEY_MEDIA_ID); - do { - FeedItem item = FeedItemCursorMapper.convert(cursor); - result.add(item); - if (!cursor.isNull(indexMediaId)) { - item.setMedia(FeedMediaCursorMapper.convert(cursor)); - } - } while (cursor.moveToNext()); + while (cursor.moveToNext()) { + result.add(cursor.getFeedItem()); } return result; } - private static Feed extractFeedFromCursorRow(Cursor cursor) { - Feed feed = FeedCursorMapper.convert(cursor); - FeedPreferences preferences = FeedPreferencesCursorMapper.convert(cursor); - feed.setPreferences(preferences); - return feed; - } - @NonNull public static List getQueue(PodDBAdapter adapter) { Log.d(TAG, "getQueue()"); - try (Cursor cursor = adapter.getQueueCursor()) { - List items = extractItemlistFromCursor(adapter, cursor); + try (FeedItemCursor cursor = new FeedItemCursor(adapter.getQueueCursor())) { + List items = extractItemlistFromCursor(cursor); loadAdditionalFeedItemListData(items); return items; } @@ -303,8 +276,8 @@ public final class DBReader { Log.d(TAG, "getRecentlyPublishedEpisodes() called with: offset=" + offset + ", limit=" + limit); PodDBAdapter adapter = PodDBAdapter.getInstance(); adapter.open(); - try (Cursor cursor = adapter.getEpisodesCursor(offset, limit, filter, sortOrder)) { - List items = extractItemlistFromCursor(adapter, cursor); + try (FeedItemCursor cursor = new FeedItemCursor(adapter.getEpisodesCursor(offset, limit, filter, sortOrder))) { + List items = extractItemlistFromCursor(cursor); loadAdditionalFeedItemListData(items); return items; } finally { @@ -328,8 +301,8 @@ public final class DBReader { public static List getRandomEpisodes(int limit, int seed) { PodDBAdapter adapter = PodDBAdapter.getInstance(); adapter.open(); - try (Cursor cursor = adapter.getRandomEpisodesCursor(limit, seed)) { - List items = extractItemlistFromCursor(adapter, cursor); + try (FeedItemCursor cursor = new FeedItemCursor(adapter.getRandomEpisodesCursor(limit, seed))) { + List items = extractItemlistFromCursor(cursor); loadAdditionalFeedItemListData(items); return items; } finally { @@ -348,10 +321,10 @@ public final class DBReader { PodDBAdapter adapter = PodDBAdapter.getInstance(); adapter.open(); - try (Cursor cursor = adapter.getDownloadLogCursor(DOWNLOAD_LOG_SIZE)) { + try (DownloadResultCursor cursor = new DownloadResultCursor(adapter.getDownloadLogCursor(DOWNLOAD_LOG_SIZE))) { List downloadLog = new ArrayList<>(cursor.getCount()); while (cursor.moveToNext()) { - downloadLog.add(DownloadResultCursorMapper.convert(cursor)); + downloadLog.add(cursor.getDownloadResult()); } return downloadLog; } finally { @@ -371,10 +344,11 @@ public final class DBReader { PodDBAdapter adapter = PodDBAdapter.getInstance(); adapter.open(); - try (Cursor cursor = adapter.getDownloadLog(Feed.FEEDFILETYPE_FEED, feedId)) { + try (DownloadResultCursor cursor = new DownloadResultCursor( + adapter.getDownloadLog(Feed.FEEDFILETYPE_FEED, feedId))) { List downloadLog = new ArrayList<>(cursor.getCount()); while (cursor.moveToNext()) { - downloadLog.add(DownloadResultCursorMapper.convert(cursor)); + downloadLog.add(cursor.getDownloadResult()); } return downloadLog; } finally { @@ -408,9 +382,9 @@ public final class DBReader { PodDBAdapter adapter = PodDBAdapter.getInstance(); adapter.open(); Feed feed = null; - try (Cursor cursor = adapter.getFeedCursor(feedId)) { + try (FeedCursor cursor = new FeedCursor(adapter.getFeedCursor(feedId))) { if (cursor.moveToNext()) { - feed = extractFeedFromCursorRow(cursor); + feed = cursor.getFeed(); if (filtered) { feed.setItems(getFeedItemList(feed, feed.getItemFilter())); } else { @@ -430,13 +404,11 @@ public final class DBReader { Log.d(TAG, "Loading feeditem with id " + itemId); FeedItem item = null; - try (Cursor cursor = adapter.getFeedItemCursor(Long.toString(itemId))) { - if (cursor.moveToNext()) { - List list = extractItemlistFromCursor(adapter, cursor); - if (!list.isEmpty()) { - item = list.get(0); - loadAdditionalFeedItemListData(list); - } + try (FeedItemCursor cursor = new FeedItemCursor(adapter.getFeedItemCursor(Long.toString(itemId)))) { + List list = extractItemlistFromCursor(cursor); + if (!list.isEmpty()) { + item = list.get(0); + loadAdditionalFeedItemListData(list); } return item; } @@ -473,18 +445,16 @@ public final class DBReader { Log.d(TAG, "getNextInQueue() called with: " + "itemId = [" + item.getId() + "]"); PodDBAdapter adapter = PodDBAdapter.getInstance(); adapter.open(); - try { - FeedItem nextItem = null; - try (Cursor cursor = adapter.getNextInQueue(item)) { - List list = extractItemlistFromCursor(adapter, cursor); - if (!list.isEmpty()) { - nextItem = list.get(0); - loadAdditionalFeedItemListData(list); - } + try (FeedItemCursor cursor = new FeedItemCursor(adapter.getNextInQueue(item))) { + List list = extractItemlistFromCursor(cursor); + if (!list.isEmpty()) { + FeedItem nextItem = list.get(0); + loadAdditionalFeedItemListData(list); return nextItem; - } catch (Exception e) { - return null; } + return null; + } catch (Exception e) { + return null; } finally { adapter.close(); } @@ -494,8 +464,8 @@ public final class DBReader { public static List getPausedQueue(int limit) { PodDBAdapter adapter = PodDBAdapter.getInstance(); adapter.open(); - try (Cursor cursor = adapter.getPausedQueueCursor(limit)) { - List items = extractItemlistFromCursor(adapter, cursor); + try (FeedItemCursor cursor = new FeedItemCursor(adapter.getPausedQueueCursor(limit))) { + List items = extractItemlistFromCursor(cursor); loadAdditionalFeedItemListData(items); return items; } finally { @@ -514,11 +484,8 @@ public final class DBReader { @Nullable private static FeedItem getFeedItemByGuidOrEpisodeUrl(final String guid, final String episodeUrl, PodDBAdapter adapter) { - try (Cursor cursor = adapter.getFeedItemCursor(guid, episodeUrl)) { - if (!cursor.moveToNext()) { - return null; - } - List list = extractItemlistFromCursor(adapter, cursor); + try (FeedItemCursor cursor = new FeedItemCursor(adapter.getFeedItemCursor(guid, episodeUrl))) { + List list = extractItemlistFromCursor(cursor); if (!list.isEmpty()) { return list.get(0); } @@ -584,7 +551,7 @@ public final class DBReader { } private static List loadChaptersOfFeedItem(PodDBAdapter adapter, FeedItem item) { - try (Cursor cursor = adapter.getSimpleChaptersOfFeedItemCursor(item)) { + try (ChapterCursor cursor = new ChapterCursor(adapter.getSimpleChaptersOfFeedItemCursor(item))) { int chaptersCount = cursor.getCount(); if (chaptersCount == 0) { item.setChapters(null); @@ -592,7 +559,7 @@ public final class DBReader { } ArrayList chapters = new ArrayList<>(); while (cursor.moveToNext()) { - chapters.add(ChapterCursorMapper.convert(cursor)); + chapters.add(cursor.getChapter()); } return chapters; } @@ -609,14 +576,14 @@ public final class DBReader { PodDBAdapter adapter = PodDBAdapter.getInstance(); adapter.open(); - try (Cursor mediaCursor = adapter.getSingleFeedMediaCursor(mediaId)) { + try (FeedMediaCursor mediaCursor = new FeedMediaCursor(adapter.getSingleFeedMediaCursor(mediaId))) { if (!mediaCursor.moveToFirst()) { return null; } int indexFeedItem = mediaCursor.getColumnIndex(PodDBAdapter.KEY_FEEDITEM); long itemId = mediaCursor.getLong(indexFeedItem); - FeedMedia media = FeedMediaCursorMapper.convert(mediaCursor); + FeedMedia media = mediaCursor.getFeedMedia(); FeedItem item = getFeedItem(itemId); if (item != null) { media.setItem(item); @@ -631,8 +598,8 @@ public final class DBReader { public static List getFeedItemsWithUrl(List urls) { PodDBAdapter adapter = PodDBAdapter.getInstance(); adapter.open(); - try (Cursor itemCursor = adapter.getFeedItemCursorByUrl(urls)) { - List items = extractItemlistFromCursor(adapter, itemCursor); + try (FeedItemCursor itemCursor = new FeedItemCursor(adapter.getFeedItemCursorByUrl(urls))) { + List items = extractItemlistFromCursor(itemCursor); loadAdditionalFeedItemListData(items); return items; } finally { @@ -708,7 +675,8 @@ public final class DBReader { adapter.open(); StatisticsResult result = new StatisticsResult(); - try (Cursor cursor = adapter.getFeedStatisticsCursor(includeMarkedAsPlayed, timeFilterFrom, timeFilterTo)) { + try (FeedCursor cursor = new FeedCursor(adapter.getFeedStatisticsCursor( + includeMarkedAsPlayed, timeFilterFrom, timeFilterTo))) { int indexOldestDate = cursor.getColumnIndexOrThrow("oldest_date"); int indexNumEpisodes = cursor.getColumnIndexOrThrow("num_episodes"); int indexEpisodesStarted = cursor.getColumnIndexOrThrow("episodes_started"); @@ -718,7 +686,7 @@ public final class DBReader { int indexDownloadSize = cursor.getColumnIndexOrThrow("download_size"); while (cursor.moveToNext()) { - Feed feed = extractFeedFromCursorRow(cursor); + Feed feed = cursor.getFeed(); long feedPlayedTime = Long.parseLong(cursor.getString(indexPlayedTime)) / 1000; long feedTotalTime = Long.parseLong(cursor.getString(indexTotalTime)) / 1000; @@ -860,7 +828,7 @@ public final class DBReader { public static List searchFeedItems(final long feedId, final String query) { PodDBAdapter adapter = PodDBAdapter.getInstance().open(); - Cursor searchResult = adapter.searchItems(feedId, query); + FeedItemCursor searchResult = new FeedItemCursor(adapter.searchItems(feedId, query)); List items = extractItemlistFromCursor(searchResult); loadAdditionalFeedItemListData(items); searchResult.close(); @@ -870,15 +838,14 @@ public final class DBReader { public static List searchFeeds(final String query) { PodDBAdapter adapter = PodDBAdapter.getInstance(); - Cursor cursor = adapter.searchFeeds(query); - List items = new ArrayList<>(); - if (cursor.moveToFirst()) { - do { - items.add(FeedCursorMapper.convert(cursor)); - } while (cursor.moveToNext()); - } - cursor.close(); - adapter.close(); - return items; + try (FeedCursor cursor = new FeedCursor(adapter.searchFeeds(query))) { + List items = new ArrayList<>(); + while (cursor.moveToNext()) { + items.add(cursor.getFeed()); + } + return items; + } finally { + adapter.close(); + } } } diff --git a/storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/ChapterCursor.java b/storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/ChapterCursor.java new file mode 100644 index 000000000..fbdc5a297 --- /dev/null +++ b/storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/ChapterCursor.java @@ -0,0 +1,41 @@ +package de.danoeh.antennapod.storage.database.mapper; + +import android.database.Cursor; +import android.database.CursorWrapper; +import androidx.annotation.NonNull; +import de.danoeh.antennapod.model.feed.Chapter; +import de.danoeh.antennapod.storage.database.PodDBAdapter; + +/** + * Converts a {@link Cursor} to a {@link Chapter} object. + */ +public class ChapterCursor extends CursorWrapper { + private final int indexId; + private final int indexTitle; + private final int indexStart; + private final int indexLink; + private final int indexImage; + + public ChapterCursor(Cursor cursor) { + super(cursor); + indexId = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_ID); + indexTitle = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_TITLE); + indexStart = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_START); + indexLink = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_LINK); + indexImage = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_IMAGE_URL); + } + + /** + * Create a {@link Chapter} instance from a database row (cursor). + */ + @NonNull + public Chapter getChapter() { + Chapter chapter = new Chapter( + getLong(indexStart), + getString(indexTitle), + getString(indexLink), + getString(indexImage)); + chapter.setId(getLong(indexId)); + return chapter; + } +} diff --git a/storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/ChapterCursorMapper.java b/storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/ChapterCursorMapper.java deleted file mode 100644 index b48a7f9d1..000000000 --- a/storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/ChapterCursorMapper.java +++ /dev/null @@ -1,32 +0,0 @@ -package de.danoeh.antennapod.storage.database.mapper; - -import android.database.Cursor; -import androidx.annotation.NonNull; -import de.danoeh.antennapod.model.feed.Chapter; -import de.danoeh.antennapod.storage.database.PodDBAdapter; - -/** - * Converts a {@link Cursor} to a {@link Chapter} object. - */ -public abstract class ChapterCursorMapper { - /** - * Create a {@link Chapter} instance from a database row (cursor). - */ - @NonNull - public static Chapter convert(@NonNull Cursor cursor) { - int indexId = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_ID); - int indexTitle = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_TITLE); - int indexStart = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_START); - int indexLink = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_LINK); - int indexImage = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_IMAGE_URL); - - long id = cursor.getLong(indexId); - String title = cursor.getString(indexTitle); - long start = cursor.getLong(indexStart); - String link = cursor.getString(indexLink); - String imageUrl = cursor.getString(indexImage); - Chapter chapter = new Chapter(start, title, link, imageUrl); - chapter.setId(id); - return chapter; - } -} diff --git a/storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/DownloadResultCursor.java b/storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/DownloadResultCursor.java new file mode 100644 index 000000000..8804ac09d --- /dev/null +++ b/storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/DownloadResultCursor.java @@ -0,0 +1,52 @@ +package de.danoeh.antennapod.storage.database.mapper; + +import android.database.Cursor; +import android.database.CursorWrapper; +import androidx.annotation.NonNull; +import de.danoeh.antennapod.model.download.DownloadResult; +import de.danoeh.antennapod.model.download.DownloadError; +import de.danoeh.antennapod.storage.database.PodDBAdapter; + +import java.util.Date; + +/** + * Converts a {@link Cursor} to a {@link DownloadResult} object. + */ +public class DownloadResultCursor extends CursorWrapper { + private final int indexId; + private final int indexTitle; + private final int indexFeedFile; + private final int indexFileFileType; + private final int indexSuccessful; + private final int indexReason; + private final int indexCompletionDate; + private final int indexReasonDetailed; + + public DownloadResultCursor(Cursor cursor) { + super(cursor); + indexId = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_ID); + indexTitle = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_DOWNLOADSTATUS_TITLE); + indexFeedFile = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_FEEDFILE); + indexFileFileType = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_FEEDFILETYPE); + indexSuccessful = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_SUCCESSFUL); + indexReason = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_REASON); + indexCompletionDate = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_COMPLETION_DATE); + indexReasonDetailed = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_REASON_DETAILED); + } + + /** + * Create a {@link DownloadResult} instance from a database row (cursor). + */ + @NonNull + public DownloadResult getDownloadResult() { + return new DownloadResult( + getLong(indexId), + getString(indexTitle), + getLong(indexFeedFile), + getInt(indexFileFileType), + getInt(indexSuccessful) > 0, + DownloadError.fromCode(getInt(indexReason)), + new Date(getLong(indexCompletionDate)), + getString(indexReasonDetailed)); + } +} diff --git a/storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/DownloadResultCursorMapper.java b/storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/DownloadResultCursorMapper.java deleted file mode 100644 index d8f40d6a3..000000000 --- a/storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/DownloadResultCursorMapper.java +++ /dev/null @@ -1,35 +0,0 @@ -package de.danoeh.antennapod.storage.database.mapper; - -import android.database.Cursor; -import androidx.annotation.NonNull; -import de.danoeh.antennapod.model.download.DownloadResult; -import de.danoeh.antennapod.model.download.DownloadError; -import de.danoeh.antennapod.storage.database.PodDBAdapter; - -import java.util.Date; - -/** - * Converts a {@link Cursor} to a {@link DownloadResult} object. - */ -public abstract class DownloadResultCursorMapper { - /** - * Create a {@link DownloadResult} instance from a database row (cursor). - */ - @NonNull - public static DownloadResult convert(@NonNull Cursor cursor) { - int indexId = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_ID); - int indexTitle = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_DOWNLOADSTATUS_TITLE); - int indexFeedFile = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_FEEDFILE); - int indexFileFileType = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_FEEDFILETYPE); - int indexSuccessful = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_SUCCESSFUL); - int indexReason = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_REASON); - int indexCompletionDate = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_COMPLETION_DATE); - int indexReasonDetailed = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_REASON_DETAILED); - - return new DownloadResult(cursor.getLong(indexId), cursor.getString(indexTitle), cursor.getLong(indexFeedFile), - cursor.getInt(indexFileFileType), cursor.getInt(indexSuccessful) > 0, - DownloadError.fromCode(cursor.getInt(indexReason)), - new Date(cursor.getLong(indexCompletionDate)), - cursor.getString(indexReasonDetailed)); - } -} diff --git a/storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/FeedCursor.java b/storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/FeedCursor.java new file mode 100644 index 000000000..2707275ca --- /dev/null +++ b/storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/FeedCursor.java @@ -0,0 +1,92 @@ +package de.danoeh.antennapod.storage.database.mapper; + +import android.database.Cursor; + +import android.database.CursorWrapper; +import androidx.annotation.NonNull; + +import de.danoeh.antennapod.model.feed.Feed; +import de.danoeh.antennapod.model.feed.SortOrder; +import de.danoeh.antennapod.storage.database.PodDBAdapter; + +/** + * Converts a {@link Cursor} to a {@link Feed} object. + */ +public class FeedCursor extends CursorWrapper { + private final FeedPreferencesCursor preferencesCursor; + private final int indexId; + private final int indexLastUpdate; + private final int indexTitle; + private final int indexCustomTitle; + private final int indexLink; + private final int indexDescription; + private final int indexPaymentLink; + private final int indexAuthor; + private final int indexLanguage; + private final int indexType; + private final int indexFeedIdentifier; + private final int indexFileUrl; + private final int indexDownloadUrl; + private final int indexLastRefreshed; + private final int indexIsPaged; + private final int indexNextPageLink; + private final int indexHide; + private final int indexSortOrder; + private final int indexLastUpdateFailed; + private final int indexImageUrl; + + public FeedCursor(Cursor cursor) { + super(new FeedPreferencesCursor(cursor)); + preferencesCursor = (FeedPreferencesCursor) getWrappedCursor(); + indexId = cursor.getColumnIndexOrThrow(PodDBAdapter.SELECT_KEY_FEED_ID); + indexLastUpdate = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_LASTUPDATE); + indexTitle = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_TITLE); + indexCustomTitle = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_CUSTOM_TITLE); + indexLink = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_LINK); + indexDescription = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_DESCRIPTION); + indexPaymentLink = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_PAYMENT_LINK); + indexAuthor = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_AUTHOR); + indexLanguage = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_LANGUAGE); + indexType = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_TYPE); + indexFeedIdentifier = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_FEED_IDENTIFIER); + indexFileUrl = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_FILE_URL); + indexDownloadUrl = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_DOWNLOAD_URL); + indexLastRefreshed = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_LAST_REFRESH_ATTEMPT); + indexIsPaged = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_IS_PAGED); + indexNextPageLink = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_NEXT_PAGE_LINK); + indexHide = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_HIDE); + indexSortOrder = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_SORT_ORDER); + indexLastUpdateFailed = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_LAST_UPDATE_FAILED); + indexImageUrl = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_IMAGE_URL); + } + + /** + * Create a {@link Feed} instance from the current database row. + */ + @NonNull + public Feed getFeed() { + Feed feed = new Feed( + getLong(indexId), + getString(indexLastUpdate), + getString(indexTitle), + getString(indexCustomTitle), + getString(indexLink), + getString(indexDescription), + getString(indexPaymentLink), + getString(indexAuthor), + getString(indexLanguage), + getString(indexType), + getString(indexFeedIdentifier), + getString(indexImageUrl), + getString(indexFileUrl), + getString(indexDownloadUrl), + getLong(indexLastRefreshed), + getInt(indexIsPaged) > 0, + getString(indexNextPageLink), + getString(indexHide), + SortOrder.fromCodeString(getString(indexSortOrder)), + getInt(indexLastUpdateFailed) > 0); + feed.setPreferences(preferencesCursor.getFeedPreferences()); + return feed; + } +} diff --git a/storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/FeedCursorMapper.java b/storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/FeedCursorMapper.java deleted file mode 100644 index f7be7009f..000000000 --- a/storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/FeedCursorMapper.java +++ /dev/null @@ -1,70 +0,0 @@ -package de.danoeh.antennapod.storage.database.mapper; - -import android.database.Cursor; - -import androidx.annotation.NonNull; - -import de.danoeh.antennapod.model.feed.Feed; -import de.danoeh.antennapod.model.feed.FeedPreferences; -import de.danoeh.antennapod.model.feed.SortOrder; -import de.danoeh.antennapod.storage.database.PodDBAdapter; - -/** - * Converts a {@link Cursor} to a {@link Feed} object. - */ -public abstract class FeedCursorMapper { - - /** - * Create a {@link Feed} instance from a database row (cursor). - */ - @NonNull - public static Feed convert(@NonNull Cursor cursor) { - int indexId = cursor.getColumnIndexOrThrow(PodDBAdapter.SELECT_KEY_FEED_ID); - int indexLastUpdate = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_LASTUPDATE); - int indexTitle = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_TITLE); - int indexCustomTitle = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_CUSTOM_TITLE); - int indexLink = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_LINK); - int indexDescription = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_DESCRIPTION); - int indexPaymentLink = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_PAYMENT_LINK); - int indexAuthor = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_AUTHOR); - int indexLanguage = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_LANGUAGE); - int indexType = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_TYPE); - int indexFeedIdentifier = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_FEED_IDENTIFIER); - int indexFileUrl = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_FILE_URL); - int indexDownloadUrl = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_DOWNLOAD_URL); - int indexLastRefreshed = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_LAST_REFRESH_ATTEMPT); - int indexIsPaged = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_IS_PAGED); - int indexNextPageLink = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_NEXT_PAGE_LINK); - int indexHide = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_HIDE); - int indexSortOrder = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_SORT_ORDER); - int indexLastUpdateFailed = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_LAST_UPDATE_FAILED); - int indexImageUrl = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_IMAGE_URL); - - Feed feed = new Feed( - cursor.getLong(indexId), - cursor.getString(indexLastUpdate), - cursor.getString(indexTitle), - cursor.getString(indexCustomTitle), - cursor.getString(indexLink), - cursor.getString(indexDescription), - cursor.getString(indexPaymentLink), - cursor.getString(indexAuthor), - cursor.getString(indexLanguage), - cursor.getString(indexType), - cursor.getString(indexFeedIdentifier), - cursor.getString(indexImageUrl), - cursor.getString(indexFileUrl), - cursor.getString(indexDownloadUrl), - cursor.getLong(indexLastRefreshed), - cursor.getInt(indexIsPaged) > 0, - cursor.getString(indexNextPageLink), - cursor.getString(indexHide), - SortOrder.fromCodeString(cursor.getString(indexSortOrder)), - cursor.getInt(indexLastUpdateFailed) > 0 - ); - - FeedPreferences preferences = FeedPreferencesCursorMapper.convert(cursor); - feed.setPreferences(preferences); - return feed; - } -} diff --git a/storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/FeedItemCursor.java b/storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/FeedItemCursor.java new file mode 100644 index 000000000..d526299e4 --- /dev/null +++ b/storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/FeedItemCursor.java @@ -0,0 +1,71 @@ +package de.danoeh.antennapod.storage.database.mapper; + +import android.database.Cursor; +import android.database.CursorWrapper; +import androidx.annotation.NonNull; +import de.danoeh.antennapod.model.feed.FeedItem; +import de.danoeh.antennapod.storage.database.PodDBAdapter; + +import java.util.Date; + +/** + * Converts a {@link Cursor} to a {@link FeedItem} object. + */ +public class FeedItemCursor extends CursorWrapper { + private final FeedMediaCursor feedMediaCursor; + private final int indexId; + private final int indexTitle; + private final int indexLink; + private final int indexPubDate; + private final int indexPaymentLink; + private final int indexFeedId; + private final int indexHasChapters; + private final int indexRead; + private final int indexItemIdentifier; + private final int indexAutoDownload; + private final int indexImageUrl; + private final int indexPodcastIndexChapterUrl; + private final int indexMediaId; + + public FeedItemCursor(Cursor cursor) { + super(new FeedMediaCursor(cursor)); + feedMediaCursor = (FeedMediaCursor) getWrappedCursor(); + indexId = cursor.getColumnIndexOrThrow(PodDBAdapter.SELECT_KEY_ITEM_ID); + indexTitle = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_TITLE); + indexLink = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_LINK); + indexPubDate = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_PUBDATE); + indexPaymentLink = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_PAYMENT_LINK); + indexFeedId = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_FEED); + indexHasChapters = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_HAS_CHAPTERS); + indexRead = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_READ); + indexItemIdentifier = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_ITEM_IDENTIFIER); + indexAutoDownload = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_AUTO_DOWNLOAD_ENABLED); + indexImageUrl = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_IMAGE_URL); + indexPodcastIndexChapterUrl = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_PODCASTINDEX_CHAPTER_URL); + indexMediaId = cursor.getColumnIndexOrThrow(PodDBAdapter.SELECT_KEY_MEDIA_ID); + } + + /** + * Create a {@link FeedItem} instance from a database row (cursor). + */ + @NonNull + public FeedItem getFeedItem() { + FeedItem item = new FeedItem( + getInt(indexId), + getString(indexTitle), + getString(indexLink), + new Date(getLong(indexPubDate)), + getString(indexPaymentLink), + getLong(indexFeedId), + getInt(indexHasChapters) > 0, + getString(indexImageUrl), + getInt(indexRead), + getString(indexItemIdentifier), + getLong(indexAutoDownload) > 0, + getString(indexPodcastIndexChapterUrl)); + if (!isNull(indexMediaId)) { + item.setMedia(feedMediaCursor.getFeedMedia()); + } + return item; + } +} diff --git a/storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/FeedItemCursorMapper.java b/storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/FeedItemCursorMapper.java deleted file mode 100644 index c2c9b89d4..000000000 --- a/storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/FeedItemCursorMapper.java +++ /dev/null @@ -1,48 +0,0 @@ -package de.danoeh.antennapod.storage.database.mapper; - -import android.database.Cursor; -import androidx.annotation.NonNull; -import de.danoeh.antennapod.model.feed.FeedItem; -import de.danoeh.antennapod.storage.database.PodDBAdapter; - -import java.util.Date; - -/** - * Converts a {@link Cursor} to a {@link FeedItem} object. - */ -public abstract class FeedItemCursorMapper { - /** - * Create a {@link FeedItem} instance from a database row (cursor). - */ - @NonNull - public static FeedItem convert(@NonNull Cursor cursor) { - int indexId = cursor.getColumnIndexOrThrow(PodDBAdapter.SELECT_KEY_ITEM_ID); - int indexTitle = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_TITLE); - int indexLink = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_LINK); - int indexPubDate = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_PUBDATE); - int indexPaymentLink = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_PAYMENT_LINK); - int indexFeedId = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_FEED); - int indexHasChapters = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_HAS_CHAPTERS); - int indexRead = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_READ); - int indexItemIdentifier = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_ITEM_IDENTIFIER); - int indexAutoDownload = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_AUTO_DOWNLOAD_ENABLED); - int indexImageUrl = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_IMAGE_URL); - int indexPodcastIndexChapterUrl = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_PODCASTINDEX_CHAPTER_URL); - - long id = cursor.getInt(indexId); - String title = cursor.getString(indexTitle); - String link = cursor.getString(indexLink); - Date pubDate = new Date(cursor.getLong(indexPubDate)); - String paymentLink = cursor.getString(indexPaymentLink); - long feedId = cursor.getLong(indexFeedId); - boolean hasChapters = cursor.getInt(indexHasChapters) > 0; - int state = cursor.getInt(indexRead); - String itemIdentifier = cursor.getString(indexItemIdentifier); - boolean autoDownloadEnabled = cursor.getLong(indexAutoDownload) > 0; - String imageUrl = cursor.getString(indexImageUrl); - String podcastIndexChapterUrl = cursor.getString(indexPodcastIndexChapterUrl); - - return new FeedItem(id, title, link, pubDate, paymentLink, feedId, - hasChapters, imageUrl, state, itemIdentifier, autoDownloadEnabled, podcastIndexChapterUrl); - } -} diff --git a/storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/FeedMediaCursor.java b/storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/FeedMediaCursor.java new file mode 100644 index 000000000..48e897c74 --- /dev/null +++ b/storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/FeedMediaCursor.java @@ -0,0 +1,81 @@ +package de.danoeh.antennapod.storage.database.mapper; + +import android.database.Cursor; +import android.database.CursorWrapper; +import androidx.annotation.NonNull; +import de.danoeh.antennapod.model.feed.FeedMedia; +import de.danoeh.antennapod.storage.database.PodDBAdapter; + +import java.util.Date; + +/** + * Converts a {@link Cursor} to a {@link FeedMedia} object. + */ +public class FeedMediaCursor extends CursorWrapper { + private final int indexId; + private final int indexPlaybackCompletionDate; + private final int indexDuration; + private final int indexPosition; + private final int indexSize; + private final int indexMimeType; + private final int indexFileUrl; + private final int indexDownloadUrl; + private final int indexDownloaded; + private final int indexPlayedDuration; + private final int indexLastPlayedTime; + private final int indexHasEmbeddedPicture; + + public FeedMediaCursor(Cursor cursor) { + super(cursor); + indexId = cursor.getColumnIndexOrThrow(PodDBAdapter.SELECT_KEY_MEDIA_ID); + indexPlaybackCompletionDate = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_PLAYBACK_COMPLETION_DATE); + indexDuration = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_DURATION); + indexPosition = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_POSITION); + indexSize = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_SIZE); + indexMimeType = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_MIME_TYPE); + indexFileUrl = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_FILE_URL); + indexDownloadUrl = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_DOWNLOAD_URL); + indexDownloaded = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_DOWNLOADED); + indexPlayedDuration = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_PLAYED_DURATION); + indexLastPlayedTime = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_LAST_PLAYED_TIME); + indexHasEmbeddedPicture = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_HAS_EMBEDDED_PICTURE); + } + + /** + * Create a {@link FeedMedia} instance from a database row (cursor). + */ + @NonNull + public FeedMedia getFeedMedia() { + long playbackCompletionTime = getLong(indexPlaybackCompletionDate); + Date playbackCompletionDate = playbackCompletionTime > 0 ? new Date(playbackCompletionTime) : null; + + Boolean hasEmbeddedPicture; + switch (getInt(indexHasEmbeddedPicture)) { + case 1: + hasEmbeddedPicture = Boolean.TRUE; + break; + case 0: + hasEmbeddedPicture = Boolean.FALSE; + break; + default: + hasEmbeddedPicture = null; + break; + } + + return new FeedMedia( + getLong(indexId), + null, + getInt(indexDuration), + getInt(indexPosition), + getLong(indexSize), + getString(indexMimeType), + getString(indexFileUrl), + getString(indexDownloadUrl), + getInt(indexDownloaded) > 0, + playbackCompletionDate, + getInt(indexPlayedDuration), + hasEmbeddedPicture, + getLong(indexLastPlayedTime) + ); + } +} diff --git a/storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/FeedMediaCursorMapper.java b/storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/FeedMediaCursorMapper.java deleted file mode 100644 index f57e91b83..000000000 --- a/storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/FeedMediaCursorMapper.java +++ /dev/null @@ -1,67 +0,0 @@ -package de.danoeh.antennapod.storage.database.mapper; - -import android.database.Cursor; -import androidx.annotation.NonNull; -import de.danoeh.antennapod.model.feed.FeedMedia; -import de.danoeh.antennapod.storage.database.PodDBAdapter; - -import java.util.Date; - -/** - * Converts a {@link Cursor} to a {@link FeedMedia} object. - */ -public abstract class FeedMediaCursorMapper { - /** - * Create a {@link FeedMedia} instance from a database row (cursor). - */ - @NonNull - public static FeedMedia convert(@NonNull Cursor cursor) { - int indexId = cursor.getColumnIndexOrThrow(PodDBAdapter.SELECT_KEY_MEDIA_ID); - int indexPlaybackCompletionDate = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_PLAYBACK_COMPLETION_DATE); - int indexDuration = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_DURATION); - int indexPosition = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_POSITION); - int indexSize = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_SIZE); - int indexMimeType = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_MIME_TYPE); - int indexFileUrl = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_FILE_URL); - int indexDownloadUrl = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_DOWNLOAD_URL); - int indexDownloaded = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_DOWNLOADED); - int indexPlayedDuration = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_PLAYED_DURATION); - int indexLastPlayedTime = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_LAST_PLAYED_TIME); - - long mediaId = cursor.getLong(indexId); - Date playbackCompletionDate = null; - long playbackCompletionTime = cursor.getLong(indexPlaybackCompletionDate); - if (playbackCompletionTime > 0) { - playbackCompletionDate = new Date(playbackCompletionTime); - } - - Boolean hasEmbeddedPicture; - switch (cursor.getInt(cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_HAS_EMBEDDED_PICTURE))) { - case 1: - hasEmbeddedPicture = Boolean.TRUE; - break; - case 0: - hasEmbeddedPicture = Boolean.FALSE; - break; - default: - hasEmbeddedPicture = null; - break; - } - - return new FeedMedia( - mediaId, - null, - cursor.getInt(indexDuration), - cursor.getInt(indexPosition), - cursor.getLong(indexSize), - cursor.getString(indexMimeType), - cursor.getString(indexFileUrl), - cursor.getString(indexDownloadUrl), - cursor.getInt(indexDownloaded) > 0, - playbackCompletionDate, - cursor.getInt(indexPlayedDuration), - hasEmbeddedPicture, - cursor.getLong(indexLastPlayedTime) - ); - } -} diff --git a/storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/FeedPreferencesCursor.java b/storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/FeedPreferencesCursor.java new file mode 100644 index 000000000..147650e15 --- /dev/null +++ b/storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/FeedPreferencesCursor.java @@ -0,0 +1,85 @@ +package de.danoeh.antennapod.storage.database.mapper; + +import android.database.Cursor; +import android.database.CursorWrapper; +import android.text.TextUtils; +import androidx.annotation.NonNull; +import de.danoeh.antennapod.model.feed.FeedFilter; +import de.danoeh.antennapod.model.feed.FeedPreferences; +import de.danoeh.antennapod.model.feed.VolumeAdaptionSetting; +import de.danoeh.antennapod.storage.database.PodDBAdapter; + +import java.util.Arrays; +import java.util.HashSet; + +/** + * Converts a {@link Cursor} to a {@link FeedPreferences} object. + */ +public class FeedPreferencesCursor extends CursorWrapper { + private final int indexId; + private final int indexAutoDownload; + private final int indexAutoRefresh; + private final int indexAutoDeleteAction; + private final int indexVolumeAdaption; + private final int indexUsername; + private final int indexPassword; + private final int indexIncludeFilter; + private final int indexExcludeFilter; + private final int indexMinimalDurationFilter; + private final int indexFeedPlaybackSpeed; + private final int indexFeedSkipSilence; + private final int indexAutoSkipIntro; + private final int indexAutoSkipEnding; + private final int indexEpisodeNotification; + private final int indexNewEpisodesAction; + private final int indexTags; + + public FeedPreferencesCursor(Cursor cursor) { + super(cursor); + indexId = cursor.getColumnIndexOrThrow(PodDBAdapter.SELECT_KEY_FEED_ID); + indexAutoDownload = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_AUTO_DOWNLOAD_ENABLED); + indexAutoRefresh = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_KEEP_UPDATED); + indexAutoDeleteAction = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_AUTO_DELETE_ACTION); + indexVolumeAdaption = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_FEED_VOLUME_ADAPTION); + indexUsername = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_USERNAME); + indexPassword = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_PASSWORD); + indexIncludeFilter = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_INCLUDE_FILTER); + indexExcludeFilter = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_EXCLUDE_FILTER); + indexMinimalDurationFilter = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_MINIMAL_DURATION_FILTER); + indexFeedPlaybackSpeed = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_FEED_PLAYBACK_SPEED); + indexFeedSkipSilence = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_FEED_SKIP_SILENCE); + indexAutoSkipIntro = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_FEED_SKIP_INTRO); + indexAutoSkipEnding = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_FEED_SKIP_ENDING); + indexEpisodeNotification = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_EPISODE_NOTIFICATION); + indexNewEpisodesAction = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_NEW_EPISODES_ACTION); + indexTags = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_FEED_TAGS); + } + + /** + * Create a {@link FeedPreferences} instance from a database row (cursor). + */ + @NonNull + public FeedPreferences getFeedPreferences() { + String tagsString = getString(indexTags); + if (TextUtils.isEmpty(tagsString)) { + tagsString = FeedPreferences.TAG_ROOT; + } + return new FeedPreferences( + getLong(indexId), + getInt(indexAutoDownload) > 0, + getInt(indexAutoRefresh) > 0, + FeedPreferences.AutoDeleteAction.fromCode(getInt(indexAutoDeleteAction)), + VolumeAdaptionSetting.fromInteger(getInt(indexVolumeAdaption)), + getString(indexUsername), + getString(indexPassword), + new FeedFilter(getString(indexIncludeFilter), + getString(indexExcludeFilter), getInt(indexMinimalDurationFilter)), + getFloat(indexFeedPlaybackSpeed), + getInt(indexAutoSkipIntro), + getInt(indexAutoSkipEnding), + FeedPreferences.SkipSilence.fromCode(getInt(indexFeedSkipSilence)), + getInt(indexEpisodeNotification) > 0, + FeedPreferences.NewEpisodesAction.fromCode(getInt(indexNewEpisodesAction)), + new HashSet<>(Arrays.asList(tagsString.split(FeedPreferences.TAG_SEPARATOR)))); + } +} diff --git a/storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/FeedPreferencesCursorMapper.java b/storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/FeedPreferencesCursorMapper.java deleted file mode 100644 index 83b62b8a3..000000000 --- a/storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/FeedPreferencesCursorMapper.java +++ /dev/null @@ -1,82 +0,0 @@ -package de.danoeh.antennapod.storage.database.mapper; - -import android.database.Cursor; -import android.text.TextUtils; -import androidx.annotation.NonNull; -import de.danoeh.antennapod.model.feed.FeedFilter; -import de.danoeh.antennapod.model.feed.FeedPreferences; -import de.danoeh.antennapod.model.feed.VolumeAdaptionSetting; -import de.danoeh.antennapod.storage.database.PodDBAdapter; - -import java.util.Arrays; -import java.util.HashSet; - -/** - * Converts a {@link Cursor} to a {@link FeedPreferences} object. - */ -public abstract class FeedPreferencesCursorMapper { - /** - * Create a {@link FeedPreferences} instance from a database row (cursor). - */ - @NonNull - public static FeedPreferences convert(@NonNull Cursor cursor) { - int indexId = cursor.getColumnIndexOrThrow(PodDBAdapter.SELECT_KEY_FEED_ID); - int indexAutoDownload = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_AUTO_DOWNLOAD_ENABLED); - int indexAutoRefresh = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_KEEP_UPDATED); - int indexAutoDeleteAction = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_AUTO_DELETE_ACTION); - int indexVolumeAdaption = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_FEED_VOLUME_ADAPTION); - int indexUsername = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_USERNAME); - int indexPassword = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_PASSWORD); - int indexIncludeFilter = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_INCLUDE_FILTER); - int indexExcludeFilter = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_EXCLUDE_FILTER); - int indexMinimalDurationFilter = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_MINIMAL_DURATION_FILTER); - int indexFeedPlaybackSpeed = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_FEED_PLAYBACK_SPEED); - int indexFeedSkipSilence = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_FEED_SKIP_SILENCE); - int indexAutoSkipIntro = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_FEED_SKIP_INTRO); - int indexAutoSkipEnding = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_FEED_SKIP_ENDING); - int indexEpisodeNotification = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_EPISODE_NOTIFICATION); - int indexNewEpisodesAction = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_NEW_EPISODES_ACTION); - int indexTags = cursor.getColumnIndexOrThrow(PodDBAdapter.KEY_FEED_TAGS); - - long feedId = cursor.getLong(indexId); - boolean autoDownload = cursor.getInt(indexAutoDownload) > 0; - boolean autoRefresh = cursor.getInt(indexAutoRefresh) > 0; - FeedPreferences.AutoDeleteAction autoDeleteAction = - FeedPreferences.AutoDeleteAction.fromCode(cursor.getInt(indexAutoDeleteAction)); - int volumeAdaptionValue = cursor.getInt(indexVolumeAdaption); - VolumeAdaptionSetting volumeAdaptionSetting = VolumeAdaptionSetting.fromInteger(volumeAdaptionValue); - String username = cursor.getString(indexUsername); - String password = cursor.getString(indexPassword); - String includeFilter = cursor.getString(indexIncludeFilter); - String excludeFilter = cursor.getString(indexExcludeFilter); - int minimalDurationFilter = cursor.getInt(indexMinimalDurationFilter); - float feedPlaybackSpeed = cursor.getFloat(indexFeedPlaybackSpeed); - int feedAutoSkipIntro = cursor.getInt(indexAutoSkipIntro); - int feedAutoSkipEnding = cursor.getInt(indexAutoSkipEnding); - FeedPreferences.SkipSilence feedSkipSilence = - FeedPreferences.SkipSilence.fromCode(cursor.getInt(indexFeedSkipSilence)); - FeedPreferences.NewEpisodesAction feedNewEpisodesAction = - FeedPreferences.NewEpisodesAction.fromCode(cursor.getInt(indexNewEpisodesAction)); - boolean showNotification = cursor.getInt(indexEpisodeNotification) > 0; - String tagsString = cursor.getString(indexTags); - if (TextUtils.isEmpty(tagsString)) { - tagsString = FeedPreferences.TAG_ROOT; - } - - return new FeedPreferences(feedId, - autoDownload, - autoRefresh, - autoDeleteAction, - volumeAdaptionSetting, - username, - password, - new FeedFilter(includeFilter, excludeFilter, minimalDurationFilter), - feedPlaybackSpeed, - feedAutoSkipIntro, - feedAutoSkipEnding, - feedSkipSilence, - showNotification, - feedNewEpisodesAction, - new HashSet<>(Arrays.asList(tagsString.split(FeedPreferences.TAG_SEPARATOR)))); - } -} diff --git a/storage/database/src/test/java/de/danoeh/antennapod/storage/database/mapper/FeedCursorMapperTest.java b/storage/database/src/test/java/de/danoeh/antennapod/storage/database/mapper/FeedCursorMapperTest.java index 5e7a4843e..2e1697c9f 100644 --- a/storage/database/src/test/java/de/danoeh/antennapod/storage/database/mapper/FeedCursorMapperTest.java +++ b/storage/database/src/test/java/de/danoeh/antennapod/storage/database/mapper/FeedCursorMapperTest.java @@ -2,7 +2,6 @@ package de.danoeh.antennapod.storage.database.mapper; import android.content.ContentValues; import android.content.Context; -import android.database.Cursor; import androidx.test.platform.app.InstrumentationRegistry; @@ -40,9 +39,9 @@ public class FeedCursorMapperTest { @SuppressWarnings("ConstantConditions") @Test public void testFromCursor() { - try (Cursor cursor = adapter.getAllFeedsCursor()) { + try (FeedCursor cursor = new FeedCursor(adapter.getAllFeedsCursor())) { cursor.moveToNext(); - Feed feed = FeedCursorMapper.convert(cursor); + Feed feed = cursor.getFeed(); assertTrue(feed.getId() >= 0); assertEquals("feed custom title", feed.getTitle()); assertEquals("feed custom title", feed.getCustomTitle()); -- cgit v1.2.3