Added simple table and call to handle offline marking of stories as read.

This commit is contained in:
RyanBateman 2012-08-01 13:44:39 -04:00
parent 482b316501
commit ecd86b1036
7 changed files with 96 additions and 8 deletions

View file

@ -48,6 +48,12 @@ public class BlurDatabase extends SQLiteOpenHelper {
DatabaseConstants.COMMENT_TEXT + TEXT + ", " +
DatabaseConstants.COMMENT_USERID + TEXT +
")";
private final String OFFLINE_UPDATE_SQL = "CREATE TABLE " + DatabaseConstants.UPDATE_TABLE + " (" +
DatabaseConstants.UPDATE_ID + INTEGER + " PRIMARY KEY, " +
DatabaseConstants.UPDATE_TYPE + INTEGER + ", " +
DatabaseConstants.UPDATE_ARGUMENTS + TEXT +
")";
private final String STORY_SQL = "CREATE TABLE " + DatabaseConstants.STORY_TABLE + " (" +
DatabaseConstants.STORY_AUTHORS + TEXT + ", " +
@ -91,6 +97,7 @@ public class BlurDatabase extends SQLiteOpenHelper {
db.execSQL(COMMENT_SQL);
db.execSQL(CLASSIFIER_SQL);
db.execSQL(FEED_FOLDER_SQL);
db.execSQL(OFFLINE_UPDATE_SQL);
}
@Override

View file

@ -41,6 +41,15 @@ public class DatabaseConstants {
public static final String CLASSIFIER_KEY = "key";
public static final String CLASSIFIER_VALUE = "value";
public static final String UPDATE_TABLE = "offline_updates";
public static final String UPDATE_ID = BaseColumns._ID;
public static final String UPDATE_TYPE = "update_type";
public static final String UPDATE_ARGUMENTS = "update_argument";
public static final String[] UPDATE_COLUMNS = {
UPDATE_ID, UPDATE_TYPE, UPDATE_ARGUMENTS
};
public static final String STORY_TABLE = "stories";
public static final String STORY_ID = BaseColumns._ID;
public static final String STORY_AUTHORS = "authors";
@ -85,7 +94,6 @@ public class DatabaseConstants {
STORY_PERMALINK, STORY_READ, STORY_SHARE_COUNT, STORY_TAGS, STORY_TITLE, STORY_SHARED_USER_IDS
};
public static final String FOLDER_INTELLIGENCE_ALL = " HAVING SUM(" + DatabaseConstants.FEED_NEGATIVE_COUNT + " + " + DatabaseConstants.FEED_NEUTRAL_COUNT + " + " + DatabaseConstants.FEED_POSITIVE_COUNT + ") > 0 ";
public static final String FOLDER_INTELLIGENCE_SOME = " HAVING SUM(" + DatabaseConstants.FEED_NEUTRAL_COUNT + " + " + DatabaseConstants.FEED_POSITIVE_COUNT + ") > 0 ";
public static final String FOLDER_INTELLIGENCE_BEST = " HAVING SUM(" + DatabaseConstants.FEED_POSITIVE_COUNT + ") > 0 ";
@ -94,6 +102,7 @@ public class DatabaseConstants {
"AND " + DatabaseConstants.STORY_READ + " = '0'";
public static final String STORY_INTELLIGENCE_SOME = " (" + DatabaseConstants.STORY_INTELLIGENCE_AUTHORS + " + " + DatabaseConstants.STORY_INTELLIGENCE_FEED + " + " + DatabaseConstants.STORY_INTELLIGENCE_TAGS + " + " + DatabaseConstants.STORY_INTELLIGENCE_TITLE + ") >= 0 " +
"AND " + DatabaseConstants.STORY_READ + " = '0'";

View file

@ -17,7 +17,9 @@ public class FeedProvider extends ContentProvider {
public static final String AUTHORITY = "com.newsblur";
public static final String VERSION = "v1";
public static final Uri NEWSBLUR_URI = Uri.parse("content://" + AUTHORITY + "/" + VERSION);
public static final Uri OFFLINE_URI = Uri.parse("content://" + AUTHORITY + "/" + VERSION + "/offline_updates/");
public static final Uri FEEDS_URI = Uri.parse("content://" + AUTHORITY + "/" + VERSION + "/feeds/");
public static final Uri MODIFY_COUNT_URI = Uri.parse("content://" + AUTHORITY + "/" + VERSION + "/feedcount/");
public static final Uri STORIES_URI = Uri.parse("content://" + AUTHORITY + "/" + VERSION + "/stories/");
@ -36,6 +38,7 @@ public class FeedProvider extends ContentProvider {
private static final int STORY_COMMENTS = 7;
private static final int INDIVIDUAL_STORY = 8;
private static final int DECREMENT_COUNT = 9;
private static final int OFFLINE_UPDATES = 9;
private BlurDatabase databaseHelper;
@ -53,11 +56,18 @@ public class FeedProvider extends ContentProvider {
uriMatcher.addURI(AUTHORITY, VERSION + "/feedfoldermap/*/", SPECIFIC_FEED_FOLDER_MAP);
uriMatcher.addURI(AUTHORITY, VERSION + "/folders/", ALL_FOLDERS);
uriMatcher.addURI(AUTHORITY, VERSION + "/folders/*/", INDIVIDUAL_FOLDER);
uriMatcher.addURI(AUTHORITY, VERSION + "/offline_updates/", OFFLINE_UPDATES);
}
@Override
public int delete(Uri arg0, String arg1, String[] arg2) {
return 0;
public int delete(Uri uri, String selection, String[] selectionArgs) {
final SQLiteDatabase db = databaseHelper.getWritableDatabase();
switch (uriMatcher.match(uri)) {
case OFFLINE_UPDATES:
return db.delete(DatabaseConstants.UPDATE_TABLE, selection, selectionArgs);
default:
return 0;
}
}
@Override
@ -113,6 +123,14 @@ public class FeedProvider extends ContentProvider {
db.setTransactionSuccessful();
db.endTransaction();
break;
// Inserting a story
case OFFLINE_UPDATES:
db.beginTransaction();
db.insertWithOnConflict(DatabaseConstants.UPDATE_TABLE, null, values, SQLiteDatabase.CONFLICT_REPLACE);
db.setTransactionSuccessful();
db.endTransaction();
break;
case UriMatcher.NO_MATCH:
Log.d(TAG, "No match found for URI: " + uri.toString());
@ -212,7 +230,8 @@ public class FeedProvider extends ContentProvider {
folderBuilder.append(" ORDER BY ");
folderBuilder.append(DatabaseConstants.FOLDER_TABLE + "." + DatabaseConstants.FOLDER_NAME + " COLLATE NOCASE");
return db.rawQuery(folderBuilder.toString(), null);
case OFFLINE_UPDATES:
return db.query(DatabaseConstants.UPDATE_TABLE, null, null, null, null, null, null);
default:
throw new UnsupportedOperationException("Unknown URI: " + uri);
}
@ -228,7 +247,7 @@ public class FeedProvider extends ContentProvider {
case INDIVIDUAL_STORY:
return db.update(DatabaseConstants.STORY_TABLE, values, DatabaseConstants.STORY_ID + " = ?", new String[] { uri.getLastPathSegment() });
// In order to run a raw SQL query whereby we make decrement the column we need to a dynamic reference - something the usual content provider call easily handle. Hence this circuitous workaround.
// In order to run a raw SQL query whereby we make decrement the column we need to a dynamic reference - something the usual content provider can't easily handle. Hence this circuitous hack.
case DECREMENT_COUNT:
db.execSQL("UPDATE " + DatabaseConstants.FEED_TABLE + " SET " + selectionArgs[0] + " = " + selectionArgs[0] + " - 1 WHERE " + DatabaseConstants.FEED_ID + " = " + selectionArgs[1]);
return 0;

View file

@ -0,0 +1,31 @@
package com.newsblur.domain;
import android.content.ContentValues;
import android.database.Cursor;
import android.text.TextUtils;
import com.newsblur.database.DatabaseConstants;
public class OfflineUpdate {
public int id;
public UpdateType type;
public String[] arguments;
public ContentValues getContentValues() {
ContentValues values = new ContentValues();
values.put(DatabaseConstants.UPDATE_ARGUMENTS, TextUtils.join(",", arguments));
values.put(DatabaseConstants.UPDATE_TYPE, type.name());
return values;
}
public static OfflineUpdate fromCursor(final Cursor cursor) {
OfflineUpdate update = new OfflineUpdate();
update.arguments = TextUtils.split(cursor.getString(cursor.getColumnIndex(DatabaseConstants.UPDATE_ARGUMENTS)), ",");
update.type = UpdateType.valueOf(cursor.getString(cursor.getColumnIndex(DatabaseConstants.UPDATE_TYPE)));
update.id = cursor.getInt(cursor.getColumnIndex(DatabaseConstants.UPDATE_ID));
return update;
}
public static enum UpdateType { MARK_FEED_AS_READ };
}

View file

@ -83,6 +83,7 @@ public class FolderFeedListFragment extends Fragment implements OnGroupClickList
list.setAdapter(folderAdapter);
list.setOnGroupClickListener(this);
list.setOnChildClickListener(this);
return v;
}

View file

@ -40,7 +40,7 @@ public class MarkStoryAsReadTask extends AsyncTask<Story, Void, Void> {
} else {
selectionArgs = new String[] { DatabaseConstants.FEED_NEGATIVE_COUNT, story.feedId } ;
}
Log.d("TAG", "Returned: " + contentResolver.update(FeedProvider.MODIFY_COUNT_URI, null, null, selectionArgs));
contentResolver.update(FeedProvider.MODIFY_COUNT_URI, null, null, selectionArgs);
Uri storyUri = FeedProvider.STORY_URI.buildUpon().appendPath(story.id).build();
ContentValues values = new ContentValues();

View file

@ -2,11 +2,15 @@ package com.newsblur.service;
import android.app.IntentService;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.os.ResultReceiver;
import android.text.TextUtils;
import android.util.Log;
import com.newsblur.database.DatabaseConstants;
import com.newsblur.database.FeedProvider;
import com.newsblur.domain.OfflineUpdate;
import com.newsblur.network.APIClient;
import com.newsblur.network.APIManager;
@ -62,12 +66,29 @@ public class SyncService extends IntentService {
case EXTRA_TASK_FOLDER_UPDATE:
apiManager.getFolderFeedMapping();
break;
// For the moment, we only retry offline updates when we refresh counts
case EXTRA_TASK_REFRESH_COUNTS:
Cursor cursor = getContentResolver().query(FeedProvider.OFFLINE_URI, null, null, null, null);
while (cursor.moveToNext()) {
OfflineUpdate update = OfflineUpdate.fromCursor(cursor);
if (apiManager.markStoryAsRead(update.arguments[0], update.arguments[1])) {
getContentResolver().delete(FeedProvider.OFFLINE_URI, DatabaseConstants.UPDATE_ID + " = ?", new String[] { Integer.toString(update.id) });
}
}
apiManager.refreshFeedCounts();
break;
case EXTRA_TASK_MARK_STORY_READ:
if (!TextUtils.isEmpty(intent.getStringExtra(EXTRA_TASK_FEED_ID)) && !TextUtils.isEmpty(intent.getStringExtra(EXTRA_TASK_STORY_ID))) {
apiManager.markStoryAsRead(intent.getStringExtra(EXTRA_TASK_FEED_ID), intent.getStringExtra(EXTRA_TASK_STORY_ID));
final String feedId = intent.getStringExtra(EXTRA_TASK_FEED_ID);
final String storyId = intent.getStringExtra(EXTRA_TASK_STORY_ID);
if (!TextUtils.isEmpty(feedId) && !TextUtils.isEmpty(storyId)) {
if (!apiManager.markStoryAsRead(feedId, storyId)) {
Log.d(TAG, "Unable to mark-as-read online. Saving for later.");
OfflineUpdate update = new OfflineUpdate();
update.arguments = new String[] { feedId, storyId };
update.type = OfflineUpdate.UpdateType.MARK_FEED_AS_READ;
getContentResolver().insert(FeedProvider.OFFLINE_URI, update.getContentValues());
}
} else {
Log.e(TAG, "No feed/story to mark as read included in SyncRequest");
receiver.send(STATUS_ERROR, Bundle.EMPTY);