app: remove Room

Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>
This commit is contained in:
Harsh Shandilya 2020-12-08 16:19:49 +05:30
parent 042b8f60d5
commit f17becff10
No known key found for this signature in database
GPG key ID: 366D7BBAD1031E80
12 changed files with 2 additions and 627 deletions

View file

@ -13,9 +13,6 @@ android {
defaultConfig { defaultConfig {
applicationId = "dev.msfjarvis.lobsters" applicationId = "dev.msfjarvis.lobsters"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
javaCompileOptions.annotationProcessorOptions {
argument("room.schemaLocation", "${projectDir}/schemas")
}
} }
buildFeatures.compose = true buildFeatures.compose = true
@ -28,8 +25,6 @@ android {
dependencies { dependencies {
kapt(Dependencies.AndroidX.Hilt.daggerCompiler) kapt(Dependencies.AndroidX.Hilt.daggerCompiler)
kapt(Dependencies.AndroidX.Room.compiler)
kapt(Dependencies.ThirdParty.Roomigrant.compiler)
implementation(project(":model")) implementation(project(":model"))
implementation(Dependencies.AndroidX.appCompat) implementation(Dependencies.AndroidX.appCompat)
implementation(Dependencies.AndroidX.browser) implementation(Dependencies.AndroidX.browser)
@ -46,12 +41,9 @@ dependencies {
implementation(Dependencies.AndroidX.Hilt.dagger) implementation(Dependencies.AndroidX.Hilt.dagger)
implementation(Dependencies.AndroidX.Lifecycle.runtimeKtx) implementation(Dependencies.AndroidX.Lifecycle.runtimeKtx)
implementation(Dependencies.AndroidX.Lifecycle.viewmodelKtx) implementation(Dependencies.AndroidX.Lifecycle.viewmodelKtx)
implementation(Dependencies.AndroidX.Room.runtime)
implementation(Dependencies.AndroidX.Room.ktx)
implementation(Dependencies.Kotlin.Coroutines.android) implementation(Dependencies.Kotlin.Coroutines.android)
implementation(Dependencies.ThirdParty.accompanist) implementation(Dependencies.ThirdParty.accompanist)
implementation(Dependencies.ThirdParty.Moshi.lib) implementation(Dependencies.ThirdParty.Moshi.lib)
implementation(Dependencies.ThirdParty.Roomigrant.runtime)
testImplementation(Dependencies.Testing.junit) testImplementation(Dependencies.Testing.junit)
androidTestImplementation(Dependencies.Testing.daggerHilt) androidTestImplementation(Dependencies.Testing.daggerHilt)
androidTestImplementation(Dependencies.Testing.uiTest) androidTestImplementation(Dependencies.Testing.uiTest)

View file

@ -1,198 +0,0 @@
{
"formatVersion": 1,
"database": {
"version": 2,
"identityHash": "5146546ebef999689c82a1b89e667eb4",
"entities": [
{
"tableName": "lobsters_posts",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`shortId` TEXT NOT NULL, `shortIdUrl` TEXT NOT NULL, `createdAt` TEXT NOT NULL, `title` TEXT NOT NULL, `url` TEXT NOT NULL, `score` INTEGER NOT NULL, `flags` INTEGER NOT NULL, `commentCount` INTEGER NOT NULL, `description` TEXT NOT NULL, `commentsUrl` TEXT NOT NULL, `submitterUser` TEXT NOT NULL, `tags` TEXT NOT NULL, `isLiked` INTEGER NOT NULL, PRIMARY KEY(`shortId`))",
"fields": [
{
"fieldPath": "post.shortId",
"columnName": "shortId",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "post.shortIdUrl",
"columnName": "shortIdUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "post.createdAt",
"columnName": "createdAt",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "post.title",
"columnName": "title",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "post.url",
"columnName": "url",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "post.score",
"columnName": "score",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "post.flags",
"columnName": "flags",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "post.commentCount",
"columnName": "commentCount",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "post.description",
"columnName": "description",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "post.commentsUrl",
"columnName": "commentsUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "post.submitterUser",
"columnName": "submitterUser",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "post.tags",
"columnName": "tags",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "post.isLiked",
"columnName": "isLiked",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"shortId"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "lobsters_saved_posts",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`shortId` TEXT NOT NULL, `shortIdUrl` TEXT NOT NULL, `createdAt` TEXT NOT NULL, `title` TEXT NOT NULL, `url` TEXT NOT NULL, `score` INTEGER NOT NULL, `flags` INTEGER NOT NULL, `commentCount` INTEGER NOT NULL, `description` TEXT NOT NULL, `commentsUrl` TEXT NOT NULL, `submitterUser` TEXT NOT NULL, `tags` TEXT NOT NULL, `isLiked` INTEGER NOT NULL, PRIMARY KEY(`shortId`))",
"fields": [
{
"fieldPath": "post.shortId",
"columnName": "shortId",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "post.shortIdUrl",
"columnName": "shortIdUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "post.createdAt",
"columnName": "createdAt",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "post.title",
"columnName": "title",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "post.url",
"columnName": "url",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "post.score",
"columnName": "score",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "post.flags",
"columnName": "flags",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "post.commentCount",
"columnName": "commentCount",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "post.description",
"columnName": "description",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "post.commentsUrl",
"columnName": "commentsUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "post.submitterUser",
"columnName": "submitterUser",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "post.tags",
"columnName": "tags",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "post.isLiked",
"columnName": "isLiked",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"shortId"
],
"autoGenerate": false
},
"indices": [],
"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, '5146546ebef999689c82a1b89e667eb4')"
]
}
}

View file

@ -1,186 +0,0 @@
{
"formatVersion": 1,
"database": {
"version": 3,
"identityHash": "fb910a30af3f2c97fcd1f530c798e6e5",
"entities": [
{
"tableName": "lobsters_posts",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`shortId` TEXT NOT NULL, `shortIdUrl` TEXT NOT NULL, `createdAt` TEXT NOT NULL, `title` TEXT NOT NULL, `url` TEXT NOT NULL, `score` INTEGER NOT NULL, `flags` INTEGER NOT NULL, `commentCount` INTEGER NOT NULL, `description` TEXT NOT NULL, `commentsUrl` TEXT NOT NULL, `submitterUser` TEXT NOT NULL, `tags` TEXT NOT NULL, PRIMARY KEY(`shortId`))",
"fields": [
{
"fieldPath": "post.shortId",
"columnName": "shortId",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "post.shortIdUrl",
"columnName": "shortIdUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "post.createdAt",
"columnName": "createdAt",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "post.title",
"columnName": "title",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "post.url",
"columnName": "url",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "post.score",
"columnName": "score",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "post.flags",
"columnName": "flags",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "post.commentCount",
"columnName": "commentCount",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "post.description",
"columnName": "description",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "post.commentsUrl",
"columnName": "commentsUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "post.submitterUser",
"columnName": "submitterUser",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "post.tags",
"columnName": "tags",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"shortId"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "lobsters_saved_posts",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`shortId` TEXT NOT NULL, `shortIdUrl` TEXT NOT NULL, `createdAt` TEXT NOT NULL, `title` TEXT NOT NULL, `url` TEXT NOT NULL, `score` INTEGER NOT NULL, `flags` INTEGER NOT NULL, `commentCount` INTEGER NOT NULL, `description` TEXT NOT NULL, `commentsUrl` TEXT NOT NULL, `submitterUser` TEXT NOT NULL, `tags` TEXT NOT NULL, PRIMARY KEY(`shortId`))",
"fields": [
{
"fieldPath": "post.shortId",
"columnName": "shortId",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "post.shortIdUrl",
"columnName": "shortIdUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "post.createdAt",
"columnName": "createdAt",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "post.title",
"columnName": "title",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "post.url",
"columnName": "url",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "post.score",
"columnName": "score",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "post.flags",
"columnName": "flags",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "post.commentCount",
"columnName": "commentCount",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "post.description",
"columnName": "description",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "post.commentsUrl",
"columnName": "commentsUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "post.submitterUser",
"columnName": "submitterUser",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "post.tags",
"columnName": "tags",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"shortId"
],
"autoGenerate": false
},
"indices": [],
"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, 'fb910a30af3f2c97fcd1f530c798e6e5')"
]
}
}

View file

@ -1,14 +0,0 @@
package dev.msfjarvis.lobsters.data.model
import androidx.room.Embedded
import androidx.room.Entity
import dev.msfjarvis.lobsters.model.LobstersPost
@Entity(
tableName = "lobsters_posts",
primaryKeys = ["shortId"],
)
data class LobstersEntity(
@Embedded
val post: LobstersPost
)

View file

@ -1,14 +0,0 @@
package dev.msfjarvis.lobsters.data.model
import androidx.room.Embedded
import androidx.room.Entity
import dev.msfjarvis.lobsters.model.LobstersPost
@Entity(
tableName = "lobsters_saved_posts",
primaryKeys = ["shortId"],
)
data class SavedLobstersEntity(
@Embedded
val post: LobstersPost
)

View file

@ -1,36 +0,0 @@
package dev.msfjarvis.lobsters.data.source
import androidx.room.TypeConverter
import com.squareup.moshi.Moshi
import dev.msfjarvis.lobsters.model.Submitter
import dev.msfjarvis.lobsters.model.SubmitterJsonAdapter
object LobstersApiTypeConverters {
private const val SEPARATOR = ","
private val moshi = Moshi.Builder().build()
private val submitterAdapter = SubmitterJsonAdapter(moshi)
@TypeConverter
@JvmStatic
fun toSubmitterUser(value: String?): Submitter? {
return value?.let { submitterAdapter.fromJson(value) }
}
@TypeConverter
@JvmStatic
fun fromSubmitterUser(value: Submitter?): String? {
return submitterAdapter.toJson(value)
}
@TypeConverter
@JvmStatic
fun toTagList(value: String?): List<String>? {
return value?.split(SEPARATOR)
}
@TypeConverter
@JvmStatic
fun fromTagList(value: List<String>?): String? {
return value?.joinToString(SEPARATOR)
}
}

View file

@ -1,46 +0,0 @@
package dev.msfjarvis.lobsters.data.source
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Transaction
import androidx.room.Update
import dev.msfjarvis.lobsters.data.model.LobstersEntity
import dev.msfjarvis.lobsters.model.LobstersPost
import kotlinx.coroutines.flow.Flow
@Dao
abstract class PostsDao {
@Query("SELECT * FROM lobsters_posts")
abstract fun loadPosts(): Flow<List<LobstersPost>>
@Update
suspend fun updatePost(vararg posts: LobstersPost) {
updatePosts(posts.map { LobstersEntity(it) })
}
@Update(onConflict = OnConflictStrategy.IGNORE)
protected abstract suspend fun updatePosts(posts: List<LobstersEntity>)
@Transaction
open suspend fun insertPosts(vararg posts: LobstersPost) {
insertPosts(posts.map { LobstersEntity(it) })
}
@Insert(onConflict = OnConflictStrategy.IGNORE)
protected abstract suspend fun insertPosts(posts: List<LobstersEntity>)
@Transaction
open suspend fun deletePosts(vararg posts: LobstersPost) {
deletePosts(posts.map { LobstersEntity(it) })
}
@Delete
protected abstract suspend fun deletePosts(posts: List<LobstersEntity>)
@Query("DELETE FROM lobsters_posts")
abstract suspend fun deleteAllPosts()
}

View file

@ -1,25 +0,0 @@
package dev.msfjarvis.lobsters.data.source
import androidx.room.Database
import androidx.room.RoomDatabase
import androidx.room.TypeConverters
import dev.matrix.roomigrant.GenerateRoomMigrations
import dev.msfjarvis.lobsters.data.model.LobstersEntity
import dev.msfjarvis.lobsters.data.model.SavedLobstersEntity
@Database(
entities = [
LobstersEntity::class,
SavedLobstersEntity::class
],
version = 3,
exportSchema = true,
)
@TypeConverters(
LobstersApiTypeConverters::class,
)
@GenerateRoomMigrations
abstract class PostsDatabase : RoomDatabase() {
abstract fun postsDao(): PostsDao
abstract fun savedPostsDao(): SavedPostsDao
}

View file

@ -1,42 +0,0 @@
package dev.msfjarvis.lobsters.data.source
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Transaction
import dev.msfjarvis.lobsters.data.model.SavedLobstersEntity
import dev.msfjarvis.lobsters.model.LobstersPost
import kotlinx.coroutines.flow.Flow
@Dao
abstract class SavedPostsDao {
@Query("SELECT * FROM lobsters_saved_posts")
abstract fun loadPosts(): Flow<List<LobstersPost>>
@Transaction
open suspend fun insertPosts(vararg posts: LobstersPost) {
insertPosts(posts.map { SavedLobstersEntity(it) })
}
@Insert(onConflict = OnConflictStrategy.IGNORE)
protected abstract suspend fun insertPosts(posts: List<SavedLobstersEntity>)
@Transaction
open suspend fun deletePosts(vararg posts: LobstersPost) {
deletePosts(posts.map { SavedLobstersEntity(it) })
}
@Delete
protected abstract suspend fun deletePosts(posts: List<SavedLobstersEntity>)
@Query("DELETE FROM lobsters_saved_posts")
abstract suspend fun deleteAllPosts()
@Query("DELETE FROM lobsters_saved_posts WHERE shortId LIKE :shortId")
abstract suspend fun deletePostById(shortId: String)
@Query("SELECT EXISTS(SELECT 1 FROM lobsters_saved_posts WHERE shortId LIKE :shortId)")
abstract suspend fun isLiked(shortId: String): Boolean
}

View file

@ -1,23 +0,0 @@
package dev.msfjarvis.lobsters.injection
import android.content.Context
import androidx.room.Room
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.components.ViewModelComponent
import dagger.hilt.android.qualifiers.ApplicationContext
import dev.msfjarvis.lobsters.data.source.PostsDatabase
import dev.msfjarvis.lobsters.data.source.PostsDatabase_Migrations
@Module
@InstallIn(ViewModelComponent::class)
object PersistenceModule {
@Provides
fun providePostsDatabase(@ApplicationContext context: Context): PostsDatabase {
return Room.databaseBuilder(context, PostsDatabase::class.java, "posts.db")
.addMigrations(*PostsDatabase_Migrations.build())
.build()
}
}

View file

@ -6,47 +6,29 @@ import androidx.paging.Pager
import androidx.paging.PagingConfig import androidx.paging.PagingConfig
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
import dev.msfjarvis.lobsters.data.remote.LobstersPagingSource import dev.msfjarvis.lobsters.data.remote.LobstersPagingSource
import dev.msfjarvis.lobsters.data.source.PostsDatabase
import dev.msfjarvis.lobsters.model.LobstersPost import dev.msfjarvis.lobsters.model.LobstersPost
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import javax.inject.Inject import javax.inject.Inject
@HiltViewModel @HiltViewModel
class LobstersViewModel @Inject constructor( class LobstersViewModel @Inject constructor(
private val pagingSource: LobstersPagingSource, private val pagingSource: LobstersPagingSource,
database: PostsDatabase,
) : ViewModel() { ) : ViewModel() {
private val _savedPosts = MutableStateFlow<List<LobstersPost>>(emptyList()) private val _savedPosts = MutableStateFlow<List<LobstersPost>>(emptyList())
private val savedPostsDao = database.savedPostsDao() val savedPosts = _savedPosts.asStateFlow()
val savedPosts: StateFlow<List<LobstersPost>> get() = _savedPosts
val posts = Pager(PagingConfig(25)) { val posts = Pager(PagingConfig(25)) {
pagingSource pagingSource
}.flow }.flow
init {
getSavedPosts()
}
private fun getSavedPosts() {
viewModelScope.launch {
savedPostsDao.loadPosts().collectLatest { _savedPosts.value = it }
}
}
fun savePost(post: LobstersPost) { fun savePost(post: LobstersPost) {
viewModelScope.launch { viewModelScope.launch {
savedPostsDao.insertPosts(post)
getSavedPosts()
} }
} }
fun removeSavedPost(post: LobstersPost) { fun removeSavedPost(post: LobstersPost) {
viewModelScope.launch { viewModelScope.launch {
savedPostsDao.deletePostById(post.shortId)
getSavedPosts()
} }
} }
} }

View file

@ -49,14 +49,6 @@ object Dependencies {
const val runtimeKtx = "androidx.lifecycle:lifecycle-runtime-ktx:$version" const val runtimeKtx = "androidx.lifecycle:lifecycle-runtime-ktx:$version"
const val viewmodelKtx = "androidx.lifecycle:lifecycle-viewmodel-ktx:$version" const val viewmodelKtx = "androidx.lifecycle:lifecycle-viewmodel-ktx:$version"
} }
object Room {
private const val version = "2.3.0-beta01"
const val compiler = "androidx.room:room-compiler:$version"
const val ktx = "androidx.room:room-ktx:$version"
const val runtime = "androidx.room:room-runtime:$version"
}
} }
object ThirdParty { object ThirdParty {
@ -77,13 +69,6 @@ object Dependencies {
const val moshi = "com.squareup.retrofit2:converter-moshi:$version" const val moshi = "com.squareup.retrofit2:converter-moshi:$version"
} }
object Roomigrant {
private const val version = "0.2.0"
const val compiler = "com.github.MatrixDev.Roomigrant:RoomigrantCompiler:$version"
const val runtime = "com.github.MatrixDev.Roomigrant:RoomigrantLib:$version"
}
object SQLDelight { object SQLDelight {
private const val version = "1.4.4" private const val version = "1.4.4"