mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-12-22 17:11:51 +01:00
Initial commit for categories
This commit is contained in:
parent
72b2471619
commit
1c4b5b3a72
@ -16,23 +16,34 @@ import com.pushtorefresh.storio.sqlite.queries.RawQuery;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import eu.kanade.mangafeed.data.database.models.MangaSync;
|
import eu.kanade.mangafeed.data.database.models.Category;
|
||||||
import eu.kanade.mangafeed.data.mangasync.base.MangaSyncService;
|
import eu.kanade.mangafeed.data.database.models.CategoryStorIOSQLiteDeleteResolver;
|
||||||
|
import eu.kanade.mangafeed.data.database.models.CategoryStorIOSQLiteGetResolver;
|
||||||
|
import eu.kanade.mangafeed.data.database.models.CategoryStorIOSQLitePutResolver;
|
||||||
import eu.kanade.mangafeed.data.database.models.Chapter;
|
import eu.kanade.mangafeed.data.database.models.Chapter;
|
||||||
import eu.kanade.mangafeed.data.database.models.ChapterStorIOSQLiteDeleteResolver;
|
import eu.kanade.mangafeed.data.database.models.ChapterStorIOSQLiteDeleteResolver;
|
||||||
import eu.kanade.mangafeed.data.database.models.ChapterStorIOSQLiteGetResolver;
|
import eu.kanade.mangafeed.data.database.models.ChapterStorIOSQLiteGetResolver;
|
||||||
import eu.kanade.mangafeed.data.database.models.ChapterStorIOSQLitePutResolver;
|
import eu.kanade.mangafeed.data.database.models.ChapterStorIOSQLitePutResolver;
|
||||||
import eu.kanade.mangafeed.data.database.models.Manga;
|
import eu.kanade.mangafeed.data.database.models.Manga;
|
||||||
|
import eu.kanade.mangafeed.data.database.models.MangaCategory;
|
||||||
|
import eu.kanade.mangafeed.data.database.models.MangaCategoryStorIOSQLiteDeleteResolver;
|
||||||
|
import eu.kanade.mangafeed.data.database.models.MangaCategoryStorIOSQLiteGetResolver;
|
||||||
|
import eu.kanade.mangafeed.data.database.models.MangaCategoryStorIOSQLitePutResolver;
|
||||||
import eu.kanade.mangafeed.data.database.models.MangaStorIOSQLiteDeleteResolver;
|
import eu.kanade.mangafeed.data.database.models.MangaStorIOSQLiteDeleteResolver;
|
||||||
import eu.kanade.mangafeed.data.database.models.MangaStorIOSQLiteGetResolver;
|
import eu.kanade.mangafeed.data.database.models.MangaStorIOSQLiteGetResolver;
|
||||||
import eu.kanade.mangafeed.data.database.models.MangaStorIOSQLitePutResolver;
|
import eu.kanade.mangafeed.data.database.models.MangaStorIOSQLitePutResolver;
|
||||||
|
import eu.kanade.mangafeed.data.database.models.MangaSync;
|
||||||
import eu.kanade.mangafeed.data.database.models.MangaSyncStorIOSQLiteDeleteResolver;
|
import eu.kanade.mangafeed.data.database.models.MangaSyncStorIOSQLiteDeleteResolver;
|
||||||
import eu.kanade.mangafeed.data.database.models.MangaSyncStorIOSQLiteGetResolver;
|
import eu.kanade.mangafeed.data.database.models.MangaSyncStorIOSQLiteGetResolver;
|
||||||
import eu.kanade.mangafeed.data.database.models.MangaSyncStorIOSQLitePutResolver;
|
import eu.kanade.mangafeed.data.database.models.MangaSyncStorIOSQLitePutResolver;
|
||||||
|
import eu.kanade.mangafeed.data.database.resolvers.LibraryMangaGetResolver;
|
||||||
import eu.kanade.mangafeed.data.database.resolvers.MangaWithUnreadGetResolver;
|
import eu.kanade.mangafeed.data.database.resolvers.MangaWithUnreadGetResolver;
|
||||||
import eu.kanade.mangafeed.data.database.tables.MangaSyncTable;
|
import eu.kanade.mangafeed.data.database.tables.CategoryTable;
|
||||||
import eu.kanade.mangafeed.data.database.tables.ChapterTable;
|
import eu.kanade.mangafeed.data.database.tables.ChapterTable;
|
||||||
|
import eu.kanade.mangafeed.data.database.tables.MangaCategoryTable;
|
||||||
|
import eu.kanade.mangafeed.data.database.tables.MangaSyncTable;
|
||||||
import eu.kanade.mangafeed.data.database.tables.MangaTable;
|
import eu.kanade.mangafeed.data.database.tables.MangaTable;
|
||||||
|
import eu.kanade.mangafeed.data.mangasync.base.MangaSyncService;
|
||||||
import eu.kanade.mangafeed.util.ChapterRecognition;
|
import eu.kanade.mangafeed.util.ChapterRecognition;
|
||||||
import eu.kanade.mangafeed.util.PostResult;
|
import eu.kanade.mangafeed.util.PostResult;
|
||||||
import rx.Observable;
|
import rx.Observable;
|
||||||
@ -60,6 +71,16 @@ public class DatabaseHelper {
|
|||||||
.getResolver(new MangaSyncStorIOSQLiteGetResolver())
|
.getResolver(new MangaSyncStorIOSQLiteGetResolver())
|
||||||
.deleteResolver(new MangaSyncStorIOSQLiteDeleteResolver())
|
.deleteResolver(new MangaSyncStorIOSQLiteDeleteResolver())
|
||||||
.build())
|
.build())
|
||||||
|
.addTypeMapping(Category.class, SQLiteTypeMapping.<Category>builder()
|
||||||
|
.putResolver(new CategoryStorIOSQLitePutResolver())
|
||||||
|
.getResolver(new CategoryStorIOSQLiteGetResolver())
|
||||||
|
.deleteResolver(new CategoryStorIOSQLiteDeleteResolver())
|
||||||
|
.build())
|
||||||
|
.addTypeMapping(MangaCategory.class, SQLiteTypeMapping.<MangaCategory>builder()
|
||||||
|
.putResolver(new MangaCategoryStorIOSQLitePutResolver())
|
||||||
|
.getResolver(new MangaCategoryStorIOSQLiteGetResolver())
|
||||||
|
.deleteResolver(new MangaCategoryStorIOSQLiteDeleteResolver())
|
||||||
|
.build())
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,6 +100,37 @@ public class DatabaseHelper {
|
|||||||
MangaTable.COLUMN_TITLE
|
MangaTable.COLUMN_TITLE
|
||||||
);
|
);
|
||||||
|
|
||||||
|
private final String libraryMangaQuery = String.format(
|
||||||
|
"SELECT M.*, COALESCE(MC.%10$s, 0) AS %12$s " +
|
||||||
|
"FROM (" +
|
||||||
|
"SELECT %1$s.*, COALESCE(C.unread, 0) AS %6$s " +
|
||||||
|
"FROM %1$s " +
|
||||||
|
"LEFT JOIN (" +
|
||||||
|
"SELECT %5$s, COUNT(*) AS unread " +
|
||||||
|
"FROM %2$s " +
|
||||||
|
"WHERE %7$s = 0 " +
|
||||||
|
"GROUP BY %5$s" +
|
||||||
|
") AS C " +
|
||||||
|
"ON %4$s = C.%5$s " +
|
||||||
|
"WHERE %8$s = 1 " +
|
||||||
|
"GROUP BY %4$s " +
|
||||||
|
"ORDER BY %9$s" +
|
||||||
|
") AS M " +
|
||||||
|
"LEFT JOIN (SELECT * FROM %3$s) AS MC ON MC.%11$s = M.%4$s",
|
||||||
|
MangaTable.TABLE,
|
||||||
|
ChapterTable.TABLE,
|
||||||
|
MangaCategoryTable.TABLE,
|
||||||
|
MangaTable.COLUMN_ID,
|
||||||
|
ChapterTable.COLUMN_MANGA_ID,
|
||||||
|
MangaTable.COLUMN_UNREAD,
|
||||||
|
ChapterTable.COLUMN_READ,
|
||||||
|
MangaTable.COLUMN_FAVORITE,
|
||||||
|
MangaTable.COLUMN_TITLE,
|
||||||
|
MangaCategoryTable.COLUMN_CATEGORY_ID,
|
||||||
|
MangaCategoryTable.COLUMN_MANGA_ID,
|
||||||
|
MangaTable.COLUMN_CATEGORY
|
||||||
|
);
|
||||||
|
|
||||||
public PreparedGetListOfObjects<Manga> getMangas() {
|
public PreparedGetListOfObjects<Manga> getMangas() {
|
||||||
return db.get()
|
return db.get()
|
||||||
.listOfObjects(Manga.class)
|
.listOfObjects(Manga.class)
|
||||||
@ -95,7 +147,18 @@ public class DatabaseHelper {
|
|||||||
.query(favoriteMangasWithUnreadQuery)
|
.query(favoriteMangasWithUnreadQuery)
|
||||||
.observesTables(MangaTable.TABLE, ChapterTable.TABLE)
|
.observesTables(MangaTable.TABLE, ChapterTable.TABLE)
|
||||||
.build())
|
.build())
|
||||||
.withGetResolver(MangaWithUnreadGetResolver.instance)
|
.withGetResolver(MangaWithUnreadGetResolver.INSTANCE)
|
||||||
|
.prepare();
|
||||||
|
}
|
||||||
|
|
||||||
|
public PreparedGetListOfObjects<Manga> getLibraryMangas() {
|
||||||
|
return db.get()
|
||||||
|
.listOfObjects(Manga.class)
|
||||||
|
.withQuery(RawQuery.builder()
|
||||||
|
.query(libraryMangaQuery)
|
||||||
|
.observesTables(MangaTable.TABLE, ChapterTable.TABLE, CategoryTable.TABLE)
|
||||||
|
.build())
|
||||||
|
.withGetResolver(LibraryMangaGetResolver.INSTANCE)
|
||||||
.prepare();
|
.prepare();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -337,4 +400,39 @@ public class DatabaseHelper {
|
|||||||
.object(manga)
|
.object(manga)
|
||||||
.prepare();
|
.prepare();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Categories related queries
|
||||||
|
|
||||||
|
public PreparedGetListOfObjects<Category> getCategories() {
|
||||||
|
return db.get()
|
||||||
|
.listOfObjects(Category.class)
|
||||||
|
.withQuery(Query.builder()
|
||||||
|
.table(CategoryTable.TABLE)
|
||||||
|
.build())
|
||||||
|
.prepare();
|
||||||
|
}
|
||||||
|
|
||||||
|
public PreparedPutObject<Category> insertCategory(Category category) {
|
||||||
|
return db.put()
|
||||||
|
.object(category)
|
||||||
|
.prepare();
|
||||||
|
}
|
||||||
|
|
||||||
|
public PreparedDeleteObject<Category> deleteCategory(Category category) {
|
||||||
|
return db.delete()
|
||||||
|
.object(category)
|
||||||
|
.prepare();
|
||||||
|
}
|
||||||
|
|
||||||
|
public PreparedPutObject<MangaCategory> insertMangaCategory(MangaCategory mangaCategory) {
|
||||||
|
return db.put()
|
||||||
|
.object(mangaCategory)
|
||||||
|
.prepare();
|
||||||
|
}
|
||||||
|
|
||||||
|
public PreparedPutCollectionOfObjects<MangaCategory> insertMangasCategory(List<MangaCategory> mangasCategory) {
|
||||||
|
return db.put()
|
||||||
|
.objects(mangasCategory)
|
||||||
|
.prepare();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,8 @@ import android.database.sqlite.SQLiteDatabase;
|
|||||||
import android.database.sqlite.SQLiteOpenHelper;
|
import android.database.sqlite.SQLiteOpenHelper;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
|
import eu.kanade.mangafeed.data.database.tables.CategoryTable;
|
||||||
|
import eu.kanade.mangafeed.data.database.tables.MangaCategoryTable;
|
||||||
import eu.kanade.mangafeed.data.database.tables.MangaSyncTable;
|
import eu.kanade.mangafeed.data.database.tables.MangaSyncTable;
|
||||||
import eu.kanade.mangafeed.data.database.tables.ChapterTable;
|
import eu.kanade.mangafeed.data.database.tables.ChapterTable;
|
||||||
import eu.kanade.mangafeed.data.database.tables.MangaTable;
|
import eu.kanade.mangafeed.data.database.tables.MangaTable;
|
||||||
@ -12,7 +14,7 @@ import eu.kanade.mangafeed.data.database.tables.MangaTable;
|
|||||||
public class DbOpenHelper extends SQLiteOpenHelper {
|
public class DbOpenHelper extends SQLiteOpenHelper {
|
||||||
|
|
||||||
public static final String DATABASE_NAME = "mangafeed.db";
|
public static final String DATABASE_NAME = "mangafeed.db";
|
||||||
public static final int DATABASE_VERSION = 3;
|
public static final int DATABASE_VERSION = 1;
|
||||||
|
|
||||||
public DbOpenHelper(@NonNull Context context) {
|
public DbOpenHelper(@NonNull Context context) {
|
||||||
super(context, DATABASE_NAME, null, DATABASE_VERSION);
|
super(context, DATABASE_NAME, null, DATABASE_VERSION);
|
||||||
@ -23,16 +25,22 @@ public class DbOpenHelper extends SQLiteOpenHelper {
|
|||||||
db.execSQL(MangaTable.getCreateTableQuery());
|
db.execSQL(MangaTable.getCreateTableQuery());
|
||||||
db.execSQL(ChapterTable.getCreateTableQuery());
|
db.execSQL(ChapterTable.getCreateTableQuery());
|
||||||
db.execSQL(MangaSyncTable.getCreateTableQuery());
|
db.execSQL(MangaSyncTable.getCreateTableQuery());
|
||||||
|
db.execSQL(CategoryTable.getCreateTableQuery());
|
||||||
|
db.execSQL(MangaCategoryTable.getCreateTableQuery());
|
||||||
|
|
||||||
|
// DB indexes
|
||||||
|
db.execSQL(MangaTable.getCreateUrlIndexQuery());
|
||||||
|
db.execSQL(MangaTable.getCreateFavoriteIndexQuery());
|
||||||
|
db.execSQL(ChapterTable.getCreateMangaIdIndexQuery());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUpgrade(@NonNull SQLiteDatabase db, int oldVersion, int newVersion) {
|
public void onUpgrade(@NonNull SQLiteDatabase db, int oldVersion, int newVersion) {
|
||||||
if (oldVersion < 3)
|
|
||||||
db.execSQL(MangaSyncTable.getCreateTableQuery());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onConfigure(SQLiteDatabase db){
|
public void onConfigure(@NonNull SQLiteDatabase db) {
|
||||||
db.setForeignKeyConstraintsEnabled(true);
|
db.setForeignKeyConstraintsEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
package eu.kanade.mangafeed.data.database.models;
|
||||||
|
|
||||||
|
import com.pushtorefresh.storio.sqlite.annotations.StorIOSQLiteColumn;
|
||||||
|
import com.pushtorefresh.storio.sqlite.annotations.StorIOSQLiteType;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import eu.kanade.mangafeed.data.database.tables.CategoryTable;
|
||||||
|
|
||||||
|
@StorIOSQLiteType(table = CategoryTable.TABLE)
|
||||||
|
public class Category implements Serializable {
|
||||||
|
|
||||||
|
@StorIOSQLiteColumn(name = CategoryTable.COLUMN_ID, key = true)
|
||||||
|
public Long id;
|
||||||
|
|
||||||
|
@StorIOSQLiteColumn(name = CategoryTable.COLUMN_NAME)
|
||||||
|
public String name;
|
||||||
|
|
||||||
|
public Category() {}
|
||||||
|
|
||||||
|
public static Category create(String name) {
|
||||||
|
Category c = new Category();
|
||||||
|
c.name = name;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
}
|
@ -40,7 +40,6 @@ public class Chapter implements Serializable {
|
|||||||
|
|
||||||
public int status;
|
public int status;
|
||||||
|
|
||||||
|
|
||||||
public Chapter() {}
|
public Chapter() {}
|
||||||
|
|
||||||
public void setUrl(String url) {
|
public void setUrl(String url) {
|
||||||
|
@ -36,7 +36,7 @@ public class Manga implements Serializable {
|
|||||||
public String title;
|
public String title;
|
||||||
|
|
||||||
@StorIOSQLiteColumn(name = MangaTable.COLUMN_STATUS)
|
@StorIOSQLiteColumn(name = MangaTable.COLUMN_STATUS)
|
||||||
public String status;
|
public int status;
|
||||||
|
|
||||||
@StorIOSQLiteColumn(name = MangaTable.COLUMN_THUMBNAIL_URL)
|
@StorIOSQLiteColumn(name = MangaTable.COLUMN_THUMBNAIL_URL)
|
||||||
public String thumbnail_url;
|
public String thumbnail_url;
|
||||||
@ -58,6 +58,8 @@ public class Manga implements Serializable {
|
|||||||
|
|
||||||
public int unread;
|
public int unread;
|
||||||
|
|
||||||
|
public long category;
|
||||||
|
|
||||||
public Manga() {}
|
public Manga() {}
|
||||||
|
|
||||||
public void setUrl(String url) {
|
public void setUrl(String url) {
|
||||||
@ -83,12 +85,11 @@ public class Manga implements Serializable {
|
|||||||
if (network.genre != null)
|
if (network.genre != null)
|
||||||
local.genre = network.genre;
|
local.genre = network.genre;
|
||||||
|
|
||||||
if (network.status != null)
|
|
||||||
local.status = network.status;
|
|
||||||
|
|
||||||
if (network.thumbnail_url != null)
|
if (network.thumbnail_url != null)
|
||||||
local.thumbnail_url = network.thumbnail_url;
|
local.thumbnail_url = network.thumbnail_url;
|
||||||
|
|
||||||
|
local.status = network.status;
|
||||||
|
|
||||||
local.initialized = true;
|
local.initialized = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
package eu.kanade.mangafeed.data.database.models;
|
||||||
|
|
||||||
|
import com.pushtorefresh.storio.sqlite.annotations.StorIOSQLiteColumn;
|
||||||
|
import com.pushtorefresh.storio.sqlite.annotations.StorIOSQLiteType;
|
||||||
|
|
||||||
|
import eu.kanade.mangafeed.data.database.tables.MangaCategoryTable;
|
||||||
|
|
||||||
|
@StorIOSQLiteType(table = MangaCategoryTable.TABLE)
|
||||||
|
public class MangaCategory {
|
||||||
|
|
||||||
|
@StorIOSQLiteColumn(name = MangaCategoryTable.COLUMN_ID, key = true)
|
||||||
|
public Long id;
|
||||||
|
|
||||||
|
@StorIOSQLiteColumn(name = MangaCategoryTable.COLUMN_MANGA_ID)
|
||||||
|
public long manga_id;
|
||||||
|
|
||||||
|
@StorIOSQLiteColumn(name = MangaCategoryTable.COLUMN_CATEGORY_ID)
|
||||||
|
public long category_id;
|
||||||
|
|
||||||
|
public MangaCategory() {}
|
||||||
|
|
||||||
|
public static MangaCategory create(Manga manga, Category category) {
|
||||||
|
MangaCategory mc = new MangaCategory();
|
||||||
|
mc.manga_id = manga.id;
|
||||||
|
mc.category_id = category.id;
|
||||||
|
return mc;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
package eu.kanade.mangafeed.data.database.resolvers;
|
||||||
|
|
||||||
|
import android.database.Cursor;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
|
import eu.kanade.mangafeed.data.database.models.Manga;
|
||||||
|
import eu.kanade.mangafeed.data.database.models.MangaStorIOSQLiteGetResolver;
|
||||||
|
import eu.kanade.mangafeed.data.database.tables.MangaTable;
|
||||||
|
|
||||||
|
public class LibraryMangaGetResolver extends MangaStorIOSQLiteGetResolver {
|
||||||
|
|
||||||
|
public static final LibraryMangaGetResolver INSTANCE = new LibraryMangaGetResolver();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NonNull
|
||||||
|
public Manga mapFromCursor(@NonNull Cursor cursor) {
|
||||||
|
Manga manga = super.mapFromCursor(cursor);
|
||||||
|
|
||||||
|
int unreadColumn = cursor.getColumnIndex(MangaTable.COLUMN_UNREAD);
|
||||||
|
manga.unread = cursor.getInt(unreadColumn);
|
||||||
|
|
||||||
|
int categoryColumn = cursor.getColumnIndex(MangaTable.COLUMN_CATEGORY);
|
||||||
|
manga.category = cursor.getLong(categoryColumn);
|
||||||
|
|
||||||
|
return manga;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -9,7 +9,7 @@ import eu.kanade.mangafeed.data.database.tables.MangaTable;
|
|||||||
|
|
||||||
public class MangaWithUnreadGetResolver extends MangaStorIOSQLiteGetResolver {
|
public class MangaWithUnreadGetResolver extends MangaStorIOSQLiteGetResolver {
|
||||||
|
|
||||||
public static final MangaWithUnreadGetResolver instance = new MangaWithUnreadGetResolver();
|
public static final MangaWithUnreadGetResolver INSTANCE = new MangaWithUnreadGetResolver();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@NonNull
|
@NonNull
|
||||||
|
@ -12,4 +12,20 @@ public class CategoryTable {
|
|||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public static final String COLUMN_NAME = "name";
|
public static final String COLUMN_NAME = "name";
|
||||||
|
|
||||||
|
// This is just class with Meta Data, we don't need instances
|
||||||
|
private CategoryTable() {
|
||||||
|
throw new IllegalStateException("No instances please");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Better than static final field -> allows VM to unload useless String
|
||||||
|
// Because you need this string only once per application life on the device
|
||||||
|
@NonNull
|
||||||
|
public static String getCreateTableQuery() {
|
||||||
|
return "CREATE TABLE " + TABLE + "("
|
||||||
|
+ COLUMN_ID + " INTEGER NOT NULL PRIMARY KEY, "
|
||||||
|
+ COLUMN_NAME + " TEXT NOT NULL"
|
||||||
|
+ ");";
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,8 +48,12 @@ public class ChapterTable {
|
|||||||
+ COLUMN_DATE_UPLOAD + " LONG NOT NULL, "
|
+ COLUMN_DATE_UPLOAD + " LONG NOT NULL, "
|
||||||
+ "FOREIGN KEY(" + COLUMN_MANGA_ID + ") REFERENCES " + MangaTable.TABLE + "(" + MangaTable.COLUMN_ID + ") "
|
+ "FOREIGN KEY(" + COLUMN_MANGA_ID + ") REFERENCES " + MangaTable.TABLE + "(" + MangaTable.COLUMN_ID + ") "
|
||||||
+ "ON DELETE CASCADE"
|
+ "ON DELETE CASCADE"
|
||||||
+ ");"
|
+ ");";
|
||||||
+ "CREATE INDEX " + TABLE + "_" + COLUMN_MANGA_ID + "_index ON " + TABLE + "(" + COLUMN_MANGA_ID + ");";
|
}
|
||||||
|
|
||||||
|
public static String getCreateMangaIdIndexQuery() {
|
||||||
|
return "CREATE INDEX " + TABLE + "_" + COLUMN_MANGA_ID + "_index ON " + TABLE + "(" + COLUMN_MANGA_ID + ");";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -8,8 +8,33 @@ public class MangaCategoryTable {
|
|||||||
public static final String TABLE = "mangas_categories";
|
public static final String TABLE = "mangas_categories";
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public static final String COLUMN_MANGA_ID = "_manga_id";
|
public static final String COLUMN_ID = "_id";
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public static final String COLUMN_CATEGORY_ID = "_category_id";
|
public static final String COLUMN_MANGA_ID = "manga_id";
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public static final String COLUMN_CATEGORY_ID = "category_id";
|
||||||
|
|
||||||
|
// This is just class with Meta Data, we don't need instances
|
||||||
|
private MangaCategoryTable() {
|
||||||
|
throw new IllegalStateException("No instances please");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Better than static final field -> allows VM to unload useless String
|
||||||
|
// Because you need this string only once per application life on the device
|
||||||
|
@NonNull
|
||||||
|
public static String getCreateTableQuery() {
|
||||||
|
return "CREATE TABLE " + TABLE + "("
|
||||||
|
+ COLUMN_ID + " INTEGER NOT NULL PRIMARY KEY, "
|
||||||
|
+ COLUMN_MANGA_ID + " INTEGER NOT NULL, "
|
||||||
|
+ COLUMN_CATEGORY_ID + " INTEGER NOT NULL, "
|
||||||
|
+ "FOREIGN KEY(" + COLUMN_CATEGORY_ID + ") REFERENCES " + CategoryTable.TABLE + "(" + CategoryTable.COLUMN_ID + ") "
|
||||||
|
+ "ON DELETE CASCADE, "
|
||||||
|
+ "FOREIGN KEY(" + COLUMN_MANGA_ID + ") REFERENCES " + MangaTable.TABLE + "(" + MangaTable.COLUMN_ID + ") "
|
||||||
|
+ "ON DELETE CASCADE"
|
||||||
|
+ ");";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -50,11 +50,14 @@ public class MangaTable {
|
|||||||
public static final String COLUMN_VIEWER = "viewer";
|
public static final String COLUMN_VIEWER = "viewer";
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public static final String COLUMN_CHAPTER_FLAGS = "chapter_order";
|
public static final String COLUMN_CHAPTER_FLAGS = "chapter_flags";
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public static final String COLUMN_UNREAD = "unread";
|
public static final String COLUMN_UNREAD = "unread";
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public static final String COLUMN_CATEGORY = "category";
|
||||||
|
|
||||||
// This is just class with Meta Data, we don't need instances
|
// This is just class with Meta Data, we don't need instances
|
||||||
private MangaTable() {
|
private MangaTable() {
|
||||||
throw new IllegalStateException("No instances please");
|
throw new IllegalStateException("No instances please");
|
||||||
@ -73,15 +76,23 @@ public class MangaTable {
|
|||||||
+ COLUMN_DESCRIPTION + " TEXT, "
|
+ COLUMN_DESCRIPTION + " TEXT, "
|
||||||
+ COLUMN_GENRE + " TEXT, "
|
+ COLUMN_GENRE + " TEXT, "
|
||||||
+ COLUMN_TITLE + " TEXT NOT NULL, "
|
+ COLUMN_TITLE + " TEXT NOT NULL, "
|
||||||
+ COLUMN_STATUS + " TEXT, "
|
+ COLUMN_STATUS + " INTEGER NOT NULL, "
|
||||||
+ COLUMN_THUMBNAIL_URL + " TEXT, "
|
+ COLUMN_THUMBNAIL_URL + " TEXT, "
|
||||||
+ COLUMN_FAVORITE + " INTEGER NOT NULL, "
|
+ COLUMN_FAVORITE + " INTEGER NOT NULL, "
|
||||||
+ COLUMN_LAST_UPDATE + " LONG, "
|
+ COLUMN_LAST_UPDATE + " LONG, "
|
||||||
+ COLUMN_INITIALIZED + " BOOLEAN NOT NULL, "
|
+ COLUMN_INITIALIZED + " BOOLEAN NOT NULL, "
|
||||||
+ COLUMN_VIEWER + " INTEGER NOT NULL, "
|
+ COLUMN_VIEWER + " INTEGER NOT NULL, "
|
||||||
+ COLUMN_CHAPTER_FLAGS + " INTEGER NOT NULL"
|
+ COLUMN_CHAPTER_FLAGS + " INTEGER NOT NULL"
|
||||||
+ ");"
|
+ ");";
|
||||||
+ "CREATE INDEX " + TABLE + "_" + COLUMN_URL + "_index ON " + TABLE + "(" + COLUMN_URL + ");";
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getCreateUrlIndexQuery() {
|
||||||
|
return "CREATE INDEX " + TABLE + "_" + COLUMN_URL + "_index ON " + TABLE + "(" + COLUMN_URL + ");";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getCreateFavoriteIndexQuery() {
|
||||||
|
return "CREATE INDEX " + TABLE + "_" + COLUMN_FAVORITE + "_index ON " + TABLE + "(" + COLUMN_FAVORITE + ");";
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -296,7 +296,7 @@ public class Batoto extends Source {
|
|||||||
|
|
||||||
boolean fieldCompleted = unparsedHtml.contains("<td>Complete</td>");
|
boolean fieldCompleted = unparsedHtml.contains("<td>Complete</td>");
|
||||||
//TODO fix
|
//TODO fix
|
||||||
newManga.status = fieldCompleted + "";
|
newManga.status = 0;
|
||||||
|
|
||||||
newManga.initialized = true;
|
newManga.initialized = true;
|
||||||
|
|
||||||
|
@ -249,7 +249,8 @@ public class Mangahere extends Source {
|
|||||||
}
|
}
|
||||||
if (statusElement != null) {
|
if (statusElement != null) {
|
||||||
boolean fieldCompleted = statusElement.text().contains("Completed");
|
boolean fieldCompleted = statusElement.text().contains("Completed");
|
||||||
newManga.status = fieldCompleted + "";
|
// TODO fix status
|
||||||
|
// newManga.status = fieldCompleted + "";
|
||||||
}
|
}
|
||||||
|
|
||||||
beginIndex = unparsedHtml.indexOf("<img");
|
beginIndex = unparsedHtml.indexOf("<img");
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
package eu.kanade.mangafeed.ui.library;
|
package eu.kanade.mangafeed.ui.library;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.util.Pair;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
@ -44,4 +48,12 @@ public class LibraryPresenter extends BasePresenter<LibraryFragment> {
|
|||||||
.subscribe());
|
.subscribe());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Observable<Map<Long, List<Manga>>> getLibraryMangasObservable() {
|
||||||
|
return db.getLibraryMangas().createObservable()
|
||||||
|
.flatMap(mangas -> Observable.from(mangas)
|
||||||
|
.groupBy(manga -> manga.category)
|
||||||
|
.flatMap(group -> group.toList().map(list -> new Pair<>(group.getKey(), list)))
|
||||||
|
.toMap(pair -> pair.first, pair -> pair.second));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
119
app/src/test/java/eu/kanade/mangafeed/CategoryTest.java
Normal file
119
app/src/test/java/eu/kanade/mangafeed/CategoryTest.java
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
package eu.kanade.mangafeed;
|
||||||
|
|
||||||
|
import android.app.Application;
|
||||||
|
import android.os.Build;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.robolectric.RobolectricGradleTestRunner;
|
||||||
|
import org.robolectric.RuntimeEnvironment;
|
||||||
|
import org.robolectric.annotation.Config;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import eu.kanade.mangafeed.data.database.DatabaseHelper;
|
||||||
|
import eu.kanade.mangafeed.data.database.models.Category;
|
||||||
|
import eu.kanade.mangafeed.data.database.models.Manga;
|
||||||
|
import eu.kanade.mangafeed.data.database.models.MangaCategory;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.hasSize;
|
||||||
|
import static org.hamcrest.Matchers.is;
|
||||||
|
import static org.hamcrest.Matchers.not;
|
||||||
|
|
||||||
|
@Config(constants = BuildConfig.class, sdk = Build.VERSION_CODES.LOLLIPOP)
|
||||||
|
@RunWith(RobolectricGradleTestRunner.class)
|
||||||
|
public class CategoryTest {
|
||||||
|
|
||||||
|
DatabaseHelper db;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() {
|
||||||
|
Application app = RuntimeEnvironment.application;
|
||||||
|
db = new DatabaseHelper(app);
|
||||||
|
|
||||||
|
// Create 5 mangas
|
||||||
|
createManga("a");
|
||||||
|
createManga("b");
|
||||||
|
createManga("c");
|
||||||
|
createManga("d");
|
||||||
|
createManga("e");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHasCategories() {
|
||||||
|
// Create 2 categories
|
||||||
|
createCategory("Reading");
|
||||||
|
createCategory("Hold");
|
||||||
|
|
||||||
|
List<Category> categories = db.getCategories().executeAsBlocking();
|
||||||
|
assertThat(categories, hasSize(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHasLibraryMangas() {
|
||||||
|
List<Manga> mangas = db.getLibraryMangas().executeAsBlocking();
|
||||||
|
assertThat(mangas, hasSize(5));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHasCorrectFavorites() {
|
||||||
|
Manga m = new Manga();
|
||||||
|
m.title = "title";
|
||||||
|
m.author = "";
|
||||||
|
m.artist = "";
|
||||||
|
m.thumbnail_url = "";
|
||||||
|
m.genre = "a list of genres";
|
||||||
|
m.description = "long description";
|
||||||
|
m.url = "url to manga";
|
||||||
|
m.favorite = false;
|
||||||
|
db.insertManga(m).executeAsBlocking();
|
||||||
|
List<Manga> mangas = db.getLibraryMangas().executeAsBlocking();
|
||||||
|
assertThat(mangas, hasSize(5));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMangaInCategory() {
|
||||||
|
// Create 2 categories
|
||||||
|
createCategory("Reading");
|
||||||
|
createCategory("Hold");
|
||||||
|
|
||||||
|
// It should not have 0 as id
|
||||||
|
Category c = db.getCategories().executeAsBlocking().get(0);
|
||||||
|
assertThat(c.id, not(0));
|
||||||
|
|
||||||
|
// Add a manga to a category
|
||||||
|
Manga m = db.getMangas().executeAsBlocking().get(0);
|
||||||
|
MangaCategory mc = MangaCategory.create(m, c);
|
||||||
|
db.insertMangaCategory(mc).executeAsBlocking();
|
||||||
|
|
||||||
|
// Get mangas from library and assert manga category is the same
|
||||||
|
List<Manga> mangas = db.getLibraryMangas().executeAsBlocking();
|
||||||
|
for (Manga manga : mangas) {
|
||||||
|
if (manga.id.equals(m.id)) {
|
||||||
|
assertThat(manga.category, is(c.id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createManga(String title) {
|
||||||
|
Manga m = new Manga();
|
||||||
|
m.title = title;
|
||||||
|
m.author = "";
|
||||||
|
m.artist = "";
|
||||||
|
m.thumbnail_url = "";
|
||||||
|
m.genre = "a list of genres";
|
||||||
|
m.description = "long description";
|
||||||
|
m.url = "url to manga";
|
||||||
|
m.favorite = true;
|
||||||
|
db.insertManga(m).executeAsBlocking();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createCategory(String name) {
|
||||||
|
Category c = new Category();
|
||||||
|
c.name = name;
|
||||||
|
db.insertCategory(c).executeAsBlocking();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user