Merge database operations in a single class, deleting duplicated methods (as observable or blocking) and let the consumer decide the option
This commit is contained in:
parent
a130506514
commit
7c37262a9f
13 changed files with 177 additions and 458 deletions
|
@ -5,17 +5,17 @@ import android.content.Context;
|
||||||
import com.pushtorefresh.storio.sqlite.SQLiteTypeMapping;
|
import com.pushtorefresh.storio.sqlite.SQLiteTypeMapping;
|
||||||
import com.pushtorefresh.storio.sqlite.StorIOSQLite;
|
import com.pushtorefresh.storio.sqlite.StorIOSQLite;
|
||||||
import com.pushtorefresh.storio.sqlite.impl.DefaultStorIOSQLite;
|
import com.pushtorefresh.storio.sqlite.impl.DefaultStorIOSQLite;
|
||||||
import com.pushtorefresh.storio.sqlite.operations.delete.DeleteResult;
|
import com.pushtorefresh.storio.sqlite.operations.delete.PreparedDeleteCollectionOfObjects;
|
||||||
import com.pushtorefresh.storio.sqlite.operations.delete.DeleteResults;
|
import com.pushtorefresh.storio.sqlite.operations.delete.PreparedDeleteObject;
|
||||||
import com.pushtorefresh.storio.sqlite.operations.put.PutResult;
|
import com.pushtorefresh.storio.sqlite.operations.get.PreparedGetListOfObjects;
|
||||||
|
import com.pushtorefresh.storio.sqlite.operations.put.PreparedPutCollectionOfObjects;
|
||||||
|
import com.pushtorefresh.storio.sqlite.operations.put.PreparedPutObject;
|
||||||
import com.pushtorefresh.storio.sqlite.operations.put.PutResults;
|
import com.pushtorefresh.storio.sqlite.operations.put.PutResults;
|
||||||
|
import com.pushtorefresh.storio.sqlite.queries.Query;
|
||||||
|
import com.pushtorefresh.storio.sqlite.queries.RawQuery;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import eu.kanade.mangafeed.data.managers.ChapterManager;
|
|
||||||
import eu.kanade.mangafeed.data.managers.ChapterManagerImpl;
|
|
||||||
import eu.kanade.mangafeed.data.managers.MangaManager;
|
|
||||||
import eu.kanade.mangafeed.data.managers.MangaManagerImpl;
|
|
||||||
import eu.kanade.mangafeed.data.models.Chapter;
|
import eu.kanade.mangafeed.data.models.Chapter;
|
||||||
import eu.kanade.mangafeed.data.models.ChapterStorIOSQLiteDeleteResolver;
|
import eu.kanade.mangafeed.data.models.ChapterStorIOSQLiteDeleteResolver;
|
||||||
import eu.kanade.mangafeed.data.models.ChapterStorIOSQLiteGetResolver;
|
import eu.kanade.mangafeed.data.models.ChapterStorIOSQLiteGetResolver;
|
||||||
|
@ -24,18 +24,18 @@ import eu.kanade.mangafeed.data.models.Manga;
|
||||||
import eu.kanade.mangafeed.data.models.MangaStorIOSQLiteDeleteResolver;
|
import eu.kanade.mangafeed.data.models.MangaStorIOSQLiteDeleteResolver;
|
||||||
import eu.kanade.mangafeed.data.models.MangaStorIOSQLitePutResolver;
|
import eu.kanade.mangafeed.data.models.MangaStorIOSQLitePutResolver;
|
||||||
import eu.kanade.mangafeed.data.resolvers.MangaWithUnreadGetResolver;
|
import eu.kanade.mangafeed.data.resolvers.MangaWithUnreadGetResolver;
|
||||||
|
import eu.kanade.mangafeed.data.tables.ChaptersTable;
|
||||||
|
import eu.kanade.mangafeed.data.tables.MangasTable;
|
||||||
import eu.kanade.mangafeed.util.PostResult;
|
import eu.kanade.mangafeed.util.PostResult;
|
||||||
import rx.Observable;
|
import rx.Observable;
|
||||||
|
|
||||||
public class DatabaseHelper implements MangaManager, ChapterManager {
|
public class DatabaseHelper {
|
||||||
|
|
||||||
private StorIOSQLite mDb;
|
private StorIOSQLite db;
|
||||||
private MangaManagerImpl mMangaManager;
|
|
||||||
private ChapterManagerImpl mChapterManager;
|
|
||||||
|
|
||||||
public DatabaseHelper(Context context) {
|
public DatabaseHelper(Context context) {
|
||||||
|
|
||||||
mDb = DefaultStorIOSQLite.builder()
|
db = DefaultStorIOSQLite.builder()
|
||||||
.sqliteOpenHelper(new DbOpenHelper(context))
|
.sqliteOpenHelper(new DbOpenHelper(context))
|
||||||
.addTypeMapping(Manga.class, SQLiteTypeMapping.<Manga>builder()
|
.addTypeMapping(Manga.class, SQLiteTypeMapping.<Manga>builder()
|
||||||
.putResolver(new MangaStorIOSQLitePutResolver())
|
.putResolver(new MangaStorIOSQLitePutResolver())
|
||||||
|
@ -48,103 +48,175 @@ public class DatabaseHelper implements MangaManager, ChapterManager {
|
||||||
.deleteResolver(new ChapterStorIOSQLiteDeleteResolver())
|
.deleteResolver(new ChapterStorIOSQLiteDeleteResolver())
|
||||||
.build())
|
.build())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
mMangaManager = new MangaManagerImpl(mDb);
|
|
||||||
mChapterManager = new ChapterManagerImpl(mDb);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
// Mangas related queries
|
||||||
public Observable<List<Chapter>> getChapters(Manga manga) {
|
|
||||||
return mChapterManager.getChapters(manga);
|
private final String favoriteMangasWithUnreadQuery = String.format(
|
||||||
|
"SELECT %1$s.*, COUNT(C.%4$s) AS %5$s FROM %1$s LEFT JOIN " +
|
||||||
|
"(SELECT %4$s FROM %2$s WHERE %6$s = 0) AS C ON %3$s = C.%4$s " +
|
||||||
|
"WHERE %7$s = 1 GROUP BY %3$s",
|
||||||
|
MangasTable.TABLE,
|
||||||
|
ChaptersTable.TABLE,
|
||||||
|
MangasTable.TABLE + "." + MangasTable.COLUMN_ID,
|
||||||
|
ChaptersTable.COLUMN_MANGA_ID,
|
||||||
|
MangasTable.COLUMN_UNREAD,
|
||||||
|
ChaptersTable.COLUMN_READ,
|
||||||
|
MangasTable.COLUMN_FAVORITE
|
||||||
|
);
|
||||||
|
|
||||||
|
public PreparedGetListOfObjects<Manga> getMangas() {
|
||||||
|
return db.get()
|
||||||
|
.listOfObjects(Manga.class)
|
||||||
|
.withQuery(Query.builder()
|
||||||
|
.table(MangasTable.TABLE)
|
||||||
|
.build())
|
||||||
|
.prepare();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public PreparedGetListOfObjects<Manga> getMangasWithUnread() {
|
||||||
public Observable<List<Chapter>> getChapters(long manga_id) {
|
return db.get()
|
||||||
return mChapterManager.getChapters(manga_id);
|
.listOfObjects(Manga.class)
|
||||||
|
.withQuery(RawQuery.builder()
|
||||||
|
.query(favoriteMangasWithUnreadQuery)
|
||||||
|
.observesTables(MangasTable.TABLE, ChaptersTable.TABLE)
|
||||||
|
.build())
|
||||||
|
.prepare();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public PreparedGetListOfObjects<Manga> getFavoriteMangas() {
|
||||||
public Observable<PutResult> insertChapter(Chapter chapter) {
|
return db.get()
|
||||||
return mChapterManager.insertChapter(chapter);
|
.listOfObjects(Manga.class)
|
||||||
|
.withQuery(Query.builder()
|
||||||
|
.table(MangasTable.TABLE)
|
||||||
|
.where(MangasTable.COLUMN_FAVORITE + "=?")
|
||||||
|
.whereArgs(1)
|
||||||
|
.build())
|
||||||
|
.prepare();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public PreparedGetListOfObjects<Manga> getManga(String url) {
|
||||||
public Observable<PutResults<Chapter>> insertChapters(List<Chapter> chapters) {
|
return db.get()
|
||||||
return mChapterManager.insertChapters(chapters);
|
.listOfObjects(Manga.class)
|
||||||
|
.withQuery(Query.builder()
|
||||||
|
.table(MangasTable.TABLE)
|
||||||
|
.where(MangasTable.COLUMN_URL + "=?")
|
||||||
|
.whereArgs(url)
|
||||||
|
.build())
|
||||||
|
.prepare();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public PreparedGetListOfObjects<Manga> getManga(long id) {
|
||||||
public PutResult insertChapterBlock(Chapter chapter) {
|
return db.get()
|
||||||
return mChapterManager.insertChapterBlock(chapter);
|
.listOfObjects(Manga.class)
|
||||||
|
.withQuery(Query.builder()
|
||||||
|
.table(MangasTable.TABLE)
|
||||||
|
.where(MangasTable.COLUMN_ID + "=?")
|
||||||
|
.whereArgs(id)
|
||||||
|
.build())
|
||||||
|
.prepare();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public PreparedPutObject<Manga> insertManga(Manga manga) {
|
||||||
|
return db.put()
|
||||||
|
.object(manga)
|
||||||
|
.prepare();
|
||||||
|
}
|
||||||
|
|
||||||
|
public PreparedPutCollectionOfObjects<Manga> insertMangas(List<Manga> mangas) {
|
||||||
|
return db.put()
|
||||||
|
.objects(mangas)
|
||||||
|
.prepare();
|
||||||
|
}
|
||||||
|
|
||||||
|
public PreparedDeleteObject<Manga> deleteManga(Manga manga) {
|
||||||
|
return db.delete()
|
||||||
|
.object(manga)
|
||||||
|
.prepare();
|
||||||
|
}
|
||||||
|
|
||||||
|
public PreparedDeleteCollectionOfObjects<Manga> deleteMangas(List<Manga> mangas) {
|
||||||
|
return db.delete()
|
||||||
|
.objects(mangas)
|
||||||
|
.prepare();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Chapters related queries
|
||||||
|
|
||||||
|
public PreparedGetListOfObjects<Chapter> getChapters(Manga manga) {
|
||||||
|
return db.get()
|
||||||
|
.listOfObjects(Chapter.class)
|
||||||
|
.withQuery(Query.builder()
|
||||||
|
.table(ChaptersTable.TABLE)
|
||||||
|
.where(ChaptersTable.COLUMN_MANGA_ID + "=?")
|
||||||
|
.whereArgs(manga.id)
|
||||||
|
.build())
|
||||||
|
.prepare();
|
||||||
|
}
|
||||||
|
|
||||||
|
public PreparedGetListOfObjects<Chapter> getChapters(long manga_id) {
|
||||||
|
return db.get()
|
||||||
|
.listOfObjects(Chapter.class)
|
||||||
|
.withQuery(Query.builder()
|
||||||
|
.table(ChaptersTable.TABLE)
|
||||||
|
.where(ChaptersTable.COLUMN_MANGA_ID + "=?")
|
||||||
|
.whereArgs(manga_id)
|
||||||
|
.build())
|
||||||
|
.prepare();
|
||||||
|
}
|
||||||
|
|
||||||
|
public PreparedPutObject<Chapter> insertChapter(Chapter chapter) {
|
||||||
|
return db.put()
|
||||||
|
.object(chapter)
|
||||||
|
.prepare();
|
||||||
|
}
|
||||||
|
|
||||||
|
public PreparedPutCollectionOfObjects<Chapter> insertChapters(List<Chapter> chapters) {
|
||||||
|
return db.put()
|
||||||
|
.objects(chapters)
|
||||||
|
.prepare();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add new chapters or delete if the source deletes them
|
||||||
public Observable<PostResult> insertOrRemoveChapters(Manga manga, List<Chapter> chapters) {
|
public Observable<PostResult> insertOrRemoveChapters(Manga manga, List<Chapter> chapters) {
|
||||||
return mChapterManager.insertOrRemoveChapters(manga, chapters);
|
for (Chapter chapter : chapters) {
|
||||||
|
chapter.manga_id = manga.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
Observable<List<Chapter>> chapterList = Observable.create(subscriber -> {
|
||||||
public Observable<DeleteResult> deleteChapter(Chapter chapter) {
|
subscriber.onNext(getChapters(manga).executeAsBlocking());
|
||||||
return mChapterManager.deleteChapter(chapter);
|
subscriber.onCompleted();
|
||||||
|
});
|
||||||
|
|
||||||
|
Observable<Integer> newChaptersObs = chapterList
|
||||||
|
.flatMap(dbChapters -> Observable.from(chapters)
|
||||||
|
.filter(c -> !dbChapters.contains(c))
|
||||||
|
.toList()
|
||||||
|
.flatMap(newChapters -> insertChapters(newChapters).createObservable())
|
||||||
|
.map(PutResults::numberOfInserts));
|
||||||
|
|
||||||
|
Observable<Integer> deletedChaptersObs = chapterList
|
||||||
|
.flatMap(dbChapters -> Observable.from(dbChapters)
|
||||||
|
.filter(c -> !chapters.contains(c))
|
||||||
|
.toList()
|
||||||
|
.flatMap(deletedChapters -> deleteChapters(deletedChapters).createObservable())
|
||||||
|
.map( d -> d.results().size() ));
|
||||||
|
|
||||||
|
return Observable.zip(newChaptersObs, deletedChaptersObs,
|
||||||
|
(insertions, deletions) -> new PostResult(0, insertions, deletions)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public PreparedDeleteObject<Chapter> deleteChapter(Chapter chapter) {
|
||||||
public Observable<DeleteResults<Chapter>> deleteChapters(List<Chapter> chapters) {
|
return db.delete()
|
||||||
return mChapterManager.deleteChapters(chapters);
|
.object(chapter)
|
||||||
|
.prepare();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public PreparedDeleteCollectionOfObjects<Chapter> deleteChapters(List<Chapter> chapters) {
|
||||||
public Observable<List<Manga>> getMangas() {
|
return db.delete()
|
||||||
return mMangaManager.getMangas();
|
.objects(chapters)
|
||||||
}
|
.prepare();
|
||||||
|
|
||||||
@Override
|
|
||||||
public Observable<List<Manga>> getMangasWithUnread() {
|
|
||||||
return mMangaManager.getMangasWithUnread();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Observable<List<Manga>> getFavoriteMangas() {
|
|
||||||
return mMangaManager.getFavoriteMangas();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Observable<List<Manga>> getManga(String url) {
|
|
||||||
return mMangaManager.getManga(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Observable<List<Manga>> getManga(long id) {
|
|
||||||
return mMangaManager.getManga(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Manga getMangaBlock(String url) {
|
|
||||||
return mMangaManager.getMangaBlock(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Observable<PutResult> insertManga(Manga manga) {
|
|
||||||
return mMangaManager.insertManga(manga);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Observable<PutResults<Manga>> insertMangas(List<Manga> mangas) {
|
|
||||||
return mMangaManager.insertMangas(mangas);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PutResult insertMangaBlock(Manga manga) {
|
|
||||||
return mMangaManager.insertMangaBlock(manga);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Observable<DeleteResult> deleteManga(Manga manga) {
|
|
||||||
return mMangaManager.deleteManga(manga);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Observable<DeleteResults<Manga>> deleteMangas(List<Manga> mangas) {
|
|
||||||
return mMangaManager.deleteMangas(mangas);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
package eu.kanade.mangafeed.data.managers;
|
|
||||||
|
|
||||||
import com.pushtorefresh.storio.sqlite.StorIOSQLite;
|
|
||||||
|
|
||||||
public abstract class BaseManager {
|
|
||||||
|
|
||||||
protected StorIOSQLite db;
|
|
||||||
|
|
||||||
public BaseManager(StorIOSQLite db) {
|
|
||||||
this.db = db;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
package eu.kanade.mangafeed.data.managers;
|
|
||||||
|
|
||||||
import com.pushtorefresh.storio.sqlite.operations.delete.DeleteResult;
|
|
||||||
import com.pushtorefresh.storio.sqlite.operations.delete.DeleteResults;
|
|
||||||
import com.pushtorefresh.storio.sqlite.operations.put.PutResult;
|
|
||||||
import com.pushtorefresh.storio.sqlite.operations.put.PutResults;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import eu.kanade.mangafeed.data.models.Chapter;
|
|
||||||
import eu.kanade.mangafeed.data.models.Manga;
|
|
||||||
import eu.kanade.mangafeed.util.PostResult;
|
|
||||||
import rx.Observable;
|
|
||||||
|
|
||||||
public interface ChapterManager {
|
|
||||||
|
|
||||||
Observable<List<Chapter>> getChapters(Manga manga);
|
|
||||||
|
|
||||||
Observable<List<Chapter>> getChapters(long manga_id);
|
|
||||||
|
|
||||||
Observable<PutResult> insertChapter(Chapter chapter);
|
|
||||||
|
|
||||||
Observable<PutResults<Chapter>> insertChapters(List<Chapter> chapters);
|
|
||||||
|
|
||||||
PutResult insertChapterBlock(Chapter chapter);
|
|
||||||
|
|
||||||
Observable<PostResult> insertOrRemoveChapters(Manga manga, List<Chapter> chapters);
|
|
||||||
|
|
||||||
Observable<DeleteResult> deleteChapter(Chapter chapter);
|
|
||||||
|
|
||||||
Observable<DeleteResults<Chapter>> deleteChapters(List<Chapter> chapters);
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,125 +0,0 @@
|
||||||
package eu.kanade.mangafeed.data.managers;
|
|
||||||
|
|
||||||
import com.pushtorefresh.storio.sqlite.StorIOSQLite;
|
|
||||||
import com.pushtorefresh.storio.sqlite.operations.delete.DeleteResult;
|
|
||||||
import com.pushtorefresh.storio.sqlite.operations.delete.DeleteResults;
|
|
||||||
import com.pushtorefresh.storio.sqlite.operations.get.PreparedGetListOfObjects;
|
|
||||||
import com.pushtorefresh.storio.sqlite.operations.put.PutResult;
|
|
||||||
import com.pushtorefresh.storio.sqlite.operations.put.PutResults;
|
|
||||||
import com.pushtorefresh.storio.sqlite.queries.Query;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import eu.kanade.mangafeed.data.models.Chapter;
|
|
||||||
import eu.kanade.mangafeed.data.models.Manga;
|
|
||||||
import eu.kanade.mangafeed.data.tables.ChaptersTable;
|
|
||||||
import eu.kanade.mangafeed.util.PostResult;
|
|
||||||
import rx.Observable;
|
|
||||||
|
|
||||||
public class ChapterManagerImpl extends BaseManager implements ChapterManager {
|
|
||||||
|
|
||||||
public ChapterManagerImpl(StorIOSQLite db) {
|
|
||||||
super(db);
|
|
||||||
}
|
|
||||||
|
|
||||||
private PreparedGetListOfObjects<Chapter> prepareGetChapters(Manga manga) {
|
|
||||||
return db.get()
|
|
||||||
.listOfObjects(Chapter.class)
|
|
||||||
.withQuery(Query.builder()
|
|
||||||
.table(ChaptersTable.TABLE)
|
|
||||||
.where(ChaptersTable.COLUMN_MANGA_ID + "=?")
|
|
||||||
.whereArgs(manga.id)
|
|
||||||
.build())
|
|
||||||
.prepare();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Observable<List<Chapter>> getChapters(Manga manga) {
|
|
||||||
return prepareGetChapters(manga).createObservable();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Observable<List<Chapter>> getChapters(long manga_id) {
|
|
||||||
return db.get()
|
|
||||||
.listOfObjects(Chapter.class)
|
|
||||||
.withQuery(Query.builder()
|
|
||||||
.table(ChaptersTable.TABLE)
|
|
||||||
.where(ChaptersTable.COLUMN_MANGA_ID + "=?")
|
|
||||||
.whereArgs(manga_id)
|
|
||||||
.build())
|
|
||||||
.prepare()
|
|
||||||
.createObservable();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Observable<PutResult> insertChapter(Chapter chapter) {
|
|
||||||
return db.put()
|
|
||||||
.object(chapter)
|
|
||||||
.prepare()
|
|
||||||
.createObservable();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Observable<PutResults<Chapter>> insertChapters(List<Chapter> chapters) {
|
|
||||||
return db.put()
|
|
||||||
.objects(chapters)
|
|
||||||
.prepare()
|
|
||||||
.createObservable();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PutResult insertChapterBlock(Chapter chapter) {
|
|
||||||
return db.put()
|
|
||||||
.object(chapter)
|
|
||||||
.prepare()
|
|
||||||
.executeAsBlocking();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add new chapters or delete if the source deletes them
|
|
||||||
@Override
|
|
||||||
public Observable<PostResult> insertOrRemoveChapters(Manga manga, List<Chapter> chapters) {
|
|
||||||
for (Chapter chapter : chapters) {
|
|
||||||
chapter.manga_id = manga.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
Observable<List<Chapter>> chapterList = Observable.create(subscriber -> {
|
|
||||||
subscriber.onNext(prepareGetChapters(manga).executeAsBlocking());
|
|
||||||
subscriber.onCompleted();
|
|
||||||
});
|
|
||||||
|
|
||||||
Observable<Integer> newChaptersObs = chapterList
|
|
||||||
.flatMap(dbChapters -> Observable.from(chapters)
|
|
||||||
.filter(c -> !dbChapters.contains(c))
|
|
||||||
.toList()
|
|
||||||
.flatMap(this::insertChapters)
|
|
||||||
.map(PutResults::numberOfInserts));
|
|
||||||
|
|
||||||
Observable<Integer> deletedChaptersObs = chapterList
|
|
||||||
.flatMap(dbChapters -> Observable.from(dbChapters)
|
|
||||||
.filter(c -> !chapters.contains(c))
|
|
||||||
.toList()
|
|
||||||
.flatMap(this::deleteChapters)
|
|
||||||
.map( d -> d.results().size() ));
|
|
||||||
|
|
||||||
return Observable.zip(newChaptersObs, deletedChaptersObs,
|
|
||||||
(insertions, deletions) -> new PostResult(0, insertions, deletions)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Observable<DeleteResult> deleteChapter(Chapter chapter) {
|
|
||||||
return db.delete()
|
|
||||||
.object(chapter)
|
|
||||||
.prepare()
|
|
||||||
.createObservable();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Observable<DeleteResults<Chapter>> deleteChapters(List<Chapter> chapters) {
|
|
||||||
return db.delete()
|
|
||||||
.objects(chapters)
|
|
||||||
.prepare()
|
|
||||||
.createObservable();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
package eu.kanade.mangafeed.data.managers;
|
|
||||||
|
|
||||||
import com.pushtorefresh.storio.sqlite.operations.delete.DeleteResult;
|
|
||||||
import com.pushtorefresh.storio.sqlite.operations.delete.DeleteResults;
|
|
||||||
import com.pushtorefresh.storio.sqlite.operations.put.PutResult;
|
|
||||||
import com.pushtorefresh.storio.sqlite.operations.put.PutResults;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import eu.kanade.mangafeed.data.models.Manga;
|
|
||||||
import rx.Observable;
|
|
||||||
|
|
||||||
public interface MangaManager {
|
|
||||||
|
|
||||||
Observable<List<Manga>> getMangas();
|
|
||||||
|
|
||||||
Observable<List<Manga>> getMangasWithUnread();
|
|
||||||
|
|
||||||
Observable<List<Manga>> getFavoriteMangas();
|
|
||||||
|
|
||||||
Observable<List<Manga>> getManga(String url);
|
|
||||||
|
|
||||||
Observable<List<Manga>> getManga(long id);
|
|
||||||
|
|
||||||
Manga getMangaBlock(String url);
|
|
||||||
|
|
||||||
Observable<PutResult> insertManga(Manga manga);
|
|
||||||
|
|
||||||
Observable<PutResults<Manga>> insertMangas(List<Manga> mangas);
|
|
||||||
|
|
||||||
PutResult insertMangaBlock(Manga manga);
|
|
||||||
|
|
||||||
Observable<DeleteResult> deleteManga(Manga manga);
|
|
||||||
|
|
||||||
Observable<DeleteResults<Manga>> deleteMangas(List<Manga> mangas);
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,147 +0,0 @@
|
||||||
package eu.kanade.mangafeed.data.managers;
|
|
||||||
|
|
||||||
import com.pushtorefresh.storio.sqlite.StorIOSQLite;
|
|
||||||
import com.pushtorefresh.storio.sqlite.operations.delete.DeleteResult;
|
|
||||||
import com.pushtorefresh.storio.sqlite.operations.delete.DeleteResults;
|
|
||||||
import com.pushtorefresh.storio.sqlite.operations.put.PutResult;
|
|
||||||
import com.pushtorefresh.storio.sqlite.operations.put.PutResults;
|
|
||||||
import com.pushtorefresh.storio.sqlite.queries.Query;
|
|
||||||
import com.pushtorefresh.storio.sqlite.queries.RawQuery;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import eu.kanade.mangafeed.data.models.Manga;
|
|
||||||
import eu.kanade.mangafeed.data.tables.ChaptersTable;
|
|
||||||
import eu.kanade.mangafeed.data.tables.MangasTable;
|
|
||||||
import rx.Observable;
|
|
||||||
|
|
||||||
public class MangaManagerImpl extends BaseManager implements MangaManager {
|
|
||||||
|
|
||||||
public MangaManagerImpl(StorIOSQLite db) {
|
|
||||||
super(db);
|
|
||||||
}
|
|
||||||
|
|
||||||
private final String favoriteMangasWithUnreadQuery = String.format(
|
|
||||||
"SELECT %1$s.*, COUNT(C.%4$s) AS %5$s FROM %1$s LEFT JOIN " +
|
|
||||||
"(SELECT %4$s FROM %2$s WHERE %6$s = 0) AS C ON %3$s = C.%4$s " +
|
|
||||||
"WHERE %7$s = 1 GROUP BY %3$s",
|
|
||||||
MangasTable.TABLE,
|
|
||||||
ChaptersTable.TABLE,
|
|
||||||
MangasTable.TABLE + "." + MangasTable.COLUMN_ID,
|
|
||||||
ChaptersTable.COLUMN_MANGA_ID,
|
|
||||||
MangasTable.COLUMN_UNREAD,
|
|
||||||
ChaptersTable.COLUMN_READ,
|
|
||||||
MangasTable.COLUMN_FAVORITE
|
|
||||||
);
|
|
||||||
|
|
||||||
public Observable<List<Manga>> getMangas() {
|
|
||||||
return db.get()
|
|
||||||
.listOfObjects(Manga.class)
|
|
||||||
.withQuery(Query.builder()
|
|
||||||
.table(MangasTable.TABLE)
|
|
||||||
.build())
|
|
||||||
.prepare()
|
|
||||||
.createObservable();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Observable<List<Manga>> getMangasWithUnread() {
|
|
||||||
return db.get()
|
|
||||||
.listOfObjects(Manga.class)
|
|
||||||
.withQuery(RawQuery.builder()
|
|
||||||
.query(favoriteMangasWithUnreadQuery)
|
|
||||||
.observesTables(MangasTable.TABLE, ChaptersTable.TABLE)
|
|
||||||
.build())
|
|
||||||
.prepare()
|
|
||||||
.createObservable();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Observable<List<Manga>> getFavoriteMangas() {
|
|
||||||
return db.get()
|
|
||||||
.listOfObjects(Manga.class)
|
|
||||||
.withQuery(Query.builder()
|
|
||||||
.table(MangasTable.TABLE)
|
|
||||||
.where(MangasTable.COLUMN_FAVORITE + "=?")
|
|
||||||
.whereArgs(1)
|
|
||||||
.build())
|
|
||||||
.prepare()
|
|
||||||
.createObservable();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Observable<List<Manga>> getManga(String url) {
|
|
||||||
return db.get()
|
|
||||||
.listOfObjects(Manga.class)
|
|
||||||
.withQuery(Query.builder()
|
|
||||||
.table(MangasTable.TABLE)
|
|
||||||
.where(MangasTable.COLUMN_URL + "=?")
|
|
||||||
.whereArgs(url)
|
|
||||||
.build())
|
|
||||||
.prepare()
|
|
||||||
.createObservable();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Observable<List<Manga>> getManga(long id) {
|
|
||||||
return db.get()
|
|
||||||
.listOfObjects(Manga.class)
|
|
||||||
.withQuery(Query.builder()
|
|
||||||
.table(MangasTable.TABLE)
|
|
||||||
.where(MangasTable.COLUMN_ID + "=?")
|
|
||||||
.whereArgs(id)
|
|
||||||
.build())
|
|
||||||
.prepare()
|
|
||||||
.createObservable();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Manga getMangaBlock(String url) {
|
|
||||||
List<Manga> result = db.get()
|
|
||||||
.listOfObjects(Manga.class)
|
|
||||||
.withQuery(Query.builder()
|
|
||||||
.table(MangasTable.TABLE)
|
|
||||||
.where(MangasTable.COLUMN_URL + "=?")
|
|
||||||
.whereArgs(url)
|
|
||||||
.build())
|
|
||||||
.prepare()
|
|
||||||
.executeAsBlocking();
|
|
||||||
|
|
||||||
if (result.isEmpty())
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return result.get(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Observable<PutResult> insertManga(Manga manga) {
|
|
||||||
return db.put()
|
|
||||||
.object(manga)
|
|
||||||
.prepare()
|
|
||||||
.createObservable();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Observable<PutResults<Manga>> insertMangas(List<Manga> mangas) {
|
|
||||||
return db.put()
|
|
||||||
.objects(mangas)
|
|
||||||
.prepare()
|
|
||||||
.createObservable();
|
|
||||||
}
|
|
||||||
|
|
||||||
public PutResult insertMangaBlock(Manga manga) {
|
|
||||||
return db.put()
|
|
||||||
.object(manga)
|
|
||||||
.prepare()
|
|
||||||
.executeAsBlocking();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Observable<DeleteResult> deleteManga(Manga manga) {
|
|
||||||
return db.delete()
|
|
||||||
.object(manga)
|
|
||||||
.prepare()
|
|
||||||
.createObservable();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Observable<DeleteResults<Manga>> deleteMangas(List<Manga> mangas) {
|
|
||||||
return db.delete()
|
|
||||||
.objects(mangas)
|
|
||||||
.prepare()
|
|
||||||
.createObservable();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -71,7 +71,7 @@ public class LibraryUpdateService extends Service {
|
||||||
if (favoriteMangasSubscription != null && !favoriteMangasSubscription.isUnsubscribed())
|
if (favoriteMangasSubscription != null && !favoriteMangasSubscription.isUnsubscribed())
|
||||||
favoriteMangasSubscription.unsubscribe();
|
favoriteMangasSubscription.unsubscribe();
|
||||||
|
|
||||||
favoriteMangasSubscription = db.getFavoriteMangas()
|
favoriteMangasSubscription = db.getFavoriteMangas().createObservable()
|
||||||
.subscribe(mangas -> {
|
.subscribe(mangas -> {
|
||||||
// Don't receive further db updates
|
// Don't receive further db updates
|
||||||
favoriteMangasSubscription.unsubscribe();
|
favoriteMangasSubscription.unsubscribe();
|
||||||
|
|
|
@ -112,9 +112,10 @@ public class CataloguePresenter extends BasePresenter<CatalogueFragment> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Manga networkToLocalManga(Manga networkManga) {
|
private Manga networkToLocalManga(Manga networkManga) {
|
||||||
Manga localManga = db.getMangaBlock(networkManga.url);
|
List<Manga> dbResult = db.getManga(networkManga.url).executeAsBlocking();
|
||||||
|
Manga localManga = !dbResult.isEmpty() ? dbResult.get(0) : null;
|
||||||
if (localManga == null) {
|
if (localManga == null) {
|
||||||
PutResult result = db.insertMangaBlock(networkManga);
|
PutResult result = db.insertManga(networkManga).executeAsBlocking();
|
||||||
networkManga.id = result.insertedId();
|
networkManga.id = result.insertedId();
|
||||||
localManga = networkManga;
|
localManga = networkManga;
|
||||||
}
|
}
|
||||||
|
@ -154,7 +155,7 @@ public class CataloguePresenter extends BasePresenter<CatalogueFragment> {
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.flatMap(networkManga -> {
|
.flatMap(networkManga -> {
|
||||||
Manga.copyFromNetwork(manga, networkManga);
|
Manga.copyFromNetwork(manga, networkManga);
|
||||||
db.insertMangaBlock(manga);
|
db.insertManga(manga).executeAsBlocking();
|
||||||
return Observable.just(manga);
|
return Observable.just(manga);
|
||||||
});
|
});
|
||||||
mangaObservables.add(tempObs);
|
mangaObservables.add(tempObs);
|
||||||
|
|
|
@ -37,7 +37,7 @@ public class LibraryPresenter extends BasePresenter<LibraryFragment> {
|
||||||
if (mFavoriteMangasSubscription != null)
|
if (mFavoriteMangasSubscription != null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
add(mFavoriteMangasSubscription = db.getMangasWithUnread()
|
add(mFavoriteMangasSubscription = db.getMangasWithUnread().createObservable()
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.compose(deliverLatestCache())
|
.compose(deliverLatestCache())
|
||||||
|
@ -57,7 +57,7 @@ public class LibraryPresenter extends BasePresenter<LibraryFragment> {
|
||||||
return manga;
|
return manga;
|
||||||
})
|
})
|
||||||
.toList()
|
.toList()
|
||||||
.flatMap(db::insertMangas)
|
.flatMap(mangas -> db.insertMangas(mangas).createObservable())
|
||||||
.subscribe());
|
.subscribe());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -101,7 +101,7 @@ public class MangaChaptersPresenter extends BasePresenter<MangaChaptersFragment>
|
||||||
}
|
}
|
||||||
|
|
||||||
private Observable<List<Chapter>> getDbChaptersObs() {
|
private Observable<List<Chapter>> getDbChaptersObs() {
|
||||||
return db.getChapters(manga.id)
|
return db.getChapters(manga.id).createObservable()
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread());
|
.observeOn(AndroidSchedulers.mainThread());
|
||||||
}
|
}
|
||||||
|
@ -126,7 +126,7 @@ public class MangaChaptersPresenter extends BasePresenter<MangaChaptersFragment>
|
||||||
return chapter;
|
return chapter;
|
||||||
})
|
})
|
||||||
.toList()
|
.toList()
|
||||||
.flatMap(db::insertChapters)
|
.flatMap(chapters -> db.insertChapters(chapters).createObservable())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.doOnCompleted(() -> remove(markReadSubscription))
|
.doOnCompleted(() -> remove(markReadSubscription))
|
||||||
.subscribe(result -> {
|
.subscribe(result -> {
|
||||||
|
|
|
@ -42,7 +42,7 @@ public class MangaDetailPresenter extends BasePresenter<MangaDetailActivity> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Observable<Manga> getDbMangaObservable() {
|
private Observable<Manga> getDbMangaObservable() {
|
||||||
return db.getManga(mangaId)
|
return db.getManga(mangaId).createObservable()
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.flatMap(Observable::from)
|
.flatMap(Observable::from)
|
||||||
.observeOn(AndroidSchedulers.mainThread());
|
.observeOn(AndroidSchedulers.mainThread());
|
||||||
|
|
|
@ -67,7 +67,7 @@ public class MangaInfoPresenter extends BasePresenter<MangaInfoFragment> {
|
||||||
|
|
||||||
public void toggleFavorite() {
|
public void toggleFavorite() {
|
||||||
manga.favorite = !manga.favorite;
|
manga.favorite = !manga.favorite;
|
||||||
db.insertMangaBlock(manga);
|
db.insertManga(manga).executeAsBlocking();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,6 +135,6 @@ public class ReaderPresenter extends BasePresenter<ReaderActivity> {
|
||||||
if (currentPage == pageList.size() - 1) {
|
if (currentPage == pageList.size() - 1) {
|
||||||
chapter.read = true;
|
chapter.read = true;
|
||||||
}
|
}
|
||||||
db.insertChapterBlock(chapter);
|
db.insertChapter(chapter).executeAsBlocking();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue