diff options
author | daniel oeh <daniel.oeh@gmail.com> | 2013-08-05 01:27:38 +0200 |
---|---|---|
committer | daniel oeh <daniel.oeh@gmail.com> | 2013-08-05 01:27:38 +0200 |
commit | 6d1a8535f5dbf9bcdd552ad382f2944f7b0d31ad (patch) | |
tree | 59d865da4594d0f961a40d56beb3ed77abb14bff | |
parent | edd84c6a4c5542b8c764e8720cc96019db653e9a (diff) | |
download | AntennaPod-6d1a8535f5dbf9bcdd552ad382f2944f7b0d31ad.zip |
Added FeedItemStatistics.
Makes it possible to get number of (new, in progress) episodes of a feed without loading the whole list of items
-rw-r--r-- | src/de/danoeh/antennapod/adapter/FeedlistAdapter.java | 72 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/fragment/FeedlistFragment.java | 461 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/storage/DBReader.java | 893 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/storage/FeedItemStatistics.java | 42 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/storage/PodDBAdapter.java | 1884 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/util/ShownotesProvider.java | 17 |
6 files changed, 1747 insertions, 1622 deletions
diff --git a/src/de/danoeh/antennapod/adapter/FeedlistAdapter.java b/src/de/danoeh/antennapod/adapter/FeedlistAdapter.java index aa10ed8e6..89427a47e 100644 --- a/src/de/danoeh/antennapod/adapter/FeedlistAdapter.java +++ b/src/de/danoeh/antennapod/adapter/FeedlistAdapter.java @@ -12,6 +12,7 @@ import de.danoeh.antennapod.R; import de.danoeh.antennapod.asynctask.ImageLoader; import de.danoeh.antennapod.feed.Feed; import de.danoeh.antennapod.storage.DownloadRequester; +import de.danoeh.antennapod.storage.FeedItemStatistics; import de.danoeh.antennapod.util.ThemeUtils; public class FeedlistAdapter extends BaseAdapter { @@ -43,6 +44,7 @@ public class FeedlistAdapter extends BaseAdapter { public View getView(int position, View convertView, ViewGroup parent) { final Holder holder; final Feed feed = getItem(position); + final FeedItemStatistics feedItemStatistics = itemAccess.getFeedItemStatistics(position); // Inflate Layout if (convertView == null) { @@ -82,42 +84,40 @@ public class FeedlistAdapter extends BaseAdapter { } holder.title.setText(feed.getTitle()); - int numOfItems = feed.getNumOfItems(true); - if (DownloadRequester.getInstance().isDownloadingFile(feed)) { - holder.lastUpdate.setText(R.string.refreshing_label); - } else { - if (numOfItems > 0) { - holder.lastUpdate.setText(convertView.getResources().getString( - R.string.most_recent_prefix) - + DateUtils.getRelativeTimeSpanString( - feed.getItemAtIndex(true, 0).getPubDate().getTime(), - System.currentTimeMillis(), 0, 0)); - } else { - holder.lastUpdate.setText(""); - } - } - holder.numberOfEpisodes.setText(numOfItems - + convertView.getResources() - .getString(R.string.episodes_suffix)); - - int newItems = feed.getNumOfNewItems(); - int inProgressItems = feed.getNumOfStartedItems(); - - if (newItems > 0) { - holder.newEpisodes.setText(Integer.toString(newItems)); - holder.newEpisodesLabel.setVisibility(View.VISIBLE); - } else { - holder.newEpisodesLabel.setVisibility(View.INVISIBLE); - } - - if (inProgressItems > 0) { - holder.inProgressEpisodes - .setText(Integer.toString(inProgressItems)); - holder.inProgressEpisodesLabel.setVisibility(View.VISIBLE); - } else { - holder.inProgressEpisodesLabel.setVisibility(View.INVISIBLE); - } + if (feedItemStatistics != null) { + if (DownloadRequester.getInstance().isDownloadingFile(feed)) { + holder.lastUpdate.setText(R.string.refreshing_label); + } else { + if (feedItemStatistics.getNumberOfItems() > 0) { + holder.lastUpdate.setText(convertView.getResources().getString( + R.string.most_recent_prefix) + + DateUtils.getRelativeTimeSpanString( + feedItemStatistics.getLastUpdate().getTime(), + System.currentTimeMillis(), 0, 0)); + } else { + holder.lastUpdate.setText(""); + } + } + holder.numberOfEpisodes.setText(feedItemStatistics.getNumberOfItems() + + convertView.getResources() + .getString(R.string.episodes_suffix)); + + if (feedItemStatistics.getNumberOfNewItems() > 0) { + holder.newEpisodes.setText(Integer.toString(feedItemStatistics.getNumberOfNewItems())); + holder.newEpisodesLabel.setVisibility(View.VISIBLE); + } else { + holder.newEpisodesLabel.setVisibility(View.INVISIBLE); + } + + if (feedItemStatistics.getNumberOfInProgressItems() > 0) { + holder.inProgressEpisodes + .setText(Integer.toString(feedItemStatistics.getNumberOfInProgressItems())); + holder.inProgressEpisodesLabel.setVisibility(View.VISIBLE); + } else { + holder.inProgressEpisodesLabel.setVisibility(View.INVISIBLE); + } + } final String imageUrl = (feed.getImage() != null) ? feed.getImage() .getFile_url() : null; holder.image.setTag(imageUrl); @@ -169,5 +169,7 @@ public class FeedlistAdapter extends BaseAdapter { int getCount(); Feed getItem(int position); + + FeedItemStatistics getFeedItemStatistics(int position); } } diff --git a/src/de/danoeh/antennapod/fragment/FeedlistFragment.java b/src/de/danoeh/antennapod/fragment/FeedlistFragment.java index 80deee47e..ef9994649 100644 --- a/src/de/danoeh/antennapod/fragment/FeedlistFragment.java +++ b/src/de/danoeh/antennapod/fragment/FeedlistFragment.java @@ -32,231 +32,244 @@ import de.danoeh.antennapod.feed.EventDistributor; import de.danoeh.antennapod.feed.Feed; import de.danoeh.antennapod.storage.DBReader; import de.danoeh.antennapod.storage.DownloadRequestException; +import de.danoeh.antennapod.storage.FeedItemStatistics; import de.danoeh.antennapod.util.menuhandler.FeedMenuHandler; public class FeedlistFragment extends SherlockFragment implements - ActionMode.Callback, AdapterView.OnItemClickListener, - AdapterView.OnItemLongClickListener { - private static final String TAG = "FeedlistFragment"; - - private static final int EVENTS = EventDistributor.DOWNLOAD_HANDLED - | EventDistributor.DOWNLOAD_QUEUED - | EventDistributor.FEED_LIST_UPDATE - | EventDistributor.UNREAD_ITEMS_UPDATE; - - public static final String EXTRA_SELECTED_FEED = "extra.de.danoeh.antennapod.activity.selected_feed"; - - private FeedlistAdapter fla; - private List<Feed> feeds; - - private Feed selectedFeed; - private ActionMode mActionMode; - - private GridView gridView; - private ListView listView; - private TextView txtvEmpty; - - private FeedlistAdapter.ItemAccess itemAccess = new FeedlistAdapter.ItemAccess() { - - @Override - public Feed getItem(int position) { - if (feeds != null) { - return feeds.get(position); - } else { - return null; - } - } - - @Override - public int getCount() { - if (feeds != null) { - return feeds.size(); - } else { - return 0; - } - } - }; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - if (AppConfig.DEBUG) - Log.d(TAG, "Creating"); - fla = new FeedlistAdapter(getActivity(), itemAccess); - loadFeeds(); - } - - private void loadFeeds() { - AsyncTask<Void, Void, List<Feed>> loadTask = new AsyncTask<Void, Void, List<Feed>>() { - @Override - protected List<Feed> doInBackground(Void... params) { - return DBReader.getFeedList(getActivity()); - } - - @Override - protected void onPostExecute(List<Feed> result) { - super.onPostExecute(result); - if (result != null) { - feeds = result; - if (fla != null) { - fla.notifyDataSetChanged(); - } - } else { - Log.e(TAG, "Failed to load feeds"); - } - } - }; - loadTask.execute(); - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View result = inflater.inflate(R.layout.feedlist, container, false); - listView = (ListView) result.findViewById(android.R.id.list); - gridView = (GridView) result.findViewById(R.id.grid); - txtvEmpty = (TextView) result.findViewById(android.R.id.empty); - - return result; - - } - - @Override - public void onViewCreated(View view, Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - if (listView != null) { - listView.setOnItemClickListener(this); - listView.setOnItemLongClickListener(this); - listView.setAdapter(fla); - listView.setEmptyView(txtvEmpty); - if (AppConfig.DEBUG) - Log.d(TAG, "Using ListView"); - } else { - gridView.setOnItemClickListener(this); - gridView.setOnItemLongClickListener(this); - gridView.setAdapter(fla); - gridView.setEmptyView(txtvEmpty); - if (AppConfig.DEBUG) - Log.d(TAG, "Using GridView"); - } - } - - @Override - public void onResume() { - super.onResume(); - if (AppConfig.DEBUG) - Log.d(TAG, "Resuming"); - EventDistributor.getInstance().register(contentUpdate); - } - - @Override - public void onPause() { - super.onPause(); - EventDistributor.getInstance().unregister(contentUpdate); - if (mActionMode != null) { - mActionMode.finish(); - } - } - - private EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() { - - @Override - public void update(EventDistributor eventDistributor, Integer arg) { - if ((EVENTS & arg) != 0) { - if (AppConfig.DEBUG) - Log.d(TAG, "Received contentUpdate Intent."); - loadFeeds(); - } - } - }; - - @Override - public boolean onCreateActionMode(ActionMode mode, Menu menu) { - FeedMenuHandler.onCreateOptionsMenu(mode.getMenuInflater(), menu); - mode.setTitle(selectedFeed.getTitle()); - return true; - } - - @Override - public boolean onPrepareActionMode(ActionMode mode, Menu menu) { - return FeedMenuHandler.onPrepareOptionsMenu(menu, selectedFeed); - } - - @SuppressLint("NewApi") - @Override - public boolean onActionItemClicked(ActionMode mode, MenuItem item) { - try { - if (FeedMenuHandler.onOptionsItemClicked(getSherlockActivity(), - item, selectedFeed)) { - loadFeeds(); - } else { - switch (item.getItemId()) { - case R.id.remove_item: - final FeedRemover remover = new FeedRemover( - getSherlockActivity(), selectedFeed) { - @Override - protected void onPostExecute(Void result) { - super.onPostExecute(result); - loadFeeds(); - } - }; - ConfirmationDialog conDialog = new ConfirmationDialog( - getActivity(), R.string.remove_feed_label, - R.string.feed_delete_confirmation_msg) { - - @Override - public void onConfirmButtonPressed( - DialogInterface dialog) { - dialog.dismiss(); - remover.executeAsync(); - } - }; - conDialog.createNewDialog().show(); - break; - } - } - } catch (DownloadRequestException e) { - e.printStackTrace(); - DownloadRequestErrorDialogCreator.newRequestErrorDialog( - getActivity(), e.getMessage()); - } - mode.finish(); - return true; - } - - @Override - public void onDestroyActionMode(ActionMode mode) { - mActionMode = null; - selectedFeed = null; - fla.setSelectedItemIndex(FeedlistAdapter.SELECTION_NONE); - } - - @Override - public void onItemClick(AdapterView<?> arg0, View arg1, int position, - long id) { - Feed selection = fla.getItem(position); - Intent showFeed = new Intent(getActivity(), FeedItemlistActivity.class); - showFeed.putExtra(EXTRA_SELECTED_FEED, selection.getId()); - - getActivity().startActivity(showFeed); - } - - @Override - public boolean onItemLongClick(AdapterView<?> parent, View view, - int position, long id) { - Feed selection = fla.getItem(position); - if (AppConfig.DEBUG) - Log.d(TAG, "Selected Feed with title " + selection.getTitle()); - if (selection != null) { - if (mActionMode != null) { - mActionMode.finish(); - } - fla.setSelectedItemIndex(position); - selectedFeed = selection; - mActionMode = getSherlockActivity().startActionMode( - FeedlistFragment.this); - - } - return true; - } + ActionMode.Callback, AdapterView.OnItemClickListener, + AdapterView.OnItemLongClickListener { + private static final String TAG = "FeedlistFragment"; + + private static final int EVENTS = EventDistributor.DOWNLOAD_HANDLED + | EventDistributor.DOWNLOAD_QUEUED + | EventDistributor.FEED_LIST_UPDATE + | EventDistributor.UNREAD_ITEMS_UPDATE; + + public static final String EXTRA_SELECTED_FEED = "extra.de.danoeh.antennapod.activity.selected_feed"; + + private FeedlistAdapter fla; + private List<Feed> feeds; + private List<FeedItemStatistics> feedItemStatistics; + + private Feed selectedFeed; + private ActionMode mActionMode; + + private GridView gridView; + private ListView listView; + private TextView txtvEmpty; + + private FeedlistAdapter.ItemAccess itemAccess = new FeedlistAdapter.ItemAccess() { + + @Override + public Feed getItem(int position) { + if (feeds != null) { + return feeds.get(position); + } else { + return null; + } + } + + @Override + public FeedItemStatistics getFeedItemStatistics(int position) { + if (feedItemStatistics != null && position < feedItemStatistics.size()) { + return feedItemStatistics.get(position); + } else { + return null; + } + } + + @Override + public int getCount() { + if (feeds != null) { + return feeds.size(); + } else { + return 0; + } + } + }; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + if (AppConfig.DEBUG) + Log.d(TAG, "Creating"); + fla = new FeedlistAdapter(getActivity(), itemAccess); + loadFeeds(); + } + + private void loadFeeds() { + AsyncTask<Void, Void, List[]> loadTask = new AsyncTask<Void, Void, List[]>() { + @Override + protected List[] doInBackground(Void... params) { + return new List[]{DBReader.getFeedList(getActivity()), + DBReader.getFeedStatisticsList(getActivity())}; + } + + @Override + protected void onPostExecute(List[] result) { + super.onPostExecute(result); + if (result != null) { + feeds = result[0]; + feedItemStatistics = result[1]; + if (fla != null) { + fla.notifyDataSetChanged(); + } + } else { + Log.e(TAG, "Failed to load feeds"); + } + } + }; + loadTask.execute(); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View result = inflater.inflate(R.layout.feedlist, container, false); + listView = (ListView) result.findViewById(android.R.id.list); + gridView = (GridView) result.findViewById(R.id.grid); + txtvEmpty = (TextView) result.findViewById(android.R.id.empty); + + return result; + + } + + @Override + public void onViewCreated(View view, Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + if (listView != null) { + listView.setOnItemClickListener(this); + listView.setOnItemLongClickListener(this); + listView.setAdapter(fla); + listView.setEmptyView(txtvEmpty); + if (AppConfig.DEBUG) + Log.d(TAG, "Using ListView"); + } else { + gridView.setOnItemClickListener(this); + gridView.setOnItemLongClickListener(this); + gridView.setAdapter(fla); + gridView.setEmptyView(txtvEmpty); + if (AppConfig.DEBUG) + Log.d(TAG, "Using GridView"); + } + } + + @Override + public void onResume() { + super.onResume(); + if (AppConfig.DEBUG) + Log.d(TAG, "Resuming"); + EventDistributor.getInstance().register(contentUpdate); + } + + @Override + public void onPause() { + super.onPause(); + EventDistributor.getInstance().unregister(contentUpdate); + if (mActionMode != null) { + mActionMode.finish(); + } + } + + private EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() { + + @Override + public void update(EventDistributor eventDistributor, Integer arg) { + if ((EVENTS & arg) != 0) { + if (AppConfig.DEBUG) + Log.d(TAG, "Received contentUpdate Intent."); + loadFeeds(); + } + } + }; + + @Override + public boolean onCreateActionMode(ActionMode mode, Menu menu) { + FeedMenuHandler.onCreateOptionsMenu(mode.getMenuInflater(), menu); + mode.setTitle(selectedFeed.getTitle()); + return true; + } + + @Override + public boolean onPrepareActionMode(ActionMode mode, Menu menu) { + return FeedMenuHandler.onPrepareOptionsMenu(menu, selectedFeed); + } + + @SuppressLint("NewApi") + @Override + public boolean onActionItemClicked(ActionMode mode, MenuItem item) { + try { + if (FeedMenuHandler.onOptionsItemClicked(getSherlockActivity(), + item, selectedFeed)) { + loadFeeds(); + } else { + switch (item.getItemId()) { + case R.id.remove_item: + final FeedRemover remover = new FeedRemover( + getSherlockActivity(), selectedFeed) { + @Override + protected void onPostExecute(Void result) { + super.onPostExecute(result); + loadFeeds(); + } + }; + ConfirmationDialog conDialog = new ConfirmationDialog( + getActivity(), R.string.remove_feed_label, + R.string.feed_delete_confirmation_msg) { + + @Override + public void onConfirmButtonPressed( + DialogInterface dialog) { + dialog.dismiss(); + remover.executeAsync(); + } + }; + conDialog.createNewDialog().show(); + break; + } + } + } catch (DownloadRequestException e) { + e.printStackTrace(); + DownloadRequestErrorDialogCreator.newRequestErrorDialog( + getActivity(), e.getMessage()); + } + mode.finish(); + return true; + } + + @Override + public void onDestroyActionMode(ActionMode mode) { + mActionMode = null; + selectedFeed = null; + fla.setSelectedItemIndex(FeedlistAdapter.SELECTION_NONE); + } + + @Override + public void onItemClick(AdapterView<?> arg0, View arg1, int position, + long id) { + Feed selection = fla.getItem(position); + Intent showFeed = new Intent(getActivity(), FeedItemlistActivity.class); + showFeed.putExtra(EXTRA_SELECTED_FEED, selection.getId()); + + getActivity().startActivity(showFeed); + } + + @Override + public boolean onItemLongClick(AdapterView<?> parent, View view, + int position, long id) { + Feed selection = fla.getItem(position); + if (AppConfig.DEBUG) + Log.d(TAG, "Selected Feed with title " + selection.getTitle()); + if (selection != null) { + if (mActionMode != null) { + mActionMode.finish(); + } + fla.setSelectedItemIndex(position); + selectedFeed = selection; + mActionMode = getSherlockActivity().startActionMode( + FeedlistFragment.this); + + } + return true; + } } diff --git a/src/de/danoeh/antennapod/storage/DBReader.java b/src/de/danoeh/antennapod/storage/DBReader.java index 5d6dd9756..ababcdf78 100644 --- a/src/de/danoeh/antennapod/storage/DBReader.java +++ b/src/de/danoeh/antennapod/storage/DBReader.java @@ -23,90 +23,90 @@ 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<Feed> getFeedList(final Context context) { - if (AppConfig.DEBUG) - Log.d(TAG, "Extracting Feedlist"); - - PodDBAdapter adapter = new PodDBAdapter(context); - adapter.open(); - - Cursor feedlistCursor = adapter.getAllFeedsCursor(); - List<Feed> feeds = new ArrayList<Feed>(feedlistCursor.getCount()); - - if (feedlistCursor.moveToFirst()) { - do { - Feed feed = extractFeedFromCursorRow(adapter, feedlistCursor); - feeds.add(feed); - } while (feedlistCursor.moveToNext()); - } - feedlistCursor.close(); - return feeds; - } - - static List<Feed> getExpiredFeedsList(final Context context, final long expirationTime) { - if (AppConfig.DEBUG) - Log.d(TAG, String.format("getExpiredFeedsList(%d)", expirationTime)); - - PodDBAdapter adapter = new PodDBAdapter(context); - adapter.open(); - - Cursor feedlistCursor = adapter.getExpiredFeedsCursor(expirationTime); - List<Feed> feeds = new ArrayList<Feed>(feedlistCursor.getCount()); - - if (feedlistCursor.moveToFirst()) { - do { - Feed feed = extractFeedFromCursorRow(adapter, feedlistCursor); - feeds.add(feed); - } while (feedlistCursor.moveToNext()); - } - feedlistCursor.close(); - return feeds; - } - - public static void loadFeedDataOfFeedItemlist(Context context, - List<FeedItem> items) { - List<Feed> feeds = getFeedList(context); - for (FeedItem item : items) { - for (Feed feed : feeds) { - if (feed.getId() == item.getFeedId()) { - item.setFeed(feed); - break; - } - } + private static final String TAG = "DBReader"; + + private DBReader() { + } + + public static List<Feed> getFeedList(final Context context) { + if (AppConfig.DEBUG) + Log.d(TAG, "Extracting Feedlist"); + + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + + Cursor feedlistCursor = adapter.getAllFeedsCursor(); + List<Feed> feeds = new ArrayList<Feed>(feedlistCursor.getCount()); + + if (feedlistCursor.moveToFirst()) { + do { + Feed feed = extractFeedFromCursorRow(adapter, feedlistCursor); + feeds.add(feed); + } while (feedlistCursor.moveToNext()); + } + feedlistCursor.close(); + return feeds; + } + + static List<Feed> getExpiredFeedsList(final Context context, final long expirationTime) { + if (AppConfig.DEBUG) + Log.d(TAG, String.format("getExpiredFeedsList(%d)", expirationTime)); + + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + + Cursor feedlistCursor = adapter.getExpiredFeedsCursor(expirationTime); + List<Feed> feeds = new ArrayList<Feed>(feedlistCursor.getCount()); + + if (feedlistCursor.moveToFirst()) { + do { + Feed feed = extractFeedFromCursorRow(adapter, feedlistCursor); + feeds.add(feed); + } while (feedlistCursor.moveToNext()); + } + feedlistCursor.close(); + return feeds; + } + + public static void loadFeedDataOfFeedItemlist(Context context, + List<FeedItem> items) { + List<Feed> feeds = getFeedList(context); + for (FeedItem item : items) { + for (Feed feed : feeds) { + if (feed.getId() == item.getFeedId()) { + item.setFeed(feed); + break; + } + } if (item.getFeed() == null) { Log.w(TAG, "No match found for item with ID " + item.getId() + ". Feed ID was " + item.getFeedId()); } - } - } + } + } - public static List<FeedItem> getFeedItemList(Context context, - final Feed feed) { - if (AppConfig.DEBUG) - Log.d(TAG, "Extracting Feeditems of feed " + feed.getTitle()); + public static List<FeedItem> 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(); + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); - Cursor itemlistCursor = adapter.getAllItemsOfFeedCursor(feed); - List<FeedItem> items = extractItemlistFromCursor(adapter, - itemlistCursor); - itemlistCursor.close(); + Cursor itemlistCursor = adapter.getAllItemsOfFeedCursor(feed); + List<FeedItem> items = extractItemlistFromCursor(adapter, + itemlistCursor); + itemlistCursor.close(); - Collections.sort(items, new FeedItemPubdateComparator()); + Collections.sort(items, new FeedItemPubdateComparator()); - adapter.close(); + adapter.close(); - for (FeedItem item : items) { - item.setFeed(feed); - } + for (FeedItem item : items) { + item.setFeed(feed); + } - return items; - } + return items; + } static List<FeedItem> extractItemlistFromCursor(Context context, Cursor itemlistCursor) { PodDBAdapter adapter = new PodDBAdapter(context); @@ -116,178 +116,178 @@ public final class DBReader { return result; } - private static List<FeedItem> extractItemlistFromCursor( - PodDBAdapter adapter, Cursor itemlistCursor) { - ArrayList<String> itemIds = new ArrayList<String>(); - List<FeedItem> items = new ArrayList<FeedItem>( - 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)); - itemIds.add(String.valueOf(item.getId())); - - item.setRead((itemlistCursor + private static List<FeedItem> extractItemlistFromCursor( + PodDBAdapter adapter, Cursor itemlistCursor) { + ArrayList<String> itemIds = new ArrayList<String>(); + List<FeedItem> items = new ArrayList<FeedItem>( + 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)); + itemIds.add(String.valueOf(item.getId())); + + item.setRead((itemlistCursor .getInt(PodDBAdapter.IDX_FI_SMALL_READ) > 0)); - 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<Chapter>()); - 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, itemIds); - return items; - } - - private static void extractMediafromItemlist(PodDBAdapter adapter, - List<FeedItem> items, ArrayList<String> itemIds) { - - List<FeedItem> itemsCopy = new ArrayList<FeedItem>(items); - Cursor cursor = adapter.getFeedMediaCursorByItemID(itemIds + 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<Chapter>()); + 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, itemIds); + return items; + } + + private static void extractMediafromItemlist(PodDBAdapter adapter, + List<FeedItem> items, ArrayList<String> itemIds) { + + List<FeedItem> itemsCopy = new ArrayList<FeedItem>(items); + Cursor cursor = adapter.getFeedMediaCursorByItemID(itemIds .toArray(new String[itemIds.size()])); - if (cursor.moveToFirst()) { - do { + if (cursor.moveToFirst()) { + do { long itemId = cursor.getLong(PodDBAdapter.KEY_MEDIA_FEEDITEM_INDEX); - // find matching feed item - FeedItem item = getMatchingItemForMedia(itemId, itemsCopy); - if (item != null) { - item.setMedia(extractFeedMediaFromCursorRow(cursor)); + // find matching feed item + FeedItem item = getMatchingItemForMedia(itemId, itemsCopy); + if (item != null) { + item.setMedia(extractFeedMediaFromCursorRow(cursor)); item.getMedia().setItem(item); - } - } while (cursor.moveToNext()); - cursor.close(); - } - } + } + } while (cursor.moveToNext()); + cursor.close(); + } + } private static FeedMedia extractFeedMediaFromCursorRow(final Cursor cursor) { - long mediaId = cursor.getLong(PodDBAdapter.KEY_ID_INDEX); - Date playbackCompletionDate = null; - long playbackCompletionTime = cursor - .getLong(PodDBAdapter.KEY_PLAYBACK_COMPLETION_DATE_INDEX); - if (playbackCompletionTime > 0) { - playbackCompletionDate = new Date( - playbackCompletionTime); - } + long mediaId = cursor.getLong(PodDBAdapter.KEY_ID_INDEX); + Date playbackCompletionDate = null; + long playbackCompletionTime = cursor + .getLong(PodDBAdapter.KEY_PLAYBACK_COMPLETION_DATE_INDEX); + if (playbackCompletionTime > 0) { + playbackCompletionDate = new Date( + playbackCompletionTime); + } + + return new FeedMedia( + mediaId, + null, + 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); + } + + 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; + } - return new FeedMedia( - mediaId, - null, - 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); + private static FeedItem getMatchingItemForMedia(long itemId, + List<FeedItem> items) { + for (FeedItem item : items) { + if (item.getId() == itemId) { + return item; + } + } + 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; - } - - private static FeedItem getMatchingItemForMedia(long itemId, - List<FeedItem> items) { - for (FeedItem item : items) { - if (item.getId() == itemId) { - return item; - } - } - return null; - } - - static List<FeedItem> getQueue(Context context, PodDBAdapter adapter) { - if (AppConfig.DEBUG) - Log.d(TAG, "Extracting queue"); - - Cursor itemlistCursor = adapter.getQueueCursor(); - List<FeedItem> items = extractItemlistFromCursor(adapter, - itemlistCursor); - itemlistCursor.close(); - loadFeedDataOfFeedItemlist(context, items); - - return items; - } + static List<FeedItem> getQueue(Context context, PodDBAdapter adapter) { + if (AppConfig.DEBUG) + Log.d(TAG, "Extracting queue"); + + Cursor itemlistCursor = adapter.getQueueCursor(); + List<FeedItem> items = extractItemlistFromCursor(adapter, + itemlistCursor); + itemlistCursor.close(); + loadFeedDataOfFeedItemlist(context, items); + + return items; + } public static List<Long> getQueueIDList(Context context) { PodDBAdapter adapter = new PodDBAdapter(context); @@ -312,178 +312,198 @@ public final class DBReader { return queueIds; } - public static List<FeedItem> getQueue(Context context) { - if (AppConfig.DEBUG) - Log.d(TAG, "Extracting queue"); - - PodDBAdapter adapter = new PodDBAdapter(context); - adapter.open(); - List<FeedItem> items = getQueue(context, adapter); - adapter.close(); - return items; - } - - public static List<FeedItem> getDownloadedItems(Context context) { - if (AppConfig.DEBUG) - Log.d(TAG, "Extracting downloaded items"); - - PodDBAdapter adapter = new PodDBAdapter(context); - adapter.open(); - - Cursor itemlistCursor = adapter.getDownloadedItemsCursor(); - List<FeedItem> items = extractItemlistFromCursor(adapter, - itemlistCursor); - itemlistCursor.close(); - loadFeedDataOfFeedItemlist(context, items); - Collections.sort(items, new FeedItemPubdateComparator()); - - adapter.close(); - return items; - - } - - public static List<FeedItem> 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<FeedItem> items = extractItemlistFromCursor(adapter, - itemlistCursor); - itemlistCursor.close(); - - loadFeedDataOfFeedItemlist(context, items); - - adapter.close(); - - return items; - } - - public static long[] getUnreadItemIds(Context context) { - PodDBAdapter adapter = new PodDBAdapter(context); - adapter.open(); - Cursor cursor = adapter.getUnreadItemIdsCursor(); - long[] itemIds = new long[cursor.getCount()]; - int i = 0; - if (cursor.moveToFirst()) { - do { - itemIds[i] = cursor.getLong(PodDBAdapter.KEY_ID_INDEX); - i++; - } while (cursor.moveToNext()); - } - return itemIds; - } - - public static List<FeedItem> getPlaybackHistory(final Context context) { - if (AppConfig.DEBUG) - Log.d(TAG, "Loading playback history"); - final int PLAYBACK_HISTORY_SIZE = 50; - - PodDBAdapter adapter = new PodDBAdapter(context); - adapter.open(); - - Cursor mediaCursor = adapter.getCompletedMediaCursor(PLAYBACK_HISTORY_SIZE); - String[] itemIds = new String[mediaCursor.getCount()]; - for (int i = 0; i < itemIds.length && mediaCursor.moveToPosition(i); i++) { - itemIds[i] = Long.toString(mediaCursor.getLong(PodDBAdapter.KEY_MEDIA_FEEDITEM_INDEX)); - } - mediaCursor.close(); - Cursor itemCursor = adapter.getFeedItemCursor(itemIds); - List<FeedItem> items = extractItemlistFromCursor(adapter, itemCursor); + public static List<FeedItem> getQueue(Context context) { + if (AppConfig.DEBUG) + Log.d(TAG, "Extracting queue"); + + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + List<FeedItem> items = getQueue(context, adapter); + adapter.close(); + return items; + } + + public static List<FeedItem> getDownloadedItems(Context context) { + if (AppConfig.DEBUG) + Log.d(TAG, "Extracting downloaded items"); + + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + + Cursor itemlistCursor = adapter.getDownloadedItemsCursor(); + List<FeedItem> items = extractItemlistFromCursor(adapter, + itemlistCursor); + itemlistCursor.close(); loadFeedDataOfFeedItemlist(context, items); - itemCursor.close(); - - adapter.close(); - return items; - } - - public static List<DownloadStatus> getDownloadLog(Context context) { - if (AppConfig.DEBUG) - Log.d(TAG, "Extracting DownloadLog"); - - PodDBAdapter adapter = new PodDBAdapter(context); - adapter.open(); - Cursor logCursor = adapter.getDownloadLogCursor(); - List<DownloadStatus> downloadLog = new ArrayList<DownloadStatus>( - 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)); - } else { + Collections.sort(items, new FeedItemPubdateComparator()); + + adapter.close(); + return items; + + } + + public static List<FeedItem> 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<FeedItem> items = extractItemlistFromCursor(adapter, + itemlistCursor); + itemlistCursor.close(); + + loadFeedDataOfFeedItemlist(context, items); + + adapter.close(); + + return items; + } + + public static long[] getUnreadItemIds(Context context) { + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + Cursor cursor = adapter.getUnreadItemIdsCursor(); + long[] itemIds = new long[cursor.getCount()]; + int i = 0; + if (cursor.moveToFirst()) { + do { + itemIds[i] = cursor.getLong(PodDBAdapter.KEY_ID_INDEX); + i++; + } while (cursor.moveToNext()); + } + return itemIds; + } + + public static List<FeedItem> getPlaybackHistory(final Context context) { + if (AppConfig.DEBUG) + Log.d(TAG, "Loading playback history"); + final int PLAYBACK_HISTORY_SIZE = 50; + + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + + Cursor mediaCursor = adapter.getCompletedMediaCursor(PLAYBACK_HISTORY_SIZE); + String[] itemIds = new String[mediaCursor.getCount()]; + for (int i = 0; i < itemIds.length && mediaCursor.moveToPosition(i); i++) { + itemIds[i] = Long.toString(mediaCursor.getLong(PodDBAdapter.KEY_MEDIA_FEEDITEM_INDEX)); + } + mediaCursor.close(); + Cursor itemCursor = adapter.getFeedItemCursor(itemIds); + List<FeedItem> items = extractItemlistFromCursor(adapter, itemCursor); + loadFeedDataOfFeedItemlist(context, items); + itemCursor.close(); + + adapter.close(); + return items; + } + + public static List<DownloadStatus> getDownloadLog(Context context) { + if (AppConfig.DEBUG) + Log.d(TAG, "Extracting DownloadLog"); + + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + Cursor logCursor = adapter.getDownloadLogCursor(); + List<DownloadStatus> downloadLog = new ArrayList<DownloadStatus>( + 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 List<FeedItemStatistics> getFeedStatisticsList(final Context context) { + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + List<FeedItemStatistics> result = new ArrayList<FeedItemStatistics>(); + Cursor cursor = adapter.getFeedStatisticsCursor(); + if (cursor.moveToFirst()) { + do { + result.add(new FeedItemStatistics(cursor.getLong(PodDBAdapter.IDX_FEEDSTATISTICS_FEED), + cursor.getInt(PodDBAdapter.IDX_FEEDSTATISTICS_NUM_ITEMS), + cursor.getInt(PodDBAdapter.IDX_FEEDSTATISTICS_NEW_ITEMS), + cursor.getInt(PodDBAdapter.IDX_FEEDSTATISTICS_IN_PROGRESS_EPISODES), + new Date(cursor.getLong(PodDBAdapter.IDX_FEEDSTATISTICS_LATEST_EPISODE)))); + } while (cursor.moveToNext()); + } + + cursor.close(); + adapter.close(); + return result; + } + + 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)); + } else { Log.e(TAG, "getFeed could not find feed with id " + feedId); } - adapter.close(); - return feed; - } - - static FeedItem getFeedItem(final Context context, final long itemId, PodDBAdapter adapter) { - if (AppConfig.DEBUG) - Log.d(TAG, "Loading feeditem with id " + itemId); - FeedItem item = null; - - Cursor itemCursor = adapter.getFeedItemCursor(Long.toString(itemId)); - if (itemCursor.moveToFirst()) { - List<FeedItem> list = extractItemlistFromCursor(adapter, itemCursor); - if (list.size() > 0) { - item = list.get(0); + adapter.close(); + return feed; + } + + static FeedItem getFeedItem(final Context context, final long itemId, PodDBAdapter adapter) { + if (AppConfig.DEBUG) + Log.d(TAG, "Loading feeditem with id " + itemId); + FeedItem item = null; + + Cursor itemCursor = adapter.getFeedItemCursor(Long.toString(itemId)); + if (itemCursor.moveToFirst()) { + List<FeedItem> list = extractItemlistFromCursor(adapter, itemCursor); + if (list.size() > 0) { + item = list.get(0); loadFeedDataOfFeedItemlist(context, list); - } - } - return item; + } + } + return item; - } + } - public static FeedItem getFeedItem(final Context context, final long itemId) { - if (AppConfig.DEBUG) - Log.d(TAG, "Loading feeditem with id " + itemId); + public static FeedItem getFeedItem(final Context context, final long itemId) { + if (AppConfig.DEBUG) + Log.d(TAG, "Loading feeditem with id " + itemId); - PodDBAdapter adapter = new PodDBAdapter(context); - adapter.open(); - FeedItem item = getFeedItem(context, itemId, adapter); - adapter.close(); - return item; + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + FeedItem item = getFeedItem(context, itemId, adapter); + adapter.close(); + return item; - } + } public static void loadExtraInformationOfFeedItem(final Context context, final FeedItem item) { PodDBAdapter adapter = new PodDBAdapter(context); @@ -499,14 +519,14 @@ public final class DBReader { } adapter.close(); } - - public static int getNumberOfDownloadedEpisodes(final Context context) { - PodDBAdapter adapter = new PodDBAdapter(context); - adapter.open(); - final int result = adapter.getNumberOfDownloadedEpisodes(); - adapter.close(); - return result; - } + + public static int getNumberOfDownloadedEpisodes(final Context context) { + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + final int result = adapter.getNumberOfDownloadedEpisodes(); + adapter.close(); + return result; + } public static int getNumberOfUnreadItems(final Context context) { PodDBAdapter adapter = new PodDBAdapter(context); @@ -519,10 +539,9 @@ public final class DBReader { /** * Searches the DB for a FeedImage of the given id. * - * @param imageId - * The id of the object + * @param imageId The id of the object * @return The found object - * */ + */ public static FeedImage getFeedImage(final Context context, final long imageId) { PodDBAdapter adapter = new PodDBAdapter(context); adapter.open(); @@ -531,37 +550,35 @@ public final class DBReader { return result; } - /** - * Searches the DB for a FeedImage of the given id. - * - * @param id - * The id of the object - * @return The found object - * */ - 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; - } + /** + * Searches the DB for a FeedImage of the given id. + * + * @param id The id of the object + * @return The found object + */ + 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; + } /** * Searches the DB for a FeedMedia of the given id. * - * @param mediaId - * The id of the object + * @param mediaId The id of the object * @return The found object - * */ + */ public static FeedMedia getFeedMedia(final Context context, final long mediaId) { PodDBAdapter adapter = new PodDBAdapter(context); diff --git a/src/de/danoeh/antennapod/storage/FeedItemStatistics.java b/src/de/danoeh/antennapod/storage/FeedItemStatistics.java new file mode 100644 index 000000000..17e838761 --- /dev/null +++ b/src/de/danoeh/antennapod/storage/FeedItemStatistics.java @@ -0,0 +1,42 @@ +package de.danoeh.antennapod.storage; + +import java.util.Date; + +/** + * Contains information about a feed's items. + */ +public class FeedItemStatistics { + private long feedID; + private int numberOfItems; + private int numberOfNewItems; + private int numberOfInProgressItems; + private Date lastUpdate; + + public FeedItemStatistics(long feedID, int numberOfItems, int numberOfNewItems, int numberOfInProgressItems, Date lastUpdate) { + this.feedID = feedID; + this.numberOfItems = numberOfItems; + this.numberOfNewItems = numberOfNewItems; + this.numberOfInProgressItems = numberOfInProgressItems; + this.lastUpdate = lastUpdate; + } + + public long getFeedID() { + return feedID; + } + + public int getNumberOfItems() { + return numberOfItems; + } + + public int getNumberOfNewItems() { + return numberOfNewItems; + } + + public int getNumberOfInProgressItems() { + return numberOfInProgressItems; + } + + public Date getLastUpdate() { + return lastUpdate; + } +} diff --git a/src/de/danoeh/antennapod/storage/PodDBAdapter.java b/src/de/danoeh/antennapod/storage/PodDBAdapter.java index 198d95d64..5171b6932 100644 --- a/src/de/danoeh/antennapod/storage/PodDBAdapter.java +++ b/src/de/danoeh/antennapod/storage/PodDBAdapter.java @@ -26,214 +26,224 @@ import de.danoeh.antennapod.service.download.DownloadStatus; /** * Implements methods for accessing the database - * */ + */ public class PodDBAdapter { - private static final String TAG = "PodDBAdapter"; - private static final int DATABASE_VERSION = 9; - private static final String DATABASE_NAME = "Antennapod.db"; - - /** Maximum number of arguments for IN-operator. */ - public static final int IN_OPERATOR_MAXIMUM = 800; - - /** Maximum number of entries per search request. */ + private static final String TAG = "PodDBAdapter"; + private static final int DATABASE_VERSION = 9; + private static final String DATABASE_NAME = "Antennapod.db"; + + /** + * Maximum number of arguments for IN-operator. + */ + public static final int IN_OPERATOR_MAXIMUM = 800; + + /** + * Maximum number of entries per search request. + */ public static final int SEARCH_LIMIT = 30; - // ----------- Column indices - // ----------- General indices - public static final int KEY_ID_INDEX = 0; - public static final int KEY_TITLE_INDEX = 1; - public static final int KEY_FILE_URL_INDEX = 2; - public static final int KEY_DOWNLOAD_URL_INDEX = 3; - public static final int KEY_DOWNLOADED_INDEX = 4; - public static final int KEY_LINK_INDEX = 5; - public static final int KEY_DESCRIPTION_INDEX = 6; - public static final int KEY_PAYMENT_LINK_INDEX = 7; - // ----------- Feed indices - public static final int KEY_LAST_UPDATE_INDEX = 8; - public static final int KEY_LANGUAGE_INDEX = 9; - public static final int KEY_AUTHOR_INDEX = 10; - public static final int KEY_IMAGE_INDEX = 11; - public static final int KEY_TYPE_INDEX = 12; - public static final int KEY_FEED_IDENTIFIER_INDEX = 13; - // ----------- FeedItem indices - public static final int KEY_CONTENT_ENCODED_INDEX = 2; - public static final int KEY_PUBDATE_INDEX = 3; - public static final int KEY_READ_INDEX = 4; - public static final int KEY_MEDIA_INDEX = 8; - public static final int KEY_FEED_INDEX = 9; - public static final int KEY_HAS_SIMPLECHAPTERS_INDEX = 10; - public static final int KEY_ITEM_IDENTIFIER_INDEX = 11; - // ---------- FeedMedia indices - public static final int KEY_DURATION_INDEX = 1; - public static final int KEY_POSITION_INDEX = 5; - public static final int KEY_SIZE_INDEX = 6; - public static final int KEY_MIME_TYPE_INDEX = 7; - public static final int KEY_PLAYBACK_COMPLETION_DATE_INDEX = 8; + // ----------- Column indices + // ----------- General indices + public static final int KEY_ID_INDEX = 0; + public static final int KEY_TITLE_INDEX = 1; + public static final int KEY_FILE_URL_INDEX = 2; + public static final int KEY_DOWNLOAD_URL_INDEX = 3; + public static final int KEY_DOWNLOADED_INDEX = 4; + public static final int KEY_LINK_INDEX = 5; + public static final int KEY_DESCRIPTION_INDEX = 6; + public static final int KEY_PAYMENT_LINK_INDEX = 7; + // ----------- Feed indices + public static final int KEY_LAST_UPDATE_INDEX = 8; + public static final int KEY_LANGUAGE_INDEX = 9; + public static final int KEY_AUTHOR_INDEX = 10; + public static final int KEY_IMAGE_INDEX = 11; + public static final int KEY_TYPE_INDEX = 12; + public static final int KEY_FEED_IDENTIFIER_INDEX = 13; + // ----------- FeedItem indices + public static final int KEY_CONTENT_ENCODED_INDEX = 2; + public static final int KEY_PUBDATE_INDEX = 3; + public static final int KEY_READ_INDEX = 4; + public static final int KEY_MEDIA_INDEX = 8; + public static final int KEY_FEED_INDEX = 9; + public static final int KEY_HAS_SIMPLECHAPTERS_INDEX = 10; + public static final int KEY_ITEM_IDENTIFIER_INDEX = 11; + // ---------- FeedMedia indices + public static final int KEY_DURATION_INDEX = 1; + public static final int KEY_POSITION_INDEX = 5; + public static final int KEY_SIZE_INDEX = 6; + public static final int KEY_MIME_TYPE_INDEX = 7; + public static final int KEY_PLAYBACK_COMPLETION_DATE_INDEX = 8; public static final int KEY_MEDIA_FEEDITEM_INDEX = 9; - // --------- Download log indices - public static final int KEY_FEEDFILE_INDEX = 1; - public static final int KEY_FEEDFILETYPE_INDEX = 2; - public static final int KEY_REASON_INDEX = 3; - public static final int KEY_SUCCESSFUL_INDEX = 4; - public static final int KEY_COMPLETION_DATE_INDEX = 5; - public static final int KEY_REASON_DETAILED_INDEX = 6; - public static final int KEY_DOWNLOADSTATUS_TITLE_INDEX = 7; - // --------- Queue indices - public static final int KEY_FEEDITEM_INDEX = 1; - public static final int KEY_QUEUE_FEED_INDEX = 2; - // --------- Chapters indices - public static final int KEY_CHAPTER_START_INDEX = 2; - public static final int KEY_CHAPTER_FEEDITEM_INDEX = 3; - public static final int KEY_CHAPTER_LINK_INDEX = 4; - public static final int KEY_CHAPTER_TYPE_INDEX = 5; - - // Key-constants - public static final String KEY_ID = "id"; - public static final String KEY_TITLE = "title"; - public static final String KEY_NAME = "name"; - public static final String KEY_LINK = "link"; - public static final String KEY_DESCRIPTION = "description"; - public static final String KEY_FILE_URL = "file_url"; - public static final String KEY_DOWNLOAD_URL = "download_url"; - public static final String KEY_PUBDATE = "pubDate"; - public static final String KEY_READ = "read"; - public static final String KEY_DURATION = "duration"; - public static final String KEY_POSITION = "position"; - public static final String KEY_SIZE = "filesize"; - public static final String KEY_MIME_TYPE = "mime_type"; - public static final String KEY_IMAGE = "image"; - public static final String KEY_FEED = "feed"; - public static final String KEY_MEDIA = "media"; - public static final String KEY_DOWNLOADED = "downloaded"; - public static final String KEY_LASTUPDATE = "last_update"; - public static final String KEY_FEEDFILE = "feedfile"; - public static final String KEY_REASON = "reason"; - public static final String KEY_SUCCESSFUL = "successful"; - public static final String KEY_FEEDFILETYPE = "feedfile_type"; - public static final String KEY_COMPLETION_DATE = "completion_date"; - public static final String KEY_FEEDITEM = "feeditem"; - public static final String KEY_CONTENT_ENCODED = "content_encoded"; - public static final String KEY_PAYMENT_LINK = "payment_link"; - public static final String KEY_START = "start"; - public static final String KEY_LANGUAGE = "language"; - public static final String KEY_AUTHOR = "author"; - public static final String KEY_HAS_CHAPTERS = "has_simple_chapters"; - public static final String KEY_TYPE = "type"; - public static final String KEY_ITEM_IDENTIFIER = "item_identifier"; - public static final String KEY_FEED_IDENTIFIER = "feed_identifier"; - public static final String KEY_REASON_DETAILED = "reason_detailed"; - public static final String KEY_DOWNLOADSTATUS_TITLE = "title"; - public static final String KEY_CHAPTER_TYPE = "type"; - public static final String KEY_PLAYBACK_COMPLETION_DATE = "playback_completion_date"; - - // Table names - public static final String TABLE_NAME_FEEDS = "Feeds"; - public static final String TABLE_NAME_FEED_ITEMS = "FeedItems"; - public static final String TABLE_NAME_FEED_IMAGES = "FeedImages"; - public static final String TABLE_NAME_FEED_MEDIA = "FeedMedia"; - public static final String TABLE_NAME_DOWNLOAD_LOG = "DownloadLog"; - public static final String TABLE_NAME_QUEUE = "Queue"; - public static final String TABLE_NAME_SIMPLECHAPTERS = "SimpleChapters"; - - // SQL Statements for creating new tables - private static final String TABLE_PRIMARY_KEY = KEY_ID - + " INTEGER PRIMARY KEY AUTOINCREMENT ,"; - - private static final String CREATE_TABLE_FEEDS = "CREATE TABLE " - + TABLE_NAME_FEEDS + " (" + TABLE_PRIMARY_KEY + KEY_TITLE - + " TEXT," + KEY_FILE_URL + " TEXT," + KEY_DOWNLOAD_URL + " TEXT," - + KEY_DOWNLOADED + " INTEGER," + KEY_LINK + " TEXT," - + KEY_DESCRIPTION + " TEXT," + KEY_PAYMENT_LINK + " TEXT," - + KEY_LASTUPDATE + " TEXT," + KEY_LANGUAGE + " TEXT," + KEY_AUTHOR - + " TEXT," + KEY_IMAGE + " INTEGER," + KEY_TYPE + " TEXT," - + KEY_FEED_IDENTIFIER + " TEXT)";; - - private static final String CREATE_TABLE_FEED_ITEMS = "CREATE TABLE " - + TABLE_NAME_FEED_ITEMS + " (" + TABLE_PRIMARY_KEY + KEY_TITLE - + " TEXT," + KEY_CONTENT_ENCODED + " TEXT," + KEY_PUBDATE - + " INTEGER," + KEY_READ + " INTEGER," + KEY_LINK + " TEXT," - + KEY_DESCRIPTION + " TEXT," + KEY_PAYMENT_LINK + " TEXT," - + KEY_MEDIA + " INTEGER," + KEY_FEED + " INTEGER," - + KEY_HAS_CHAPTERS + " INTEGER," + KEY_ITEM_IDENTIFIER + " TEXT)"; - - private static final String CREATE_TABLE_FEED_IMAGES = "CREATE TABLE " - + TABLE_NAME_FEED_IMAGES + " (" + TABLE_PRIMARY_KEY + KEY_TITLE - + " TEXT," + KEY_FILE_URL + " TEXT," + KEY_DOWNLOAD_URL + " TEXT," - + KEY_DOWNLOADED + " INTEGER)"; - - private static final String CREATE_TABLE_FEED_MEDIA = "CREATE TABLE " - + TABLE_NAME_FEED_MEDIA + " (" + TABLE_PRIMARY_KEY + KEY_DURATION - + " INTEGER," + KEY_FILE_URL + " TEXT," + KEY_DOWNLOAD_URL - + " TEXT," + KEY_DOWNLOADED + " INTEGER," + KEY_POSITION - + " INTEGER," + KEY_SIZE + " INTEGER," + KEY_MIME_TYPE + " TEXT," - + KEY_PLAYBACK_COMPLETION_DATE + " INTEGER," + // --------- Download log indices + public static final int KEY_FEEDFILE_INDEX = 1; + public static final int KEY_FEEDFILETYPE_INDEX = 2; + public static final int KEY_REASON_INDEX = 3; + public static final int KEY_SUCCESSFUL_INDEX = 4; + public static final int KEY_COMPLETION_DATE_INDEX = 5; + public static final int KEY_REASON_DETAILED_INDEX = 6; + public static final int KEY_DOWNLOADSTATUS_TITLE_INDEX = 7; + // --------- Queue indices + public static final int KEY_FEEDITEM_INDEX = 1; + public static final int KEY_QUEUE_FEED_INDEX = 2; + // --------- Chapters indices + public static final int KEY_CHAPTER_START_INDEX = 2; + public static final int KEY_CHAPTER_FEEDITEM_INDEX = 3; + public static final int KEY_CHAPTER_LINK_INDEX = 4; + public static final int KEY_CHAPTER_TYPE_INDEX = 5; + + // Key-constants + public static final String KEY_ID = "id"; + public static final String KEY_TITLE = "title"; + public static final String KEY_NAME = "name"; + public static final String KEY_LINK = "link"; + public static final String KEY_DESCRIPTION = "description"; + public static final String KEY_FILE_URL = "file_url"; + public static final String KEY_DOWNLOAD_URL = "download_url"; + public static final String KEY_PUBDATE = "pubDate"; + public static final String KEY_READ = "read"; + public static final String KEY_DURATION = "duration"; + public static final String KEY_POSITION = "position"; + public static final String KEY_SIZE = "filesize"; + public static final String KEY_MIME_TYPE = "mime_type"; + public static final String KEY_IMAGE = "image"; + public static final String KEY_FEED = "feed"; + public static final String KEY_MEDIA = "media"; + public static final String KEY_DOWNLOADED = "downloaded"; + public static final String KEY_LASTUPDATE = "last_update"; + public static final String KEY_FEEDFILE = "feedfile"; + public static final String KEY_REASON = "reason"; + public static final String KEY_SUCCESSFUL = "successful"; + public static final String KEY_FEEDFILETYPE = "feedfile_type"; + public static final String KEY_COMPLETION_DATE = "completion_date"; + public static final String KEY_FEEDITEM = "feeditem"; + public static final String KEY_CONTENT_ENCODED = "content_encoded"; + public static final String KEY_PAYMENT_LINK = "payment_link"; + public static final String KEY_START = "start"; + public static final String KEY_LANGUAGE = "language"; + public static final String KEY_AUTHOR = "author"; + public static final String KEY_HAS_CHAPTERS = "has_simple_chapters"; + public static final String KEY_TYPE = "type"; + public static final String KEY_ITEM_IDENTIFIER = "item_identifier"; + public static final String KEY_FEED_IDENTIFIER = "feed_identifier"; + public static final String KEY_REASON_DETAILED = "reason_detailed"; + public static final String KEY_DOWNLOADSTATUS_TITLE = "title"; + public static final String KEY_CHAPTER_TYPE = "type"; + public static final String KEY_PLAYBACK_COMPLETION_DATE = "playback_completion_date"; + + // Table names + public static final String TABLE_NAME_FEEDS = "Feeds"; + public static final String TABLE_NAME_FEED_ITEMS = "FeedItems"; + public static final String TABLE_NAME_FEED_IMAGES = "FeedImages"; + public static final String TABLE_NAME_FEED_MEDIA = "FeedMedia"; + public static final String TABLE_NAME_DOWNLOAD_LOG = "DownloadLog"; + public static final String TABLE_NAME_QUEUE = "Queue"; + public static final String TABLE_NAME_SIMPLECHAPTERS = "SimpleChapters"; + + // SQL Statements for creating new tables + private static final String TABLE_PRIMARY_KEY = KEY_ID + + " INTEGER PRIMARY KEY AUTOINCREMENT ,"; + + private static final String CREATE_TABLE_FEEDS = "CREATE TABLE " + + TABLE_NAME_FEEDS + " (" + TABLE_PRIMARY_KEY + KEY_TITLE + + " TEXT," + KEY_FILE_URL + " TEXT," + KEY_DOWNLOAD_URL + " TEXT," + + KEY_DOWNLOADED + " INTEGER," + KEY_LINK + " TEXT," + + KEY_DESCRIPTION + " TEXT," + KEY_PAYMENT_LINK + " TEXT," + + KEY_LASTUPDATE + " TEXT," + KEY_LANGUAGE + " TEXT," + KEY_AUTHOR + + " TEXT," + KEY_IMAGE + " INTEGER," + KEY_TYPE + " TEXT," + + KEY_FEED_IDENTIFIER + " TEXT)"; + ; + + private static final String CREATE_TABLE_FEED_ITEMS = "CREATE TABLE " + + TABLE_NAME_FEED_ITEMS + " (" + TABLE_PRIMARY_KEY + KEY_TITLE + + " TEXT," + KEY_CONTENT_ENCODED + " TEXT," + KEY_PUBDATE + + " INTEGER," + KEY_READ + " INTEGER," + KEY_LINK + " TEXT," + + KEY_DESCRIPTION + " TEXT," + KEY_PAYMENT_LINK + " TEXT," + + KEY_MEDIA + " INTEGER," + KEY_FEED + " INTEGER," + + KEY_HAS_CHAPTERS + " INTEGER," + KEY_ITEM_IDENTIFIER + " TEXT)"; + + private static final String CREATE_TABLE_FEED_IMAGES = "CREATE TABLE " + + TABLE_NAME_FEED_IMAGES + " (" + TABLE_PRIMARY_KEY + KEY_TITLE + + " TEXT," + KEY_FILE_URL + " TEXT," + KEY_DOWNLOAD_URL + " TEXT," + + KEY_DOWNLOADED + " INTEGER)"; + + private static final String CREATE_TABLE_FEED_MEDIA = "CREATE TABLE " + + TABLE_NAME_FEED_MEDIA + " (" + TABLE_PRIMARY_KEY + KEY_DURATION + + " INTEGER," + KEY_FILE_URL + " TEXT," + KEY_DOWNLOAD_URL + + " TEXT," + KEY_DOWNLOADED + " INTEGER," + KEY_POSITION + + " INTEGER," + KEY_SIZE + " INTEGER," + KEY_MIME_TYPE + " TEXT," + + KEY_PLAYBACK_COMPLETION_DATE + " INTEGER," + KEY_FEEDITEM + " INTEGER)"; - private static final String CREATE_TABLE_DOWNLOAD_LOG = "CREATE TABLE " - + TABLE_NAME_DOWNLOAD_LOG + " (" + TABLE_PRIMARY_KEY + KEY_FEEDFILE - + " INTEGER," + KEY_FEEDFILETYPE + " INTEGER," + KEY_REASON - + " INTEGER," + KEY_SUCCESSFUL + " INTEGER," + KEY_COMPLETION_DATE - + " INTEGER," + KEY_REASON_DETAILED + " TEXT," - + KEY_DOWNLOADSTATUS_TITLE + " TEXT)"; - - private static final String CREATE_TABLE_QUEUE = "CREATE TABLE " - + TABLE_NAME_QUEUE + "(" + KEY_ID + " INTEGER PRIMARY KEY," - + KEY_FEEDITEM + " INTEGER," + KEY_FEED + " INTEGER)"; - - private static final String CREATE_TABLE_SIMPLECHAPTERS = "CREATE TABLE " - + TABLE_NAME_SIMPLECHAPTERS + " (" + TABLE_PRIMARY_KEY + KEY_TITLE - + " TEXT," + KEY_START + " INTEGER," + KEY_FEEDITEM + " INTEGER," - + KEY_LINK + " TEXT," + KEY_CHAPTER_TYPE + " INTEGER)"; - - private SQLiteDatabase db; - private final Context context; - private PodDBHelper helper; - - /** - * Select all columns from the feeditems-table except description and - * content-encoded. - */ - private static final String[] SEL_FI_SMALL = { - TABLE_NAME_FEED_ITEMS + "." + KEY_ID, - TABLE_NAME_FEED_ITEMS + "." + KEY_TITLE, - TABLE_NAME_FEED_ITEMS + "." + KEY_PUBDATE, - TABLE_NAME_FEED_ITEMS + "." + KEY_READ, - TABLE_NAME_FEED_ITEMS + "." + KEY_LINK, - TABLE_NAME_FEED_ITEMS + "." + KEY_PAYMENT_LINK, KEY_MEDIA, - TABLE_NAME_FEED_ITEMS + "." + KEY_FEED, - TABLE_NAME_FEED_ITEMS + "." + KEY_HAS_CHAPTERS, - TABLE_NAME_FEED_ITEMS + "." + KEY_ITEM_IDENTIFIER }; - - /** Contains SEL_FI_SMALL as comma-separated list. Useful for raw queries. */ - private static final String SEL_FI_SMALL_STR; - static { - String selFiSmall = Arrays.toString(SEL_FI_SMALL); - SEL_FI_SMALL_STR = selFiSmall.substring(1, selFiSmall.length() - 1); - } - - // column indices for SEL_FI_SMALL - - public static final int IDX_FI_SMALL_ID = 0; - public static final int IDX_FI_SMALL_TITLE = 1; - public static final int IDX_FI_SMALL_PUBDATE = 2; - public static final int IDX_FI_SMALL_READ = 3; - public static final int IDX_FI_SMALL_LINK = 4; - public static final int IDX_FI_SMALL_PAYMENT_LINK = 5; - public static final int IDX_FI_SMALL_MEDIA = 6; - public static final int IDX_FI_SMALL_FEED = 7; - public static final int IDX_FI_SMALL_HAS_CHAPTERS = 8; - public static final int IDX_FI_SMALL_ITEM_IDENTIFIER = 9; - - /** Select id, description and content-encoded column from feeditems. */ - public static final String[] SEL_FI_EXTRA = { KEY_ID, KEY_DESCRIPTION, - KEY_CONTENT_ENCODED, KEY_FEED }; - - // column indices for SEL_FI_EXTRA - - public static final int IDX_FI_EXTRA_ID = 0; - public static final int IDX_FI_EXTRA_DESCRIPTION = 1; - public static final int IDX_FI_EXTRA_CONTENT_ENCODED = 2; - public static final int IDX_FI_EXTRA_FEED = 3; + private static final String CREATE_TABLE_DOWNLOAD_LOG = "CREATE TABLE " + + TABLE_NAME_DOWNLOAD_LOG + " (" + TABLE_PRIMARY_KEY + KEY_FEEDFILE + + " INTEGER," + KEY_FEEDFILETYPE + " INTEGER," + KEY_REASON + + " INTEGER," + KEY_SUCCESSFUL + " INTEGER," + KEY_COMPLETION_DATE + + " INTEGER," + KEY_REASON_DETAILED + " TEXT," + + KEY_DOWNLOADSTATUS_TITLE + " TEXT)"; + + private static final String CREATE_TABLE_QUEUE = "CREATE TABLE " + + TABLE_NAME_QUEUE + "(" + KEY_ID + " INTEGER PRIMARY KEY," + + KEY_FEEDITEM + " INTEGER," + KEY_FEED + " INTEGER)"; + + private static final String CREATE_TABLE_SIMPLECHAPTERS = "CREATE TABLE " + + TABLE_NAME_SIMPLECHAPTERS + " (" + TABLE_PRIMARY_KEY + KEY_TITLE + + " TEXT," + KEY_START + " INTEGER," + KEY_FEEDITEM + " INTEGER," + + KEY_LINK + " TEXT," + KEY_CHAPTER_TYPE + " INTEGER)"; + + private SQLiteDatabase db; + private final Context context; + private PodDBHelper helper; + + /** + * Select all columns from the feeditems-table except description and + * content-encoded. + */ + private static final String[] SEL_FI_SMALL = { + TABLE_NAME_FEED_ITEMS + "." + KEY_ID, + TABLE_NAME_FEED_ITEMS + "." + KEY_TITLE, + TABLE_NAME_FEED_ITEMS + "." + KEY_PUBDATE, + TABLE_NAME_FEED_ITEMS + "." + KEY_READ, + TABLE_NAME_FEED_ITEMS + "." + KEY_LINK, + TABLE_NAME_FEED_ITEMS + "." + KEY_PAYMENT_LINK, KEY_MEDIA, + TABLE_NAME_FEED_ITEMS + "." + KEY_FEED, + TABLE_NAME_FEED_ITEMS + "." + KEY_HAS_CHAPTERS, + TABLE_NAME_FEED_ITEMS + "." + KEY_ITEM_IDENTIFIER}; + + /** + * Contains SEL_FI_SMALL as comma-separated list. Useful for raw queries. + */ + private static final String SEL_FI_SMALL_STR; + + static { + String selFiSmall = Arrays.toString(SEL_FI_SMALL); + SEL_FI_SMALL_STR = selFiSmall.substring(1, selFiSmall.length() - 1); + } + + // column indices for SEL_FI_SMALL + + public static final int IDX_FI_SMALL_ID = 0; + public static final int IDX_FI_SMALL_TITLE = 1; + public static final int IDX_FI_SMALL_PUBDATE = 2; + public static final int IDX_FI_SMALL_READ = 3; + public static final int IDX_FI_SMALL_LINK = 4; + public static final int IDX_FI_SMALL_PAYMENT_LINK = 5; + public static final int IDX_FI_SMALL_MEDIA = 6; + public static final int IDX_FI_SMALL_FEED = 7; + public static final int IDX_FI_SMALL_HAS_CHAPTERS = 8; + public static final int IDX_FI_SMALL_ITEM_IDENTIFIER = 9; + + /** + * Select id, description and content-encoded column from feeditems. + */ + public static final String[] SEL_FI_EXTRA = {KEY_ID, KEY_DESCRIPTION, + KEY_CONTENT_ENCODED, KEY_FEED}; + + // column indices for SEL_FI_EXTRA + + public static final int IDX_FI_EXTRA_ID = 0; + public static final int IDX_FI_EXTRA_DESCRIPTION = 1; + public static final int IDX_FI_EXTRA_CONTENT_ENCODED = 2; + public static final int IDX_FI_EXTRA_FEED = 3; static PodDBHelper dbHelperSingleton; @@ -244,492 +254,494 @@ public class PodDBAdapter { return dbHelperSingleton; } - public PodDBAdapter(Context c) { - this.context = c; - helper = getDbHelperSingleton(c.getApplicationContext()); - } - - public PodDBAdapter open() { - if (db == null || !db.isOpen() || db.isReadOnly()) { - if (AppConfig.DEBUG) - Log.d(TAG, "Opening DB"); - try { - db = helper.getWritableDatabase(); - } catch (SQLException ex) { - ex.printStackTrace(); - db = helper.getReadableDatabase(); - } - } - return this; - } - - public void close() { - if (AppConfig.DEBUG) - Log.d(TAG, "Closing DB"); - //db.close(); - } - - /** - * Inserts or updates a feed entry - * - * @return the id of the entry - * */ - public long setFeed(Feed feed) { - ContentValues values = new ContentValues(); - values.put(KEY_TITLE, feed.getTitle()); - values.put(KEY_LINK, feed.getLink()); - values.put(KEY_DESCRIPTION, feed.getDescription()); - values.put(KEY_PAYMENT_LINK, feed.getPaymentLink()); - values.put(KEY_AUTHOR, feed.getAuthor()); - values.put(KEY_LANGUAGE, feed.getLanguage()); - if (feed.getImage() != null) { - if (feed.getImage().getId() == 0) { - setImage(feed.getImage()); - } - values.put(KEY_IMAGE, feed.getImage().getId()); - } - - values.put(KEY_FILE_URL, feed.getFile_url()); - values.put(KEY_DOWNLOAD_URL, feed.getDownload_url()); - values.put(KEY_DOWNLOADED, feed.isDownloaded()); - values.put(KEY_LASTUPDATE, feed.getLastUpdate().getTime()); - values.put(KEY_TYPE, feed.getType()); - values.put(KEY_FEED_IDENTIFIER, feed.getFeedIdentifier()); - if (feed.getId() == 0) { - // Create new entry - if (AppConfig.DEBUG) - Log.d(this.toString(), "Inserting new Feed into db"); - feed.setId(db.insert(TABLE_NAME_FEEDS, null, values)); - } else { - if (AppConfig.DEBUG) - Log.d(this.toString(), "Updating existing Feed in db"); - db.update(TABLE_NAME_FEEDS, values, KEY_ID + "=?", - new String[] { Long.toString(feed.getId()) }); - } - return feed.getId(); - } - - /** - * Inserts or updates an image entry - * - * @return the id of the entry - * */ - public long setImage(FeedImage image) { + public PodDBAdapter(Context c) { + this.context = c; + helper = getDbHelperSingleton(c.getApplicationContext()); + } + + public PodDBAdapter open() { + if (db == null || !db.isOpen() || db.isReadOnly()) { + if (AppConfig.DEBUG) + Log.d(TAG, "Opening DB"); + try { + db = helper.getWritableDatabase(); + } catch (SQLException ex) { + ex.printStackTrace(); + db = helper.getReadableDatabase(); + } + } + return this; + } + + public void close() { + if (AppConfig.DEBUG) + Log.d(TAG, "Closing DB"); + //db.close(); + } + + /** + * Inserts or updates a feed entry + * + * @return the id of the entry + */ + public long setFeed(Feed feed) { + ContentValues values = new ContentValues(); + values.put(KEY_TITLE, feed.getTitle()); + values.put(KEY_LINK, feed.getLink()); + values.put(KEY_DESCRIPTION, feed.getDescription()); + values.put(KEY_PAYMENT_LINK, feed.getPaymentLink()); + values.put(KEY_AUTHOR, feed.getAuthor()); + values.put(KEY_LANGUAGE, feed.getLanguage()); + if (feed.getImage() != null) { + if (feed.getImage().getId() == 0) { + setImage(feed.getImage()); + } + values.put(KEY_IMAGE, feed.getImage().getId()); + } + + values.put(KEY_FILE_URL, feed.getFile_url()); + values.put(KEY_DOWNLOAD_URL, feed.getDownload_url()); + values.put(KEY_DOWNLOADED, feed.isDownloaded()); + values.put(KEY_LASTUPDATE, feed.getLastUpdate().getTime()); + values.put(KEY_TYPE, feed.getType()); + values.put(KEY_FEED_IDENTIFIER, feed.getFeedIdentifier()); + if (feed.getId() == 0) { + // Create new entry + if (AppConfig.DEBUG) + Log.d(this.toString(), "Inserting new Feed into db"); + feed.setId(db.insert(TABLE_NAME_FEEDS, null, values)); + } else { + if (AppConfig.DEBUG) + Log.d(this.toString(), "Updating existing Feed in db"); + db.update(TABLE_NAME_FEEDS, values, KEY_ID + "=?", + new String[]{String.valueOf(feed.getId())}); + } + return feed.getId(); + } + + /** + * Inserts or updates an image entry + * + * @return the id of the entry + */ + public long setImage(FeedImage image) { db.beginTransaction(); - ContentValues values = new ContentValues(); - values.put(KEY_TITLE, image.getTitle()); - values.put(KEY_DOWNLOAD_URL, image.getDownload_url()); - values.put(KEY_DOWNLOADED, image.isDownloaded()); - values.put(KEY_FILE_URL, image.getFile_url()); - if (image.getId() == 0) { - image.setId(db.insert(TABLE_NAME_FEED_IMAGES, null, values)); - } else { - db.update(TABLE_NAME_FEED_IMAGES, values, KEY_ID + "=?", - new String[] { String.valueOf(image.getId()) }); - } - if (image.getFeed() != null && image.getFeed().getId() != 0 ) { + ContentValues values = new ContentValues(); + values.put(KEY_TITLE, image.getTitle()); + values.put(KEY_DOWNLOAD_URL, image.getDownload_url()); + values.put(KEY_DOWNLOADED, image.isDownloaded()); + values.put(KEY_FILE_URL, image.getFile_url()); + if (image.getId() == 0) { + image.setId(db.insert(TABLE_NAME_FEED_IMAGES, null, values)); + } else { + db.update(TABLE_NAME_FEED_IMAGES, values, KEY_ID + "=?", + new String[]{String.valueOf(image.getId())}); + } + if (image.getFeed() != null && image.getFeed().getId() != 0) { values.clear(); values.put(KEY_IMAGE, image.getId()); - db.update(TABLE_NAME_FEEDS, values, KEY_ID + "=?", new String[] {String.valueOf(image.getFeed().getId())}); + db.update(TABLE_NAME_FEEDS, values, KEY_ID + "=?", new String[]{String.valueOf(image.getFeed().getId())}); } db.setTransactionSuccessful(); db.endTransaction(); - return image.getId(); - } - - /** - * Inserts or updates an image entry - * - * @return the id of the entry - */ - public long setMedia(FeedMedia media) { - ContentValues values = new ContentValues(); - values.put(KEY_DURATION, media.getDuration()); - values.put(KEY_POSITION, media.getPosition()); - values.put(KEY_SIZE, media.getSize()); - values.put(KEY_MIME_TYPE, media.getMime_type()); - values.put(KEY_DOWNLOAD_URL, media.getDownload_url()); - values.put(KEY_DOWNLOADED, media.isDownloaded()); - values.put(KEY_FILE_URL, media.getFile_url()); - if (media.getPlaybackCompletionDate() != null) { - values.put(KEY_PLAYBACK_COMPLETION_DATE, media - .getPlaybackCompletionDate().getTime()); - } else { - values.put(KEY_PLAYBACK_COMPLETION_DATE, 0); - } + return image.getId(); + } + + /** + * Inserts or updates an image entry + * + * @return the id of the entry + */ + public long setMedia(FeedMedia media) { + ContentValues values = new ContentValues(); + values.put(KEY_DURATION, media.getDuration()); + values.put(KEY_POSITION, media.getPosition()); + values.put(KEY_SIZE, media.getSize()); + values.put(KEY_MIME_TYPE, media.getMime_type()); + values.put(KEY_DOWNLOAD_URL, media.getDownload_url()); + values.put(KEY_DOWNLOADED, media.isDownloaded()); + values.put(KEY_FILE_URL, media.getFile_url()); + if (media.getPlaybackCompletionDate() != null) { + values.put(KEY_PLAYBACK_COMPLETION_DATE, media + .getPlaybackCompletionDate().getTime()); + } else { + values.put(KEY_PLAYBACK_COMPLETION_DATE, 0); + } if (media.getItem() != null) { values.put(KEY_FEEDITEM, media.getItem().getId()); } - if (media.getId() == 0) { - media.setId(db.insert(TABLE_NAME_FEED_MEDIA, null, values)); - } else { - db.update(TABLE_NAME_FEED_MEDIA, values, KEY_ID + "=?", - new String[] { String.valueOf(media.getId()) }); - } - return media.getId(); - } + if (media.getId() == 0) { + media.setId(db.insert(TABLE_NAME_FEED_MEDIA, null, values)); + } else { + db.update(TABLE_NAME_FEED_MEDIA, values, KEY_ID + "=?", + new String[]{String.valueOf(media.getId())}); + } + return media.getId(); + } public void setFeedMediaPosition(FeedMedia media) { if (media.getId() != 0) { ContentValues values = new ContentValues(); values.put(KEY_POSITION, media.getPosition()); db.update(TABLE_NAME_FEED_MEDIA, values, KEY_ID + "=?", - new String[] { String.valueOf(media.getId()) }); + new String[]{String.valueOf(media.getId())}); } else { Log.e(TAG, "setFeedMediaPosition: ID of media was 0"); } } - /** - * Insert all FeedItems of a feed and the feed object itself in a single - * transaction - */ - public void setCompleteFeed(Feed feed) { - db.beginTransaction(); - setFeed(feed); - for (FeedItem item : feed.getItemsArray()) { - setFeedItem(item); - } - db.setTransactionSuccessful(); - db.endTransaction(); - } - - public void setFeedItemlist(List<FeedItem> items) { - db.beginTransaction(); - for (FeedItem item : items) { - setFeedItem(item); - } - db.setTransactionSuccessful(); - db.endTransaction(); - } - - public long setSingleFeedItem(FeedItem item) { - db.beginTransaction(); - long result = setFeedItem(item); - db.setTransactionSuccessful(); - db.endTransaction(); - return result; - } - - /** - * Inserts or updates a feeditem entry - * - * @return the id of the entry - */ - private long setFeedItem(FeedItem item) { - ContentValues values = new ContentValues(); - values.put(KEY_TITLE, item.getTitle()); - values.put(KEY_LINK, item.getLink()); - if (item.getDescription() != null) { - values.put(KEY_DESCRIPTION, item.getDescription()); - } - if (item.getContentEncoded() != null) { - values.put(KEY_CONTENT_ENCODED, item.getContentEncoded()); - } - values.put(KEY_PUBDATE, item.getPubDate().getTime()); - values.put(KEY_PAYMENT_LINK, item.getPaymentLink()); - if (item.getFeed().getId() == 0) { - setFeed(item.getFeed()); - } - values.put(KEY_FEED, item.getFeed().getId()); - values.put(KEY_READ, item.isRead()); - values.put(KEY_HAS_CHAPTERS, item.getChapters() != null); - values.put(KEY_ITEM_IDENTIFIER, item.getItemIdentifier()); - if (item.getId() == 0) { - item.setId(db.insert(TABLE_NAME_FEED_ITEMS, null, values)); - } else { - db.update(TABLE_NAME_FEED_ITEMS, values, KEY_ID + "=?", - new String[] { String.valueOf(item.getId()) }); - } + /** + * Insert all FeedItems of a feed and the feed object itself in a single + * transaction + */ + public void setCompleteFeed(Feed feed) { + db.beginTransaction(); + setFeed(feed); + for (FeedItem item : feed.getItemsArray()) { + setFeedItem(item); + } + db.setTransactionSuccessful(); + db.endTransaction(); + } + + public void setFeedItemlist(List<FeedItem> items) { + db.beginTransaction(); + for (FeedItem item : items) { + setFeedItem(item); + } + db.setTransactionSuccessful(); + db.endTransaction(); + } + + public long setSingleFeedItem(FeedItem item) { + db.beginTransaction(); + long result = setFeedItem(item); + db.setTransactionSuccessful(); + db.endTransaction(); + return result; + } + + /** + * Inserts or updates a feeditem entry + * + * @return the id of the entry + */ + private long setFeedItem(FeedItem item) { + ContentValues values = new ContentValues(); + values.put(KEY_TITLE, item.getTitle()); + values.put(KEY_LINK, item.getLink()); + if (item.getDescription() != null) { + values.put(KEY_DESCRIPTION, item.getDescription()); + } + if (item.getContentEncoded() != null) { + values.put(KEY_CONTENT_ENCODED, item.getContentEncoded()); + } + values.put(KEY_PUBDATE, item.getPubDate().getTime()); + values.put(KEY_PAYMENT_LINK, item.getPaymentLink()); + if (item.getFeed().getId() == 0) { + setFeed(item.getFeed()); + } + values.put(KEY_FEED, item.getFeed().getId()); + values.put(KEY_READ, item.isRead()); + values.put(KEY_HAS_CHAPTERS, item.getChapters() != null); + values.put(KEY_ITEM_IDENTIFIER, item.getItemIdentifier()); + if (item.getId() == 0) { + item.setId(db.insert(TABLE_NAME_FEED_ITEMS, null, values)); + } else { + db.update(TABLE_NAME_FEED_ITEMS, values, KEY_ID + "=?", + new String[]{String.valueOf(item.getId())}); + } if (item.getMedia() != null) { if (item.getMedia().getId() == 0) { setMedia(item.getMedia()); } } - if (item.getChapters() != null) { - setChapters(item); - } - return item.getId(); - } - - public void setFeedItemRead(boolean read, long itemId, long mediaId, - boolean resetMediaPosition) { - db.beginTransaction(); - ContentValues values = new ContentValues(); - - values.put(KEY_READ, read); - db.update(TABLE_NAME_FEED_ITEMS, values, "?=?", new String[] { KEY_ID, - Long.toString(itemId) }); - - if (resetMediaPosition) { - values.clear(); - values.put(KEY_POSITION, 0); - db.update(TABLE_NAME_FEED_MEDIA, values, "?=?", new String[] { - KEY_ID, Long.toString(mediaId) }); - } - - db.setTransactionSuccessful(); - db.endTransaction(); - } - - public void setFeedItemRead(boolean read, long... itemIds) { - db.beginTransaction(); - ContentValues values = new ContentValues(); - for (long id : itemIds) { - values.clear(); - values.put(KEY_READ, read); - db.update(TABLE_NAME_FEED_ITEMS, values, "?=?", new String[] { - KEY_ID, Long.toString(id) }); - } - db.setTransactionSuccessful(); - db.endTransaction(); - } - - public void setChapters(FeedItem item) { - ContentValues values = new ContentValues(); - for (Chapter chapter : item.getChapters()) { - values.put(KEY_TITLE, chapter.getTitle()); - values.put(KEY_START, chapter.getStart()); - values.put(KEY_FEEDITEM, item.getId()); - values.put(KEY_LINK, chapter.getLink()); - values.put(KEY_CHAPTER_TYPE, chapter.getChapterType()); - if (chapter.getId() == 0) { - chapter.setId(db - .insert(TABLE_NAME_SIMPLECHAPTERS, null, values)); - } else { - db.update(TABLE_NAME_SIMPLECHAPTERS, values, KEY_ID + "=?", - new String[] { String.valueOf(chapter.getId()) }); - } - } - } - - /** - * Inserts or updates a download status. - * */ - public long setDownloadStatus(DownloadStatus status) { - ContentValues values = new ContentValues(); - values.put(KEY_FEEDFILE, status.getFeedfileId()); - values.put(KEY_FEEDFILETYPE, status.getFeedfileType()); - values.put(KEY_REASON, status.getReason()); - values.put(KEY_SUCCESSFUL, status.isSuccessful()); - values.put(KEY_COMPLETION_DATE, status.getCompletionDate().getTime()); - values.put(KEY_REASON_DETAILED, status.getReasonDetailed()); - values.put(KEY_DOWNLOADSTATUS_TITLE, status.getTitle()); - if (status.getId() == 0) { - status.setId(db.insert(TABLE_NAME_DOWNLOAD_LOG, null, values)); - } else { - db.update(TABLE_NAME_DOWNLOAD_LOG, values, KEY_ID + "=?", - new String[] { String.valueOf(status.getId()) }); - } - - return status.getId(); - } - - public long getDownloadLogSize() { - Cursor result = db.rawQuery("SELECT COUNT(?) AS ? FROM ?", - new String[] { KEY_ID, KEY_ID, TABLE_NAME_DOWNLOAD_LOG }); - long count = result.getLong(KEY_ID_INDEX); - result.close(); - return count; - } - - public void removeDownloadLogItems(long count) { - if (count > 0) { - db.rawQuery("DELETE FROM ? ORDER BY ? ASC LIMIT ?", - new String[] { TABLE_NAME_DOWNLOAD_LOG, - KEY_COMPLETION_DATE, Long.toString(count) }); - } - } - - public void setQueue(List<FeedItem> queue) { - ContentValues values = new ContentValues(); - db.beginTransaction(); - db.delete(TABLE_NAME_QUEUE, null, null); - for (int i = 0; i < queue.size(); i++) { - FeedItem item = queue.get(i); - values.put(KEY_ID, i); - values.put(KEY_FEEDITEM, item.getId()); - values.put(KEY_FEED, item.getFeed().getId()); - db.insertWithOnConflict(TABLE_NAME_QUEUE, null, values, - SQLiteDatabase.CONFLICT_REPLACE); - } - db.setTransactionSuccessful(); - db.endTransaction(); - } - - public void clearQueue() { - db.delete(TABLE_NAME_QUEUE, null, null); - } - - public void removeFeedMedia(FeedMedia media) { - db.delete(TABLE_NAME_FEED_MEDIA, KEY_ID + "=?", - new String[] { String.valueOf(media.getId()) }); - } - - public void removeChaptersOfItem(FeedItem item) { - db.delete(TABLE_NAME_SIMPLECHAPTERS, KEY_FEEDITEM + "=?", - new String[] { String.valueOf(item.getId()) }); - } - - public void removeFeedImage(FeedImage image) { - db.delete(TABLE_NAME_FEED_IMAGES, KEY_ID + "=?", - new String[] { String.valueOf(image.getId()) }); - } - - /** Remove a FeedItem and its FeedMedia entry. */ - public void removeFeedItem(FeedItem item) { - if (item.getMedia() != null) { - removeFeedMedia(item.getMedia()); - } - if (item.getChapters() != null) { - removeChaptersOfItem(item); - } - db.delete(TABLE_NAME_FEED_ITEMS, KEY_ID + "=?", - new String[] { String.valueOf(item.getId()) }); - } - - /** Remove a feed with all its FeedItems and Media entries. */ - public void removeFeed(Feed feed) { - db.beginTransaction(); - if (feed.getImage() != null) { - removeFeedImage(feed.getImage()); - } - for (FeedItem item : feed.getItemsArray()) { - removeFeedItem(item); - } - db.delete(TABLE_NAME_FEEDS, KEY_ID + "=?", - new String[] { String.valueOf(feed.getId()) }); - db.setTransactionSuccessful(); - db.endTransaction(); - } - - public void removeDownloadStatus(DownloadStatus remove) { - db.delete(TABLE_NAME_DOWNLOAD_LOG, KEY_ID + "=?", - new String[] { String.valueOf(remove.getId()) }); - } - - public void clearPlaybackHistory() { - ContentValues values = new ContentValues(); - values.put(KEY_PLAYBACK_COMPLETION_DATE, 0); - db.update(TABLE_NAME_FEED_MEDIA, values, null, null); - } - - /** - * Get all Feeds from the Feed Table. - * - * @return The cursor of the query - * */ - public final Cursor getAllFeedsCursor() { - open(); - Cursor c = db.query(TABLE_NAME_FEEDS, null, null, null, null, null, - KEY_TITLE + " ASC"); - return c; - } - - public final Cursor getExpiredFeedsCursor(long expirationTime) { - open(); - Cursor c = db.query(TABLE_NAME_FEEDS, null, "?<?", new String[] { - KEY_LASTUPDATE, Long.toString(expirationTime) }, null, null, - null); - return c; - } - - /** - * Returns a cursor with all FeedItems of a Feed. Uses SEL_FI_SMALL - * - * @param feed - * The feed you want to get the FeedItems from. - * @return The cursor of the query - * */ - public final Cursor getAllItemsOfFeedCursor(final Feed feed) { - return getAllItemsOfFeedCursor(feed.getId()); - } - - public final Cursor getAllItemsOfFeedCursor(final long feedId) { - open(); - Cursor c = db.query(TABLE_NAME_FEED_ITEMS, SEL_FI_SMALL, KEY_FEED - + "=?", new String[] { String.valueOf(feedId) }, null, null, - null); - return c; - } - - /** Return a cursor with the SEL_FI_EXTRA selection of a single feeditem. */ - public final Cursor getExtraInformationOfItem(final FeedItem item) { - open(); - Cursor c = db - .query(TABLE_NAME_FEED_ITEMS, SEL_FI_EXTRA, KEY_ID + "=?", - new String[] { String.valueOf(item.getId()) }, null, - null, null); - return c; - } - - /** - * Returns a cursor for a DB query in the FeedMedia table for a given ID. - * - * @param item - * The item you want to get the FeedMedia from - * @return The cursor of the query - * */ - public final Cursor getFeedMediaOfItemCursor(final FeedItem item) { - open(); - Cursor c = db.query(TABLE_NAME_FEED_MEDIA, null, KEY_ID + "=?", - new String[] { String.valueOf(item.getMedia().getId()) }, null, - null, null); - return c; - } - - /** - * Returns a cursor for a DB query in the FeedImages table for a given ID. - * - * @param id - * ID of the FeedImage - * @return The cursor of the query - * */ - public final Cursor getImageOfFeedCursor(final long id) { - open(); - Cursor c = db.query(TABLE_NAME_FEED_IMAGES, null, KEY_ID + "=?", - new String[] { String.valueOf(id) }, null, null, null); - return c; - } - - public final Cursor getSimpleChaptersOfFeedItemCursor(final FeedItem item) { - open(); - Cursor c = db.query(TABLE_NAME_SIMPLECHAPTERS, null, KEY_FEEDITEM - + "=?", new String[] { String.valueOf(item.getId()) }, null, - null, null); - return c; - } - - public final Cursor getDownloadLogCursor() { - open(); - Cursor c = db.query(TABLE_NAME_DOWNLOAD_LOG, null, null, null, null, - null, null); - 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(); - Object[] args = (Object[]) new String[] { - SEL_FI_SMALL_STR + "," + TABLE_NAME_QUEUE + "." + KEY_ID, - TABLE_NAME_FEED_ITEMS, TABLE_NAME_QUEUE, - TABLE_NAME_FEED_ITEMS + "." + KEY_ID, - TABLE_NAME_QUEUE + "." + KEY_FEEDITEM, - TABLE_NAME_QUEUE + "." + KEY_ID }; - String query = String.format( - "SELECT %s FROM %s INNER JOIN %s ON %s=%s ORDER BY %s", args); - Cursor c = db.rawQuery(query, null); - /* + if (item.getChapters() != null) { + setChapters(item); + } + return item.getId(); + } + + public void setFeedItemRead(boolean read, long itemId, long mediaId, + boolean resetMediaPosition) { + db.beginTransaction(); + ContentValues values = new ContentValues(); + + values.put(KEY_READ, read); + db.update(TABLE_NAME_FEED_ITEMS, values, KEY_ID + "=?", new String[]{String.valueOf(itemId)}); + + if (resetMediaPosition) { + values.clear(); + values.put(KEY_POSITION, 0); + db.update(TABLE_NAME_FEED_MEDIA, values, "?=?", new String[]{ + KEY_ID, String.valueOf(mediaId)}); + } + + db.setTransactionSuccessful(); + db.endTransaction(); + } + + public void setFeedItemRead(boolean read, long... itemIds) { + db.beginTransaction(); + ContentValues values = new ContentValues(); + for (long id : itemIds) { + values.clear(); + values.put(KEY_READ, read); + db.update(TABLE_NAME_FEED_ITEMS, values, "?=?", new String[]{ + KEY_ID, String.valueOf(id)}); + } + db.setTransactionSuccessful(); + db.endTransaction(); + } + + public void setChapters(FeedItem item) { + ContentValues values = new ContentValues(); + for (Chapter chapter : item.getChapters()) { + values.put(KEY_TITLE, chapter.getTitle()); + values.put(KEY_START, chapter.getStart()); + values.put(KEY_FEEDITEM, item.getId()); + values.put(KEY_LINK, chapter.getLink()); + values.put(KEY_CHAPTER_TYPE, chapter.getChapterType()); + if (chapter.getId() == 0) { + chapter.setId(db + .insert(TABLE_NAME_SIMPLECHAPTERS, null, values)); + } else { + db.update(TABLE_NAME_SIMPLECHAPTERS, values, KEY_ID + "=?", + new String[]{String.valueOf(chapter.getId())}); + } + } + } + + /** + * Inserts or updates a download status. + */ + public long setDownloadStatus(DownloadStatus status) { + ContentValues values = new ContentValues(); + values.put(KEY_FEEDFILE, status.getFeedfileId()); + values.put(KEY_FEEDFILETYPE, status.getFeedfileType()); + values.put(KEY_REASON, status.getReason()); + values.put(KEY_SUCCESSFUL, status.isSuccessful()); + values.put(KEY_COMPLETION_DATE, status.getCompletionDate().getTime()); + values.put(KEY_REASON_DETAILED, status.getReasonDetailed()); + values.put(KEY_DOWNLOADSTATUS_TITLE, status.getTitle()); + if (status.getId() == 0) { + status.setId(db.insert(TABLE_NAME_DOWNLOAD_LOG, null, values)); + } else { + db.update(TABLE_NAME_DOWNLOAD_LOG, values, KEY_ID + "=?", + new String[]{String.valueOf(status.getId())}); + } + + return status.getId(); + } + + public long getDownloadLogSize() { + Cursor result = db.rawQuery("SELECT COUNT(?) AS ? FROM ?", + new String[]{KEY_ID, KEY_ID, TABLE_NAME_DOWNLOAD_LOG}); + long count = result.getLong(KEY_ID_INDEX); + result.close(); + return count; + } + + public void removeDownloadLogItems(long count) { + if (count > 0) { + db.rawQuery("DELETE FROM ? ORDER BY ? ASC LIMIT ?", + new String[]{TABLE_NAME_DOWNLOAD_LOG, + KEY_COMPLETION_DATE, String.valueOf(count)}); + } + } + + public void setQueue(List<FeedItem> queue) { + ContentValues values = new ContentValues(); + db.beginTransaction(); + db.delete(TABLE_NAME_QUEUE, null, null); + for (int i = 0; i < queue.size(); i++) { + FeedItem item = queue.get(i); + values.put(KEY_ID, i); + values.put(KEY_FEEDITEM, item.getId()); + values.put(KEY_FEED, item.getFeed().getId()); + db.insertWithOnConflict(TABLE_NAME_QUEUE, null, values, + SQLiteDatabase.CONFLICT_REPLACE); + } + db.setTransactionSuccessful(); + db.endTransaction(); + } + + public void clearQueue() { + db.delete(TABLE_NAME_QUEUE, null, null); + } + + public void removeFeedMedia(FeedMedia media) { + db.delete(TABLE_NAME_FEED_MEDIA, KEY_ID + "=?", + new String[]{String.valueOf(media.getId())}); + } + + public void removeChaptersOfItem(FeedItem item) { + db.delete(TABLE_NAME_SIMPLECHAPTERS, KEY_FEEDITEM + "=?", + new String[]{String.valueOf(item.getId())}); + } + + public void removeFeedImage(FeedImage image) { + db.delete(TABLE_NAME_FEED_IMAGES, KEY_ID + "=?", + new String[]{String.valueOf(image.getId())}); + } + + /** + * Remove a FeedItem and its FeedMedia entry. + */ + public void removeFeedItem(FeedItem item) { + if (item.getMedia() != null) { + removeFeedMedia(item.getMedia()); + } + if (item.getChapters() != null) { + removeChaptersOfItem(item); + } + db.delete(TABLE_NAME_FEED_ITEMS, KEY_ID + "=?", + new String[]{String.valueOf(item.getId())}); + } + + /** + * Remove a feed with all its FeedItems and Media entries. + */ + public void removeFeed(Feed feed) { + db.beginTransaction(); + if (feed.getImage() != null) { + removeFeedImage(feed.getImage()); + } + for (FeedItem item : feed.getItemsArray()) { + removeFeedItem(item); + } + db.delete(TABLE_NAME_FEEDS, KEY_ID + "=?", + new String[]{String.valueOf(feed.getId())}); + db.setTransactionSuccessful(); + db.endTransaction(); + } + + public void removeDownloadStatus(DownloadStatus remove) { + db.delete(TABLE_NAME_DOWNLOAD_LOG, KEY_ID + "=?", + new String[]{String.valueOf(remove.getId())}); + } + + public void clearPlaybackHistory() { + ContentValues values = new ContentValues(); + values.put(KEY_PLAYBACK_COMPLETION_DATE, 0); + db.update(TABLE_NAME_FEED_MEDIA, values, null, null); + } + + /** + * Get all Feeds from the Feed Table. + * + * @return The cursor of the query + */ + public final Cursor getAllFeedsCursor() { + open(); + Cursor c = db.query(TABLE_NAME_FEEDS, null, null, null, null, null, + KEY_TITLE + " ASC"); + return c; + } + + public final Cursor getExpiredFeedsCursor(long expirationTime) { + open(); + Cursor c = db.query(TABLE_NAME_FEEDS, null, "?<?", new String[]{ + KEY_LASTUPDATE, String.valueOf(expirationTime)}, null, null, + null); + return c; + } + + /** + * Returns a cursor with all FeedItems of a Feed. Uses SEL_FI_SMALL + * + * @param feed The feed you want to get the FeedItems from. + * @return The cursor of the query + */ + public final Cursor getAllItemsOfFeedCursor(final Feed feed) { + return getAllItemsOfFeedCursor(feed.getId()); + } + + public final Cursor getAllItemsOfFeedCursor(final long feedId) { + open(); + Cursor c = db.query(TABLE_NAME_FEED_ITEMS, SEL_FI_SMALL, KEY_FEED + + "=?", new String[]{String.valueOf(feedId)}, null, null, + null); + return c; + } + + /** + * Return a cursor with the SEL_FI_EXTRA selection of a single feeditem. + */ + public final Cursor getExtraInformationOfItem(final FeedItem item) { + open(); + Cursor c = db + .query(TABLE_NAME_FEED_ITEMS, SEL_FI_EXTRA, KEY_ID + "=?", + new String[]{String.valueOf(item.getId())}, null, + null, null); + return c; + } + + /** + * Returns a cursor for a DB query in the FeedMedia table for a given ID. + * + * @param item The item you want to get the FeedMedia from + * @return The cursor of the query + */ + public final Cursor getFeedMediaOfItemCursor(final FeedItem item) { + open(); + Cursor c = db.query(TABLE_NAME_FEED_MEDIA, null, KEY_ID + "=?", + new String[]{String.valueOf(item.getMedia().getId())}, null, + null, null); + return c; + } + + /** + * Returns a cursor for a DB query in the FeedImages table for a given ID. + * + * @param id ID of the FeedImage + * @return The cursor of the query + */ + public final Cursor getImageOfFeedCursor(final long id) { + open(); + Cursor c = db.query(TABLE_NAME_FEED_IMAGES, null, KEY_ID + "=?", + new String[]{String.valueOf(id)}, null, null, null); + return c; + } + + public final Cursor getSimpleChaptersOfFeedItemCursor(final FeedItem item) { + open(); + Cursor c = db.query(TABLE_NAME_SIMPLECHAPTERS, null, KEY_FEEDITEM + + "=?", new String[]{String.valueOf(item.getId())}, null, + null, null); + return c; + } + + public final Cursor getDownloadLogCursor() { + open(); + Cursor c = db.query(TABLE_NAME_DOWNLOAD_LOG, null, null, null, null, + null, null); + 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(); + Object[] args = (Object[]) new String[]{ + SEL_FI_SMALL_STR + "," + TABLE_NAME_QUEUE + "." + KEY_ID, + TABLE_NAME_FEED_ITEMS, TABLE_NAME_QUEUE, + TABLE_NAME_FEED_ITEMS + "." + KEY_ID, + TABLE_NAME_QUEUE + "." + KEY_FEEDITEM, + TABLE_NAME_QUEUE + "." + KEY_ID}; + String query = String.format( + "SELECT %s FROM %s INNER JOIN %s ON %s=%s ORDER BY %s", args); + Cursor c = db.rawQuery(query, 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; - } + return c; + } public Cursor getQueueIDCursor() { open(); @@ -737,128 +749,128 @@ public class PodDBAdapter { 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; - } - - public final Cursor getUnreadItemIdsCursor() { - open(); - Cursor c = db.query(TABLE_NAME_FEED_ITEMS, new String[] { KEY_ID }, - KEY_READ + "=0", null, null, null, KEY_PUBDATE + " DESC"); - return c; - - } - - public Cursor getDownloadedItemsCursor() { - open(); + /** + * 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; + } + + public final Cursor getUnreadItemIdsCursor() { + open(); + Cursor c = db.query(TABLE_NAME_FEED_ITEMS, new String[]{KEY_ID}, + KEY_READ + "=0", null, null, null, KEY_PUBDATE + " DESC"); + return c; + + } + + public Cursor getDownloadedItemsCursor() { + open(); final String query = "SELECT " + SEL_FI_SMALL_STR + " FROM " + TABLE_NAME_FEED_ITEMS + " INNER JOIN " + TABLE_NAME_FEED_MEDIA + " ON " + TABLE_NAME_FEED_ITEMS + "." + KEY_ID + "=" + TABLE_NAME_FEED_MEDIA + "." + KEY_ID + " WHERE " + TABLE_NAME_FEED_MEDIA + "." + KEY_DOWNLOADED + ">0"; - Cursor c = db.rawQuery(query, null); - 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(TABLE_NAME_FEED_MEDIA, null, - KEY_PLAYBACK_COMPLETION_DATE + " IS NOT NULL", null, null, - null, KEY_PLAYBACK_COMPLETION_DATE + " DESC LIMIT " + limit); - return c; - } + Cursor c = db.rawQuery(query, null); + 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(TABLE_NAME_FEED_MEDIA, null, + KEY_PLAYBACK_COMPLETION_DATE + " IS NOT NULL", null, null, + null, KEY_PLAYBACK_COMPLETION_DATE + " DESC LIMIT " + limit); + return c; + } public final Cursor getSingleFeedMediaCursor(long id) { - return db.query(TABLE_NAME_FEED_MEDIA, null, KEY_ID + "=?", new String[] {Long.toString(id)}, null, null, null); + return db.query(TABLE_NAME_FEED_MEDIA, null, KEY_ID + "=?", new String[]{String.valueOf(id)}, null, null, null); } - public final Cursor getFeedMediaCursorByItemID(String... mediaIds) { - int length = mediaIds.length; - if (length > IN_OPERATOR_MAXIMUM) { - Log.w(TAG, "Length of id array is larger than " - + IN_OPERATOR_MAXIMUM + ". Creating multiple cursors"); - int numCursors = (int) (((double) length) / (IN_OPERATOR_MAXIMUM)) + 1; - Cursor[] cursors = new Cursor[numCursors]; - for (int i = 0; i < numCursors; i++) { - int neededLength = 0; - String[] parts = null; - final int elementsLeft = length - i * IN_OPERATOR_MAXIMUM; - - if (elementsLeft >= IN_OPERATOR_MAXIMUM) { - neededLength = IN_OPERATOR_MAXIMUM; - parts = Arrays.copyOfRange(mediaIds, i - * IN_OPERATOR_MAXIMUM, (i + 1) - * IN_OPERATOR_MAXIMUM); - } else { - neededLength = elementsLeft; - parts = Arrays.copyOfRange(mediaIds, i - * IN_OPERATOR_MAXIMUM, (i * IN_OPERATOR_MAXIMUM) - + neededLength); - } - - cursors[i] = db.rawQuery("SELECT * FROM " - + TABLE_NAME_FEED_MEDIA + " WHERE " + KEY_FEEDITEM + " IN " - + buildInOperator(neededLength), parts); - } - return new MergeCursor(cursors); - } else { - return db.query(TABLE_NAME_FEED_MEDIA, null, KEY_FEEDITEM + " IN " - + buildInOperator(length), mediaIds, null, null, null); - } - } - - /** Builds an IN-operator argument depending on the number of items. */ - private String buildInOperator(int size) { + public final Cursor getFeedMediaCursorByItemID(String... mediaIds) { + int length = mediaIds.length; + if (length > IN_OPERATOR_MAXIMUM) { + Log.w(TAG, "Length of id array is larger than " + + IN_OPERATOR_MAXIMUM + ". Creating multiple cursors"); + int numCursors = (int) (((double) length) / (IN_OPERATOR_MAXIMUM)) + 1; + Cursor[] cursors = new Cursor[numCursors]; + for (int i = 0; i < numCursors; i++) { + int neededLength = 0; + String[] parts = null; + final int elementsLeft = length - i * IN_OPERATOR_MAXIMUM; + + if (elementsLeft >= IN_OPERATOR_MAXIMUM) { + neededLength = IN_OPERATOR_MAXIMUM; + parts = Arrays.copyOfRange(mediaIds, i + * IN_OPERATOR_MAXIMUM, (i + 1) + * IN_OPERATOR_MAXIMUM); + } else { + neededLength = elementsLeft; + parts = Arrays.copyOfRange(mediaIds, i + * IN_OPERATOR_MAXIMUM, (i * IN_OPERATOR_MAXIMUM) + + neededLength); + } + + cursors[i] = db.rawQuery("SELECT * FROM " + + TABLE_NAME_FEED_MEDIA + " WHERE " + KEY_FEEDITEM + " IN " + + buildInOperator(neededLength), parts); + } + return new MergeCursor(cursors); + } else { + return db.query(TABLE_NAME_FEED_MEDIA, null, KEY_FEEDITEM + " IN " + + buildInOperator(length), mediaIds, null, null, null); + } + } + + /** + * Builds an IN-operator argument depending on the number of items. + */ + private String buildInOperator(int size) { if (size == 1) { return "(?)"; } - StringBuffer buffer = new StringBuffer("("); - for (int i = 0; i < size - 1; i++) { - buffer.append("?,"); - } - buffer.append("?)"); - return buffer.toString(); - } - - 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 String... ids) { - if (ids.length > IN_OPERATOR_MAXIMUM) { - throw new IllegalArgumentException( - "number of IDs must not be larger than " - + IN_OPERATOR_MAXIMUM); - } - - open(); - return db.query(TABLE_NAME_FEED_ITEMS, SEL_FI_SMALL, KEY_ID + " IN " - + buildInOperator(ids.length), ids, null, null, null); - - } + StringBuffer buffer = new StringBuffer("("); + for (int i = 0; i < size - 1; i++) { + buffer.append("?,"); + } + buffer.append("?)"); + return buffer.toString(); + } + + 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 String... ids) { + if (ids.length > IN_OPERATOR_MAXIMUM) { + throw new IllegalArgumentException( + "number of IDs must not be larger than " + + IN_OPERATOR_MAXIMUM); + } + + open(); + return db.query(TABLE_NAME_FEED_ITEMS, SEL_FI_SMALL, KEY_ID + " IN " + + buildInOperator(ids.length), ids, null, null, null); + + } public final int getNumberOfUnreadItems() { final String query = "SELECT COUNT(DISTINCT " + KEY_ID + ") AS count FROM " + TABLE_NAME_FEED_ITEMS + @@ -872,75 +884,75 @@ public class PodDBAdapter { return result; } - public final int getNumberOfDownloadedEpisodes() { + public final int getNumberOfDownloadedEpisodes() { final String query = "SELECT COUNT(DISTINCT " + KEY_ID + ") AS count FROM " + TABLE_NAME_FEED_MEDIA + - " WHERE " + KEY_DOWNLOADED + " > 0"; + " WHERE " + KEY_DOWNLOADED + " > 0"; - Cursor c = db.rawQuery(query, null); + Cursor c = db.rawQuery(query, null); int result = 0; if (c.moveToFirst()) { - result = c.getInt(0); + result = c.getInt(0); } - c.close(); - return result; - } - - /** - * Uses DatabaseUtils to escape a search query and removes ' at the - * beginning and the end of the string returned by the escape method. - */ - private String prepareSearchQuery(String query) { - StringBuilder builder = new StringBuilder(); - DatabaseUtils.appendEscapedSQLString(builder, query); - builder.deleteCharAt(0); - builder.deleteCharAt(builder.length() - 1); - return builder.toString(); - } - - /** - * Searches for the given query in the description of all items or the items - * of a specified feed. - * - * @return A cursor with all search results in SEL_FI_EXTRA selection. - * */ - public Cursor searchItemDescriptions(long feedID, String query) { - if (feedID != 0) { - // search items in specific feed - return db.query(TABLE_NAME_FEED_ITEMS, SEL_FI_SMALL, KEY_FEED - + "=? AND " + KEY_DESCRIPTION + " LIKE '%" - + prepareSearchQuery(query) + "%'", - new String[] { String.valueOf(feedID) }, null, null, - null); - } else { - // search through all items - return db.query(TABLE_NAME_FEED_ITEMS, SEL_FI_SMALL, - KEY_DESCRIPTION + " LIKE '%" + prepareSearchQuery(query) - + "%'", null, null, null, null); - } - } - - /** - * Searches for the given query in the content-encoded field of all items or - * the items of a specified feed. - * - * @return A cursor with all search results in SEL_FI_EXTRA selection. - * */ - public Cursor searchItemContentEncoded(long feedID, String query) { - if (feedID != 0) { - // search items in specific feed - return db.query(TABLE_NAME_FEED_ITEMS, SEL_FI_SMALL, KEY_FEED - + "=? AND " + KEY_CONTENT_ENCODED + " LIKE '%" - + prepareSearchQuery(query) + "%'", - new String[] { String.valueOf(feedID) }, null, null, - null); - } else { - // search through all items - return db.query(TABLE_NAME_FEED_ITEMS, SEL_FI_SMALL, - KEY_CONTENT_ENCODED + " LIKE '%" - + prepareSearchQuery(query) + "%'", null, null, - null, null); - } - } + c.close(); + return result; + } + + /** + * Uses DatabaseUtils to escape a search query and removes ' at the + * beginning and the end of the string returned by the escape method. + */ + private String prepareSearchQuery(String query) { + StringBuilder builder = new StringBuilder(); + DatabaseUtils.appendEscapedSQLString(builder, query); + builder.deleteCharAt(0); + builder.deleteCharAt(builder.length() - 1); + return builder.toString(); + } + + /** + * Searches for the given query in the description of all items or the items + * of a specified feed. + * + * @return A cursor with all search results in SEL_FI_EXTRA selection. + */ + public Cursor searchItemDescriptions(long feedID, String query) { + if (feedID != 0) { + // search items in specific feed + return db.query(TABLE_NAME_FEED_ITEMS, SEL_FI_SMALL, KEY_FEED + + "=? AND " + KEY_DESCRIPTION + " LIKE '%" + + prepareSearchQuery(query) + "%'", + new String[]{String.valueOf(feedID)}, null, null, + null); + } else { + // search through all items + return db.query(TABLE_NAME_FEED_ITEMS, SEL_FI_SMALL, + KEY_DESCRIPTION + " LIKE '%" + prepareSearchQuery(query) + + "%'", null, null, null, null); + } + } + + /** + * Searches for the given query in the content-encoded field of all items or + * the items of a specified feed. + * + * @return A cursor with all search results in SEL_FI_EXTRA selection. + */ + public Cursor searchItemContentEncoded(long feedID, String query) { + if (feedID != 0) { + // search items in specific feed + return db.query(TABLE_NAME_FEED_ITEMS, SEL_FI_SMALL, KEY_FEED + + "=? AND " + KEY_CONTENT_ENCODED + " LIKE '%" + + prepareSearchQuery(query) + "%'", + new String[]{String.valueOf(feedID)}, null, null, + null); + } else { + // search through all items + return db.query(TABLE_NAME_FEED_ITEMS, SEL_FI_SMALL, + KEY_CONTENT_ENCODED + " LIKE '%" + + prepareSearchQuery(query) + "%'", null, null, + null, null); + } + } public Cursor searchItemTitles(long feedID, String query) { if (feedID != 0) { @@ -948,7 +960,7 @@ public class PodDBAdapter { return db.query(TABLE_NAME_FEED_ITEMS, SEL_FI_SMALL, KEY_FEED + "=? AND " + KEY_TITLE + " LIKE '%" + prepareSearchQuery(query) + "%'", - new String[] { String.valueOf(feedID) }, null, null, + new String[]{String.valueOf(feedID)}, null, null, null); } else { // search through all items @@ -962,109 +974,131 @@ public class PodDBAdapter { public Cursor searchItemChapters(long feedID, String searchQuery) { final String query; if (feedID != 0) { - query = "SELECT " + SEL_FI_SMALL_STR + " FROM " + TABLE_NAME_FEED_ITEMS + " INNER JOIN " + - TABLE_NAME_SIMPLECHAPTERS + " ON " + TABLE_NAME_SIMPLECHAPTERS + "." + KEY_FEEDITEM + "=" + - TABLE_NAME_FEED_ITEMS + "." + KEY_ID + " WHERE " + TABLE_NAME_FEED_ITEMS + "." + KEY_FEED + "=" + - feedID + " AND "+ TABLE_NAME_SIMPLECHAPTERS + "." + KEY_TITLE + " LIKE '%" - + prepareSearchQuery(searchQuery) + "%'"; + query = "SELECT " + SEL_FI_SMALL_STR + " FROM " + TABLE_NAME_FEED_ITEMS + " INNER JOIN " + + TABLE_NAME_SIMPLECHAPTERS + " ON " + TABLE_NAME_SIMPLECHAPTERS + "." + KEY_FEEDITEM + "=" + + TABLE_NAME_FEED_ITEMS + "." + KEY_ID + " WHERE " + TABLE_NAME_FEED_ITEMS + "." + KEY_FEED + "=" + + feedID + " AND " + TABLE_NAME_SIMPLECHAPTERS + "." + KEY_TITLE + " LIKE '%" + + prepareSearchQuery(searchQuery) + "%'"; } else { - query = "SELECT " + SEL_FI_SMALL_STR + " FROM " + TABLE_NAME_FEED_ITEMS + " INNER JOIN " + - TABLE_NAME_SIMPLECHAPTERS + " ON " + TABLE_NAME_SIMPLECHAPTERS + "." + KEY_FEEDITEM + "=" + + query = "SELECT " + SEL_FI_SMALL_STR + " FROM " + TABLE_NAME_FEED_ITEMS + " INNER JOIN " + + TABLE_NAME_SIMPLECHAPTERS + " ON " + TABLE_NAME_SIMPLECHAPTERS + "." + KEY_FEEDITEM + "=" + TABLE_NAME_FEED_ITEMS + "." + KEY_ID + " WHERE " + TABLE_NAME_SIMPLECHAPTERS + "." + KEY_TITLE + " LIKE '%" + prepareSearchQuery(searchQuery) + "%'"; } return db.rawQuery(query, null); } - /** Helper class for opening the Antennapod database. */ - private static class PodDBHelper extends SQLiteOpenHelper { - /** - * Constructor. - * - * @param context - * Context to use - * @param name - * Name of the database - * @param factory - * to use for creating cursor objects - * @param version - * number of the database - * */ - public PodDBHelper(final Context context, final String name, - final CursorFactory factory, final int version) { - super(context, name, factory, version); - } - - @Override - public void onCreate(final SQLiteDatabase db) { - db.execSQL(CREATE_TABLE_FEEDS); - db.execSQL(CREATE_TABLE_FEED_ITEMS); - db.execSQL(CREATE_TABLE_FEED_IMAGES); - db.execSQL(CREATE_TABLE_FEED_MEDIA); - db.execSQL(CREATE_TABLE_DOWNLOAD_LOG); - db.execSQL(CREATE_TABLE_QUEUE); - db.execSQL(CREATE_TABLE_SIMPLECHAPTERS); - } - @Override - public void onUpgrade(final SQLiteDatabase db, final int oldVersion, - final int newVersion) { - Log.w("DBAdapter", "Upgrading from version " + oldVersion + " to " - + newVersion + "."); - if (oldVersion <= 1) { - db.execSQL("ALTER TABLE " + TABLE_NAME_FEEDS + " ADD COLUMN " - + KEY_TYPE + " TEXT"); - } - if (oldVersion <= 2) { - db.execSQL("ALTER TABLE " + TABLE_NAME_SIMPLECHAPTERS - + " ADD COLUMN " + KEY_LINK + " TEXT"); - } - if (oldVersion <= 3) { - db.execSQL("ALTER TABLE " + TABLE_NAME_FEED_ITEMS - + " ADD COLUMN " + KEY_ITEM_IDENTIFIER + " TEXT"); - } - if (oldVersion <= 4) { - db.execSQL("ALTER TABLE " + TABLE_NAME_FEEDS + " ADD COLUMN " - + KEY_FEED_IDENTIFIER + " TEXT"); - } - if (oldVersion <= 5) { - db.execSQL("ALTER TABLE " + TABLE_NAME_DOWNLOAD_LOG - + " ADD COLUMN " + KEY_REASON_DETAILED + " TEXT"); - db.execSQL("ALTER TABLE " + TABLE_NAME_DOWNLOAD_LOG - + " ADD COLUMN " + KEY_DOWNLOADSTATUS_TITLE + " TEXT"); - } - if (oldVersion <= 6) { - db.execSQL("ALTER TABLE " + TABLE_NAME_SIMPLECHAPTERS - + " ADD COLUMN " + KEY_CHAPTER_TYPE + " INTEGER"); + public static final int IDX_FEEDSTATISTICS_FEED = 0; + public static final int IDX_FEEDSTATISTICS_NUM_ITEMS = 1; + public static final int IDX_FEEDSTATISTICS_NEW_ITEMS = 2; + public static final int IDX_FEEDSTATISTICS_LATEST_EPISODE = 3; + public static final int IDX_FEEDSTATISTICS_IN_PROGRESS_EPISODES = 4; + + /** + * Select number of items, new items, the date of the latest episode and the number of episodes in progress. The result + * is sorted by the title of the feed. + */ + private static final String FEED_STATISTICS_QUERY = "SELECT feed, num_items, new_items, latest_episode, in_progress FROM " + + "(SELECT feed,count(*) AS num_items," + + " COUNT(CASE WHEN read=0 THEN 1 END) AS new_items," + + " MAX(pubDate) AS latest_episode," + + " COUNT(CASE WHEN position>0 THEN 1 END) AS in_progress," + + " COUNT(CASE WHEN downloaded=1 THEN 1 END) AS episodes_downloaded " + + " FROM FeedItems INNER JOIN FeedMedia ON FeedItems.id=FeedMedia.feeditem GROUP BY FeedItems.feed)" + + " INNER JOIN Feeds ON Feeds.id = feed ORDER BY Feeds.title;"; + + public Cursor getFeedStatisticsCursor() { + return db.rawQuery(FEED_STATISTICS_QUERY, null); + } + + /** + * Helper class for opening the Antennapod database. + */ + private static class PodDBHelper extends SQLiteOpenHelper { + /** + * Constructor. + * + * @param context Context to use + * @param name Name of the database + * @param factory to use for creating cursor objects + * @param version number of the database + */ + public PodDBHelper(final Context context, final String name, + final CursorFactory factory, final int version) { + super(context, name, factory, version); } - if (oldVersion <= 7) { - db.execSQL("ALTER TABLE " + TABLE_NAME_FEED_MEDIA - + " ADD COLUMN " + KEY_PLAYBACK_COMPLETION_DATE - + " INTEGER"); + + @Override + public void onCreate(final SQLiteDatabase db) { + db.execSQL(CREATE_TABLE_FEEDS); + db.execSQL(CREATE_TABLE_FEED_ITEMS); + db.execSQL(CREATE_TABLE_FEED_IMAGES); + db.execSQL(CREATE_TABLE_FEED_MEDIA); + db.execSQL(CREATE_TABLE_DOWNLOAD_LOG); + db.execSQL(CREATE_TABLE_QUEUE); + db.execSQL(CREATE_TABLE_SIMPLECHAPTERS); } - if (oldVersion <= 8) { - final int KEY_ID_POSITION = 0; - final int KEY_MEDIA_POSITION = 1; - - // Add feeditem column to feedmedia table - db.execSQL("ALTER TABLE " + TABLE_NAME_FEED_MEDIA - + " ADD COLUMN " + KEY_FEEDITEM - + " INTEGER"); - Cursor feeditemCursor = db.query(TABLE_NAME_FEED_ITEMS, new String[]{KEY_ID, KEY_MEDIA}, "? > 0", new String[] {KEY_MEDIA}, null, null, null); - if (feeditemCursor.moveToFirst()) { - db.beginTransaction(); - ContentValues contentValues = new ContentValues(); - do { - long mediaId = feeditemCursor.getLong(KEY_MEDIA_POSITION); - contentValues.put(KEY_FEEDITEM, feeditemCursor.getLong(KEY_ID_POSITION)); - db.update(TABLE_NAME_FEED_MEDIA, contentValues, "?=?", new String[] {KEY_ID, Long.toString(mediaId)}); - contentValues.clear(); - } while (feeditemCursor.moveToNext()); - db.setTransactionSuccessful(); - db.endTransaction(); + + @Override + public void onUpgrade(final SQLiteDatabase db, final int oldVersion, + final int newVersion) { + Log.w("DBAdapter", "Upgrading from version " + oldVersion + " to " + + newVersion + "."); + if (oldVersion <= 1) { + db.execSQL("ALTER TABLE " + TABLE_NAME_FEEDS + " ADD COLUMN " + + KEY_TYPE + " TEXT"); + } + if (oldVersion <= 2) { + db.execSQL("ALTER TABLE " + TABLE_NAME_SIMPLECHAPTERS + + " ADD COLUMN " + KEY_LINK + " TEXT"); + } + if (oldVersion <= 3) { + db.execSQL("ALTER TABLE " + TABLE_NAME_FEED_ITEMS + + " ADD COLUMN " + KEY_ITEM_IDENTIFIER + " TEXT"); + } + if (oldVersion <= 4) { + db.execSQL("ALTER TABLE " + TABLE_NAME_FEEDS + " ADD COLUMN " + + KEY_FEED_IDENTIFIER + " TEXT"); + } + if (oldVersion <= 5) { + db.execSQL("ALTER TABLE " + TABLE_NAME_DOWNLOAD_LOG + + " ADD COLUMN " + KEY_REASON_DETAILED + " TEXT"); + db.execSQL("ALTER TABLE " + TABLE_NAME_DOWNLOAD_LOG + + " ADD COLUMN " + KEY_DOWNLOADSTATUS_TITLE + " TEXT"); + } + if (oldVersion <= 6) { + db.execSQL("ALTER TABLE " + TABLE_NAME_SIMPLECHAPTERS + + " ADD COLUMN " + KEY_CHAPTER_TYPE + " INTEGER"); + } + if (oldVersion <= 7) { + db.execSQL("ALTER TABLE " + TABLE_NAME_FEED_MEDIA + + " ADD COLUMN " + KEY_PLAYBACK_COMPLETION_DATE + + " INTEGER"); + } + if (oldVersion <= 8) { + final int KEY_ID_POSITION = 0; + final int KEY_MEDIA_POSITION = 1; + + // Add feeditem column to feedmedia table + db.execSQL("ALTER TABLE " + TABLE_NAME_FEED_MEDIA + + " ADD COLUMN " + KEY_FEEDITEM + + " INTEGER"); + Cursor feeditemCursor = db.query(TABLE_NAME_FEED_ITEMS, new String[]{KEY_ID, KEY_MEDIA}, "? > 0", new String[]{KEY_MEDIA}, null, null, null); + if (feeditemCursor.moveToFirst()) { + db.beginTransaction(); + ContentValues contentValues = new ContentValues(); + do { + long mediaId = feeditemCursor.getLong(KEY_MEDIA_POSITION); + contentValues.put(KEY_FEEDITEM, feeditemCursor.getLong(KEY_ID_POSITION)); + db.update(TABLE_NAME_FEED_MEDIA, contentValues, "?=?", new String[]{KEY_ID, String.valueOf(mediaId)}); + contentValues.clear(); + } while (feeditemCursor.moveToNext()); + db.setTransactionSuccessful(); + db.endTransaction(); + } + feeditemCursor.close(); } - feeditemCursor.close(); } } - } } diff --git a/src/de/danoeh/antennapod/util/ShownotesProvider.java b/src/de/danoeh/antennapod/util/ShownotesProvider.java new file mode 100644 index 000000000..d273e0b8f --- /dev/null +++ b/src/de/danoeh/antennapod/util/ShownotesProvider.java @@ -0,0 +1,17 @@ +package de.danoeh.antennapod.util; + +import java.util.concurrent.Callable; +import java.util.concurrent.FutureTask; + +/** + * Created by daniel on 04.08.13. + */ +public interface ShownotesProvider { + /** + * Loads shownotes. If the shownotes have to be loaded from a file or from a + * database, it should be done in a separate thread. After the shownotes + * have been loaded, callback.onShownotesLoaded should be called. + */ + public Callable<String> loadShownotes(); + +} |