diff options
author | daniel oeh <daniel.oeh@gmail.com> | 2013-08-09 21:51:13 +0200 |
---|---|---|
committer | daniel oeh <daniel.oeh@gmail.com> | 2013-08-09 21:51:13 +0200 |
commit | fa155f833b43e0a484c4b8cb227b61c7ce97942c (patch) | |
tree | 4ab584bf5167a695611b557b718dd02b6dfe3c8e /src | |
parent | ce9f87ff3eb4ffcaf3c8174b97baac967026e1fa (diff) | |
download | AntennaPod-fa155f833b43e0a484c4b8cb227b61c7ce97942c.zip |
Added documentation to DBWriter
Diffstat (limited to 'src')
-rw-r--r-- | src/de/danoeh/antennapod/service/PlaybackService.java | 3 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/storage/DBReader.java | 2 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/storage/DBWriter.java | 1142 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/storage/PodDBAdapter.java | 4 |
4 files changed, 647 insertions, 504 deletions
diff --git a/src/de/danoeh/antennapod/service/PlaybackService.java b/src/de/danoeh/antennapod/service/PlaybackService.java index a173dfdfb..63a4d0471 100644 --- a/src/de/danoeh/antennapod/service/PlaybackService.java +++ b/src/de/danoeh/antennapod/service/PlaybackService.java @@ -775,7 +775,6 @@ public class PlaybackService extends Service { if (media instanceof FeedMedia) { FeedItem item = ((FeedMedia) media).getItem(); - ((FeedMedia) media).setPlaybackCompletionDate(new Date()); DBWriter.markItemRead(PlaybackService.this, item, true, true); nextItem = DBTasks.getQueueSuccessorOfItem(this, item.getId(), queue); isInQueue = media instanceof FeedMedia @@ -783,7 +782,7 @@ public class PlaybackService extends Service { if (isInQueue) { DBWriter.removeQueueItem(PlaybackService.this, item.getId(), true); } - DBWriter.addItemToPlaybackHistory(PlaybackService.this, item); + DBWriter.addItemToPlaybackHistory(PlaybackService.this, (FeedMedia) media); DBWriter.setFeedMedia(PlaybackService.this, (FeedMedia) media); long autoDeleteMediaId = ((FeedComponent) media).getId(); if (shouldStream) { diff --git a/src/de/danoeh/antennapod/storage/DBReader.java b/src/de/danoeh/antennapod/storage/DBReader.java index 71d11f13b..b1ebbc45d 100644 --- a/src/de/danoeh/antennapod/storage/DBReader.java +++ b/src/de/danoeh/antennapod/storage/DBReader.java @@ -27,6 +27,8 @@ import de.danoeh.antennapod.util.comparator.FeedItemPubdateComparator; * Provides methods for reading data from the AntennaPod database. * In general, all database calls in DBReader-methods are executed on the caller's thread. * This means that the caller should make sure that DBReader-methods are not executed on the GUI-thread. + * This class will use the {@link de.danoeh.antennapod.feed.EventDistributor} to notify listeners about changes in the database. + */ public final class DBReader { private static final String TAG = "DBReader"; diff --git a/src/de/danoeh/antennapod/storage/DBWriter.java b/src/de/danoeh/antennapod/storage/DBWriter.java index 3db0b8a33..4ad9e9e1f 100644 --- a/src/de/danoeh/antennapod/storage/DBWriter.java +++ b/src/de/danoeh/antennapod/storage/DBWriter.java @@ -1,7 +1,7 @@ package de.danoeh.antennapod.storage; import java.io.File; -import java.util.Collections; +import java.util.Date; import java.util.LinkedList; import java.util.List; import java.util.concurrent.ExecutorService; @@ -22,517 +22,645 @@ import de.danoeh.antennapod.service.PlaybackService; import de.danoeh.antennapod.service.download.DownloadStatus; import de.danoeh.antennapod.util.QueueAccess; +/** + * Provides methods for writing data to AntennaPod's database. + * In general, DBWriter-methods will be executed on an internal ExecutorService. + * Some methods return a Future-object which the caller can use for waiting for the method's completion. The returned Future's + * will NOT contain any results. + * The caller can also use the {@link EventDistributor} in order to be notified about the method's completion asynchronously. + * This class will use the {@link EventDistributor} to notify listeners about changes in the database. + */ public class DBWriter { - private static final String TAG = "DBWriter"; - - private static final ExecutorService dbExec; - static { - dbExec = Executors.newSingleThreadExecutor(new ThreadFactory() { - - @Override - public Thread newThread(Runnable r) { - Thread t = new Thread(r); - t.setPriority(Thread.MIN_PRIORITY); - return t; - } - }); - } - - private DBWriter() { - } - - public static void deleteFeedMediaOfItem(final Context context, - final long itemId) { - dbExec.submit(new Runnable() { - @Override - public void run() { - final FeedItem item = DBReader.getFeedItem(context, itemId); - if (item != null && item.hasMedia()) { - final FeedMedia media = item.getMedia(); - boolean result = false; - if (media.isDownloaded()) { - // delete downloaded media file - File mediaFile = new File(media.getFile_url()); - if (mediaFile.exists()) { - result = mediaFile.delete(); - } - media.setDownloaded(false); - media.setFile_url(null); - setFeedMedia(context, media); - - // If media is currently being played, change playback - // type to 'stream' and shutdown playback service - SharedPreferences prefs = PreferenceManager - .getDefaultSharedPreferences(context); - if (PlaybackPreferences.getCurrentlyPlayingMedia() == FeedMedia.PLAYABLE_TYPE_FEEDMEDIA) { - if (media.getId() == PlaybackPreferences - .getCurrentlyPlayingFeedMediaId()) { - SharedPreferences.Editor editor = prefs.edit(); - editor.putBoolean( - PlaybackPreferences.PREF_CURRENT_EPISODE_IS_STREAM, - true); - editor.commit(); - } - if (PlaybackPreferences - .getCurrentlyPlayingFeedMediaId() == media - .getId()) { - context.sendBroadcast(new Intent( - PlaybackService.ACTION_SHUTDOWN_PLAYBACK_SERVICE)); - } - } - } - if (AppConfig.DEBUG) - Log.d(TAG, "Deleting File. Result: " + result); - } - } - }); - } - - public static Future<?> deleteFeed(final Context context, final long feedId) { - return dbExec.submit(new Runnable() { - @Override - public void run() { - DownloadRequester requester = DownloadRequester.getInstance(); - SharedPreferences prefs = PreferenceManager - .getDefaultSharedPreferences(context - .getApplicationContext()); - final Feed feed = DBReader.getFeed(context, feedId); - if (feed != null) { - if (PlaybackPreferences.getCurrentlyPlayingMedia() == FeedMedia.PLAYABLE_TYPE_FEEDMEDIA - && PlaybackPreferences.getLastPlayedFeedId() == feed - .getId()) { - context.sendBroadcast(new Intent( - PlaybackService.ACTION_SHUTDOWN_PLAYBACK_SERVICE)); - SharedPreferences.Editor editor = prefs.edit(); - editor.putLong( - PlaybackPreferences.PREF_CURRENTLY_PLAYING_FEED_ID, - -1); - editor.commit(); - } - - PodDBAdapter adapter = new PodDBAdapter(context); - adapter.open(); - // delete image file - if (feed.getImage() != null) { - if (feed.getImage().isDownloaded() - && feed.getImage().getFile_url() != null) { - File imageFile = new File(feed.getImage() - .getFile_url()); - imageFile.delete(); - } else if (requester.isDownloadingFile(feed.getImage())) { - requester.cancelDownload(context, feed.getImage()); - } - } - // delete stored media files and mark them as read - List<FeedItem> queue = DBReader.getQueue(context); - boolean queueWasModified = false; - if (feed.getItems() == null) { - DBReader.getFeedItemList(context, feed); - } - - for (FeedItem item : feed.getItems()) { - queueWasModified |= queue.remove(item); - if (item.getMedia() != null - && item.getMedia().isDownloaded()) { - File mediaFile = new File(item.getMedia() - .getFile_url()); - mediaFile.delete(); - } else if (item.getMedia() != null - && requester.isDownloadingFile(item.getMedia())) { - requester.cancelDownload(context, item.getMedia()); - } - } - if (queueWasModified) { - adapter.setQueue(queue); - } - adapter.removeFeed(feed); - adapter.close(); - EventDistributor.getInstance().sendFeedUpdateBroadcast(); - } - } - }); - } - - public static void clearPlaybackHistory(final Context context) { - dbExec.submit(new Runnable() { - - @Override - public void run() { - PodDBAdapter adapter = new PodDBAdapter(context); - adapter.open(); - adapter.clearPlaybackHistory(); - adapter.close(); - EventDistributor.getInstance() - .sendPlaybackHistoryUpdateBroadcast(); - } - }); - } - - public static void addItemToPlaybackHistory(final Context context, - final FeedItem item) { - if (item.hasMedia() - && item.getMedia().getPlaybackCompletionDate() != null) { - if (AppConfig.DEBUG) - Log.d(TAG, "Adding new item to playback history"); - EventDistributor.getInstance().sendPlaybackHistoryUpdateBroadcast(); - } - - } - - private static void cleanupDownloadLog(final PodDBAdapter adapter) { - final int DOWNLOAD_LOG_SIZE = 50; - final long logSize = adapter.getDownloadLogSize(); - if (logSize > DOWNLOAD_LOG_SIZE) { - if (AppConfig.DEBUG) - Log.d(TAG, "Cleaning up download log"); - adapter.removeDownloadLogItems(logSize - DOWNLOAD_LOG_SIZE); - } - } - - public static void addDownloadStatus(final Context context, - final DownloadStatus status) { - dbExec.submit(new Runnable() { - - @Override - public void run() { - - PodDBAdapter adapter = new PodDBAdapter(context); - adapter.open(); - - adapter.setDownloadStatus(status); - cleanupDownloadLog(adapter); - adapter.close(); - EventDistributor.getInstance().sendDownloadLogUpdateBroadcast(); - } - }); - - } - - public static void addQueueItemAt(final Context context, final long itemId, - final int index, final boolean performAutoDownload) { - dbExec.submit(new Runnable() { - - @Override - public void run() { - final PodDBAdapter adapter = new PodDBAdapter(context); - adapter.open(); - final List<FeedItem> queue = DBReader - .getQueue(context, adapter); - FeedItem item = null; - - if (queue != null) { - boolean queueModified = false; - boolean unreadItemsModfied = false; - - if (!itemListContains(queue, itemId)) { - item = DBReader.getFeedItem(context, itemId); - if (item != null) { - queue.add(index, item); - queueModified = true; - if (!item.isRead()) { - item.setRead(true); - unreadItemsModfied = true; - } - } - } - if (queueModified) { - adapter.setQueue(queue); - EventDistributor.getInstance() - .sendQueueUpdateBroadcast(); - } - if (unreadItemsModfied && item != null) { - adapter.setSingleFeedItem(item); - EventDistributor.getInstance() - .sendUnreadItemsUpdateBroadcast(); - } - } - adapter.close(); - if (performAutoDownload) { - - new Thread() { - @Override - public void run() { - DBTasks.autodownloadUndownloadedItems(context); - - } - }.start(); - } - - } - }); - - } - - public static void addQueueItem(final Context context, - final long... itemIds) { - if (itemIds.length > 0) { - dbExec.submit(new Runnable() { - - @Override - public void run() { - final PodDBAdapter adapter = new PodDBAdapter(context); - adapter.open(); - final List<FeedItem> queue = DBReader.getQueue(context, - adapter); - - if (queue != null) { - boolean queueModified = false; - boolean unreadItemsModfied = false; - List<FeedItem> itemsToSave = new LinkedList<FeedItem>(); - for (int i = 0; i < itemIds.length; i++) { - if (!itemListContains(queue, itemIds[i])) { - final FeedItem item = DBReader.getFeedItem( - context, itemIds[i]); - - if (item != null) { - queue.add(item); - queueModified = true; - if (!item.isRead()) { - item.setRead(true); - itemsToSave.add(item); - unreadItemsModfied = true; - } - } - } - } - if (queueModified) { - adapter.setQueue(queue); - EventDistributor.getInstance() - .sendQueueUpdateBroadcast(); - } - if (unreadItemsModfied) { - adapter.setFeedItemlist(itemsToSave); - EventDistributor.getInstance() - .sendUnreadItemsUpdateBroadcast(); - } - } - adapter.close(); - new Thread() { - @Override - public void run() { - DBTasks.autodownloadUndownloadedItems(context); - - } - }.start(); - } - }); - } - } - - public static void clearQueue(final Context context) { - dbExec.submit(new Runnable() { - - @Override - public void run() { - PodDBAdapter adapter = new PodDBAdapter(context); - adapter.open(); - adapter.clearQueue(); - adapter.close(); - - EventDistributor.getInstance().sendQueueUpdateBroadcast(); - } - }); - } - - public static void removeQueueItem(final Context context, - final long itemId, final boolean performAutoDownload) { - dbExec.submit(new Runnable() { - - @Override - public void run() { - final PodDBAdapter adapter = new PodDBAdapter(context); - adapter.open(); - final List<FeedItem> queue = DBReader - .getQueue(context, adapter); - FeedItem item = null; - - if (queue != null) { - boolean queueModified = false; + private static final String TAG = "DBWriter"; + + private static final ExecutorService dbExec; + + static { + dbExec = Executors.newSingleThreadExecutor(new ThreadFactory() { + + @Override + public Thread newThread(Runnable r) { + Thread t = new Thread(r); + t.setPriority(Thread.MIN_PRIORITY); + return t; + } + }); + } + + private DBWriter() { + } + + /** + * Deletes a downloaded FeedMedia file from the storage device. + * + * @param context A context that is used for opening a database connection. + * @param mediaId ID of the FeedMedia object whose downloaded file should be deleted. + */ + public static Future<?> deleteFeedMediaOfItem(final Context context, + final long mediaId) { + return dbExec.submit(new Runnable() { + @Override + public void run() { + + final FeedMedia media = DBReader.getFeedMedia(context, mediaId); + if (media != null) { + boolean result = false; + if (media.isDownloaded()) { + // delete downloaded media file + File mediaFile = new File(media.getFile_url()); + if (mediaFile.exists()) { + result = mediaFile.delete(); + } + media.setDownloaded(false); + media.setFile_url(null); + setFeedMedia(context, media); + + // If media is currently being played, change playback + // type to 'stream' and shutdown playback service + SharedPreferences prefs = PreferenceManager + .getDefaultSharedPreferences(context); + if (PlaybackPreferences.getCurrentlyPlayingMedia() == FeedMedia.PLAYABLE_TYPE_FEEDMEDIA) { + if (media.getId() == PlaybackPreferences + .getCurrentlyPlayingFeedMediaId()) { + SharedPreferences.Editor editor = prefs.edit(); + editor.putBoolean( + PlaybackPreferences.PREF_CURRENT_EPISODE_IS_STREAM, + true); + editor.commit(); + } + if (PlaybackPreferences + .getCurrentlyPlayingFeedMediaId() == media + .getId()) { + context.sendBroadcast(new Intent( + PlaybackService.ACTION_SHUTDOWN_PLAYBACK_SERVICE)); + } + } + } + if (AppConfig.DEBUG) + Log.d(TAG, "Deleting File. Result: " + result); + } + } + }); + } + + /** + * Deletes a Feed and all downloaded files of its components like images and downloaded episodes. + * + * @param context A context that is used for opening a database connection. + * @param feedId ID of the Feed that should be deleted. + */ + public static Future<?> deleteFeed(final Context context, final long feedId) { + return dbExec.submit(new Runnable() { + @Override + public void run() { + DownloadRequester requester = DownloadRequester.getInstance(); + SharedPreferences prefs = PreferenceManager + .getDefaultSharedPreferences(context + .getApplicationContext()); + final Feed feed = DBReader.getFeed(context, feedId); + if (feed != null) { + if (PlaybackPreferences.getCurrentlyPlayingMedia() == FeedMedia.PLAYABLE_TYPE_FEEDMEDIA + && PlaybackPreferences.getLastPlayedFeedId() == feed + .getId()) { + context.sendBroadcast(new Intent( + PlaybackService.ACTION_SHUTDOWN_PLAYBACK_SERVICE)); + SharedPreferences.Editor editor = prefs.edit(); + editor.putLong( + PlaybackPreferences.PREF_CURRENTLY_PLAYING_FEED_ID, + -1); + editor.commit(); + } + + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + // delete image file + if (feed.getImage() != null) { + if (feed.getImage().isDownloaded() + && feed.getImage().getFile_url() != null) { + File imageFile = new File(feed.getImage() + .getFile_url()); + imageFile.delete(); + } else if (requester.isDownloadingFile(feed.getImage())) { + requester.cancelDownload(context, feed.getImage()); + } + } + // delete stored media files and mark them as read + List<FeedItem> queue = DBReader.getQueue(context); + boolean queueWasModified = false; + if (feed.getItems() == null) { + DBReader.getFeedItemList(context, feed); + } + + for (FeedItem item : feed.getItems()) { + queueWasModified |= queue.remove(item); + if (item.getMedia() != null + && item.getMedia().isDownloaded()) { + File mediaFile = new File(item.getMedia() + .getFile_url()); + mediaFile.delete(); + } else if (item.getMedia() != null + && requester.isDownloadingFile(item.getMedia())) { + requester.cancelDownload(context, item.getMedia()); + } + } + if (queueWasModified) { + adapter.setQueue(queue); + } + adapter.removeFeed(feed); + adapter.close(); + EventDistributor.getInstance().sendFeedUpdateBroadcast(); + } + } + }); + } + + /** + * Deletes the entire playback history. + * + * @param context A context that is used for opening a database connection. + */ + public static Future<?> clearPlaybackHistory(final Context context) { + return dbExec.submit(new Runnable() { + + @Override + public void run() { + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + adapter.clearPlaybackHistory(); + adapter.close(); + EventDistributor.getInstance() + .sendPlaybackHistoryUpdateBroadcast(); + } + }); + } + + /** + * Adds a FeedMedia object to the playback history. A FeedMedia object is in the playback history if + * its playback completion date is set to a non-null value. This method will set the playback completion date to the + * current date regardless of the current value. + * + * @param context A context that is used for opening a database connection. + * @param media FeedMedia that should be added to the playback history. + */ + public static Future<?> addItemToPlaybackHistory(final Context context, + final FeedMedia media) { + return dbExec.submit(new Runnable() { + @Override + public void run() { + if (AppConfig.DEBUG) + Log.d(TAG, "Adding new item to playback history"); + media.setPlaybackCompletionDate(new Date()); + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + adapter.setMedia(media); + adapter.close(); + EventDistributor.getInstance().sendPlaybackHistoryUpdateBroadcast(); + + } + }); + } + + private static void cleanupDownloadLog(final PodDBAdapter adapter) { + final long logSize = adapter.getDownloadLogSize(); + if (logSize > DBReader.DOWNLOAD_LOG_SIZE) { + if (AppConfig.DEBUG) + Log.d(TAG, "Cleaning up download log"); + adapter.removeDownloadLogItems(logSize - DBReader.DOWNLOAD_LOG_SIZE); + } + } + + /** + * Adds a Download status object to the download log. + * + * @param context A context that is used for opening a database connection. + * @param status The DownloadStatus object. + */ + public static Future<?> addDownloadStatus(final Context context, + final DownloadStatus status) { + return dbExec.submit(new Runnable() { + + @Override + public void run() { + + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + + adapter.setDownloadStatus(status); + cleanupDownloadLog(adapter); + adapter.close(); + EventDistributor.getInstance().sendDownloadLogUpdateBroadcast(); + } + }); + + } + + /** + * Inserts a FeedItem in the queue at the specified index. The 'read'-attribute of the FeedItem will be set to + * true. If the FeedItem is already in the queue, the queue will not be modified. + * + * @param context A context that is used for opening a database connection. + * @param itemId ID of the FeedItem that should be added to the queue. + * @param index Destination index. Must be in range 0..queue.size() + * @param performAutoDownload True if an auto-download process should be started after the operation + * @throws IndexOutOfBoundsException if index < 0 || index >= queue.size() + */ + public static Future<?> addQueueItemAt(final Context context, final long itemId, + final int index, final boolean performAutoDownload) { + return dbExec.submit(new Runnable() { + + @Override + public void run() { + final PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + final List<FeedItem> queue = DBReader + .getQueue(context, adapter); + FeedItem item = null; + + if (queue != null) { + boolean queueModified = false; + boolean unreadItemsModified = false; + + if (!itemListContains(queue, itemId)) { + item = DBReader.getFeedItem(context, itemId); + if (item != null) { + queue.add(index, item); + queueModified = true; + if (!item.isRead()) { + item.setRead(true); + unreadItemsModified = true; + } + } + } + if (queueModified) { + adapter.setQueue(queue); + EventDistributor.getInstance() + .sendQueueUpdateBroadcast(); + } + if (unreadItemsModified && item != null) { + adapter.setSingleFeedItem(item); + EventDistributor.getInstance() + .sendUnreadItemsUpdateBroadcast(); + } + } + adapter.close(); + if (performAutoDownload) { + + new Thread() { + @Override + public void run() { + DBTasks.autodownloadUndownloadedItems(context); + + } + }.start(); + } + + } + }); + + } + + /** + * Appends FeedItem objects to the end of the queue. The 'read'-attribute of all items will be set to true. + * If a FeedItem is already in the queue, the FeedItem will not change its position in the queue. + * + * @param context A context that is used for opening a database connection. + * @param itemIds IDs of the FeedItem objects that should be added to the queue. + */ + public static Future<?> addQueueItem(final Context context, + final long... itemIds) { + return dbExec.submit(new Runnable() { + + @Override + public void run() { + if (itemIds.length > 0) { + final PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + final List<FeedItem> queue = DBReader.getQueue(context, + adapter); + + if (queue != null) { + boolean queueModified = false; + boolean unreadItemsModified = false; + List<FeedItem> itemsToSave = new LinkedList<FeedItem>(); + for (int i = 0; i < itemIds.length; i++) { + if (!itemListContains(queue, itemIds[i])) { + final FeedItem item = DBReader.getFeedItem( + context, itemIds[i]); + + if (item != null) { + queue.add(item); + queueModified = true; + if (!item.isRead()) { + item.setRead(true); + itemsToSave.add(item); + unreadItemsModified = true; + } + } + } + } + if (queueModified) { + adapter.setQueue(queue); + EventDistributor.getInstance() + .sendQueueUpdateBroadcast(); + } + if (unreadItemsModified) { + adapter.setFeedItemlist(itemsToSave); + EventDistributor.getInstance() + .sendUnreadItemsUpdateBroadcast(); + } + } + adapter.close(); + new Thread() { + @Override + public void run() { + DBTasks.autodownloadUndownloadedItems(context); + + } + }.start(); + } + } + }); + + } + + /** + * Removes all FeedItem objects from the queue. + * + * @param context A context that is used for opening a database connection. + */ + public static Future<?> clearQueue(final Context context) { + return dbExec.submit(new Runnable() { + + @Override + public void run() { + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + adapter.clearQueue(); + adapter.close(); + + EventDistributor.getInstance().sendQueueUpdateBroadcast(); + } + }); + } + + /** + * Removes a FeedItem object from the queue. + * + * @param context A context that is used for opening a database connection. + * @param itemId ID of the FeedItem that should be removed. + * @param performAutoDownload true if an auto-download process should be started after the operation. + */ + public static Future<?> removeQueueItem(final Context context, + final long itemId, final boolean performAutoDownload) { + return dbExec.submit(new Runnable() { + + @Override + public void run() { + final PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + final List<FeedItem> queue = DBReader + .getQueue(context, adapter); + FeedItem item = null; + + if (queue != null) { + boolean queueModified = false; QueueAccess queueAccess = QueueAccess.ItemListAccess(queue); if (queueAccess.contains(itemId)) { - item = DBReader.getFeedItem(context, itemId); - if (item != null) { - queueModified = queueAccess.remove(itemId); - } - } - if (queueModified) { - adapter.setQueue(queue); - EventDistributor.getInstance() - .sendQueueUpdateBroadcast(); - } else { + item = DBReader.getFeedItem(context, itemId); + if (item != null) { + queueModified = queueAccess.remove(itemId); + } + } + if (queueModified) { + adapter.setQueue(queue); + EventDistributor.getInstance() + .sendQueueUpdateBroadcast(); + } else { Log.w(TAG, "Queue was not modified by call to removeQueueItem"); } - } else { + } else { Log.e(TAG, "removeQueueItem: Could not load queue"); } - adapter.close(); - if (performAutoDownload) { + adapter.close(); + if (performAutoDownload) { - new Thread() { - @Override - public void run() { - DBTasks.autodownloadUndownloadedItems(context); + new Thread() { + @Override + public void run() { + DBTasks.autodownloadUndownloadedItems(context); - } - }.start(); - } - } - }); + } + }.start(); + } + } + }); - } + } - public static void moveQueueItem(final Context context, final int from, - final int to, final boolean broadcastUpdate) { - dbExec.submit(new Runnable() { + /** + * Changes the position of a FeedItem in the queue. + * + * @param context A context that is used for opening a database connection. + * @param from Source index. Must be in range 0..queue.size()-1. + * @param to Destination index. Must be in range 0..queue.size()-1. + * @param broadcastUpdate true if this operation should trigger a QueueUpdateBroadcast. This option should be set to + * false if the caller wants to avoid unexpected updates of the GUI. + * @throws IndexOutOfBoundsException if (to < 0 || to >= queue.size()) || (from < 0 || from >= queue.size()) + */ + public static Future<?> moveQueueItem(final Context context, final int from, + final int to, final boolean broadcastUpdate) { + return dbExec.submit(new Runnable() { - @Override - public void run() { - final PodDBAdapter adapter = new PodDBAdapter(context); - adapter.open(); - final List<FeedItem> queue = DBReader - .getQueue(context, adapter); + @Override + public void run() { + final PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + final List<FeedItem> queue = DBReader + .getQueue(context, adapter); - if (queue != null) { - if (from >= 0 && from < queue.size() && to >= 0 - && to < queue.size()) { + if (queue != null) { + if (from >= 0 && from < queue.size() && to >= 0 + && to < queue.size()) { - final FeedItem item = queue.remove(from); - queue.add(to, item); + final FeedItem item = queue.remove(from); + queue.add(to, item); adapter.setQueue(queue); - if (broadcastUpdate) { - EventDistributor.getInstance() - .sendQueueUpdateBroadcast(); - } + if (broadcastUpdate) { + EventDistributor.getInstance() + .sendQueueUpdateBroadcast(); + } - } - } else { + } + } else { Log.e(TAG, "moveQueueItem: Could not load queue"); } - adapter.close(); - } - }); - } + adapter.close(); + } + }); + } - public static void markItemRead(Context context, FeedItem item, boolean read, boolean resetMediaPosition) { + /** + * Sets the 'read'-attribute of a FeedItem to the specified value. + * + * @param context A context that is used for opening a database connection. + * @param item The FeedItem object + * @param read New value of the 'read'-attribute + * @param resetMediaPosition true if this method should also reset the position of the FeedItem's FeedMedia object. + * If the FeedItem has no FeedMedia object, this parameter will be ignored. + */ + public static Future<?> markItemRead(Context context, FeedItem item, boolean read, boolean resetMediaPosition) { long mediaId = (item.hasMedia()) ? item.getMedia().getId() : 0; - markItemRead(context, item.getId(), read, mediaId, resetMediaPosition); + return markItemRead(context, item.getId(), read, mediaId, resetMediaPosition); + } + + /** + * Sets the 'read'-attribute of a FeedItem to the specified value. + * + * @param context A context that is used for opening a database connection. + * @param itemId ID of the FeedItem + * @param read New value of the 'read'-attribute + */ + public static Future<?> markItemRead(final Context context, final long itemId, + final boolean read) { + return markItemRead(context, itemId, read, 0, false); } - public static void markItemRead(final Context context, final long itemId, - final boolean read) { - markItemRead(context, itemId, read, 0, false); - } - - public static void markItemRead(final Context context, final long itemId, - final boolean read, final long mediaId, - final boolean resetMediaPosition) { - dbExec.submit(new Runnable() { - - @Override - public void run() { - final PodDBAdapter adapter = new PodDBAdapter(context); - adapter.open(); - adapter.setFeedItemRead(read, itemId, mediaId, - resetMediaPosition); - adapter.close(); - - EventDistributor.getInstance().sendUnreadItemsUpdateBroadcast(); - } - }); - } - - public static void markFeedRead(final Context context, final long feedId) { - dbExec.submit(new Runnable() { - - @Override - public void run() { - final PodDBAdapter adapter = new PodDBAdapter(context); - adapter.open(); - Cursor itemCursor = adapter.getAllItemsOfFeedCursor(feedId); - long[] itemIds = new long[itemCursor.getCount()]; - itemCursor.moveToFirst(); - for (int i = 0; i < itemIds.length; i++) { - itemIds[i] = itemCursor.getLong(PodDBAdapter.KEY_ID_INDEX); - } - itemCursor.close(); - adapter.setFeedItemRead(true, itemIds); - adapter.close(); - - EventDistributor.getInstance().sendUnreadItemsUpdateBroadcast(); - } - }); - - } - - public static void markAllItemsRead(final Context context) { - dbExec.submit(new Runnable() { - - @Override - public void run() { - final PodDBAdapter adapter = new PodDBAdapter(context); - adapter.open(); - Cursor itemCursor = adapter.getUnreadItemsCursor(); - long[] itemIds = new long[itemCursor.getCount()]; - itemCursor.moveToFirst(); - for (int i = 0; i < itemIds.length; i++) { - itemIds[i] = itemCursor.getLong(PodDBAdapter.KEY_ID_INDEX); - } - itemCursor.close(); - adapter.setFeedItemRead(true, itemIds); - adapter.close(); - - EventDistributor.getInstance().sendUnreadItemsUpdateBroadcast(); - } - }); - - } - - static Future<?> addNewFeed(final Context context, final Feed feed) { - return dbExec.submit(new Runnable() { - - @Override - public void run() { - final PodDBAdapter adapter = new PodDBAdapter(context); - adapter.open(); - adapter.setCompleteFeed(feed); - adapter.close(); - - EventDistributor.getInstance().sendFeedUpdateBroadcast(); - } - }); - } - - static Future<?> setCompleteFeed(final Context context, final Feed feed) { - return dbExec.submit(new Runnable() { - - @Override - public void run() { - PodDBAdapter adapter = new PodDBAdapter(context); - adapter.open(); - adapter.setCompleteFeed(feed); - adapter.close(); - - EventDistributor.getInstance().sendFeedUpdateBroadcast(); - }}); - - } - - public static Future<?> setFeedMedia(final Context context, - final FeedMedia media) { - return dbExec.submit(new Runnable() { - - @Override - public void run() { - PodDBAdapter adapter = new PodDBAdapter(context); - adapter.open(); - adapter.setMedia(media); - adapter.close(); - }}); - } + private static Future<?> markItemRead(final Context context, final long itemId, + final boolean read, final long mediaId, + final boolean resetMediaPosition) { + return dbExec.submit(new Runnable() { + + @Override + public void run() { + final PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + adapter.setFeedItemRead(read, itemId, mediaId, + resetMediaPosition); + adapter.close(); + + EventDistributor.getInstance().sendUnreadItemsUpdateBroadcast(); + } + }); + } + /** + * Sets the 'read'-attribute of all FeedItems of a specific Feed to true. + * + * @param context A context that is used for opening a database connection. + * @param feedId ID of the Feed. + */ + public static Future<?> markFeedRead(final Context context, final long feedId) { + return dbExec.submit(new Runnable() { + + @Override + public void run() { + final PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + Cursor itemCursor = adapter.getAllItemsOfFeedCursor(feedId); + long[] itemIds = new long[itemCursor.getCount()]; + itemCursor.moveToFirst(); + for (int i = 0; i < itemIds.length; i++) { + itemIds[i] = itemCursor.getLong(PodDBAdapter.KEY_ID_INDEX); + } + itemCursor.close(); + adapter.setFeedItemRead(true, itemIds); + adapter.close(); + + EventDistributor.getInstance().sendUnreadItemsUpdateBroadcast(); + } + }); + + } + + /** + * Sets the 'read'-attribute of all FeedItems to true. + * + * @param context A context that is used for opening a database connection. + */ + public static Future<?> markAllItemsRead(final Context context) { + return dbExec.submit(new Runnable() { + + @Override + public void run() { + final PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + Cursor itemCursor = adapter.getUnreadItemsCursor(); + long[] itemIds = new long[itemCursor.getCount()]; + itemCursor.moveToFirst(); + for (int i = 0; i < itemIds.length; i++) { + itemIds[i] = itemCursor.getLong(PodDBAdapter.KEY_ID_INDEX); + } + itemCursor.close(); + adapter.setFeedItemRead(true, itemIds); + adapter.close(); + + EventDistributor.getInstance().sendUnreadItemsUpdateBroadcast(); + } + }); + + } + + static Future<?> addNewFeed(final Context context, final Feed feed) { + return dbExec.submit(new Runnable() { + + @Override + public void run() { + final PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + adapter.setCompleteFeed(feed); + adapter.close(); + + EventDistributor.getInstance().sendFeedUpdateBroadcast(); + } + }); + } + + static Future<?> setCompleteFeed(final Context context, final Feed feed) { + return dbExec.submit(new Runnable() { + + @Override + public void run() { + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + adapter.setCompleteFeed(feed); + adapter.close(); + + EventDistributor.getInstance().sendFeedUpdateBroadcast(); + } + }); + + } + + /** + * Saves a FeedMedia object in the database. This method will save all attributes of the FeedMedia object. The + * contents of FeedComponent-attributes (e.g. the FeedMedia's 'item'-attribute) will not be saved. + * + * @param context A context that is used for opening a database connection. + * @param media The FeedMedia object. + */ + public static Future<?> setFeedMedia(final Context context, + final FeedMedia media) { + return dbExec.submit(new Runnable() { + + @Override + public void run() { + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + adapter.setMedia(media); + adapter.close(); + } + }); + } + + /** + * Saves only value of the 'position'-attribute of a FeedMedia object. + * + * @param context A context that is used for opening a database connection. + * @param media The FeedMedia object. + */ public static Future<?> setFeedMediaPosition(final Context context, final FeedMedia media) { - return dbExec.submit(new Runnable(){ + return dbExec.submit(new Runnable() { @Override public void run() { PodDBAdapter adapter = new PodDBAdapter(context); @@ -543,8 +671,15 @@ public class DBWriter { }); } + /** + * Saves a FeedItem object in the database. This method will save all attributes of the FeedItem object including + * the content of FeedComponent-attributes. + * + * @param context A context that is used for opening a database connection. + * @param item The FeedItem object. + */ public static Future<?> setFeedItem(final Context context, - final FeedItem item) { + final FeedItem item) { return dbExec.submit(new Runnable() { @Override @@ -553,11 +688,19 @@ public class DBWriter { adapter.open(); adapter.setSingleFeedItem(item); adapter.close(); - }}); + } + }); } + /** + * Saves a FeedImage object in the database. This method will save all attributes of the FeedImage object. The + * contents of FeedComponent-attributes (e.g. the FeedImages's 'feed'-attribute) will not be saved. + * + * @param context A context that is used for opening a database connection. + * @param image The FeedImage object. + */ public static Future<?> setFeedImage(final Context context, - final FeedImage image) { + final FeedImage image) { return dbExec.submit(new Runnable() { @Override @@ -566,15 +709,16 @@ public class DBWriter { adapter.open(); adapter.setImage(image); adapter.close(); - }}); + } + }); } - private static boolean itemListContains(List<FeedItem> items, long itemId) { - for (FeedItem item : items) { - if (item.getId() == itemId) { - return true; - } - } - return false; - } + private static boolean itemListContains(List<FeedItem> items, long itemId) { + for (FeedItem item : items) { + if (item.getId() == itemId) { + return true; + } + } + return false; + } } diff --git a/src/de/danoeh/antennapod/storage/PodDBAdapter.java b/src/de/danoeh/antennapod/storage/PodDBAdapter.java index a0c6cb11f..ac9309674 100644 --- a/src/de/danoeh/antennapod/storage/PodDBAdapter.java +++ b/src/de/danoeh/antennapod/storage/PodDBAdapter.java @@ -438,7 +438,7 @@ public class PodDBAdapter { } values.put(KEY_PUBDATE, item.getPubDate().getTime()); values.put(KEY_PAYMENT_LINK, item.getPaymentLink()); - if (item.getFeed().getId() == 0) { + if (item.getFeed() != null) { setFeed(item.getFeed()); } values.put(KEY_FEED, item.getFeed().getId()); @@ -452,9 +452,7 @@ public class PodDBAdapter { new String[]{String.valueOf(item.getId())}); } if (item.getMedia() != null) { - if (item.getMedia().getId() == 0) { setMedia(item.getMedia()); - } } if (item.getChapters() != null) { setChapters(item); |