From beda074e5f7622455687949d17fc73121432e324 Mon Sep 17 00:00:00 2001 From: daniel oeh Date: Wed, 1 May 2013 11:56:46 +0200 Subject: Added DBReader-methods --- src/de/danoeh/antennapod/storage/DBReader.java | 373 +++++++++++++++++++-- src/de/danoeh/antennapod/storage/PodDBAdapter.java | 74 ++-- 2 files changed, 407 insertions(+), 40 deletions(-) (limited to 'src/de/danoeh/antennapod/storage') diff --git a/src/de/danoeh/antennapod/storage/DBReader.java b/src/de/danoeh/antennapod/storage/DBReader.java index 12502923e..3550aa6a2 100644 --- a/src/de/danoeh/antennapod/storage/DBReader.java +++ b/src/de/danoeh/antennapod/storage/DBReader.java @@ -1,56 +1,391 @@ package de.danoeh.antennapod.storage; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; import java.util.List; +import android.content.Context; +import android.database.Cursor; +import android.database.SQLException; +import android.util.Log; +import de.danoeh.antennapod.AppConfig; import de.danoeh.antennapod.asynctask.DownloadStatus; +import de.danoeh.antennapod.feed.Chapter; import de.danoeh.antennapod.feed.Feed; +import de.danoeh.antennapod.feed.FeedImage; import de.danoeh.antennapod.feed.FeedItem; import de.danoeh.antennapod.feed.FeedMedia; +import de.danoeh.antennapod.feed.ID3Chapter; +import de.danoeh.antennapod.feed.SimpleChapter; +import de.danoeh.antennapod.feed.VorbisCommentChapter; +import de.danoeh.antennapod.util.comparator.DownloadStatusComparator; +import de.danoeh.antennapod.util.comparator.FeedItemPubdateComparator; public final class DBReader { private static final String TAG = "DBReader"; - + private DBReader() { } - public static List getFeedList() { - return null; + public static List getFeedList(final Context context) { + if (AppConfig.DEBUG) + Log.d(TAG, "Extracting Feedlist"); + + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + + Cursor feedlistCursor = adapter.getAllFeedsCursor(); + List feeds = new ArrayList(feedlistCursor.getCount()); + + if (feedlistCursor.moveToFirst()) { + do { + Feed feed = extractFeedFromCursorRow(adapter, feedlistCursor); + feeds.add(feed); + } while (feedlistCursor.moveToNext()); + } + feedlistCursor.close(); + return feeds; } - public static List getFeedItemList(long feedId) { - return null; + public static void loadFeedDataOfFeedItemlist(Context context, + List items) { + List feeds = getFeedList(context); + for (FeedItem item : items) { + for (Feed feed : feeds) { + if (feed.getId() == item.getFeedId()) { + item.setFeed(feed); + break; + } + } + } } - public static List getQueue() { - return null; + public static List getFeedItemList(Context context, + final Feed feed) { + if (AppConfig.DEBUG) + Log.d(TAG, "Extracting Feeditems of feed " + feed.getTitle()); + + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + + Cursor itemlistCursor = adapter.getAllItemsOfFeedCursor(feed); + List items = extractItemlistFromCursor(adapter, + itemlistCursor); + itemlistCursor.close(); + + Collections.sort(items, new FeedItemPubdateComparator()); + + adapter.close(); + + for (FeedItem item : items) { + item.setFeed(feed); + } + + return items; } - public static List getUnreadItemsList() { - return null; + private static List extractItemlistFromCursor( + PodDBAdapter adapter, Cursor itemlistCursor) { + ArrayList mediaIds = new ArrayList(); + List items = new ArrayList( + itemlistCursor.getCount()); + + if (itemlistCursor.moveToFirst()) { + do { + FeedItem item = new FeedItem(); + + item.setId(itemlistCursor.getLong(PodDBAdapter.IDX_FI_SMALL_ID)); + item.setTitle(itemlistCursor + .getString(PodDBAdapter.IDX_FI_SMALL_TITLE)); + item.setLink(itemlistCursor + .getString(PodDBAdapter.IDX_FI_SMALL_LINK)); + item.setPubDate(new Date(itemlistCursor + .getLong(PodDBAdapter.IDX_FI_SMALL_PUBDATE))); + item.setPaymentLink(itemlistCursor + .getString(PodDBAdapter.IDX_FI_SMALL_PAYMENT_LINK)); + item.setFeedId(itemlistCursor + .getLong(PodDBAdapter.IDX_FI_SMALL_FEED)); + long mediaId = itemlistCursor + .getLong(PodDBAdapter.IDX_FI_SMALL_MEDIA); + if (mediaId != 0) { + mediaIds.add(String.valueOf(mediaId)); + item.setMedia(new FeedMedia(mediaId, item)); + } + item.setRead((itemlistCursor + .getInt(PodDBAdapter.IDX_FI_SMALL_READ) > 0) ? true + : false); + item.setItemIdentifier(itemlistCursor + .getString(PodDBAdapter.IDX_FI_SMALL_ITEM_IDENTIFIER)); + + // extract chapters + boolean hasSimpleChapters = itemlistCursor + .getInt(PodDBAdapter.IDX_FI_SMALL_HAS_CHAPTERS) > 0; + if (hasSimpleChapters) { + Cursor chapterCursor = adapter + .getSimpleChaptersOfFeedItemCursor(item); + if (chapterCursor.moveToFirst()) { + item.setChapters(new ArrayList()); + do { + int chapterType = chapterCursor + .getInt(PodDBAdapter.KEY_CHAPTER_TYPE_INDEX); + Chapter chapter = null; + long start = chapterCursor + .getLong(PodDBAdapter.KEY_CHAPTER_START_INDEX); + String title = chapterCursor + .getString(PodDBAdapter.KEY_TITLE_INDEX); + String link = chapterCursor + .getString(PodDBAdapter.KEY_CHAPTER_LINK_INDEX); + + switch (chapterType) { + case SimpleChapter.CHAPTERTYPE_SIMPLECHAPTER: + chapter = new SimpleChapter(start, title, item, + link); + break; + case ID3Chapter.CHAPTERTYPE_ID3CHAPTER: + chapter = new ID3Chapter(start, title, item, + link); + break; + case VorbisCommentChapter.CHAPTERTYPE_VORBISCOMMENT_CHAPTER: + chapter = new VorbisCommentChapter(start, + title, item, link); + break; + } + chapter.setId(chapterCursor + .getLong(PodDBAdapter.KEY_ID_INDEX)); + item.getChapters().add(chapter); + } while (chapterCursor.moveToNext()); + } + chapterCursor.close(); + } + items.add(item); + } while (itemlistCursor.moveToNext()); + } + + extractMediafromItemlist(adapter, items, mediaIds); + Collections.sort(items, new FeedItemPubdateComparator()); + return items; } - public static List getPlaybackHistory() { - return null; + private static void extractMediafromItemlist(PodDBAdapter adapter, + List items, ArrayList mediaIds) { + + List itemsCopy = new ArrayList(items); + Cursor cursor = adapter.getFeedMediaCursor(mediaIds + .toArray(new String[mediaIds.size()])); + if (cursor.moveToFirst()) { + do { + long mediaId = cursor.getLong(PodDBAdapter.KEY_ID_INDEX); + // find matching feed item + FeedItem item = getMatchingItemForMedia(mediaId, itemsCopy); + itemsCopy.remove(item); + if (item != null) { + Date playbackCompletionDate = null; + long playbackCompletionTime = cursor + .getLong(PodDBAdapter.KEY_PLAYBACK_COMPLETION_DATE_INDEX); + if (playbackCompletionTime > 0) { + playbackCompletionDate = new Date( + playbackCompletionTime); + } + + item.setMedia(new FeedMedia( + mediaId, + item, + cursor.getInt(PodDBAdapter.KEY_DURATION_INDEX), + cursor.getInt(PodDBAdapter.KEY_POSITION_INDEX), + cursor.getLong(PodDBAdapter.KEY_SIZE_INDEX), + cursor.getString(PodDBAdapter.KEY_MIME_TYPE_INDEX), + cursor.getString(PodDBAdapter.KEY_FILE_URL_INDEX), + cursor.getString(PodDBAdapter.KEY_DOWNLOAD_URL_INDEX), + cursor.getInt(PodDBAdapter.KEY_DOWNLOADED_INDEX) > 0, + playbackCompletionDate)); + + } + } while (cursor.moveToNext()); + cursor.close(); + } } - public static List getDownloadLog() { - return null; + private static Feed extractFeedFromCursorRow(PodDBAdapter adapter, + Cursor cursor) { + Date lastUpdate = new Date( + cursor.getLong(PodDBAdapter.KEY_LAST_UPDATE_INDEX)); + Feed feed = new Feed(lastUpdate); + + feed.setId(cursor.getLong(PodDBAdapter.KEY_ID_INDEX)); + feed.setTitle(cursor.getString(PodDBAdapter.KEY_TITLE_INDEX)); + feed.setLink(cursor.getString(PodDBAdapter.KEY_LINK_INDEX)); + feed.setDescription(cursor + .getString(PodDBAdapter.KEY_DESCRIPTION_INDEX)); + feed.setPaymentLink(cursor + .getString(PodDBAdapter.KEY_PAYMENT_LINK_INDEX)); + feed.setAuthor(cursor.getString(PodDBAdapter.KEY_AUTHOR_INDEX)); + feed.setLanguage(cursor.getString(PodDBAdapter.KEY_LANGUAGE_INDEX)); + feed.setType(cursor.getString(PodDBAdapter.KEY_TYPE_INDEX)); + feed.setFeedIdentifier(cursor + .getString(PodDBAdapter.KEY_FEED_IDENTIFIER_INDEX)); + long imageIndex = cursor.getLong(PodDBAdapter.KEY_IMAGE_INDEX); + if (imageIndex != 0) { + feed.setImage(getFeedImage(adapter, imageIndex)); + feed.getImage().setFeed(feed); + } + feed.setFile_url(cursor.getString(PodDBAdapter.KEY_FILE_URL_INDEX)); + feed.setDownload_url(cursor + .getString(PodDBAdapter.KEY_DOWNLOAD_URL_INDEX)); + feed.setDownloaded(cursor.getInt(PodDBAdapter.KEY_DOWNLOADED_INDEX) > 0); + + return feed; } - public static Feed getFeed(long feedId) { + private static FeedItem getMatchingItemForMedia(long mediaId, + List items) { + for (FeedItem item : items) { + if (item.getMedia() != null && item.getMedia().getId() == mediaId) { + return item; + } + } return null; } - public FeedItem getFeedItem(long itemId) { - return null; + public static List getQueue(Context context) { + if (AppConfig.DEBUG) + Log.d(TAG, "Extracting queue"); + + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + + Cursor itemlistCursor = adapter.getQueueCursor(); + List items = extractItemlistFromCursor(adapter, + itemlistCursor); + itemlistCursor.close(); + + loadFeedDataOfFeedItemlist(context, items); + + adapter.close(); + + Collections.sort(items, new FeedItemPubdateComparator()); + + return items; } - public FeedMedia getFeedMedia(long mediaId) { - return null; + public static List getUnreadItemsList(Context context) { + if (AppConfig.DEBUG) + Log.d(TAG, "Extracting unread items list"); + + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + + Cursor itemlistCursor = adapter.getUnreadItemsCursor(); + List items = extractItemlistFromCursor(adapter, + itemlistCursor); + itemlistCursor.close(); + + loadFeedDataOfFeedItemlist(context, items); + + adapter.close(); + + return items; } - public static FeedItem getFirstQueueItem() { + public static List getPlaybackHistory() { return null; } + public static List getDownloadLog(Context context) { + if (AppConfig.DEBUG) + Log.d(TAG, "Extracting DownloadLog"); + + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + Cursor logCursor = adapter.getDownloadLogCursor(); + List downloadLog = new ArrayList( + logCursor.getCount()); + + if (logCursor.moveToFirst()) { + do { + long id = logCursor.getLong(PodDBAdapter.KEY_ID_INDEX); + + long feedfileId = logCursor + .getLong(PodDBAdapter.KEY_FEEDFILE_INDEX); + int feedfileType = logCursor + .getInt(PodDBAdapter.KEY_FEEDFILETYPE_INDEX); + boolean successful = logCursor + .getInt(PodDBAdapter.KEY_SUCCESSFUL_INDEX) > 0; + int reason = logCursor.getInt(PodDBAdapter.KEY_REASON_INDEX); + String reasonDetailed = logCursor + .getString(PodDBAdapter.KEY_REASON_DETAILED_INDEX); + String title = logCursor + .getString(PodDBAdapter.KEY_DOWNLOADSTATUS_TITLE_INDEX); + Date completionDate = new Date( + logCursor + .getLong(PodDBAdapter.KEY_COMPLETION_DATE_INDEX)); + downloadLog.add(new DownloadStatus(id, title, feedfileId, + feedfileType, successful, reason, completionDate, + reasonDetailed)); + + } while (logCursor.moveToNext()); + } + logCursor.close(); + Collections.sort(downloadLog, new DownloadStatusComparator()); + return downloadLog; + } + + public static Feed getFeed(final Context context, final long feedId) { + if (AppConfig.DEBUG) + Log.d(TAG, "Loading feed with id " + feedId); + Feed feed = null; + + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + Cursor feedCursor = adapter.getFeedCursor(feedId); + if (feedCursor.moveToFirst()) { + feed = extractFeedFromCursorRow(adapter, feedCursor); + feed.setItems(getFeedItemList(context, feed)); + } + adapter.close(); + return feed; + } + + public FeedItem getFeedItem(final Context context, final long itemId) { + if (AppConfig.DEBUG) + Log.d(TAG, "Loading feeditem with id " + itemId); + FeedItem item = null; + + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + Cursor itemCursor = adapter.getFeedItemCursor(itemId); + if (itemCursor.moveToFirst()) { + List list = extractItemlistFromCursor(adapter, itemCursor); + if (list.size() > 0) { + item = list.get(0); + } + } + adapter.close(); + return item; + + } + + /** + * Searches the DB for a FeedImage of the given id. + * + * @param id + * The id of the object + * @return The found object + * */ + private static FeedImage getFeedImage(PodDBAdapter adapter, final long id) { + Cursor cursor = adapter.getImageOfFeedCursor(id); + if ((cursor.getCount() == 0) || !cursor.moveToFirst()) { + throw new SQLException("No FeedImage found at index: " + id); + } + FeedImage image = new FeedImage(id, cursor.getString(cursor + .getColumnIndex(PodDBAdapter.KEY_TITLE)), + cursor.getString(cursor + .getColumnIndex(PodDBAdapter.KEY_FILE_URL)), + cursor.getString(cursor + .getColumnIndex(PodDBAdapter.KEY_DOWNLOAD_URL)), + cursor.getInt(cursor + .getColumnIndex(PodDBAdapter.KEY_DOWNLOADED)) > 0); + cursor.close(); + return image; + } } diff --git a/src/de/danoeh/antennapod/storage/PodDBAdapter.java b/src/de/danoeh/antennapod/storage/PodDBAdapter.java index 420264840..5ec5df2c8 100644 --- a/src/de/danoeh/antennapod/storage/PodDBAdapter.java +++ b/src/de/danoeh/antennapod/storage/PodDBAdapter.java @@ -583,10 +583,49 @@ public class PodDBAdapter { return c; } + /** + * Returns a cursor which contains all feed items in the queue. The returned + * cursor uses the SEL_FI_SMALL selection. + */ public final Cursor getQueueCursor() { open(); - Cursor c = db.query(TABLE_NAME_QUEUE, null, null, null, null, null, - null); + Cursor c = db.query(TABLE_NAME_FEED_ITEMS, SEL_FI_SMALL, + "INNER JOIN ? ON ?=?", new String[] { TABLE_NAME_QUEUE, + TABLE_NAME_FEED_ITEMS + "." + KEY_ID, + TABLE_NAME_QUEUE + "." + KEY_FEEDITEM }, null, null, + TABLE_NAME_QUEUE + "." + KEY_FEEDITEM); + return c; + } + + /** + * Returns a cursor which contains all feed items in the unread items list. + * The returned cursor uses the SEL_FI_SMALL selection. + */ + public final Cursor getUnreadItemsCursor() { + open(); + Cursor c = db.query(TABLE_NAME_FEED_ITEMS, SEL_FI_SMALL, KEY_READ + + "=0", null, null, null, KEY_PUBDATE + " DESC"); + return c; + } + + /** + * Returns a cursor which contains feed media objects with a playback + * completion date in descending order. + * + * @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 limit) { + if (limit < 0) { + throw new IllegalArgumentException("Limit must be >= 0"); + } + open(); + Cursor c = db.query(CREATE_TABLE_FEED_MEDIA, null, + KEY_PLAYBACK_COMPLETION_DATE + " IS NOT NULL", null, null, + null, KEY_PLAYBACK_COMPLETION_DATE + " DESC LIMIT " + limit); return c; } @@ -635,25 +674,18 @@ public class PodDBAdapter { return buffer.toString(); } - /** - * Searches the DB for a FeedImage of the given id. - * - * @param id - * The id of the object - * @return The found object - * */ - public final FeedImage getFeedImage(final long id) throws SQLException { - Cursor cursor = this.getImageOfFeedCursor(id); - if ((cursor.getCount() == 0) || !cursor.moveToFirst()) { - throw new SQLException("No FeedImage found at index: " + id); - } - FeedImage image = new FeedImage(id, cursor.getString(cursor - .getColumnIndex(KEY_TITLE)), cursor.getString(cursor - .getColumnIndex(KEY_FILE_URL)), cursor.getString(cursor - .getColumnIndex(KEY_DOWNLOAD_URL)), cursor.getInt(cursor - .getColumnIndex(KEY_DOWNLOADED)) > 0); - cursor.close(); - return image; + public final Cursor getFeedCursor(final long id) { + open(); + Cursor c = db.query(TABLE_NAME_FEEDS, null, KEY_ID + "=" + id, null, + null, null, null); + return c; + } + + public final Cursor getFeedItemCursor(final long id) { + open(); + Cursor c = db.query(TABLE_NAME_FEEDS, null, KEY_ID + "=" + id, null, + null, null, null); + return c; } /** -- cgit v1.2.3