Ported search components to DB*-classes

This commit is contained in:
daniel oeh 2013-08-04 21:35:44 +02:00
parent 355fc8114f
commit 24c50f7840
10 changed files with 755 additions and 680 deletions

View File

@ -5,7 +5,6 @@ import android.content.res.Configuration;
import android.util.Log;
import de.danoeh.antennapod.asynctask.ImageLoader;
import de.danoeh.antennapod.feed.EventDistributor;
import de.danoeh.antennapod.feed.FeedManager;
import de.danoeh.antennapod.preferences.PlaybackPreferences;
import de.danoeh.antennapod.preferences.UserPreferences;
@ -32,8 +31,6 @@ public class PodcastApp extends Application {
UserPreferences.createInstance(this);
PlaybackPreferences.createInstance(this);
EventDistributor.getInstance();
FeedManager manager = FeedManager.getInstance();
manager.loadDBData(getApplicationContext());
}
@Override

View File

@ -22,13 +22,14 @@ import com.actionbarsherlock.view.Window;
import de.danoeh.antennapod.AppConfig;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.feed.EventDistributor;
import de.danoeh.antennapod.feed.FeedManager;
import de.danoeh.antennapod.fragment.EpisodesFragment;
import de.danoeh.antennapod.fragment.ExternalPlayerFragment;
import de.danoeh.antennapod.fragment.FeedlistFragment;
import de.danoeh.antennapod.preferences.UserPreferences;
import de.danoeh.antennapod.service.PlaybackService;
import de.danoeh.antennapod.service.download.DownloadService;
import de.danoeh.antennapod.storage.DBReader;
import de.danoeh.antennapod.storage.DBTasks;
import de.danoeh.antennapod.storage.DownloadRequester;
import de.danoeh.antennapod.util.StorageUtils;
@ -39,7 +40,6 @@ public class MainActivity extends SherlockFragmentActivity {
private static final int EVENTS = EventDistributor.DOWNLOAD_HANDLED
| EventDistributor.DOWNLOAD_QUEUED;
private FeedManager manager;
private ViewPager viewpager;
private TabsAdapter pagerAdapter;
private ExternalPlayerFragment externalPlayerFragment;
@ -51,7 +51,6 @@ public class MainActivity extends SherlockFragmentActivity {
setTheme(UserPreferences.getTheme());
super.onCreate(savedInstanceState);
StorageUtils.checkStorageAvailability(this);
manager = FeedManager.getInstance();
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.main);
@ -80,7 +79,7 @@ public class MainActivity extends SherlockFragmentActivity {
if (!appLaunched && getIntent().getAction() != null
&& getIntent().getAction().equals(Intent.ACTION_MAIN)) {
appLaunched = true;
if (manager.getUnreadItemsSize(true) > 0) {
if (DBReader.getNumberOfUnreadItems(this) > 0) {
// select 'episodes' tab
getSupportActionBar().setSelectedNavigationItem(1);
}
@ -142,7 +141,7 @@ public class MainActivity extends SherlockFragmentActivity {
startActivity(new Intent(this, AddFeedActivity.class));
return true;
case R.id.all_feed_refresh:
manager.refreshAllFeeds(this);
DBTasks.refreshAllFeeds(this, null);
return true;
case R.id.show_downloads:
startActivity(new Intent(this, DownloadActivity.class));
@ -173,9 +172,6 @@ public class MainActivity extends SherlockFragmentActivity {
} else {
refreshAll.setVisible(true);
}
boolean hasFeeds = manager.getFeedsSize() > 0;
menu.findItem(R.id.all_feed_refresh).setVisible(hasFeeds);
return true;
}

View File

@ -1,6 +1,6 @@
package de.danoeh.antennapod.activity;
import java.util.ArrayList;
import java.util.List;
import android.annotation.SuppressLint;
import android.app.SearchManager;
@ -20,8 +20,7 @@ import de.danoeh.antennapod.R;
import de.danoeh.antennapod.adapter.SearchlistAdapter;
import de.danoeh.antennapod.feed.Feed;
import de.danoeh.antennapod.feed.FeedItem;
import de.danoeh.antennapod.feed.FeedManager;
import de.danoeh.antennapod.feed.FeedSearcher;
import de.danoeh.antennapod.storage.FeedSearcher;
import de.danoeh.antennapod.feed.SearchResult;
import de.danoeh.antennapod.fragment.FeedlistFragment;
import de.danoeh.antennapod.fragment.ItemlistFragment;
@ -34,10 +33,10 @@ public class SearchActivity extends SherlockListActivity {
public static final String EXTRA_FEED_ID = "de.danoeh.antennapod.searchactivity.extra.feedId";
private SearchlistAdapter searchAdapter;
private ArrayList<SearchResult> content;
private List<SearchResult> content;
/** Feed that is being searched or null if the search is global. */
private Feed selectedFeed;
/** ID of the feed that is being searched or null if the search is global. */
private long feedID;
private TextView txtvStatus;
@ -65,8 +64,7 @@ public class SearchActivity extends SherlockListActivity {
if (extra != null) {
if (AppConfig.DEBUG)
Log.d(TAG, "Found bundle extra");
long feedId = extra.getLong(EXTRA_FEED_ID);
selectedFeed = FeedManager.getInstance().getFeed(feedId);
feedID = extra.getLong(EXTRA_FEED_ID);
}
if (AppConfig.DEBUG)
Log.d(TAG, "Starting search");
@ -109,9 +107,9 @@ public class SearchActivity extends SherlockListActivity {
@Override
public boolean onSearchRequested() {
Bundle extra = null;
if (selectedFeed != null) {
if (feedID != 0) {
extra = new Bundle();
extra.putLong(EXTRA_FEED_ID, selectedFeed.getId());
extra.putLong(EXTRA_FEED_ID, feedID);
}
startSearch(null, false, extra, false);
return true;
@ -152,8 +150,8 @@ public class SearchActivity extends SherlockListActivity {
@Override
public void run() {
Log.d(TAG, "Starting background work");
final ArrayList<SearchResult> result = FeedSearcher
.performSearch(SearchActivity.this, query, selectedFeed);
final List<SearchResult> result = FeedSearcher
.performSearch(SearchActivity.this, query, feedID);
if (SearchActivity.this != null) {
SearchActivity.this.runOnUiThread(new Runnable() {

View File

@ -1715,8 +1715,10 @@ public class FeedManager {
}
});
}
/*
/**
*/
/**
* Searches the descriptions of FeedItems of a specific feed for a given
* string.
*
@ -1726,7 +1728,8 @@ public class FeedManager {
* The search string
* @param callback
* A callback which will be used to return the search result
* */
* *//*
public void searchFeedItemDescription(final Context context,
final Feed feed, final String query,
FeedManager.QueryTaskCallback callback) {
@ -1741,8 +1744,13 @@ public class FeedManager {
}
});
}
*/
/*
/**
*//*
*/
/**
* Searches the 'contentEncoded' field of FeedItems of a specific feed for a
* given string.
*
@ -1752,7 +1760,10 @@ public class FeedManager {
* The search string
* @param callback
* A callback which will be used to return the search result
* */
* *//*
*/
/*
public void searchFeedItemContentEncoded(final Context context,
final Feed feed, final String query,
FeedManager.QueryTaskCallback callback) {
@ -1767,6 +1778,8 @@ public class FeedManager {
}
});
}
*//*
/** Returns the number of feeds that are currently in the feeds list. */
public int getFeedsSize() {

View File

@ -283,6 +283,14 @@ public class FeedMedia extends FeedFile implements Playable {
return download_url;
}
@Override
public String getPaymentLink() {
if (item == null) {
return null;
}
return getItem().getPaymentLink();
}
@Override
public boolean localFileAvailable() {
return isDownloaded() && file_url != null;
@ -318,11 +326,6 @@ public class FeedMedia extends FeedFile implements Playable {
getItem().setChapters(chapters);
}
@Override
public String getPaymentLink() {
return getItem().getPaymentLink();
}
@Override
public Callable<String> loadShownotes() {
return new Callable<String>() {

View File

@ -7,10 +7,11 @@ public class SearchResult {
/** Higher value means more importance */
private int value;
public SearchResult(FeedComponent component, int value) {
public SearchResult(FeedComponent component, int value, String subtitle) {
super();
this.component = component;
this.value = value;
this.subtitle = subtitle;
}
public FeedComponent getComponent() {

View File

@ -108,6 +108,14 @@ public final class DBReader {
return items;
}
static List<FeedItem> extractItemlistFromCursor(Context context, Cursor itemlistCursor) {
PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open();
List<FeedItem> result = extractItemlistFromCursor(adapter, itemlistCursor);
adapter.close();
return result;
}
private static List<FeedItem> extractItemlistFromCursor(
PodDBAdapter adapter, Cursor itemlistCursor) {
ArrayList<String> itemIds = new ArrayList<String>();
@ -500,6 +508,14 @@ public final class DBReader {
return result;
}
public static int getNumberOfUnreadItems(final Context context) {
PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open();
final int result = adapter.getNumberOfUnreadItems();
adapter.close();
return result;
}
/**
* Searches the DB for a FeedImage of the given id.
*

File diff suppressed because it is too large Load Diff

View File

@ -1,32 +1,62 @@
package de.danoeh.antennapod.feed;
package de.danoeh.antennapod.storage;
import android.content.Context;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.feed.Feed;
import de.danoeh.antennapod.feed.FeedItem;
import de.danoeh.antennapod.feed.SearchResult;
import de.danoeh.antennapod.util.comparator.SearchResultValueComparator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import android.content.Context;
import android.database.Cursor;
import android.os.Looper;
import android.util.Log;
import de.danoeh.antennapod.AppConfig;
import de.danoeh.antennapod.PodcastApp;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.storage.PodDBAdapter;
import de.danoeh.antennapod.util.comparator.SearchResultValueComparator;
/** Performs search on Feeds and FeedItems */
/**
* Performs search on Feeds and FeedItems
*/
public class FeedSearcher {
private static final String TAG = "FeedSearcher";
private static final String TAG = "FeedSearcher";
// Search result values
private static final int VALUE_FEED_TITLE = 3;
private static final int VALUE_ITEM_TITLE = 2;
private static final int VALUE_ITEM_CHAPTER = 1;
private static final int VALUE_ITEM_DESCRIPTION = 0;
private static final int VALUE_WORD_MATCH = 4;
/** Performs a search in all feeds or one specific feed. */
/**
* Performs a search in all feeds or one specific feed.
*/
public static List<SearchResult> performSearch(final Context context,
final String query, final long selectedFeed) {
final int values[] = {0, 0, 1, 2};
final String[] subtitles = {context.getString(R.string.found_in_shownotes_label),
context.getString(R.string.found_in_shownotes_label),
context.getString(R.string.found_in_chapters_label),
context.getString(R.string.found_in_title_label)};
List<SearchResult> result = new ArrayList<SearchResult>();
FutureTask<List<FeedItem>>[] tasks = new FutureTask[4];
(tasks[0] = DBTasks.searchFeedItemContentEncoded(context, selectedFeed, query)).run();
(tasks[1] = DBTasks.searchFeedItemDescription(context, selectedFeed, query)).run();
(tasks[2] = DBTasks.searchFeedItemChapters(context, selectedFeed, query)).run();
(tasks[3] = DBTasks.searchFeedItemTitle(context, selectedFeed, query)).run();
try {
for (int i = 0; i < tasks.length; i++) {
FutureTask task = tasks[i];
List<FeedItem> items = (List<FeedItem>) task.get();
for (FeedItem item : items) {
result.add(new SearchResult(item, values[i], subtitles[i]));
}
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
Collections.sort(result, new SearchResultValueComparator());
return result;
}
/*
*//** Performs a search in all feeds or one specific feed. *//*
public static ArrayList<SearchResult> performSearch(final Context context,
final String query, final Feed selectedFeed) {
final String lcQuery = query.toLowerCase();
@ -49,38 +79,37 @@ public class FeedSearcher {
Log.d(TAG, "Searching item-chaptertitles");
searchFeedItemChapters(lcQuery, result, selectedFeed);
final FeedManager manager = FeedManager.getInstance();
Looper.prepare();
manager.searchFeedItemDescription(context, selectedFeed, lcQuery,
new FeedManager.QueryTaskCallback() {
DBTasks.searchFeedItemDescription(context, selectedFeed, lcQuery,
new DBTasks.QueryTaskCallback() {
@Override
public void handleResult(Cursor cResult) {
searchFeedItemContentEncodedCursor(lcQuery, result,
selectedFeed, cResult);
@Override
public void handleResult(Cursor cResult) {
searchFeedItemContentEncodedCursor(context, lcQuery, result,
selectedFeed, cResult);
}
}
@Override
public void onCompletion() {
manager.searchFeedItemContentEncoded(context,
selectedFeed, lcQuery,
new FeedManager.QueryTaskCallback() {
@Override
public void onCompletion() {
DBTasks.searchFeedItemContentEncoded(context,
selectedFeed, lcQuery,
new DBTasks.QueryTaskCallback() {
@Override
public void handleResult(Cursor cResult) {
searchFeedItemDescriptionCursor(
lcQuery, result, selectedFeed,
cResult);
}
@Override
public void handleResult(Cursor cResult) {
searchFeedItemDescriptionCursor(context,
lcQuery, result, selectedFeed,
cResult);
}
@Override
public void onCompletion() {
Looper.myLooper().quit();
}
});
}
});
@Override
public void onCompletion() {
Looper.myLooper().quit();
}
});
}
});
Looper.loop();
if (AppConfig.DEBUG)
@ -130,7 +159,6 @@ public class FeedSearcher {
private static void searchFeedItemChapters(String query,
ArrayList<SearchResult> destination, Feed selectedFeed) {
FeedManager manager = FeedManager.getInstance();
if (selectedFeed == null) {
for (Feed feed : manager.getFeeds()) {
searchFeedItemChaptersSingleFeed(query, destination, feed);
@ -157,10 +185,11 @@ public class FeedSearcher {
}
}
private static void searchFeedItemDescriptionCursor(String query,
private static void searchFeedItemDescriptionCursor(Context context, String query,
ArrayList<SearchResult> destination, Feed feed, Cursor cursor) {
FeedManager manager = FeedManager.getInstance();
if (cursor.moveToFirst()) {
List<FeedItem> items = DBReader.extractItemlistFromCursor(cursor);
if (cursor.moveToFirst()) {
do {
final long itemId = cursor
.getLong(PodDBAdapter.IDX_FI_EXTRA_ID);
@ -193,9 +222,8 @@ public class FeedSearcher {
}
}
private static void searchFeedItemContentEncodedCursor(String query,
private static void searchFeedItemContentEncodedCursor(Context context, String query,
ArrayList<SearchResult> destination, Feed feed, Cursor cursor) {
FeedManager manager = FeedManager.getInstance();
if (cursor.moveToFirst()) {
do {
final long itemId = cursor
@ -248,6 +276,6 @@ public class FeedSearcher {
} else {
return null;
}
}
}*/
}

View File

@ -35,6 +35,9 @@ public class PodDBAdapter {
/** 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;
@ -857,6 +860,18 @@ public class PodDBAdapter {
}
public final int getNumberOfUnreadItems() {
final String query = "SELECT COUNT(DISTINCT " + KEY_ID + ") AS count FROM " + TABLE_NAME_FEED_ITEMS +
" WHERE " + KEY_READ + " = 0";
Cursor c = db.rawQuery(query, null);
int result = 0;
if (c.moveToFirst()) {
result = c.getInt(0);
}
c.close();
return result;
}
public final int getNumberOfDownloadedEpisodes() {
final String query = "SELECT COUNT(DISTINCT " + KEY_ID + ") AS count FROM " + TABLE_NAME_FEED_MEDIA +
" WHERE " + KEY_DOWNLOADED + " > 0";
@ -888,17 +903,17 @@ public class PodDBAdapter {
*
* @return A cursor with all search results in SEL_FI_EXTRA selection.
* */
public Cursor searchItemDescriptions(Feed feed, String query) {
if (feed != null) {
public Cursor searchItemDescriptions(long feedID, String query) {
if (feedID != 0) {
// search items in specific feed
return db.query(TABLE_NAME_FEED_ITEMS, SEL_FI_EXTRA, KEY_FEED
return db.query(TABLE_NAME_FEED_ITEMS, SEL_FI_SMALL, KEY_FEED
+ "=? AND " + KEY_DESCRIPTION + " LIKE '%"
+ prepareSearchQuery(query) + "%'",
new String[] { String.valueOf(feed.getId()) }, null, null,
new String[] { String.valueOf(feedID) }, null, null,
null);
} else {
// search through all items
return db.query(TABLE_NAME_FEED_ITEMS, SEL_FI_EXTRA,
return db.query(TABLE_NAME_FEED_ITEMS, SEL_FI_SMALL,
KEY_DESCRIPTION + " LIKE '%" + prepareSearchQuery(query)
+ "%'", null, null, null, null);
}
@ -910,23 +925,57 @@ public class PodDBAdapter {
*
* @return A cursor with all search results in SEL_FI_EXTRA selection.
* */
public Cursor searchItemContentEncoded(Feed feed, String query) {
if (feed != null) {
public Cursor searchItemContentEncoded(long feedID, String query) {
if (feedID != 0) {
// search items in specific feed
return db.query(TABLE_NAME_FEED_ITEMS, SEL_FI_EXTRA, KEY_FEED
return db.query(TABLE_NAME_FEED_ITEMS, SEL_FI_SMALL, KEY_FEED
+ "=? AND " + KEY_CONTENT_ENCODED + " LIKE '%"
+ prepareSearchQuery(query) + "%'",
new String[] { String.valueOf(feed.getId()) }, null, null,
new String[] { String.valueOf(feedID) }, null, null,
null);
} else {
// search through all items
return db.query(TABLE_NAME_FEED_ITEMS, SEL_FI_EXTRA,
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) {
// search items in specific feed
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,
null);
} else {
// search through all items
return db.query(TABLE_NAME_FEED_ITEMS, SEL_FI_SMALL,
KEY_TITLE + " LIKE '%"
+ prepareSearchQuery(query) + "%'", null, null,
null, null);
}
}
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) + "%'";
} else {
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 {
/**