all: inject room dbs
Inject room databases instead of lazily creating them. This should make repositories much easier to test.
This commit is contained in:
parent
dd2017c510
commit
e017d53139
7 changed files with 49 additions and 86 deletions
|
|
@ -17,14 +17,12 @@
|
||||||
|
|
||||||
package org.oxycblt.auxio.music.cache
|
package org.oxycblt.auxio.music.cache
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import androidx.room.Dao
|
import androidx.room.Dao
|
||||||
import androidx.room.Database
|
import androidx.room.Database
|
||||||
import androidx.room.Entity
|
import androidx.room.Entity
|
||||||
import androidx.room.Insert
|
import androidx.room.Insert
|
||||||
import androidx.room.PrimaryKey
|
import androidx.room.PrimaryKey
|
||||||
import androidx.room.Query
|
import androidx.room.Query
|
||||||
import androidx.room.Room
|
|
||||||
import androidx.room.RoomDatabase
|
import androidx.room.RoomDatabase
|
||||||
import androidx.room.TypeConverter
|
import androidx.room.TypeConverter
|
||||||
import androidx.room.TypeConverters
|
import androidx.room.TypeConverters
|
||||||
|
|
@ -36,35 +34,6 @@ import org.oxycblt.auxio.music.model.RawSong
|
||||||
@Database(entities = [CachedSong::class], version = 27, exportSchema = false)
|
@Database(entities = [CachedSong::class], version = 27, exportSchema = false)
|
||||||
abstract class CacheDatabase : RoomDatabase() {
|
abstract class CacheDatabase : RoomDatabase() {
|
||||||
abstract fun cachedSongsDao(): CachedSongsDao
|
abstract fun cachedSongsDao(): CachedSongsDao
|
||||||
|
|
||||||
companion object {
|
|
||||||
@Volatile private var INSTANCE: CacheDatabase? = null
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get/create the shared instance of this database.
|
|
||||||
* @param context [Context] required.
|
|
||||||
*/
|
|
||||||
fun getInstance(context: Context): CacheDatabase {
|
|
||||||
val instance = INSTANCE
|
|
||||||
if (instance != null) {
|
|
||||||
return instance
|
|
||||||
}
|
|
||||||
|
|
||||||
synchronized(this) {
|
|
||||||
val newInstance =
|
|
||||||
Room.databaseBuilder(
|
|
||||||
context.applicationContext,
|
|
||||||
CacheDatabase::class.java,
|
|
||||||
"auxio_tag_cache.db")
|
|
||||||
.fallbackToDestructiveMigration()
|
|
||||||
.fallbackToDestructiveMigrationFrom(0)
|
|
||||||
.fallbackToDestructiveMigrationOnDowngrade()
|
|
||||||
.build()
|
|
||||||
INSTANCE = newInstance
|
|
||||||
return newInstance
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
|
|
|
||||||
|
|
@ -17,10 +17,15 @@
|
||||||
|
|
||||||
package org.oxycblt.auxio.music.cache
|
package org.oxycblt.auxio.music.cache
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.room.Room
|
||||||
import dagger.Binds
|
import dagger.Binds
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
|
import dagger.Provides
|
||||||
import dagger.hilt.InstallIn
|
import dagger.hilt.InstallIn
|
||||||
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
import dagger.hilt.components.SingletonComponent
|
import dagger.hilt.components.SingletonComponent
|
||||||
|
import javax.inject.Singleton
|
||||||
import org.oxycblt.auxio.music.extractor.CacheRepository
|
import org.oxycblt.auxio.music.extractor.CacheRepository
|
||||||
import org.oxycblt.auxio.music.extractor.CacheRepositoryImpl
|
import org.oxycblt.auxio.music.extractor.CacheRepositoryImpl
|
||||||
|
|
||||||
|
|
@ -29,3 +34,19 @@ import org.oxycblt.auxio.music.extractor.CacheRepositoryImpl
|
||||||
interface CacheModule {
|
interface CacheModule {
|
||||||
@Binds fun cacheRepository(cacheRepository: CacheRepositoryImpl): CacheRepository
|
@Binds fun cacheRepository(cacheRepository: CacheRepositoryImpl): CacheRepository
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Module
|
||||||
|
@InstallIn(SingletonComponent::class)
|
||||||
|
class CacheRoomModule {
|
||||||
|
@Singleton
|
||||||
|
@Provides
|
||||||
|
fun database(@ApplicationContext context: Context) =
|
||||||
|
Room.databaseBuilder(
|
||||||
|
context.applicationContext, CacheDatabase::class.java, "music_cache.db")
|
||||||
|
.fallbackToDestructiveMigration()
|
||||||
|
.fallbackToDestructiveMigrationFrom(0)
|
||||||
|
.fallbackToDestructiveMigrationOnDowngrade()
|
||||||
|
.build()
|
||||||
|
|
||||||
|
@Provides fun cachedSongsDao(database: CacheDatabase) = database.cachedSongsDao()
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,10 +17,7 @@
|
||||||
|
|
||||||
package org.oxycblt.auxio.music.extractor
|
package org.oxycblt.auxio.music.extractor
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import org.oxycblt.auxio.music.cache.CacheDatabase
|
|
||||||
import org.oxycblt.auxio.music.cache.CachedSong
|
import org.oxycblt.auxio.music.cache.CachedSong
|
||||||
import org.oxycblt.auxio.music.cache.CachedSongsDao
|
import org.oxycblt.auxio.music.cache.CachedSongsDao
|
||||||
import org.oxycblt.auxio.music.model.RawSong
|
import org.oxycblt.auxio.music.model.RawSong
|
||||||
|
|
@ -44,12 +41,8 @@ interface CacheRepository {
|
||||||
suspend fun writeCache(rawSongs: List<RawSong>)
|
suspend fun writeCache(rawSongs: List<RawSong>)
|
||||||
}
|
}
|
||||||
|
|
||||||
class CacheRepositoryImpl @Inject constructor(@ApplicationContext private val context: Context) :
|
class CacheRepositoryImpl @Inject constructor(private val cachedSongsDao: CachedSongsDao) :
|
||||||
CacheRepository {
|
CacheRepository {
|
||||||
private val cachedSongsDao: CachedSongsDao by lazy {
|
|
||||||
CacheDatabase.getInstance(context).cachedSongsDao()
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun readCache(): Cache? =
|
override suspend fun readCache(): Cache? =
|
||||||
try {
|
try {
|
||||||
// Faster to load the whole database into memory than do a query on each
|
// Faster to load the whole database into memory than do a query on each
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@
|
||||||
|
|
||||||
package org.oxycblt.auxio.playback.persist
|
package org.oxycblt.auxio.playback.persist
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import androidx.room.Dao
|
import androidx.room.Dao
|
||||||
import androidx.room.Database
|
import androidx.room.Database
|
||||||
import androidx.room.Entity
|
import androidx.room.Entity
|
||||||
|
|
@ -25,7 +24,6 @@ import androidx.room.Insert
|
||||||
import androidx.room.OnConflictStrategy
|
import androidx.room.OnConflictStrategy
|
||||||
import androidx.room.PrimaryKey
|
import androidx.room.PrimaryKey
|
||||||
import androidx.room.Query
|
import androidx.room.Query
|
||||||
import androidx.room.Room
|
|
||||||
import androidx.room.RoomDatabase
|
import androidx.room.RoomDatabase
|
||||||
import androidx.room.TypeConverter
|
import androidx.room.TypeConverter
|
||||||
import androidx.room.TypeConverters
|
import androidx.room.TypeConverters
|
||||||
|
|
@ -61,35 +59,6 @@ abstract class PersistenceDatabase : RoomDatabase() {
|
||||||
/** @see [Music.UID.fromString] */
|
/** @see [Music.UID.fromString] */
|
||||||
@TypeConverter fun toMusicUid(string: String?) = string?.let(Music.UID::fromString)
|
@TypeConverter fun toMusicUid(string: String?) = string?.let(Music.UID::fromString)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
|
||||||
@Volatile private var INSTANCE: PersistenceDatabase? = null
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get/create the shared instance of this database.
|
|
||||||
* @param context [Context] required.
|
|
||||||
*/
|
|
||||||
fun getInstance(context: Context): PersistenceDatabase {
|
|
||||||
val instance = INSTANCE
|
|
||||||
if (instance != null) {
|
|
||||||
return instance
|
|
||||||
}
|
|
||||||
|
|
||||||
synchronized(this) {
|
|
||||||
val newInstance =
|
|
||||||
Room.databaseBuilder(
|
|
||||||
context.applicationContext,
|
|
||||||
PersistenceDatabase::class.java,
|
|
||||||
"auxio_playback_persistence.db")
|
|
||||||
.fallbackToDestructiveMigration()
|
|
||||||
.fallbackToDestructiveMigrationFrom(1)
|
|
||||||
.fallbackToDestructiveMigrationOnDowngrade()
|
|
||||||
.build()
|
|
||||||
INSTANCE = newInstance
|
|
||||||
return newInstance
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -17,13 +17,38 @@
|
||||||
|
|
||||||
package org.oxycblt.auxio.playback.persist
|
package org.oxycblt.auxio.playback.persist
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.room.Room
|
||||||
import dagger.Binds
|
import dagger.Binds
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
|
import dagger.Provides
|
||||||
import dagger.hilt.InstallIn
|
import dagger.hilt.InstallIn
|
||||||
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
import dagger.hilt.components.SingletonComponent
|
import dagger.hilt.components.SingletonComponent
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@Module
|
@Module
|
||||||
@InstallIn(SingletonComponent::class)
|
@InstallIn(SingletonComponent::class)
|
||||||
interface PersistenceModule {
|
interface PersistenceModule {
|
||||||
@Binds fun repository(persistenceRepository: PersistenceRepositoryImpl): PersistenceRepository
|
@Binds fun repository(persistenceRepository: PersistenceRepositoryImpl): PersistenceRepository
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Module
|
||||||
|
@InstallIn(SingletonComponent::class)
|
||||||
|
class PersistenceRoomModule {
|
||||||
|
@Singleton
|
||||||
|
@Provides
|
||||||
|
fun database(@ApplicationContext context: Context) =
|
||||||
|
Room.databaseBuilder(
|
||||||
|
context.applicationContext,
|
||||||
|
PersistenceDatabase::class.java,
|
||||||
|
"playback_persistence.db")
|
||||||
|
.fallbackToDestructiveMigration()
|
||||||
|
.fallbackToDestructiveMigrationFrom(1)
|
||||||
|
.fallbackToDestructiveMigrationOnDowngrade()
|
||||||
|
.build()
|
||||||
|
|
||||||
|
@Provides fun playbackStateDao(database: PersistenceDatabase) = database.playbackStateDao()
|
||||||
|
|
||||||
|
@Provides fun queueDao(database: PersistenceDatabase) = database.queueDao()
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,6 @@
|
||||||
|
|
||||||
package org.oxycblt.auxio.playback.persist
|
package org.oxycblt.auxio.playback.persist
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import org.oxycblt.auxio.music.MusicParent
|
import org.oxycblt.auxio.music.MusicParent
|
||||||
import org.oxycblt.auxio.music.model.Library
|
import org.oxycblt.auxio.music.model.Library
|
||||||
|
|
@ -43,22 +41,12 @@ interface PersistenceRepository {
|
||||||
* @param state The [PlaybackStateManager.SavedState] to persist.
|
* @param state The [PlaybackStateManager.SavedState] to persist.
|
||||||
*/
|
*/
|
||||||
suspend fun saveState(state: PlaybackStateManager.SavedState?): Boolean
|
suspend fun saveState(state: PlaybackStateManager.SavedState?): Boolean
|
||||||
|
|
||||||
companion object {
|
|
||||||
/**
|
|
||||||
* Get a framework-backed implementation.
|
|
||||||
* @param context [Context] required.
|
|
||||||
*/
|
|
||||||
fun from(context: Context): PersistenceRepository = PersistenceRepositoryImpl(context)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class PersistenceRepositoryImpl
|
class PersistenceRepositoryImpl
|
||||||
@Inject
|
@Inject
|
||||||
constructor(@ApplicationContext private val context: Context) : PersistenceRepository {
|
constructor(private val playbackStateDao: PlaybackStateDao, private val queueDao: QueueDao) :
|
||||||
private val database: PersistenceDatabase by lazy { PersistenceDatabase.getInstance(context) }
|
PersistenceRepository {
|
||||||
private val playbackStateDao: PlaybackStateDao by lazy { database.playbackStateDao() }
|
|
||||||
private val queueDao: QueueDao by lazy { database.queueDao() }
|
|
||||||
|
|
||||||
override suspend fun readState(library: Library): PlaybackStateManager.SavedState? {
|
override suspend fun readState(library: Library): PlaybackStateManager.SavedState? {
|
||||||
val playbackState: PlaybackState
|
val playbackState: PlaybackState
|
||||||
|
|
|
||||||
|
|
@ -146,8 +146,6 @@ class PlaybackService :
|
||||||
.build()
|
.build()
|
||||||
.also { it.addListener(this) }
|
.also { it.addListener(this) }
|
||||||
replayGainProcessor.addToListeners(player)
|
replayGainProcessor.addToListeners(player)
|
||||||
// Initialize the core service components
|
|
||||||
persistenceRepository = PersistenceRepository.from(this)
|
|
||||||
foregroundManager = ForegroundManager(this)
|
foregroundManager = ForegroundManager(this)
|
||||||
// Initialize any listener-dependent components last as we wouldn't want a listener race
|
// Initialize any listener-dependent components last as we wouldn't want a listener race
|
||||||
// condition to cause us to load music before we were fully initialize.
|
// condition to cause us to load music before we were fully initialize.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue