diff options
12 files changed, 263 insertions, 279 deletions
diff --git a/News-Android-App/build.gradle b/News-Android-App/build.gradle index 00ec6d4d..7034f94f 100644 --- a/News-Android-App/build.gradle +++ b/News-Android-App/build.gradle @@ -162,8 +162,11 @@ dependencies { implementation ('de.greenrobot:greendao-generator:2.1.0') { exclude group: 'org.freemarker' } - //implementation 'org.freemarker:freemarker:2.3.23' // Required for DAO generation - //implementation 'org.apache.commons:commons-lang3:3.4' + + // implementation 'org.freemarker:freemarker:2.3.23' // Required for DAO generation + // implementation 'org.apache.commons:commons-lang3:3.4' // Required for DAO generation + + implementation 'com.github.gabrielemariotti.changeloglib:changelog:2.1.0' implementation 'org.jsoup:jsoup:1.13.1' implementation ('net.rdrei.android.dirchooser:library:3.0@aar') { diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/authentication/OwnCloudSyncAdapter.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/authentication/OwnCloudSyncAdapter.java index ae541280..12eaaacb 100644 --- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/authentication/OwnCloudSyncAdapter.java +++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/authentication/OwnCloudSyncAdapter.java @@ -21,7 +21,6 @@ import java.util.List; import javax.inject.Inject; import de.luhmer.owncloudnewsreader.Constants; -import de.luhmer.owncloudnewsreader.ListView.SubscriptionExpandableListAdapter; import de.luhmer.owncloudnewsreader.NewsReaderApplication; import de.luhmer.owncloudnewsreader.R; import de.luhmer.owncloudnewsreader.database.DatabaseConnectionOrm; @@ -92,8 +91,6 @@ public class OwnCloudSyncAdapter extends AbstractThreadedSyncAdapter { Log.v(TAG, "Finished sync - time needed (synchronization): " + syncStopWatch.toString()); } - - private static class NextcloudSyncResult { private final List<Folder> folders; private final List<Feed> feeds; @@ -106,7 +103,6 @@ public class OwnCloudSyncAdapter extends AbstractThreadedSyncAdapter { } } - // Start sync private void sync() { if(mApi.getNewsAPI() == null) { @@ -123,8 +119,8 @@ public class OwnCloudSyncAdapter extends AbstractThreadedSyncAdapter { (Publisher<Boolean>) s -> { Log.v(TAG, "(rssStateSync) subscribe() called with: s = [" + s + "] [" + Thread.currentThread().getName() + "]"); try { - boolean success = ItemStateSync.PerformItemStateSync(mApi.getNewsAPI(), dbConn); - s.onNext(success); + ItemStateSync.PerformItemStateSync(mApi.getNewsAPI(), dbConn); + s.onNext(true); s.onComplete(); } catch(Exception ex) { s.onError(ex); @@ -173,7 +169,7 @@ public class OwnCloudSyncAdapter extends AbstractThreadedSyncAdapter { Observable.fromPublisher(new RssItemObservable(dbConn, mApi.getNewsAPI(), mPrefs)) .subscribeOn(Schedulers.newThread()) - .blockingSubscribe(new Observer<Integer>() { + .blockingSubscribe(new Observer<>() { @Override public void onSubscribe(@NonNull Disposable d) { Log.d(TAG, "[syncRssItems] - onSubscribe() called"); @@ -215,11 +211,11 @@ public class OwnCloudSyncAdapter extends AbstractThreadedSyncAdapter { } private void updateNotification() { - DatabaseConnectionOrm dbConn = new DatabaseConnectionOrm(getContext()); + // DatabaseConnectionOrm dbConn = new DatabaseConnectionOrm(getContext()); int newItemsCountLastSync = mPrefs.getInt(Constants.LAST_UPDATE_NEW_ITEMS_COUNT_STRING, 0); if (newItemsCountLastSync > 0) { - int newItemsCount = Integer.parseInt(dbConn.getUnreadItemsCountForSpecificFolder(SubscriptionExpandableListAdapter.SPECIAL_FOLDERS.ALL_UNREAD_ITEMS)); + // int newItemsCount = Integer.parseInt(dbConn.getUnreadItemsCountForSpecificFolder(SubscriptionExpandableListAdapter.SPECIAL_FOLDERS.ALL_UNREAD_ITEMS)); // If another app is not in foreground if (!ForegroundListener.isInForeground()) { diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/DatabaseConnectionOrm.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/DatabaseConnectionOrm.java index a1776085..e89755d1 100644 --- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/DatabaseConnectionOrm.java +++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/DatabaseConnectionOrm.java @@ -83,48 +83,24 @@ public class DatabaseConnectionOrm { daoSession = DatabaseHelperOrm.getDaoSession(context, databasePath); } - /* - public void insertNewFolder (Folder folder) { - daoSession.getFolderDao().insertOrReplace(folder); - }*/ - public void deleteOldAndInsertNewFolders (final Folder... folder) { - daoSession.runInTx(new Runnable() { - @Override - public void run() { - daoSession.getFolderDao().deleteAll(); - daoSession.getFolderDao().insertInTx(folder); - } + daoSession.runInTx(() -> { + daoSession.getFolderDao().deleteAll(); + daoSession.getFolderDao().insertInTx(folder); }); } public void deleteOldAndInsertNewFolders (final Iterable<Folder> folder) { - daoSession.runInTx(new Runnable() { - @Override - public void run() { - daoSession.getFolderDao().deleteAll(); - daoSession.getFolderDao().insertInTx(folder); - } + daoSession.runInTx(() -> { + daoSession.getFolderDao().deleteAll(); + daoSession.getFolderDao().insertInTx(folder); }); - - } - - /* - public void insertNewFeed (Feed... feeds) { - daoSession.getFeedDao().insertOrReplaceInTx(feeds); } -*/ public void insertNewFeed (Iterable<Feed> feeds) { daoSession.getFeedDao().insertOrReplaceInTx(feeds); } - /* - public void insertNewItems(RssItem... items) { - daoSession.getRssItemDao().insertOrReplaceInTx(items); - } -*/ - public void insertNewItems(Iterable<RssItem> items) { daoSession.getRssItemDao().insertOrReplaceInTx(items); } @@ -445,24 +421,13 @@ public class DatabaseConnectionOrm { } } - - /* - public boolean doesRssItemAlreadyExists (long feedId) { - List<RssItem> feeds = daoSession.getRssItemDao().queryBuilder().where(RssItemDao.Properties.Id.eq(feedId)).list(); - return feeds.size() > 0; - } - */ - public void removeFeedById(final long feedId) { - daoSession.runInTx(new Runnable() { - @Override - public void run() { - daoSession.getFeedDao().deleteByKey(feedId); + daoSession.runInTx(() -> { + daoSession.getFeedDao().deleteByKey(feedId); - List<RssItem> list = daoSession.getRssItemDao().queryBuilder().where(RssItemDao.Properties.FeedId.eq(feedId)).list(); - for (RssItem rssItem : list) { - daoSession.getRssItemDao().delete(rssItem); - } + List<RssItem> list = daoSession.getRssItemDao().queryBuilder().where(RssItemDao.Properties.FeedId.eq(feedId)).list(); + for (RssItem rssItem : list) { + daoSession.getRssItemDao().delete(rssItem); } }); } diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/generator/DatabaseOrmGenerator.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/generator/DatabaseOrmGenerator.java index 0c73e70c..bbea74b5 100644 --- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/generator/DatabaseOrmGenerator.java +++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/generator/DatabaseOrmGenerator.java @@ -19,7 +19,7 @@ public class DatabaseOrmGenerator { public static void main(String[] args) throws Exception { List<SchemaVersion> versions = new ArrayList<>(); - versions.add(new Version8(true)); + versions.add(new Version9(true)); validateSchemas(versions); diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/generator/Version8.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/generator/Version9.java index fea745e4..f1582e99 100644 --- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/generator/Version8.java +++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/generator/Version9.java @@ -4,20 +4,28 @@ import de.greenrobot.daogenerator.Entity; import de.greenrobot.daogenerator.Property; import de.greenrobot.daogenerator.Schema; -public class Version8 extends SchemaVersion { +public class Version9 extends SchemaVersion { /** * Constructor * * @param current */ - public Version8(boolean current) { + public Version9(boolean current) { super(current); Schema schema = getSchema(); addEntitysToSchema(schema); } + /** + * {@inheritDoc} + */ + @Override + public int getVersionNumber() { + return 9; + } + @SuppressWarnings("unused") // id properties (folderId, etc.) need to be in database private static void addEntitysToSchema(Schema schema) { @@ -82,12 +90,4 @@ public class Version8 extends SchemaVersion { rssItem.implementsInterface("HasId<Long>"); } - - /** - * {@inheritDoc} - */ - @Override - public int getVersionNumber() { - return 8; - } } diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/model/CurrentRssItemViewDao.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/model/CurrentRssItemViewDao.java index 1bd9c10f..730c73d6 100644 --- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/model/CurrentRssItemViewDao.java +++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/model/CurrentRssItemViewDao.java @@ -55,9 +55,7 @@ public class CurrentRssItemViewDao extends AbstractDao<CurrentRssItemView, Long> return cursor.getLong(offset + 0); } - /** - * @inheritdoc - */ + /** @inheritdoc */ @Override public CurrentRssItemView readEntity(Cursor cursor, int offset) { CurrentRssItemView entity = new CurrentRssItemView( // diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/model/DaoMaster.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/model/DaoMaster.java index 53b01a3f..2b015305 100644 --- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/model/DaoMaster.java +++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/model/DaoMaster.java @@ -11,10 +11,10 @@ import de.greenrobot.dao.identityscope.IdentityScopeType; // THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT. /** - * Master of DAO (schema version 8): knows all DAOs. + * Master of DAO (schema version 9): knows all DAOs. */ public class DaoMaster extends AbstractDaoMaster { - public static final int SCHEMA_VERSION = 8; + public static final int SCHEMA_VERSION = 9; /** Creates underlying database table using DAOs. */ public static void createAllTables(SQLiteDatabase db, boolean ifNotExists) { @@ -57,6 +57,13 @@ public class DaoMaster extends AbstractDaoMaster { dropAllTables(db, true); onCreate(db); } + + @Override + public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) { + Log.i("greenDAO", "Downgrading schema from version " + oldVersion + " to " + newVersion + " by dropping all tables"); + dropAllTables(db, true); + onCreate(db); + } } public DaoMaster(SQLiteDatabase db) { diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/model/FeedDao.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/model/FeedDao.java index 45cf8e4c..dc6348be 100644 --- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/model/FeedDao.java +++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/model/FeedDao.java @@ -15,16 +15,34 @@ import de.greenrobot.dao.query.Query; import de.greenrobot.dao.query.QueryBuilder; // THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT. -/** +/** * DAO for table "FEED". -*/ + */ public class FeedDao extends AbstractDao<Feed, Long> { public static final String TABLENAME = "FEED"; + private DaoSession daoSession; + private Query<Feed> folder_FeedListQuery; + + public FeedDao(DaoConfig config) { + super(config); + } + + public FeedDao(DaoConfig config, DaoSession daoSession) { + super(config, daoSession); + this.daoSession = daoSession; + } + + /** Drops the underlying database table. */ + public static void dropTable(SQLiteDatabase db, boolean ifExists) { + String sql = "DROP TABLE " + (ifExists ? "IF EXISTS " : "") + "\"FEED\""; + db.execSQL(sql); + } + /** Creates the underlying database table. */ public static void createTable(SQLiteDatabase db, boolean ifNotExists) { - String constraint = ifNotExists? "IF NOT EXISTS ": ""; + String constraint = ifNotExists ? "IF NOT EXISTS " : ""; db.execSQL("CREATE TABLE " + constraint + "\"FEED\" (" + // "\"_id\" INTEGER PRIMARY KEY NOT NULL ," + // 0: id "\"FOLDER_ID\" INTEGER," + // 1: folderId @@ -38,19 +56,6 @@ public class FeedDao extends AbstractDao<Feed, Long> { " (\"FOLDER_ID\");"); } - private DaoSession daoSession; - - private Query<Feed> folder_FeedListQuery; - - public FeedDao(DaoConfig config) { - super(config); - } - - public FeedDao(DaoConfig config, DaoSession daoSession) { - super(config, daoSession); - this.daoSession = daoSession; - } - /** * @inheritdoc */ @@ -86,17 +91,7 @@ public class FeedDao extends AbstractDao<Feed, Long> { } } - /** - * Drops the underlying database table. - */ - public static void dropTable(SQLiteDatabase db, boolean ifExists) { - String sql = "DROP TABLE " + (ifExists ? "IF EXISTS " : "") + "\"FEED\""; - db.execSQL(sql); - } - - /** - * @inheritdoc - */ + /** @inheritdoc */ @Override public Long readKey(Cursor cursor, int offset) { return cursor.getLong(offset + 0); @@ -108,9 +103,7 @@ public class FeedDao extends AbstractDao<Feed, Long> { entity.__setDaoSession(daoSession); } - /** - * @inheritdoc - */ + /** @inheritdoc */ @Override public Feed readEntity(Cursor cursor, int offset) { Feed entity = new Feed( // @@ -139,33 +132,6 @@ public class FeedDao extends AbstractDao<Feed, Long> { entity.setNotificationChannel(cursor.isNull(offset + 6) ? null : cursor.getString(offset + 6)); } - public Feed loadDeep(Long key) { - assertSinglePk(); - if (key == null) { - return null; - } - - StringBuilder builder = new StringBuilder(getSelectDeep()); - builder.append("WHERE "); - SqlUtils.appendColumnsEqValue(builder, "T", getPkColumns()); - String sql = builder.toString(); - - String[] keyArray = new String[]{key.toString()}; - Cursor cursor = db.rawQuery(sql, keyArray); - - try { - boolean available = cursor.moveToFirst(); - if (!available) { - return null; - } else if (!cursor.isLast()) { - throw new IllegalStateException("Expected unique result, but count was " + cursor.getCount()); - } - return loadCurrentDeep(cursor, true); - } finally { - cursor.close(); - } - } - /** * @inheritdoc */ @@ -174,11 +140,23 @@ public class FeedDao extends AbstractDao<Feed, Long> { entity.setId(rowId); return rowId; } - - /** @inheritdoc */ + + protected Feed loadCurrentDeep(Cursor cursor, boolean lock) { + Feed entity = loadCurrent(cursor, 0, lock); + int offset = getAllColumns().length; + + Folder folder = loadCurrentOther(daoSession.getFolderDao(), cursor, offset); + entity.setFolder(folder); + + return entity; + } + + /** + * @inheritdoc + */ @Override public Long getKey(Feed entity) { - if(entity != null) { + if (entity != null) { return entity.getId(); } else { return null; @@ -221,33 +199,34 @@ public class FeedDao extends AbstractDao<Feed, Long> { return selectDeep; } - protected Feed loadCurrentDeep(Cursor cursor, boolean lock) { - Feed entity = loadCurrent(cursor, 0, lock); - int offset = getAllColumns().length; + public Feed loadDeep(Long key) { + assertSinglePk(); + if (key == null) { + return null; + } - Folder folder = loadCurrentOther(daoSession.getFolderDao(), cursor, offset); - entity.setFolder(folder); + StringBuilder builder = new StringBuilder(getSelectDeep()); + builder.append("WHERE "); + SqlUtils.appendColumnsEqValue(builder, "T", getPkColumns()); + String sql = builder.toString(); - return entity; - } + String[] keyArray = new String[]{key.toString()}; + Cursor cursor = db.rawQuery(sql, keyArray); - /** - * Properties of entity Feed.<br/> - * Can be used for QueryBuilder and for referencing column names. - */ - public static class Properties { - public final static Property Id = new Property(0, long.class, "id", true, "_id"); - public final static Property FolderId = new Property(1, Long.class, "folderId", false, "FOLDER_ID"); - public final static Property FeedTitle = new Property(2, String.class, "feedTitle", false, "FEED_TITLE"); - public final static Property FaviconUrl = new Property(3, String.class, "faviconUrl", false, "FAVICON_URL"); - public final static Property Link = new Property(4, String.class, "link", false, "LINK"); - public final static Property AvgColour = new Property(5, String.class, "avgColour", false, "AVG_COLOUR"); - public final static Property NotificationChannel = new Property(6, String.class, "notificationChannel", false, "NOTIFICATION_CHANNEL"); + try { + boolean available = cursor.moveToFirst(); + if (!available) { + return null; + } else if (!cursor.isLast()) { + throw new IllegalStateException("Expected unique result, but count was " + cursor.getCount()); + } + return loadCurrentDeep(cursor, true); + } finally { + cursor.close(); + } } - /** - * Reads all available rows from the given cursor and returns a list of new ImageTO objects. - */ + /** Reads all available rows from the given cursor and returns a list of new ImageTO objects. */ public List<Feed> loadAllDeepFromCursor(Cursor cursor) { int count = cursor.getCount(); List<Feed> list = new ArrayList<Feed>(count); @@ -269,7 +248,21 @@ public class FeedDao extends AbstractDao<Feed, Long> { } return list; } - + + /** + * Properties of entity Feed.<br/> + * Can be used for QueryBuilder and for referencing column names. + */ + public static class Properties { + public final static Property Id = new Property(0, long.class, "id", true, "_id"); + public final static Property FolderId = new Property(1, Long.class, "folderId", false, "FOLDER_ID"); + public final static Property FeedTitle = new Property(2, String.class, "feedTitle", false, "FEED_TITLE"); + public final static Property FaviconUrl = new Property(3, String.class, "faviconUrl", false, "FAVICON_URL"); + public final static Property Link = new Property(4, String.class, "link", false, "LINK"); + public final static Property AvgColour = new Property(5, String.class, "avgColour", false, "AVG_COLOUR"); + public final static Property NotificationChannel = new Property(6, String.class, "notificationChannel", false, "NOTIFICATION_CHANNEL"); + } + protected List<Feed> loadDeepAllAndCloseCursor(Cursor cursor) { try { return loadAllDeepFromCursor(cursor); @@ -277,7 +270,7 @@ public class FeedDao extends AbstractDao<Feed, Long> { cursor.close(); } } - + /** A raw-style query where you can pass any WHERE clause and arguments. */ public List<Feed> queryDeep(String where, String... selectionArg) { diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/model/FolderDao.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/model/FolderDao.java index b17151d0..3765d10e 100644 --- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/model/FolderDao.java +++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/model/FolderDao.java @@ -82,15 +82,6 @@ public class FolderDao extends AbstractDao<Folder, Long> { } /** - * Properties of entity Folder.<br/> - * Can be used for QueryBuilder and for referencing column names. - */ - public static class Properties { - public final static Property Id = new Property(0, long.class, "id", true, "_id"); - public final static Property Label = new Property(1, String.class, "label", false, "LABEL"); - } - - /** * @inheritdoc */ @Override @@ -104,17 +95,28 @@ public class FolderDao extends AbstractDao<Folder, Long> { */ @Override public Long getKey(Folder entity) { - if(entity != null) { + if (entity != null) { return entity.getId(); } else { return null; } } - /** @inheritdoc */ - @Override + /** + * Properties of entity Folder.<br/> + * Can be used for QueryBuilder and for referencing column names. + */ + public static class Properties { + public final static Property Id = new Property(0, long.class, "id", true, "_id"); + public final static Property Label = new Property(1, String.class, "label", false, "LABEL"); + } + + /** + * @inheritdoc + */ + @Override protected boolean isEntityUpdateable() { return true; } - + } diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/model/RssItemDao.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/model/RssItemDao.java index d6ba7141..078decd1 100644 --- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/model/RssItemDao.java +++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/model/RssItemDao.java @@ -179,15 +179,15 @@ public class RssItemDao extends AbstractDao<RssItem, Long> { cursor.getString(offset + 8), // guid cursor.getString(offset + 9), // guidHash cursor.getString(offset + 10), // fingerprint - cursor.isNull(offset + 11) ? null : cursor.getShort(offset + 11) != 0, // read_temp - cursor.isNull(offset + 12) ? null : cursor.getShort(offset + 12) != 0, // starred_temp - cursor.isNull(offset + 13) ? null : new java.util.Date(cursor.getLong(offset + 13)), // lastModified - cursor.isNull(offset + 14) ? null : new java.util.Date(cursor.getLong(offset + 14)), // pubDate - cursor.isNull(offset + 15) ? null : cursor.getString(offset + 15), // enclosureLink - cursor.isNull(offset + 16) ? null : cursor.getString(offset + 16), // enclosureMime - cursor.isNull(offset + 17) ? null : cursor.getString(offset + 17), // mediaThumbnail - cursor.isNull(offset + 18) ? null : cursor.getString(offset + 18), // mediaDescription - cursor.isNull(offset + 19) ? null : cursor.getShort(offset + 19) != 0 // rtl + cursor.isNull(offset + 11) ? null : cursor.getShort(offset + 11) != 0, // read_temp + cursor.isNull(offset + 12) ? null : cursor.getShort(offset + 12) != 0, // starred_temp + cursor.isNull(offset + 13) ? null : new java.util.Date(cursor.getLong(offset + 13)), // lastModified + cursor.isNull(offset + 14) ? null : new java.util.Date(cursor.getLong(offset + 14)), // pubDate + cursor.isNull(offset + 15) ? null : cursor.getString(offset + 15), // enclosureLink + cursor.isNull(offset + 16) ? null : cursor.getString(offset + 16), // enclosureMime + cursor.isNull(offset + 17) ? null : cursor.getString(offset + 17), // mediaThumbnail + cursor.isNull(offset + 18) ? null : cursor.getString(offset + 18), // mediaDescription + cursor.isNull(offset + 19) ? null : cursor.getShort(offset + 19) != 0 // rtl ); return entity; } @@ -217,33 +217,6 @@ public class RssItemDao extends AbstractDao<RssItem, Long> { entity.setRtl(cursor.isNull(offset + 19) ? null : cursor.getShort(offset + 19) != 0); } - public RssItem loadDeep(Long key) { - assertSinglePk(); - if (key == null) { - return null; - } - - StringBuilder builder = new StringBuilder(getSelectDeep()); - builder.append("WHERE "); - SqlUtils.appendColumnsEqValue(builder, "T", getPkColumns()); - String sql = builder.toString(); - - String[] keyArray = new String[]{key.toString()}; - Cursor cursor = db.rawQuery(sql, keyArray); - - try { - boolean available = cursor.moveToFirst(); - if (!available) { - return null; - } else if (!cursor.isLast()) { - throw new IllegalStateException("Expected unique result, but count was " + cursor.getCount()); - } - return loadCurrentDeep(cursor, true); - } finally { - cursor.close(); - } - } - /** * @inheritdoc */ @@ -258,20 +231,36 @@ public class RssItemDao extends AbstractDao<RssItem, Long> { */ @Override public Long getKey(RssItem entity) { - if(entity != null) { + if (entity != null) { return entity.getId(); } else { return null; } } - /** @inheritdoc */ - @Override + protected RssItem loadCurrentDeep(Cursor cursor, boolean lock) { + RssItem entity = loadCurrent(cursor, 0, lock); + int offset = getAllColumns().length; + + Feed feed = loadCurrentOther(daoSession.getFeedDao(), cursor, offset); + if (feed != null) { + entity.setFeed(feed); + } + + return entity; + } + + /** + * @inheritdoc + */ + @Override protected boolean isEntityUpdateable() { return true; } - - /** Internal query to resolve the "rssItemList" to-many relationship of Feed. */ + + /** + * Internal query to resolve the "rssItemList" to-many relationship of Feed. + */ public List<RssItem> _queryFeed_RssItemList(long feedId) { synchronized (this) { if (feed_RssItemListQuery == null) { @@ -300,17 +289,57 @@ public class RssItemDao extends AbstractDao<RssItem, Long> { } return selectDeep; } - - protected RssItem loadCurrentDeep(Cursor cursor, boolean lock) { - RssItem entity = loadCurrent(cursor, 0, lock); - int offset = getAllColumns().length; - Feed feed = loadCurrentOther(daoSession.getFeedDao(), cursor, offset); - if (feed != null) { - entity.setFeed(feed); + public RssItem loadDeep(Long key) { + assertSinglePk(); + if (key == null) { + return null; } - return entity; + StringBuilder builder = new StringBuilder(getSelectDeep()); + builder.append("WHERE "); + SqlUtils.appendColumnsEqValue(builder, "T", getPkColumns()); + String sql = builder.toString(); + + String[] keyArray = new String[]{key.toString()}; + Cursor cursor = db.rawQuery(sql, keyArray); + + try { + boolean available = cursor.moveToFirst(); + if (!available) { + return null; + } else if (!cursor.isLast()) { + throw new IllegalStateException("Expected unique result, but count was " + cursor.getCount()); + } + return loadCurrentDeep(cursor, true); + } finally { + cursor.close(); + } + } + + /** + * Reads all available rows from the given cursor and returns a list of new ImageTO objects. + */ + public List<RssItem> loadAllDeepFromCursor(Cursor cursor) { + int count = cursor.getCount(); + List<RssItem> list = new ArrayList<RssItem>(count); + + if (cursor.moveToFirst()) { + if (identityScope != null) { + identityScope.lock(); + identityScope.reserveRoom(count); + } + try { + do { + list.add(loadCurrentDeep(cursor, false)); + } while (cursor.moveToNext()); + } finally { + if (identityScope != null) { + identityScope.unlock(); + } + } + } + return list; } /** @@ -339,31 +368,6 @@ public class RssItemDao extends AbstractDao<RssItem, Long> { public final static Property MediaDescription = new Property(18, String.class, "mediaDescription", false, "MEDIA_DESCRIPTION"); public final static Property Rtl = new Property(19, Boolean.class, "rtl", false, "RTL"); } - - /** - * Reads all available rows from the given cursor and returns a list of new ImageTO objects. - */ - public List<RssItem> loadAllDeepFromCursor(Cursor cursor) { - int count = cursor.getCount(); - List<RssItem> list = new ArrayList<RssItem>(count); - - if (cursor.moveToFirst()) { - if (identityScope != null) { - identityScope.lock(); - identityScope.reserveRoom(count); - } - try { - do { - list.add(loadCurrentDeep(cursor, false)); - } while (cursor.moveToNext()); - } finally { - if (identityScope != null) { - identityScope.unlock(); - } - } - } - return list; - } protected List<RssItem> loadDeepAllAndCloseCursor(Cursor cursor) { try { diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/reader/nextcloud/ItemStateSync.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/reader/nextcloud/ItemStateSync.java index a9e4f069..ab281531 100644 --- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/reader/nextcloud/ItemStateSync.java +++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/reader/nextcloud/ItemStateSync.java @@ -7,13 +7,12 @@ import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; import de.luhmer.owncloudnewsreader.database.DatabaseConnectionOrm; -import de.luhmer.owncloudnewsreader.database.model.Feed; import de.luhmer.owncloudnewsreader.reader.FeedItemTags; +import retrofit2.Response; /** * Created by david on 26.05.17. @@ -23,9 +22,7 @@ public class ItemStateSync { private static final String TAG = ItemStateSync.class.getCanonicalName(); - public static boolean PerformItemStateSync(NewsAPI newsApi, DatabaseConnectionOrm dbConn) throws IOException { - boolean successful = true; - + public static void PerformItemStateSync(NewsAPI newsApi, DatabaseConnectionOrm dbConn) throws IOException { int MAX_SYNC_ITEMS_PER_REQUEST = 300; Map<FeedItemTags, List<String>> itemsToSync = new HashMap<>(); @@ -57,52 +54,70 @@ public class ItemStateSync { Collection<List<String>> itemIdsPartitioned = partitionBasedOnSize(entry.getValue(), MAX_SYNC_ITEMS_PER_REQUEST); for(List<String> itemIds : itemIdsPartitioned) { Log.d(TAG, "Marking " + itemIds.size() + " items as " + operation.toString()); - successful &= PerformTagExecution(itemIds, operation, dbConn, newsApi); + PerformTagExecution(itemIds, operation, dbConn, newsApi); } } - - return successful; } static <T> Collection<List<T>> partitionBasedOnSize(List<T> inputList, int size) { final AtomicInteger counter = new AtomicInteger(0); return inputList.stream() - .collect(Collectors.groupingBy(s -> counter.getAndIncrement()/size)) + .collect(Collectors.groupingBy(s -> counter.getAndIncrement() / size)) .values(); } - private static boolean PerformTagExecution(List<String> itemIds, FeedItemTags tag, DatabaseConnectionOrm dbConn, NewsAPI newsApi) throws IOException { - if(itemIds.size() <= 0) { // Nothing to sync --> Skip - return true; + private static void executeRequest(ExecuteRequestCallable<Response> data, OnSuccessCallable<Void> onSuccess) throws IOException { + Response response = data.call(); + if (response.isSuccessful()) { + onSuccess.call(); + } else { + if (response.errorBody() != null) { + throw new IOException(response.errorBody().toString()); + } else { + throw new IOException("mark item as read failed - http code: " + response.code()); + } } - boolean success = false; - switch(tag) { + } + + private static void PerformTagExecution(List<String> itemIds, FeedItemTags tag, DatabaseConnectionOrm dbConn, NewsAPI newsApi) throws IOException { + if (itemIds.size() <= 0) { // Nothing to sync --> Skip + return; + } + + switch (tag) { case MARK_ITEM_AS_READ: - success = newsApi.markItemsRead(new ItemIds(itemIds)).execute().isSuccessful(); - if (success) { - dbConn.change_readUnreadStateOfItem(itemIds, true); - } + executeRequest( + () -> newsApi.markItemsRead(new ItemIds(itemIds)).execute(), + () -> dbConn.change_readUnreadStateOfItem(itemIds, true) + ); break; case MARK_ITEM_AS_UNREAD: - success = newsApi.markItemsUnread(new ItemIds(itemIds)).execute().isSuccessful(); - if(success) { - dbConn.change_readUnreadStateOfItem(itemIds, false); - } + executeRequest( + () -> newsApi.markItemsUnread(new ItemIds(itemIds)).execute(), + () -> dbConn.change_readUnreadStateOfItem(itemIds, false) + ); break; case MARK_ITEM_AS_STARRED: - success = newsApi.markItemsStarred(new ItemMap(itemIds, dbConn)).execute().isSuccessful(); - if(success) { - dbConn.changeStarrUnstarrStateOfItem(itemIds, true); - } + executeRequest( + () -> newsApi.markItemsStarred(new ItemMap(itemIds, dbConn)).execute(), + () -> dbConn.changeStarrUnstarrStateOfItem(itemIds, true) + ); break; case MARK_ITEM_AS_UNSTARRED: - success = newsApi.markItemsUnstarred(new ItemMap(itemIds, dbConn)).execute().isSuccessful(); - if(success) { - dbConn.changeStarrUnstarrStateOfItem(itemIds, false); - } + executeRequest( + () -> newsApi.markItemsUnstarred(new ItemMap(itemIds, dbConn)).execute(), + () -> dbConn.changeStarrUnstarrStateOfItem(itemIds, false) + ); break; } - return success; + } + + interface ExecuteRequestCallable<T> { + T call() throws IOException; + } + + interface OnSuccessCallable<T> { + void call(); } } diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/SyncItemStateService.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/SyncItemStateService.java index b435c182..06c65d2c 100644 --- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/SyncItemStateService.java +++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/SyncItemStateService.java @@ -72,10 +72,11 @@ public class SyncItemStateService extends JobIntentService { final DatabaseConnectionOrm dbConn = new DatabaseConnectionOrm(this); try { - boolean success = ItemStateSync.PerformItemStateSync(mApi.getNewsAPI(), dbConn); - Log.v(TAG, "SyncItemStateService finished. Success: " + success); - } catch (IOException e) { - e.printStackTrace(); + ItemStateSync.PerformItemStateSync(mApi.getNewsAPI(), dbConn); + Log.v(TAG, "SyncItemStateService finished."); + } catch (IOException e) { + Log.e(TAG, "SyncItemState failed:" + e.toString()); + e.printStackTrace(); } } |