Add room database.
This commit is contained in:
parent
2ad8d5953a
commit
6a0710572a
17 changed files with 362 additions and 4 deletions
|
|
@ -1,6 +1,7 @@
|
|||
plugins {
|
||||
id 'com.android.application'
|
||||
id 'kotlin-android'
|
||||
id 'kotlin-kapt'
|
||||
id 'org.jetbrains.kotlin.android'
|
||||
}
|
||||
|
||||
|
|
@ -102,6 +103,14 @@ dependencies {
|
|||
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
|
||||
implementation 'com.google.code.gson:gson:2.8.6'
|
||||
|
||||
// Room
|
||||
implementation "androidx.room:room-runtime:2.3.0"
|
||||
implementation "androidx.room:room-ktx:2.3.0"
|
||||
kapt "androidx.room:room-compiler:2.3.0"
|
||||
|
||||
// Paging
|
||||
implementation "androidx.paging:paging-runtime-ktx:3.0.0"
|
||||
|
||||
// Test
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
androidTestImplementation "androidx.compose.ui:ui-test-junit4:1.0.0-beta06"
|
||||
|
|
|
|||
|
|
@ -3,8 +3,10 @@ package com.pixelized.biblib
|
|||
import android.app.Application
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import androidx.room.Room
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.GsonBuilder
|
||||
import com.pixelized.biblib.database.BibLibDatabase
|
||||
import com.pixelized.biblib.network.client.BibLibClient
|
||||
import com.pixelized.biblib.network.client.IBibLibClient
|
||||
import com.pixelized.biblib.repository.apiCache.APICacheRepository
|
||||
|
|
@ -21,18 +23,23 @@ class BibLibApplication : Application() {
|
|||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
|
||||
// Android.
|
||||
Bob[BibLibDatabase::class] =
|
||||
Room.databaseBuilder(this, BibLibDatabase::class.java, BibLibDatabase.DATABASE_NAME)
|
||||
.build()
|
||||
Bob[SharedPreferences::class] = getSharedPreferences(SHARED_PREF, Context.MODE_PRIVATE)
|
||||
// Web service.
|
||||
Bob[Gson::class] = GsonBuilder().create()
|
||||
Bob[BitmapCache::class] = BitmapCache(this)
|
||||
|
||||
Bob[IBibLibClient::class] = BibLibClient()
|
||||
|
||||
// Bitmap cache.
|
||||
Bob[BitmapCache::class] = BitmapCache(this)
|
||||
// Repositories.
|
||||
Bob[IGoogleSingInRepository::class] = GoogleSingInRepository(this)
|
||||
Bob[ICredentialRepository::class] = CredentialRepository()
|
||||
Bob[IAPICacheRepository::class] = APICacheRepository()
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val SHARED_PREF = "BIB_LIB_SHARED_PREF"
|
||||
private const val SHARED_PREF = "BIB_LIB_SHARED_PREF"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
package com.pixelized.biblib.database
|
||||
|
||||
import androidx.room.Database
|
||||
import androidx.room.RoomDatabase
|
||||
import androidx.room.TypeConverters
|
||||
import com.pixelized.biblib.database.converter.DateConverter
|
||||
import com.pixelized.biblib.database.crossref.BookAuthorCrossRef
|
||||
import com.pixelized.biblib.database.crossref.BookGenreCrossRef
|
||||
import com.pixelized.biblib.database.dao.*
|
||||
import com.pixelized.biblib.database.data.*
|
||||
|
||||
@Database(
|
||||
entities = [
|
||||
AuthorDbo::class,
|
||||
BookDbo::class,
|
||||
GenreDbo::class,
|
||||
LanguageDbo::class,
|
||||
SeriesDbo::class,
|
||||
BookAuthorCrossRef::class,
|
||||
BookGenreCrossRef::class,
|
||||
],
|
||||
version = BibLibDatabase.VERSION
|
||||
)
|
||||
@TypeConverters(DateConverter::class)
|
||||
abstract class BibLibDatabase : RoomDatabase() {
|
||||
|
||||
abstract fun authorDao(): AuthorDao
|
||||
abstract fun bookDao(): BookDao
|
||||
abstract fun genreDao(): GenreDao
|
||||
abstract fun languageDao(): LanguageDao
|
||||
abstract fun seriesDao(): SeriesDao
|
||||
|
||||
companion object {
|
||||
const val VERSION = 1
|
||||
const val DATABASE_NAME = "BibLibDataBase"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package com.pixelized.biblib.database.converter
|
||||
|
||||
import androidx.room.TypeConverter
|
||||
import java.util.*
|
||||
|
||||
class DateConverter {
|
||||
@TypeConverter
|
||||
fun fromTimestamp(value: Long?): Date? = value?.let { Date(it) }
|
||||
|
||||
@TypeConverter
|
||||
fun dateToTimestamp(date: Date?): Long? = date?.time
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package com.pixelized.biblib.database.crossref
|
||||
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import com.pixelized.biblib.database.data.AuthorDbo
|
||||
import com.pixelized.biblib.database.data.BookDbo
|
||||
|
||||
@Entity(primaryKeys = [BookDbo.ID, AuthorDbo.ID])
|
||||
data class BookAuthorCrossRef(
|
||||
@ColumnInfo(name = BookDbo.ID)
|
||||
val bookId: String,
|
||||
@ColumnInfo(name = AuthorDbo.ID)
|
||||
val authorId: String
|
||||
)
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package com.pixelized.biblib.database.crossref
|
||||
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import com.pixelized.biblib.database.data.BookDbo
|
||||
import com.pixelized.biblib.database.data.GenreDbo
|
||||
|
||||
@Entity(primaryKeys = [BookDbo.ID, GenreDbo.ID])
|
||||
data class BookGenreCrossRef(
|
||||
@ColumnInfo(name = BookDbo.ID)
|
||||
val bookId: String,
|
||||
@ColumnInfo(name = GenreDbo.ID)
|
||||
val genreId: String
|
||||
)
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package com.pixelized.biblib.database.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import com.pixelized.biblib.database.data.AuthorDbo
|
||||
|
||||
@Dao
|
||||
interface AuthorDao {
|
||||
@Query("SELECT * FROM ${AuthorDbo.TABLE} WHERE ${AuthorDbo.ID} LIKE :id")
|
||||
fun get(id: String?): AuthorDbo?
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
fun insert(vararg authors: AuthorDbo)
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package com.pixelized.biblib.database.dao
|
||||
|
||||
import androidx.room.*
|
||||
import com.pixelized.biblib.database.data.BookDbo
|
||||
import com.pixelized.biblib.database.relation.BookRelation
|
||||
|
||||
@Dao
|
||||
interface BookDao {
|
||||
@Transaction
|
||||
@Query("SELECT * FROM ${BookDbo.TABLE}")
|
||||
fun getAll(): List<BookRelation>
|
||||
|
||||
@Insert
|
||||
fun update(vararg books: BookDbo)
|
||||
|
||||
@Delete
|
||||
fun delete(book: BookDbo)
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package com.pixelized.biblib.database.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import com.pixelized.biblib.database.data.GenreDbo
|
||||
|
||||
@Dao
|
||||
interface GenreDao {
|
||||
@Query("SELECT * FROM ${GenreDbo.TABLE} WHERE ${GenreDbo.ID} LIKE :id")
|
||||
fun get(id: String?): GenreDbo?
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
fun insert(vararg genres: GenreDbo)
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package com.pixelized.biblib.database.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import com.pixelized.biblib.database.data.LanguageDbo
|
||||
|
||||
@Dao
|
||||
interface LanguageDao {
|
||||
@Query("SELECT * FROM ${LanguageDbo.TABLE} WHERE ${LanguageDbo.ID} LIKE :id")
|
||||
fun get(id: String?): LanguageDbo?
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
fun insert(vararg languages: LanguageDbo)
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package com.pixelized.biblib.database.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import com.pixelized.biblib.database.data.SeriesDbo
|
||||
|
||||
@Dao
|
||||
interface SeriesDao {
|
||||
@Query("SELECT * FROM ${SeriesDbo.TABLE} WHERE ${SeriesDbo.ID} LIKE :id")
|
||||
fun get(id: String?): SeriesDbo?
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
fun insert(vararg series: SeriesDbo)
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package com.pixelized.biblib.database.data
|
||||
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
|
||||
@Entity(tableName = AuthorDbo.TABLE)
|
||||
data class AuthorDbo(
|
||||
@PrimaryKey
|
||||
@ColumnInfo(name = ID)
|
||||
val id: String,
|
||||
@ColumnInfo(name = NAME)
|
||||
val name: String,
|
||||
@ColumnInfo(name = SORT)
|
||||
val sort: String,
|
||||
) {
|
||||
companion object {
|
||||
const val TABLE = "AUTHOR"
|
||||
const val ID = "${TABLE}_ID"
|
||||
const val NAME = "${TABLE}_NAME"
|
||||
const val SORT = "${TABLE}_SORT"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
package com.pixelized.biblib.database.data
|
||||
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
import java.util.*
|
||||
|
||||
@Entity(tableName = BookDbo.TABLE)
|
||||
data class BookDbo(
|
||||
@PrimaryKey
|
||||
@ColumnInfo(name = ID)
|
||||
val id: Int,
|
||||
@ColumnInfo(name = TITLE)
|
||||
val title: String,
|
||||
@ColumnInfo(name = SORT)
|
||||
val sort: String,
|
||||
@ColumnInfo(name = HAVE_COVER)
|
||||
val haveCover: Boolean,
|
||||
@ColumnInfo(name = RELEASE_DATE)
|
||||
val releaseDate: Date,
|
||||
@ColumnInfo(name = LANGUAGE_ID)
|
||||
val language: String? = null, // one-to-many
|
||||
@ColumnInfo(name = RATING)
|
||||
val rating: Int? = null,
|
||||
// details
|
||||
@ColumnInfo(name = SERIES_ID)
|
||||
val series: String? = null, // one-to-many
|
||||
@ColumnInfo(name = SYNOPSIS)
|
||||
val synopsis: String? = null,
|
||||
// source
|
||||
@ColumnInfo(name = IS_NEW)
|
||||
val isNew: Boolean = false,
|
||||
) {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other !is BookDbo) return false
|
||||
if (id != other.id) return false
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return id
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val TABLE = "BOOK"
|
||||
const val ID = "${TABLE}_ID"
|
||||
const val TITLE = "${TABLE}_TITLE"
|
||||
const val SORT = "${TABLE}_SORT"
|
||||
const val HAVE_COVER = "${TABLE}_HAVE_COVER"
|
||||
const val RELEASE_DATE = "${TABLE}_RELEASE_DATE"
|
||||
const val LANGUAGE_ID = "${TABLE}_LANGUAGE_ID"
|
||||
const val RATING = "${TABLE}_RATING"
|
||||
const val SERIES_ID = "${TABLE}_SERIES_ID"
|
||||
const val SYNOPSIS = "${TABLE}_SYNOPSIS"
|
||||
const val IS_NEW = "${TABLE}_ISNEW"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package com.pixelized.biblib.database.data
|
||||
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
|
||||
@Entity(tableName = GenreDbo.TABLE)
|
||||
data class GenreDbo(
|
||||
@PrimaryKey
|
||||
@ColumnInfo(name = ID)
|
||||
val id: String,
|
||||
@ColumnInfo(name = NAME)
|
||||
val name: String,
|
||||
) {
|
||||
companion object {
|
||||
const val TABLE = "GENRE"
|
||||
const val ID = "${TABLE}_ID"
|
||||
const val NAME = "${TABLE}_NAME"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package com.pixelized.biblib.database.data
|
||||
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
|
||||
@Entity(tableName = LanguageDbo.TABLE)
|
||||
data class LanguageDbo(
|
||||
@PrimaryKey
|
||||
@ColumnInfo(name = ID)
|
||||
val id: String,
|
||||
@ColumnInfo(name = NAME)
|
||||
val code: String,
|
||||
) {
|
||||
companion object {
|
||||
const val TABLE = "LANGUAGE"
|
||||
const val ID = "${TABLE}_ID"
|
||||
const val NAME = "${TABLE}_NAME"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
package com.pixelized.biblib.database.data
|
||||
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
|
||||
@Entity(tableName = SeriesDbo.TABLE)
|
||||
data class SeriesDbo(
|
||||
@PrimaryKey
|
||||
@ColumnInfo(name = ID)
|
||||
val id: String,
|
||||
@ColumnInfo(name = NAME)
|
||||
val name: String,
|
||||
@ColumnInfo(name = SORT)
|
||||
val sort: String,
|
||||
@ColumnInfo(name = INDEX)
|
||||
val index: Int?,
|
||||
) {
|
||||
companion object {
|
||||
const val TABLE = "SERIES"
|
||||
const val ID = "${TABLE}_ID"
|
||||
const val NAME = "${TABLE}_NAME"
|
||||
const val SORT = "${TABLE}_SORT"
|
||||
const val INDEX = "${TABLE}_INDEX"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
package com.pixelized.biblib.database.relation
|
||||
|
||||
import androidx.room.Embedded
|
||||
import androidx.room.Junction
|
||||
import androidx.room.Relation
|
||||
import com.pixelized.biblib.database.crossref.BookAuthorCrossRef
|
||||
import com.pixelized.biblib.database.crossref.BookGenreCrossRef
|
||||
import com.pixelized.biblib.database.data.*
|
||||
|
||||
data class BookRelation(
|
||||
@Embedded
|
||||
val bookDbo: BookDbo,
|
||||
@Relation(
|
||||
parentColumn = BookDbo.ID,
|
||||
entityColumn = AuthorDbo.ID,
|
||||
associateBy = Junction(BookAuthorCrossRef::class)
|
||||
)
|
||||
val authors: List<AuthorDbo>,
|
||||
@Relation(
|
||||
parentColumn = BookDbo.ID,
|
||||
entityColumn = GenreDbo.ID,
|
||||
associateBy = Junction(BookGenreCrossRef::class)
|
||||
)
|
||||
val genres: List<GenreDbo>,
|
||||
@Relation(
|
||||
parentColumn = BookDbo.LANGUAGE_ID,
|
||||
entityColumn = LanguageDbo.ID
|
||||
)
|
||||
val language: LanguageDbo,
|
||||
@Relation(
|
||||
parentColumn = BookDbo.SERIES_ID,
|
||||
entityColumn = SeriesDbo.ID
|
||||
)
|
||||
val series: SeriesDbo,
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue