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,
 | 
			
		||||
  "database": {
 | 
			
		||||
    "version": 1,
 | 
			
		||||
    "identityHash": "ee46b997bb81036c29a482590e47e98c",
 | 
			
		||||
    "identityHash": "30ba58aae4cd6855b019ac599eb57bdb",
 | 
			
		||||
    "entities": [
 | 
			
		||||
      {
 | 
			
		||||
        "tableName": "AUTHOR",
 | 
			
		||||
| 
						 | 
				
			
			@ -38,7 +38,7 @@
 | 
			
		|||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "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": [
 | 
			
		||||
          {
 | 
			
		||||
            "fieldPath": "id",
 | 
			
		||||
| 
						 | 
				
			
			@ -85,7 +85,7 @@
 | 
			
		|||
          {
 | 
			
		||||
            "fieldPath": "series",
 | 
			
		||||
            "columnName": "BOOK_SERIES_ID",
 | 
			
		||||
            "affinity": "TEXT",
 | 
			
		||||
            "affinity": "INTEGER",
 | 
			
		||||
            "notNull": false
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
| 
						 | 
				
			
			@ -170,12 +170,12 @@
 | 
			
		|||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "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": [
 | 
			
		||||
          {
 | 
			
		||||
            "fieldPath": "id",
 | 
			
		||||
            "columnName": "SERIES_ID",
 | 
			
		||||
            "affinity": "TEXT",
 | 
			
		||||
            "affinity": "INTEGER",
 | 
			
		||||
            "notNull": true
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
| 
						 | 
				
			
			@ -284,7 +284,7 @@
 | 
			
		|||
    "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, '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,
 | 
			
		||||
    // details
 | 
			
		||||
    @ColumnInfo(name = SERIES_ID)
 | 
			
		||||
    val series: String? = null,         // one-to-many
 | 
			
		||||
    val series: Int? = null,            // one-to-many
 | 
			
		||||
    @ColumnInfo(name = SYNOPSIS)
 | 
			
		||||
    val synopsis: String? = null,
 | 
			
		||||
    // source
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,7 +8,7 @@ import androidx.room.PrimaryKey
 | 
			
		|||
data class SeriesDbo(
 | 
			
		||||
    @PrimaryKey
 | 
			
		||||
    @ColumnInfo(name = ID)
 | 
			
		||||
    val id: String,
 | 
			
		||||
    val id: Int,
 | 
			
		||||
    @ColumnInfo(name = NAME)
 | 
			
		||||
    val name: String,
 | 
			
		||||
    @ColumnInfo(name = SORT)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
package com.pixelized.biblib.model.book
 | 
			
		||||
 | 
			
		||||
data class Series(
 | 
			
		||||
    val id: String?,
 | 
			
		||||
    val id: Int?,
 | 
			
		||||
    val name: String,
 | 
			
		||||
    val sort: String,
 | 
			
		||||
    val index: Int?,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,12 +20,14 @@ class PersistenceModule {
 | 
			
		|||
    fun provideDatabase(
 | 
			
		||||
        @ApplicationContext context: Context,
 | 
			
		||||
    ): BibLibDatabase {
 | 
			
		||||
        val builder = Room.databaseBuilder(
 | 
			
		||||
            context,
 | 
			
		||||
            BibLibDatabase::class.java,
 | 
			
		||||
            BibLibDatabase.DATABASE_NAME
 | 
			
		||||
        )
 | 
			
		||||
        return builder.fallbackToDestructiveMigration().build()
 | 
			
		||||
        return Room
 | 
			
		||||
            .databaseBuilder(
 | 
			
		||||
                context,
 | 
			
		||||
                BibLibDatabase::class.java,
 | 
			
		||||
                BibLibDatabase.DATABASE_NAME
 | 
			
		||||
            )
 | 
			
		||||
            .fallbackToDestructiveMigration()
 | 
			
		||||
            .build()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Provides
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,10 +2,7 @@ package com.pixelized.biblib.network.client
 | 
			
		|||
 | 
			
		||||
import com.google.gson.internal.LinkedTreeMap
 | 
			
		||||
import com.pixelized.biblib.network.data.query.AuthLoginQuery
 | 
			
		||||
import com.pixelized.biblib.network.data.response.AuthLoginResponse
 | 
			
		||||
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 com.pixelized.biblib.network.data.response.*
 | 
			
		||||
import retrofit2.http.*
 | 
			
		||||
 | 
			
		||||
interface IBibLibWebServiceAPI {
 | 
			
		||||
| 
						 | 
				
			
			@ -24,6 +21,9 @@ interface IBibLibWebServiceAPI {
 | 
			
		|||
    @GET("/api/book")
 | 
			
		||||
    suspend fun list(): BookListResponse
 | 
			
		||||
 | 
			
		||||
    @GET("/api/series")
 | 
			
		||||
    suspend fun series(): SeriesListResponse
 | 
			
		||||
 | 
			
		||||
    @GET("/api/book/{id}")
 | 
			
		||||
    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 java.text.SimpleDateFormat
 | 
			
		||||
import java.util.*
 | 
			
		||||
import kotlin.collections.HashMap
 | 
			
		||||
 | 
			
		||||
class BookFactory {
 | 
			
		||||
    private val parser get() = SimpleDateFormat(Factory.FORMAT, Locale.getDefault())
 | 
			
		||||
 | 
			
		||||
    fun fromListResponseToBook(
 | 
			
		||||
        response: BookListResponse.Book,
 | 
			
		||||
        seriesHash: HashMap<Int, Series>,
 | 
			
		||||
        isNew: Boolean = false,
 | 
			
		||||
        newOrder: Int? = null
 | 
			
		||||
    ): Book {
 | 
			
		||||
| 
						 | 
				
			
			@ -61,14 +63,7 @@ class BookFactory {
 | 
			
		|||
            null
 | 
			
		||||
        }
 | 
			
		||||
        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) {
 | 
			
		||||
            newOrder
 | 
			
		||||
        } else {
 | 
			
		||||
| 
						 | 
				
			
			@ -82,7 +77,7 @@ class BookFactory {
 | 
			
		|||
            author = author ?: throw error("author"),
 | 
			
		||||
            haveCover = cover ?: throw error("haveCover"),
 | 
			
		||||
            releaseDate = releaseDate ?: throw error("releaseDate"),
 | 
			
		||||
            series = series,
 | 
			
		||||
            series = seriesHash[id],
 | 
			
		||||
            language = language,
 | 
			
		||||
            rating = rating,
 | 
			
		||||
            isNew = isNew,
 | 
			
		||||
| 
						 | 
				
			
			@ -125,7 +120,7 @@ class BookFactory {
 | 
			
		|||
            null
 | 
			
		||||
        }
 | 
			
		||||
        val rating = response.rating?.toIntOrNull()
 | 
			
		||||
        val seriesId = response.series_id
 | 
			
		||||
        val seriesId = response.series_id?.toIntOrNull()
 | 
			
		||||
        val seriesName = response.series_name
 | 
			
		||||
        val seriesSort = response.series_sort
 | 
			
		||||
        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())
 | 
			
		||||
                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 {
 | 
			
		||||
                if (it.id != null) {
 | 
			
		||||
                    series.add(it.toDbo(it.id))
 | 
			
		||||
| 
						 | 
				
			
			@ -87,7 +89,7 @@ class BookRepository @Inject constructor(
 | 
			
		|||
        name = name,
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    private fun Series.toDbo(id: String) = SeriesDbo(
 | 
			
		||||
    private fun Series.toDbo(id: Int) = SeriesDbo(
 | 
			
		||||
        id = id,
 | 
			
		||||
        name = name,
 | 
			
		||||
        sort = sort,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,9 @@ package com.pixelized.biblib.repository.book
 | 
			
		|||
import android.util.Log
 | 
			
		||||
import com.pixelized.biblib.network.client.IBibLibClient
 | 
			
		||||
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.SeriesFactory
 | 
			
		||||
import com.pixelized.biblib.repository.apiCache.IAPICacheRepository
 | 
			
		||||
import com.pixelized.biblib.utils.exception.BookFetchException
 | 
			
		||||
import com.pixelized.biblib.utils.exception.NewBookFetchException
 | 
			
		||||
| 
						 | 
				
			
			@ -59,27 +61,44 @@ suspend fun loadAllBooks(
 | 
			
		|||
    client: IBibLibClient,
 | 
			
		||||
    cache: IAPICacheRepository,
 | 
			
		||||
    repository: IBookRepository,
 | 
			
		||||
    factory: BookFactory = BookFactory(),
 | 
			
		||||
    bookFactory: BookFactory = BookFactory(),
 | 
			
		||||
    seriesFactory: SeriesFactory = SeriesFactory(),
 | 
			
		||||
): Boolean {
 | 
			
		||||
    val response: BookListResponse = client.service.list()
 | 
			
		||||
    val seriesResponse: SeriesListResponse = client.service.series()
 | 
			
		||||
    val bookResponse: BookListResponse = client.service.list()
 | 
			
		||||
 | 
			
		||||
    return when {
 | 
			
		||||
        response.isError -> {
 | 
			
		||||
            Log.e("loadAllBooks", response.message ?: "")
 | 
			
		||||
            throw BookFetchException(response.message)
 | 
			
		||||
        bookResponse.isError -> {
 | 
			
		||||
            Log.e("loadAllBooks", bookResponse.message ?: "")
 | 
			
		||||
            throw BookFetchException(bookResponse.message)
 | 
			
		||||
        }
 | 
			
		||||
        seriesResponse.isError -> {
 | 
			
		||||
            Log.e("loadAllBooks", seriesResponse.message ?: "")
 | 
			
		||||
            throw BookFetchException(seriesResponse.message)
 | 
			
		||||
        }
 | 
			
		||||
        else -> {
 | 
			
		||||
            // prepare a list of new book ids.
 | 
			
		||||
            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 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()) {
 | 
			
		||||
                Log.e("loadAllBooks", "Book list is empty")
 | 
			
		||||
                throw BookFetchException("Book list is empty")
 | 
			
		||||
            }
 | 
			
		||||
            books.let { data -> repository.update(data) }
 | 
			
		||||
            // update the repository.
 | 
			
		||||
            repository.update(books)
 | 
			
		||||
            true
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -107,14 +107,14 @@ class BooksViewModel @Inject constructor(
 | 
			
		|||
 | 
			
		||||
    private suspend fun loadAllBooks(): Boolean {
 | 
			
		||||
        client.service.list().let { response ->
 | 
			
		||||
            val newIds = apiCache.new?.data?.map { it.book_id } ?: listOf()
 | 
			
		||||
            val factory = BookFactory()
 | 
			
		||||
            val books = response.data?.map { dto ->
 | 
			
		||||
                val isNew = newIds.contains(dto.book_id)
 | 
			
		||||
                val index = newIds.indexOf(dto.book_id)
 | 
			
		||||
                factory.fromListResponseToBook(dto, isNew, index)
 | 
			
		||||
            }
 | 
			
		||||
            books?.let { data -> bookRepository.update(data) }
 | 
			
		||||
//            val newIds = apiCache.new?.data?.map { it.book_id } ?: listOf()
 | 
			
		||||
//            val factory = BookFactory()
 | 
			
		||||
//            val books = response.data?.map { dto ->
 | 
			
		||||
//                val isNew = newIds.contains(dto.book_id)
 | 
			
		||||
//                val index = newIds.indexOf(dto.book_id)
 | 
			
		||||
//                factory.fromListResponseToBook(dto, isNew, index)
 | 
			
		||||
//            }
 | 
			
		||||
//            books?.let { data -> bookRepository.update(data) }
 | 
			
		||||
        }
 | 
			
		||||
        return true
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -133,9 +133,9 @@ private fun rememberSearchFilter(
 | 
			
		|||
        derivedStateOf {
 | 
			
		||||
            listOf(
 | 
			
		||||
                SearchFilter.Author(value = authors),
 | 
			
		||||
                SearchFilter.Series(value = series),
 | 
			
		||||
                SearchFilter.Genre(value = genre),
 | 
			
		||||
                SearchFilter.Language(value = language),
 | 
			
		||||
                SearchFilter.Series(value = series)
 | 
			
		||||
                SearchFilter.Language(value = language)
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue