Implemented DBWriter-methods

This commit is contained in:
daniel oeh 2013-05-04 00:22:00 +02:00
parent beda074e5f
commit e89f1a9b1f
4 changed files with 485 additions and 35 deletions

View File

@ -284,7 +284,7 @@ public class Feed extends FeedFile {
this.image = image;
}
List<FeedItem> getItems() {
public List<FeedItem> getItems() {
return items;
}

View File

@ -247,24 +247,28 @@ public final class DBReader {
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);
Collections.sort(items, new FeedItemPubdateComparator());
return items;
}
public static List<FeedItem> getQueue(Context context) {
if (AppConfig.DEBUG)
Log.d(TAG, "Extracting queue");
PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open();
Cursor itemlistCursor = adapter.getQueueCursor();
List<FeedItem> items = extractItemlistFromCursor(adapter,
itemlistCursor);
itemlistCursor.close();
loadFeedDataOfFeedItemlist(context, items);
List<FeedItem> items = getQueue(context, adapter);
adapter.close();
Collections.sort(items, new FeedItemPubdateComparator());
return items;
}
@ -287,8 +291,26 @@ public final class DBReader {
return items;
}
public static List<FeedItem> getPlaybackHistory() {
return null;
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; i++) {
itemIds[i] = Long.toString(mediaCursor.getLong(PodDBAdapter.KEY_FEEDITEM_INDEX));
}
mediaCursor.close();
Cursor itemCursor = adapter.getFeedItemCursor(itemIds);
List<FeedItem> items = extractItemlistFromCursor(adapter, itemCursor);
itemCursor.close();
adapter.close();
return items;
}
public static List<DownloadStatus> getDownloadLog(Context context) {
@ -346,20 +368,29 @@ public final class DBReader {
return feed;
}
public FeedItem getFeedItem(final Context context, final long itemId) {
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;
PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open();
Cursor itemCursor = adapter.getFeedItemCursor(itemId);
Cursor itemCursor = adapter.getFeedItemCursor(Long.toString(itemId));
if (itemCursor.moveToFirst()) {
List<FeedItem> list = extractItemlistFromCursor(adapter, itemCursor);
if (list.size() > 0) {
item = list.get(0);
}
}
return item;
}
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;

View File

@ -1,63 +1,441 @@
package de.danoeh.antennapod.storage;
import java.io.File;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.util.Log;
import de.danoeh.antennapod.AppConfig;
import de.danoeh.antennapod.asynctask.DownloadStatus;
import de.danoeh.antennapod.feed.EventDistributor;
import de.danoeh.antennapod.feed.Feed;
import de.danoeh.antennapod.feed.FeedItem;
import de.danoeh.antennapod.feed.FeedMedia;
import de.danoeh.antennapod.preferences.PlaybackPreferences;
import de.danoeh.antennapod.service.PlaybackService;
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 boolean deleteFeedMedia(final Context context,
final long mediaId) {
return false;
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 void deleteFeed(final Context context, final long feedId) {
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,
long itemId) {
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 removeItemFromPlaybackHistory(final Context context,
long itemId) {
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 long statusId) {
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;
if (itemListContains(queue, itemId)) {
item = DBReader.getFeedItem(context, itemId);
if (item != null) {
queue.remove(item);
queueModified = true;
}
}
if (queueModified) {
adapter.setQueue(queue);
EventDistributor.getInstance()
.sendQueueUpdateBroadcast();
}
}
adapter.close();
if (performAutoDownload) {
new Thread() {
@Override
public void run() {
DBTasks.autodownloadUndownloadedItems(context);
}
}.start();
}
}
});
}
public void moveQueueItem(final Context context, int from, int to,
boolean broadcastUpdate) {
public void moveQueueItem(final Context context, final int from,
final int to, final boolean broadcastUpdate) {
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) {
if (from >= 0 && from < queue.size() && to >= 0
&& to < queue.size()) {
final FeedItem item = queue.remove(from);
queue.add(to, item);
adapter.setQueue(queue);
if (broadcastUpdate) {
EventDistributor.getInstance()
.sendQueueUpdateBroadcast();
}
void addNewFeed(final Context context, final long feedId) {
}
}
adapter.close();
}
});
}
void addNewFeed(final Context context, final Feed feed) {
dbExec.submit(new Runnable() {
@Override
public void run() {
final PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open();
adapter.setCompleteFeed(feed);
adapter.close();
EventDistributor.getInstance().sendFeedUpdateBroadcast();
}
});
}
private static void setFeedMedia(final Context context,
final FeedMedia media) {
PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open();
adapter.setMedia(media);
adapter.close();
}
private static boolean itemListContains(List<FeedItem> items, long itemId) {
for (FeedItem item : items) {
if (item.getId() == itemId) {
return true;
}
}
return false;
}
}

View File

@ -341,6 +341,15 @@ public class PodDBAdapter {
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);
@ -439,6 +448,22 @@ public class PodDBAdapter {
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();
@ -455,6 +480,10 @@ public class PodDBAdapter {
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()) });
@ -502,6 +531,12 @@ public class PodDBAdapter {
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.
*
@ -681,11 +716,17 @@ public class PodDBAdapter {
return c;
}
public final Cursor getFeedItemCursor(final long id) {
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();
Cursor c = db.query(TABLE_NAME_FEEDS, null, KEY_ID + "=" + id, null,
null, null, null);
return c;
return db.query(TABLE_NAME_FEED_ITEMS, null, KEY_ID + " IN "
+ buildInOperator(ids.length), ids, null, null, null);
}
/**