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 {
|
plugins {
|
||||||
id 'com.android.application'
|
id 'com.android.application'
|
||||||
id 'kotlin-android'
|
id 'kotlin-android'
|
||||||
|
id 'kotlin-kapt'
|
||||||
id 'org.jetbrains.kotlin.android'
|
id 'org.jetbrains.kotlin.android'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -102,6 +103,14 @@ dependencies {
|
||||||
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
|
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
|
||||||
implementation 'com.google.code.gson:gson:2.8.6'
|
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
|
// Test
|
||||||
testImplementation 'junit:junit:4.13.2'
|
testImplementation 'junit:junit:4.13.2'
|
||||||
androidTestImplementation "androidx.compose.ui:ui-test-junit4:1.0.0-beta06"
|
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.app.Application
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
|
import androidx.room.Room
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import com.google.gson.GsonBuilder
|
import com.google.gson.GsonBuilder
|
||||||
|
import com.pixelized.biblib.database.BibLibDatabase
|
||||||
import com.pixelized.biblib.network.client.BibLibClient
|
import com.pixelized.biblib.network.client.BibLibClient
|
||||||
import com.pixelized.biblib.network.client.IBibLibClient
|
import com.pixelized.biblib.network.client.IBibLibClient
|
||||||
import com.pixelized.biblib.repository.apiCache.APICacheRepository
|
import com.pixelized.biblib.repository.apiCache.APICacheRepository
|
||||||
|
|
@ -21,18 +23,23 @@ class BibLibApplication : Application() {
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.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)
|
Bob[SharedPreferences::class] = getSharedPreferences(SHARED_PREF, Context.MODE_PRIVATE)
|
||||||
|
// Web service.
|
||||||
Bob[Gson::class] = GsonBuilder().create()
|
Bob[Gson::class] = GsonBuilder().create()
|
||||||
Bob[BitmapCache::class] = BitmapCache(this)
|
|
||||||
|
|
||||||
Bob[IBibLibClient::class] = BibLibClient()
|
Bob[IBibLibClient::class] = BibLibClient()
|
||||||
|
// Bitmap cache.
|
||||||
|
Bob[BitmapCache::class] = BitmapCache(this)
|
||||||
|
// Repositories.
|
||||||
Bob[IGoogleSingInRepository::class] = GoogleSingInRepository(this)
|
Bob[IGoogleSingInRepository::class] = GoogleSingInRepository(this)
|
||||||
Bob[ICredentialRepository::class] = CredentialRepository()
|
Bob[ICredentialRepository::class] = CredentialRepository()
|
||||||
Bob[IAPICacheRepository::class] = APICacheRepository()
|
Bob[IAPICacheRepository::class] = APICacheRepository()
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
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