Fix filtering series.
This commit is contained in:
parent
e10f5c161f
commit
5a70a393b5
14 changed files with 448 additions and 49 deletions
|
|
@ -2,7 +2,7 @@
|
||||||
"formatVersion": 1,
|
"formatVersion": 1,
|
||||||
"database": {
|
"database": {
|
||||||
"version": 1,
|
"version": 1,
|
||||||
"identityHash": "ee46b997bb81036c29a482590e47e98c",
|
"identityHash": "30ba58aae4cd6855b019ac599eb57bdb",
|
||||||
"entities": [
|
"entities": [
|
||||||
{
|
{
|
||||||
"tableName": "AUTHOR",
|
"tableName": "AUTHOR",
|
||||||
|
|
@ -38,7 +38,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tableName": "BOOK",
|
"tableName": "BOOK",
|
||||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`BOOK_ID` INTEGER NOT NULL, `BOOK_TITLE` TEXT NOT NULL, `BOOK_SORT` TEXT NOT NULL, `BOOK_HAVE_COVER` INTEGER NOT NULL, `BOOK_RELEASE_DATE` INTEGER NOT NULL, `BOOK_LANGUAGE_ID` TEXT, `BOOK_RATING` INTEGER, `BOOK_SERIES_ID` TEXT, `BOOK_SYNOPSIS` TEXT, `BOOK_ISNEW` INTEGER NOT NULL, `BOOK_NEW_ORDER` INTEGER, PRIMARY KEY(`BOOK_ID`))",
|
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`BOOK_ID` INTEGER NOT NULL, `BOOK_TITLE` TEXT NOT NULL, `BOOK_SORT` TEXT NOT NULL, `BOOK_HAVE_COVER` INTEGER NOT NULL, `BOOK_RELEASE_DATE` INTEGER NOT NULL, `BOOK_LANGUAGE_ID` TEXT, `BOOK_RATING` INTEGER, `BOOK_SERIES_ID` INTEGER, `BOOK_SYNOPSIS` TEXT, `BOOK_ISNEW` INTEGER NOT NULL, `BOOK_NEW_ORDER` INTEGER, PRIMARY KEY(`BOOK_ID`))",
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"fieldPath": "id",
|
"fieldPath": "id",
|
||||||
|
|
@ -85,7 +85,7 @@
|
||||||
{
|
{
|
||||||
"fieldPath": "series",
|
"fieldPath": "series",
|
||||||
"columnName": "BOOK_SERIES_ID",
|
"columnName": "BOOK_SERIES_ID",
|
||||||
"affinity": "TEXT",
|
"affinity": "INTEGER",
|
||||||
"notNull": false
|
"notNull": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -170,12 +170,12 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tableName": "SERIES",
|
"tableName": "SERIES",
|
||||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`SERIES_ID` TEXT NOT NULL, `SERIES_NAME` TEXT NOT NULL, `SERIES_SORT` TEXT NOT NULL, `SERIES_INDEX` INTEGER, PRIMARY KEY(`SERIES_ID`))",
|
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`SERIES_ID` INTEGER NOT NULL, `SERIES_NAME` TEXT NOT NULL, `SERIES_SORT` TEXT NOT NULL, `SERIES_INDEX` INTEGER, PRIMARY KEY(`SERIES_ID`))",
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"fieldPath": "id",
|
"fieldPath": "id",
|
||||||
"columnName": "SERIES_ID",
|
"columnName": "SERIES_ID",
|
||||||
"affinity": "TEXT",
|
"affinity": "INTEGER",
|
||||||
"notNull": true
|
"notNull": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -284,7 +284,7 @@
|
||||||
"views": [],
|
"views": [],
|
||||||
"setupQueries": [
|
"setupQueries": [
|
||||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'ee46b997bb81036c29a482590e47e98c')"
|
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '30ba58aae4cd6855b019ac599eb57bdb')"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
290
app/schemas/com.pixelized.biblib.database.BibLibDatabase/2.json
Normal file
290
app/schemas/com.pixelized.biblib.database.BibLibDatabase/2.json
Normal file
|
|
@ -0,0 +1,290 @@
|
||||||
|
{
|
||||||
|
"formatVersion": 1,
|
||||||
|
"database": {
|
||||||
|
"version": 2,
|
||||||
|
"identityHash": "30ba58aae4cd6855b019ac599eb57bdb",
|
||||||
|
"entities": [
|
||||||
|
{
|
||||||
|
"tableName": "AUTHOR",
|
||||||
|
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`AUTHOR_ID` TEXT NOT NULL, `AUTHOR_NAME` TEXT NOT NULL, `AUTHOR_SORT` TEXT NOT NULL, PRIMARY KEY(`AUTHOR_ID`))",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldPath": "id",
|
||||||
|
"columnName": "AUTHOR_ID",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "name",
|
||||||
|
"columnName": "AUTHOR_NAME",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "sort",
|
||||||
|
"columnName": "AUTHOR_SORT",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"primaryKey": {
|
||||||
|
"columnNames": [
|
||||||
|
"AUTHOR_ID"
|
||||||
|
],
|
||||||
|
"autoGenerate": false
|
||||||
|
},
|
||||||
|
"indices": [],
|
||||||
|
"foreignKeys": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tableName": "BOOK",
|
||||||
|
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`BOOK_ID` INTEGER NOT NULL, `BOOK_TITLE` TEXT NOT NULL, `BOOK_SORT` TEXT NOT NULL, `BOOK_HAVE_COVER` INTEGER NOT NULL, `BOOK_RELEASE_DATE` INTEGER NOT NULL, `BOOK_LANGUAGE_ID` TEXT, `BOOK_RATING` INTEGER, `BOOK_SERIES_ID` INTEGER, `BOOK_SYNOPSIS` TEXT, `BOOK_ISNEW` INTEGER NOT NULL, `BOOK_NEW_ORDER` INTEGER, PRIMARY KEY(`BOOK_ID`))",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldPath": "id",
|
||||||
|
"columnName": "BOOK_ID",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "title",
|
||||||
|
"columnName": "BOOK_TITLE",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "sort",
|
||||||
|
"columnName": "BOOK_SORT",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "haveCover",
|
||||||
|
"columnName": "BOOK_HAVE_COVER",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "releaseDate",
|
||||||
|
"columnName": "BOOK_RELEASE_DATE",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "language",
|
||||||
|
"columnName": "BOOK_LANGUAGE_ID",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "rating",
|
||||||
|
"columnName": "BOOK_RATING",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "series",
|
||||||
|
"columnName": "BOOK_SERIES_ID",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "synopsis",
|
||||||
|
"columnName": "BOOK_SYNOPSIS",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "isNew",
|
||||||
|
"columnName": "BOOK_ISNEW",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "newOrder",
|
||||||
|
"columnName": "BOOK_NEW_ORDER",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"primaryKey": {
|
||||||
|
"columnNames": [
|
||||||
|
"BOOK_ID"
|
||||||
|
],
|
||||||
|
"autoGenerate": false
|
||||||
|
},
|
||||||
|
"indices": [],
|
||||||
|
"foreignKeys": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tableName": "GENRE",
|
||||||
|
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GENRE_ID` TEXT NOT NULL, `GENRE_NAME` TEXT NOT NULL, PRIMARY KEY(`GENRE_ID`))",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldPath": "id",
|
||||||
|
"columnName": "GENRE_ID",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "name",
|
||||||
|
"columnName": "GENRE_NAME",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"primaryKey": {
|
||||||
|
"columnNames": [
|
||||||
|
"GENRE_ID"
|
||||||
|
],
|
||||||
|
"autoGenerate": false
|
||||||
|
},
|
||||||
|
"indices": [],
|
||||||
|
"foreignKeys": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tableName": "LANGUAGE",
|
||||||
|
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`LANGUAGE_ID` TEXT NOT NULL, `LANGUAGE_NAME` TEXT NOT NULL, PRIMARY KEY(`LANGUAGE_ID`))",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldPath": "id",
|
||||||
|
"columnName": "LANGUAGE_ID",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "code",
|
||||||
|
"columnName": "LANGUAGE_NAME",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"primaryKey": {
|
||||||
|
"columnNames": [
|
||||||
|
"LANGUAGE_ID"
|
||||||
|
],
|
||||||
|
"autoGenerate": false
|
||||||
|
},
|
||||||
|
"indices": [],
|
||||||
|
"foreignKeys": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tableName": "SERIES",
|
||||||
|
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`SERIES_ID` INTEGER NOT NULL, `SERIES_NAME` TEXT NOT NULL, `SERIES_SORT` TEXT NOT NULL, `SERIES_INDEX` INTEGER, PRIMARY KEY(`SERIES_ID`))",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldPath": "id",
|
||||||
|
"columnName": "SERIES_ID",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "name",
|
||||||
|
"columnName": "SERIES_NAME",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "sort",
|
||||||
|
"columnName": "SERIES_SORT",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "index",
|
||||||
|
"columnName": "SERIES_INDEX",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"primaryKey": {
|
||||||
|
"columnNames": [
|
||||||
|
"SERIES_ID"
|
||||||
|
],
|
||||||
|
"autoGenerate": false
|
||||||
|
},
|
||||||
|
"indices": [],
|
||||||
|
"foreignKeys": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tableName": "BookAuthorCrossRef",
|
||||||
|
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`BOOK_ID` INTEGER NOT NULL, `AUTHOR_ID` TEXT NOT NULL, PRIMARY KEY(`BOOK_ID`, `AUTHOR_ID`))",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldPath": "bookId",
|
||||||
|
"columnName": "BOOK_ID",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "authorId",
|
||||||
|
"columnName": "AUTHOR_ID",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"primaryKey": {
|
||||||
|
"columnNames": [
|
||||||
|
"BOOK_ID",
|
||||||
|
"AUTHOR_ID"
|
||||||
|
],
|
||||||
|
"autoGenerate": false
|
||||||
|
},
|
||||||
|
"indices": [
|
||||||
|
{
|
||||||
|
"name": "index_BookAuthorCrossRef_AUTHOR_ID",
|
||||||
|
"unique": false,
|
||||||
|
"columnNames": [
|
||||||
|
"AUTHOR_ID"
|
||||||
|
],
|
||||||
|
"orders": [],
|
||||||
|
"createSql": "CREATE INDEX IF NOT EXISTS `index_BookAuthorCrossRef_AUTHOR_ID` ON `${TABLE_NAME}` (`AUTHOR_ID`)"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"foreignKeys": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tableName": "BookGenreCrossRef",
|
||||||
|
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`BOOK_ID` INTEGER NOT NULL, `GENRE_ID` TEXT NOT NULL, PRIMARY KEY(`BOOK_ID`, `GENRE_ID`))",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldPath": "bookId",
|
||||||
|
"columnName": "BOOK_ID",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "genreId",
|
||||||
|
"columnName": "GENRE_ID",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"primaryKey": {
|
||||||
|
"columnNames": [
|
||||||
|
"BOOK_ID",
|
||||||
|
"GENRE_ID"
|
||||||
|
],
|
||||||
|
"autoGenerate": false
|
||||||
|
},
|
||||||
|
"indices": [
|
||||||
|
{
|
||||||
|
"name": "index_BookGenreCrossRef_GENRE_ID",
|
||||||
|
"unique": false,
|
||||||
|
"columnNames": [
|
||||||
|
"GENRE_ID"
|
||||||
|
],
|
||||||
|
"orders": [],
|
||||||
|
"createSql": "CREATE INDEX IF NOT EXISTS `index_BookGenreCrossRef_GENRE_ID` ON `${TABLE_NAME}` (`GENRE_ID`)"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"foreignKeys": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"views": [],
|
||||||
|
"setupQueries": [
|
||||||
|
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||||
|
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '30ba58aae4cd6855b019ac599eb57bdb')"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -24,7 +24,7 @@ data class BookDbo(
|
||||||
val rating: Int? = null,
|
val rating: Int? = null,
|
||||||
// details
|
// details
|
||||||
@ColumnInfo(name = SERIES_ID)
|
@ColumnInfo(name = SERIES_ID)
|
||||||
val series: String? = null, // one-to-many
|
val series: Int? = null, // one-to-many
|
||||||
@ColumnInfo(name = SYNOPSIS)
|
@ColumnInfo(name = SYNOPSIS)
|
||||||
val synopsis: String? = null,
|
val synopsis: String? = null,
|
||||||
// source
|
// source
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import androidx.room.PrimaryKey
|
||||||
data class SeriesDbo(
|
data class SeriesDbo(
|
||||||
@PrimaryKey
|
@PrimaryKey
|
||||||
@ColumnInfo(name = ID)
|
@ColumnInfo(name = ID)
|
||||||
val id: String,
|
val id: Int,
|
||||||
@ColumnInfo(name = NAME)
|
@ColumnInfo(name = NAME)
|
||||||
val name: String,
|
val name: String,
|
||||||
@ColumnInfo(name = SORT)
|
@ColumnInfo(name = SORT)
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
package com.pixelized.biblib.model.book
|
package com.pixelized.biblib.model.book
|
||||||
|
|
||||||
data class Series(
|
data class Series(
|
||||||
val id: String?,
|
val id: Int?,
|
||||||
val name: String,
|
val name: String,
|
||||||
val sort: String,
|
val sort: String,
|
||||||
val index: Int?,
|
val index: Int?,
|
||||||
|
|
|
||||||
|
|
@ -20,12 +20,14 @@ class PersistenceModule {
|
||||||
fun provideDatabase(
|
fun provideDatabase(
|
||||||
@ApplicationContext context: Context,
|
@ApplicationContext context: Context,
|
||||||
): BibLibDatabase {
|
): BibLibDatabase {
|
||||||
val builder = Room.databaseBuilder(
|
return Room
|
||||||
context,
|
.databaseBuilder(
|
||||||
BibLibDatabase::class.java,
|
context,
|
||||||
BibLibDatabase.DATABASE_NAME
|
BibLibDatabase::class.java,
|
||||||
)
|
BibLibDatabase.DATABASE_NAME
|
||||||
return builder.fallbackToDestructiveMigration().build()
|
)
|
||||||
|
.fallbackToDestructiveMigration()
|
||||||
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,7 @@ package com.pixelized.biblib.network.client
|
||||||
|
|
||||||
import com.google.gson.internal.LinkedTreeMap
|
import com.google.gson.internal.LinkedTreeMap
|
||||||
import com.pixelized.biblib.network.data.query.AuthLoginQuery
|
import com.pixelized.biblib.network.data.query.AuthLoginQuery
|
||||||
import com.pixelized.biblib.network.data.response.AuthLoginResponse
|
import com.pixelized.biblib.network.data.response.*
|
||||||
import com.pixelized.biblib.network.data.response.BookDetailResponse
|
|
||||||
import com.pixelized.biblib.network.data.response.BookListResponse
|
|
||||||
import com.pixelized.biblib.network.data.response.UserResponse
|
|
||||||
import retrofit2.http.*
|
import retrofit2.http.*
|
||||||
|
|
||||||
interface IBibLibWebServiceAPI {
|
interface IBibLibWebServiceAPI {
|
||||||
|
|
@ -24,6 +21,9 @@ interface IBibLibWebServiceAPI {
|
||||||
@GET("/api/book")
|
@GET("/api/book")
|
||||||
suspend fun list(): BookListResponse
|
suspend fun list(): BookListResponse
|
||||||
|
|
||||||
|
@GET("/api/series")
|
||||||
|
suspend fun series(): SeriesListResponse
|
||||||
|
|
||||||
@GET("/api/book/{id}")
|
@GET("/api/book/{id}")
|
||||||
suspend fun detail(@Path("id") bookId: Int): BookDetailResponse
|
suspend fun detail(@Path("id") bookId: Int): BookDetailResponse
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
package com.pixelized.biblib.network.data.response
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName
|
||||||
|
|
||||||
|
data class SeriesListResponse(
|
||||||
|
@SerializedName("lastUpdated")
|
||||||
|
val lastUpdated: String?,
|
||||||
|
@SerializedName("data")
|
||||||
|
val series: List<Series>?,
|
||||||
|
) : ErrorResponse() {
|
||||||
|
|
||||||
|
data class Series(
|
||||||
|
@SerializedName("series_id")
|
||||||
|
val series_id: Int?,
|
||||||
|
@SerializedName("series_name")
|
||||||
|
val series_name: String?,
|
||||||
|
@SerializedName("series_sort")
|
||||||
|
val series_sort: String?,
|
||||||
|
@SerializedName("books")
|
||||||
|
val books: List<Books>?,
|
||||||
|
@SerializedName("author_name")
|
||||||
|
val author_name: List<String>?,
|
||||||
|
@SerializedName("author_sort")
|
||||||
|
val author_sort: List<String>?,
|
||||||
|
@SerializedName("book_date")
|
||||||
|
val book_date: List<String>?,
|
||||||
|
)
|
||||||
|
|
||||||
|
data class Books(
|
||||||
|
@SerializedName("book_id")
|
||||||
|
val book_id: Int?,
|
||||||
|
@SerializedName("book_title")
|
||||||
|
val book_title: String?,
|
||||||
|
@SerializedName("book_has_cover")
|
||||||
|
val book_has_cover: Int?,
|
||||||
|
@SerializedName("book_date")
|
||||||
|
val book_date: String?,
|
||||||
|
@SerializedName("book_series_index")
|
||||||
|
val book_series_index: Float?,
|
||||||
|
@SerializedName("last_modified")
|
||||||
|
val last_modified: String?,
|
||||||
|
@SerializedName("author_name")
|
||||||
|
val author_name: List<String>?,
|
||||||
|
@SerializedName("lang_id")
|
||||||
|
val lang_id: Int?,
|
||||||
|
@SerializedName("lang_code")
|
||||||
|
val lang_code: String?,
|
||||||
|
@SerializedName("rating")
|
||||||
|
val rating: String?,
|
||||||
|
@SerializedName("series_id")
|
||||||
|
val series_id: Int?,
|
||||||
|
@SerializedName("series_name")
|
||||||
|
val series_name: String?,
|
||||||
|
@SerializedName("series_sort")
|
||||||
|
val series_sort: String?,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -7,12 +7,14 @@ import com.pixelized.biblib.utils.exception.MandatoryFieldMissingException
|
||||||
import com.pixelized.biblib.utils.extention.toBoolean
|
import com.pixelized.biblib.utils.extention.toBoolean
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
import kotlin.collections.HashMap
|
||||||
|
|
||||||
class BookFactory {
|
class BookFactory {
|
||||||
private val parser get() = SimpleDateFormat(Factory.FORMAT, Locale.getDefault())
|
private val parser get() = SimpleDateFormat(Factory.FORMAT, Locale.getDefault())
|
||||||
|
|
||||||
fun fromListResponseToBook(
|
fun fromListResponseToBook(
|
||||||
response: BookListResponse.Book,
|
response: BookListResponse.Book,
|
||||||
|
seriesHash: HashMap<Int, Series>,
|
||||||
isNew: Boolean = false,
|
isNew: Boolean = false,
|
||||||
newOrder: Int? = null
|
newOrder: Int? = null
|
||||||
): Book {
|
): Book {
|
||||||
|
|
@ -61,14 +63,7 @@ class BookFactory {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
val rating = response.rating?.toIntOrNull()
|
val rating = response.rating?.toIntOrNull()
|
||||||
val seriesName = response.series_name
|
|
||||||
val seriesSort = response.series_sort
|
|
||||||
val seriesIndex: Int? = response.book_series_index?.toInt()
|
|
||||||
val series: Series? = if (seriesName != null && seriesSort != null) {
|
|
||||||
Series(id = null, name = seriesName, sort = seriesSort, index = seriesIndex)
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
val newOrder = if (isNew) {
|
val newOrder = if (isNew) {
|
||||||
newOrder
|
newOrder
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -82,7 +77,7 @@ class BookFactory {
|
||||||
author = author ?: throw error("author"),
|
author = author ?: throw error("author"),
|
||||||
haveCover = cover ?: throw error("haveCover"),
|
haveCover = cover ?: throw error("haveCover"),
|
||||||
releaseDate = releaseDate ?: throw error("releaseDate"),
|
releaseDate = releaseDate ?: throw error("releaseDate"),
|
||||||
series = series,
|
series = seriesHash[id],
|
||||||
language = language,
|
language = language,
|
||||||
rating = rating,
|
rating = rating,
|
||||||
isNew = isNew,
|
isNew = isNew,
|
||||||
|
|
@ -125,7 +120,7 @@ class BookFactory {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
val rating = response.rating?.toIntOrNull()
|
val rating = response.rating?.toIntOrNull()
|
||||||
val seriesId = response.series_id
|
val seriesId = response.series_id?.toIntOrNull()
|
||||||
val seriesName = response.series_name
|
val seriesName = response.series_name
|
||||||
val seriesSort = response.series_sort
|
val seriesSort = response.series_sort
|
||||||
val seriesIndex: Int? = response.book_series_index?.toInt()
|
val seriesIndex: Int? = response.book_series_index?.toInt()
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
package com.pixelized.biblib.network.factory
|
||||||
|
|
||||||
|
import com.pixelized.biblib.model.book.Series
|
||||||
|
import com.pixelized.biblib.network.data.response.SeriesListResponse
|
||||||
|
import com.pixelized.biblib.utils.exception.MandatoryFieldMissingException
|
||||||
|
|
||||||
|
class SeriesFactory {
|
||||||
|
|
||||||
|
fun fromListResponseToSeriesHash(
|
||||||
|
response: SeriesListResponse,
|
||||||
|
): HashMap<Int, Series> {
|
||||||
|
|
||||||
|
fun error(name: String) =
|
||||||
|
MandatoryFieldMissingException("#fromListResponseToSeriesHash()", name, response)
|
||||||
|
|
||||||
|
val hash = hashMapOf<Int, Series>()
|
||||||
|
|
||||||
|
response.series?.forEachIndexed { index, data ->
|
||||||
|
// build the Series items
|
||||||
|
val series = Series(
|
||||||
|
id = data.series_id,
|
||||||
|
name = data.series_name ?: throw error("name"),
|
||||||
|
sort = data.series_sort ?: throw error("sort"),
|
||||||
|
index = index,
|
||||||
|
)
|
||||||
|
// link that item to the book id.
|
||||||
|
data.books?.forEach { book ->
|
||||||
|
book.book_id?.let { id -> hash[id] = series }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return hash
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -57,7 +57,9 @@ class BookRepository @Inject constructor(
|
||||||
genres.add(it.toDbo())
|
genres.add(it.toDbo())
|
||||||
bookGenreCrossRef.add(BookGenreCrossRef(bookId = book.id, it.id))
|
bookGenreCrossRef.add(BookGenreCrossRef(bookId = book.id, it.id))
|
||||||
}
|
}
|
||||||
book.language?.let { languages.add(it.toDbo()) }
|
book.language?.let {
|
||||||
|
languages.add(it.toDbo())
|
||||||
|
}
|
||||||
book.series?.let {
|
book.series?.let {
|
||||||
if (it.id != null) {
|
if (it.id != null) {
|
||||||
series.add(it.toDbo(it.id))
|
series.add(it.toDbo(it.id))
|
||||||
|
|
@ -87,7 +89,7 @@ class BookRepository @Inject constructor(
|
||||||
name = name,
|
name = name,
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun Series.toDbo(id: String) = SeriesDbo(
|
private fun Series.toDbo(id: Int) = SeriesDbo(
|
||||||
id = id,
|
id = id,
|
||||||
name = name,
|
name = name,
|
||||||
sort = sort,
|
sort = sort,
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,9 @@ package com.pixelized.biblib.repository.book
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import com.pixelized.biblib.network.client.IBibLibClient
|
import com.pixelized.biblib.network.client.IBibLibClient
|
||||||
import com.pixelized.biblib.network.data.response.BookListResponse
|
import com.pixelized.biblib.network.data.response.BookListResponse
|
||||||
|
import com.pixelized.biblib.network.data.response.SeriesListResponse
|
||||||
import com.pixelized.biblib.network.factory.BookFactory
|
import com.pixelized.biblib.network.factory.BookFactory
|
||||||
|
import com.pixelized.biblib.network.factory.SeriesFactory
|
||||||
import com.pixelized.biblib.repository.apiCache.IAPICacheRepository
|
import com.pixelized.biblib.repository.apiCache.IAPICacheRepository
|
||||||
import com.pixelized.biblib.utils.exception.BookFetchException
|
import com.pixelized.biblib.utils.exception.BookFetchException
|
||||||
import com.pixelized.biblib.utils.exception.NewBookFetchException
|
import com.pixelized.biblib.utils.exception.NewBookFetchException
|
||||||
|
|
@ -59,27 +61,44 @@ suspend fun loadAllBooks(
|
||||||
client: IBibLibClient,
|
client: IBibLibClient,
|
||||||
cache: IAPICacheRepository,
|
cache: IAPICacheRepository,
|
||||||
repository: IBookRepository,
|
repository: IBookRepository,
|
||||||
factory: BookFactory = BookFactory(),
|
bookFactory: BookFactory = BookFactory(),
|
||||||
|
seriesFactory: SeriesFactory = SeriesFactory(),
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val response: BookListResponse = client.service.list()
|
val seriesResponse: SeriesListResponse = client.service.series()
|
||||||
|
val bookResponse: BookListResponse = client.service.list()
|
||||||
|
|
||||||
return when {
|
return when {
|
||||||
response.isError -> {
|
bookResponse.isError -> {
|
||||||
Log.e("loadAllBooks", response.message ?: "")
|
Log.e("loadAllBooks", bookResponse.message ?: "")
|
||||||
throw BookFetchException(response.message)
|
throw BookFetchException(bookResponse.message)
|
||||||
|
}
|
||||||
|
seriesResponse.isError -> {
|
||||||
|
Log.e("loadAllBooks", seriesResponse.message ?: "")
|
||||||
|
throw BookFetchException(seriesResponse.message)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
|
// prepare a list of new book ids.
|
||||||
val newIds = cache.new?.data?.map { it.book_id } ?: listOf()
|
val newIds = cache.new?.data?.map { it.book_id } ?: listOf()
|
||||||
val books = response.data?.map { dto ->
|
// prepare a hash of series by books ids.
|
||||||
|
val series = seriesFactory.fromListResponseToSeriesHash(seriesResponse)
|
||||||
|
// parse books.
|
||||||
|
val books = bookResponse.data?.map { dto ->
|
||||||
val isNew = newIds.contains(dto.book_id)
|
val isNew = newIds.contains(dto.book_id)
|
||||||
val index = newIds.indexOf(dto.book_id)
|
val index = newIds.indexOf(dto.book_id)
|
||||||
factory.fromListResponseToBook(dto, isNew, index)
|
return@map bookFactory.fromListResponseToBook(
|
||||||
|
response = dto,
|
||||||
|
seriesHash = series,
|
||||||
|
isNew = isNew,
|
||||||
|
newOrder = index
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
// check if data is valid
|
||||||
if (books.isNullOrEmpty()) {
|
if (books.isNullOrEmpty()) {
|
||||||
Log.e("loadAllBooks", "Book list is empty")
|
Log.e("loadAllBooks", "Book list is empty")
|
||||||
throw BookFetchException("Book list is empty")
|
throw BookFetchException("Book list is empty")
|
||||||
}
|
}
|
||||||
books.let { data -> repository.update(data) }
|
// update the repository.
|
||||||
|
repository.update(books)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -107,14 +107,14 @@ class BooksViewModel @Inject constructor(
|
||||||
|
|
||||||
private suspend fun loadAllBooks(): Boolean {
|
private suspend fun loadAllBooks(): Boolean {
|
||||||
client.service.list().let { response ->
|
client.service.list().let { response ->
|
||||||
val newIds = apiCache.new?.data?.map { it.book_id } ?: listOf()
|
// val newIds = apiCache.new?.data?.map { it.book_id } ?: listOf()
|
||||||
val factory = BookFactory()
|
// val factory = BookFactory()
|
||||||
val books = response.data?.map { dto ->
|
// val books = response.data?.map { dto ->
|
||||||
val isNew = newIds.contains(dto.book_id)
|
// val isNew = newIds.contains(dto.book_id)
|
||||||
val index = newIds.indexOf(dto.book_id)
|
// val index = newIds.indexOf(dto.book_id)
|
||||||
factory.fromListResponseToBook(dto, isNew, index)
|
// factory.fromListResponseToBook(dto, isNew, index)
|
||||||
}
|
// }
|
||||||
books?.let { data -> bookRepository.update(data) }
|
// books?.let { data -> bookRepository.update(data) }
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -133,9 +133,9 @@ private fun rememberSearchFilter(
|
||||||
derivedStateOf {
|
derivedStateOf {
|
||||||
listOf(
|
listOf(
|
||||||
SearchFilter.Author(value = authors),
|
SearchFilter.Author(value = authors),
|
||||||
|
SearchFilter.Series(value = series),
|
||||||
SearchFilter.Genre(value = genre),
|
SearchFilter.Genre(value = genre),
|
||||||
SearchFilter.Language(value = language),
|
SearchFilter.Language(value = language)
|
||||||
SearchFilter.Series(value = series)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue