Add IBookRepository
This commit is contained in:
		
							parent
							
								
									6a0710572a
								
							
						
					
					
						commit
						b89bbf69a9
					
				
					 10 changed files with 145 additions and 5 deletions
				
			
		| 
						 | 
				
			
			@ -11,6 +11,8 @@ import com.pixelized.biblib.network.client.BibLibClient
 | 
			
		|||
import com.pixelized.biblib.network.client.IBibLibClient
 | 
			
		||||
import com.pixelized.biblib.repository.apiCache.APICacheRepository
 | 
			
		||||
import com.pixelized.biblib.repository.apiCache.IAPICacheRepository
 | 
			
		||||
import com.pixelized.biblib.repository.book.BookRepository
 | 
			
		||||
import com.pixelized.biblib.repository.book.IBookRepository
 | 
			
		||||
import com.pixelized.biblib.repository.credential.CredentialRepository
 | 
			
		||||
import com.pixelized.biblib.repository.credential.ICredentialRepository
 | 
			
		||||
import com.pixelized.biblib.repository.googleSignIn.GoogleSingInRepository
 | 
			
		||||
| 
						 | 
				
			
			@ -37,6 +39,7 @@ class BibLibApplication : Application() {
 | 
			
		|||
        Bob[IGoogleSingInRepository::class] = GoogleSingInRepository(this)
 | 
			
		||||
        Bob[ICredentialRepository::class] = CredentialRepository()
 | 
			
		||||
        Bob[IAPICacheRepository::class] = APICacheRepository()
 | 
			
		||||
        Bob[IBookRepository::class] = BookRepository()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    companion object {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -29,6 +29,7 @@ abstract class BibLibDatabase : RoomDatabase() {
 | 
			
		|||
    abstract fun genreDao(): GenreDao
 | 
			
		||||
    abstract fun languageDao(): LanguageDao
 | 
			
		||||
    abstract fun seriesDao(): SeriesDao
 | 
			
		||||
    abstract fun crossRefDao(): CrossRefDao
 | 
			
		||||
 | 
			
		||||
    companion object {
 | 
			
		||||
        const val VERSION = 1
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,7 +8,7 @@ import com.pixelized.biblib.database.data.BookDbo
 | 
			
		|||
@Entity(primaryKeys = [BookDbo.ID, AuthorDbo.ID])
 | 
			
		||||
data class BookAuthorCrossRef(
 | 
			
		||||
    @ColumnInfo(name = BookDbo.ID)
 | 
			
		||||
    val bookId: String,
 | 
			
		||||
    val bookId: Int,
 | 
			
		||||
    @ColumnInfo(name = AuthorDbo.ID)
 | 
			
		||||
    val authorId: String
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,7 +8,7 @@ import com.pixelized.biblib.database.data.GenreDbo
 | 
			
		|||
@Entity(primaryKeys = [BookDbo.ID, GenreDbo.ID])
 | 
			
		||||
data class BookGenreCrossRef(
 | 
			
		||||
    @ColumnInfo(name = BookDbo.ID)
 | 
			
		||||
    val bookId: String,
 | 
			
		||||
    val bookId: Int,
 | 
			
		||||
    @ColumnInfo(name = GenreDbo.ID)
 | 
			
		||||
    val genreId: String
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			@ -10,8 +10,8 @@ interface BookDao {
 | 
			
		|||
    @Query("SELECT * FROM ${BookDbo.TABLE}")
 | 
			
		||||
    fun getAll(): List<BookRelation>
 | 
			
		||||
 | 
			
		||||
    @Insert
 | 
			
		||||
    fun update(vararg books: BookDbo)
 | 
			
		||||
    @Insert(onConflict = OnConflictStrategy.REPLACE)
 | 
			
		||||
    fun insert(vararg books: BookDbo)
 | 
			
		||||
 | 
			
		||||
    @Delete
 | 
			
		||||
    fun delete(book: BookDbo)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,17 @@
 | 
			
		|||
package com.pixelized.biblib.database.dao
 | 
			
		||||
 | 
			
		||||
import androidx.room.Dao
 | 
			
		||||
import androidx.room.Insert
 | 
			
		||||
import androidx.room.OnConflictStrategy
 | 
			
		||||
import com.pixelized.biblib.database.crossref.BookAuthorCrossRef
 | 
			
		||||
import com.pixelized.biblib.database.crossref.BookGenreCrossRef
 | 
			
		||||
 | 
			
		||||
@Dao
 | 
			
		||||
interface CrossRefDao {
 | 
			
		||||
 | 
			
		||||
    @Insert(onConflict = OnConflictStrategy.REPLACE)
 | 
			
		||||
    fun insert(vararg bookAuthor: BookAuthorCrossRef)
 | 
			
		||||
 | 
			
		||||
    @Insert(onConflict = OnConflictStrategy.REPLACE)
 | 
			
		||||
    fun insert(vararg bookGenre: BookGenreCrossRef)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,86 @@
 | 
			
		|||
package com.pixelized.biblib.repository.book
 | 
			
		||||
 | 
			
		||||
import com.pixelized.biblib.database.BibLibDatabase
 | 
			
		||||
import com.pixelized.biblib.database.crossref.BookAuthorCrossRef
 | 
			
		||||
import com.pixelized.biblib.database.crossref.BookGenreCrossRef
 | 
			
		||||
import com.pixelized.biblib.database.data.*
 | 
			
		||||
import com.pixelized.biblib.model.*
 | 
			
		||||
import com.pixelized.biblib.utils.injection.inject
 | 
			
		||||
 | 
			
		||||
class BookRepository : IBookRepository {
 | 
			
		||||
    val database: BibLibDatabase by inject()
 | 
			
		||||
 | 
			
		||||
    override fun update(data: List<Book>) {
 | 
			
		||||
        val authors = mutableSetOf<AuthorDbo>()
 | 
			
		||||
        val genres = mutableSetOf<GenreDbo>()
 | 
			
		||||
        val series = mutableSetOf<SeriesDbo>()
 | 
			
		||||
        val languages = mutableSetOf<LanguageDbo>()
 | 
			
		||||
        val books = mutableListOf<BookDbo>()
 | 
			
		||||
 | 
			
		||||
        val bookAuthorCrossRef = mutableListOf<BookAuthorCrossRef>()
 | 
			
		||||
        val bookGenreCrossRef = mutableListOf<BookGenreCrossRef>()
 | 
			
		||||
 | 
			
		||||
        data.forEach { book ->
 | 
			
		||||
            book.author.forEach {
 | 
			
		||||
                authors.add(it.toDbo())
 | 
			
		||||
                bookAuthorCrossRef.add(BookAuthorCrossRef(bookId = book.id, it.id))
 | 
			
		||||
            }
 | 
			
		||||
            book.genre?.forEach {
 | 
			
		||||
                genres.add(it.toDbo())
 | 
			
		||||
                bookGenreCrossRef.add(BookGenreCrossRef(bookId = book.id, it.id))
 | 
			
		||||
            }
 | 
			
		||||
            book.language?.let { languages.add(it.toDbo()) }
 | 
			
		||||
            book.series?.let {
 | 
			
		||||
                if (it.id != null) {
 | 
			
		||||
                    series.add(it.toDbo(it.id))
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            books.add(book.toDbo())
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        database.authorDao().insert(*authors.toTypedArray())
 | 
			
		||||
        database.genreDao().insert(*genres.toTypedArray())
 | 
			
		||||
        database.languageDao().insert(*languages.toTypedArray())
 | 
			
		||||
        database.seriesDao().insert(*series.toTypedArray())
 | 
			
		||||
        database.bookDao().insert(*books.toTypedArray())
 | 
			
		||||
 | 
			
		||||
        database.crossRefDao().insert(*bookAuthorCrossRef.toTypedArray())
 | 
			
		||||
        database.crossRefDao().insert(*bookGenreCrossRef.toTypedArray())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun Author.toDbo() = AuthorDbo(
 | 
			
		||||
        id = id,
 | 
			
		||||
        name = name,
 | 
			
		||||
        sort = sort,
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    private fun Genre.toDbo() = GenreDbo(
 | 
			
		||||
        id = id,
 | 
			
		||||
        name = name,
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    private fun Series.toDbo(id: String) = SeriesDbo(
 | 
			
		||||
        id = id,
 | 
			
		||||
        name = name,
 | 
			
		||||
        sort = sort,
 | 
			
		||||
        index = index,
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    private fun Language.toDbo() = LanguageDbo(
 | 
			
		||||
        id = id,
 | 
			
		||||
        code = code
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    private fun Book.toDbo() = BookDbo(
 | 
			
		||||
        id = id,
 | 
			
		||||
        title = title,
 | 
			
		||||
        sort = sort,
 | 
			
		||||
        haveCover = haveCover,
 | 
			
		||||
        releaseDate = releaseDate,
 | 
			
		||||
        language = language?.id,
 | 
			
		||||
        rating = rating,
 | 
			
		||||
        series = series?.id,
 | 
			
		||||
        synopsis = synopsis,
 | 
			
		||||
        isNew = isNew,
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,7 @@
 | 
			
		|||
package com.pixelized.biblib.repository.book
 | 
			
		||||
 | 
			
		||||
import com.pixelized.biblib.model.Book
 | 
			
		||||
 | 
			
		||||
interface IBookRepository {
 | 
			
		||||
    fun update(data: List<Book>)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -7,6 +7,9 @@ interface IInitialisation {
 | 
			
		|||
    @Composable
 | 
			
		||||
    fun LoadApplication(content: @Composable (State) -> Unit)
 | 
			
		||||
 | 
			
		||||
    @Composable
 | 
			
		||||
    fun LoadBook(content: @Composable (State) -> Unit)
 | 
			
		||||
 | 
			
		||||
    sealed class State {
 | 
			
		||||
        object Initial : State()
 | 
			
		||||
        object Loading : State()
 | 
			
		||||
| 
						 | 
				
			
			@ -16,5 +19,7 @@ interface IInitialisation {
 | 
			
		|||
    class Mock(private val state: State = State.Loading) : IInitialisation {
 | 
			
		||||
        @Composable
 | 
			
		||||
        override fun LoadApplication(content: (State) -> Unit) = content(state)
 | 
			
		||||
        @Composable
 | 
			
		||||
        override fun LoadBook(content: (State) -> Unit) = content(state)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -4,7 +4,9 @@ import androidx.compose.runtime.*
 | 
			
		|||
import androidx.lifecycle.ViewModel
 | 
			
		||||
import com.pixelized.biblib.network.client.IBibLibClient
 | 
			
		||||
import com.pixelized.biblib.network.data.query.AuthLoginQuery
 | 
			
		||||
import com.pixelized.biblib.network.factory.BookFactory
 | 
			
		||||
import com.pixelized.biblib.repository.apiCache.IAPICacheRepository
 | 
			
		||||
import com.pixelized.biblib.repository.book.IBookRepository
 | 
			
		||||
import com.pixelized.biblib.repository.credential.ICredentialRepository
 | 
			
		||||
import com.pixelized.biblib.repository.googleSignIn.IGoogleSingInRepository
 | 
			
		||||
import com.pixelized.biblib.ui.viewmodel.initialisation.IInitialisation.State.*
 | 
			
		||||
| 
						 | 
				
			
			@ -13,6 +15,7 @@ import kotlinx.coroutines.delay
 | 
			
		|||
 | 
			
		||||
class InitialisationViewModel : ViewModel(), IInitialisation {
 | 
			
		||||
    private val credentialRepository: ICredentialRepository by inject()
 | 
			
		||||
    private val bookRepository: IBookRepository by inject()
 | 
			
		||||
    private val googleSignIn: IGoogleSingInRepository by inject()
 | 
			
		||||
    private val client: IBibLibClient by inject()
 | 
			
		||||
    private val apiCache: IAPICacheRepository by inject()
 | 
			
		||||
| 
						 | 
				
			
			@ -35,6 +38,17 @@ class InitialisationViewModel : ViewModel(), IInitialisation {
 | 
			
		|||
        content(state.value)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Composable
 | 
			
		||||
    override fun LoadBook(content: (IInitialisation.State) -> Unit) {
 | 
			
		||||
        val state: MutableState<IInitialisation.State> = remember { mutableStateOf(Initial) }
 | 
			
		||||
        LaunchedEffect(key1 = "LoadBook") {
 | 
			
		||||
            state.value = Loading
 | 
			
		||||
            loadNewBooks() && loadAllBooks()
 | 
			
		||||
            state.value = Finished(needLogin = false)
 | 
			
		||||
        }
 | 
			
		||||
        content(state.value)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private suspend fun loginWithGoogle(): Boolean {
 | 
			
		||||
        val googleToken = googleSignIn.lastGoogleToken
 | 
			
		||||
        return if (googleToken != null) {
 | 
			
		||||
| 
						 | 
				
			
			@ -89,7 +103,14 @@ class InitialisationViewModel : ViewModel(), IInitialisation {
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    private suspend fun loadAllBooks(): Boolean {
 | 
			
		||||
        apiCache.list = client.service.list()
 | 
			
		||||
        client.service.list().let { response ->
 | 
			
		||||
            // TODO: useless isn't it ?
 | 
			
		||||
            apiCache.list = response
 | 
			
		||||
 | 
			
		||||
            val factory = BookFactory()
 | 
			
		||||
            val books = response.data?.map { dto -> factory.fromListResponseToBook(dto, false) }
 | 
			
		||||
            books?.let { data -> bookRepository.update(data) }
 | 
			
		||||
        }
 | 
			
		||||
        return true
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue