Skip to content

Make DatabaseManager a Koin singleton #42

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class DatabaseIntegrationTests {
try {
//arrange database
context = ApplicationProvider.getApplicationContext()
databaseManager = DatabaseManager.getInstance(context)
databaseManager = DatabaseManager(context)

//arrange test users
user1 = User(
Expand All @@ -84,16 +84,15 @@ class DatabaseIntegrationTests {
val isAuth = authenticationService.authenticatedUser(user1.username, user1.password)

//arrange repositories
auditRepository = AuditRepositoryDb(context, authenticationService)
stockItemRepository = StockItemRepositoryDb(context)
warehouseRepository = WarehouseRepositoryDb(context)
userProfileRepository = UserProfileRepository(context)
auditRepository = AuditRepositoryDb(authenticationService, databaseManager)
stockItemRepository = StockItemRepositoryDb(databaseManager)
warehouseRepository = WarehouseRepositoryDb(databaseManager)
userProfileRepository = UserProfileRepository(databaseManager)
projectRepository = ProjectRepositoryDb(
context = context,
authenticationService = authenticationService,
auditRepository = auditRepository,
warehouseRepository = warehouseRepository,
stockItemRepository = stockItemRepository
stockItemRepository = stockItemRepository,
databaseManager = databaseManager
)

//load sample data
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
package com.couchbase.learningpath

import android.app.Application
import com.couchbase.learningpath.data.DatabaseManager
import org.koin.android.BuildConfig
import org.koin.android.ext.koin.androidContext
import org.koin.android.ext.koin.androidLogger
import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.core.context.GlobalContext
import org.koin.core.logger.Level
import org.koin.core.module.Module
import org.koin.dsl.module
import java.lang.ref.WeakReference

import com.couchbase.learningpath.data.KeyValueRepository
import com.couchbase.learningpath.data.audits.AuditRepository
Expand Down Expand Up @@ -41,6 +40,9 @@ import com.couchbase.learningpath.ui.project.ProjectListViewModel
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.InternalCoroutinesApi
import kotlinx.serialization.ExperimentalSerializationApi
import org.koin.androidx.viewmodel.dsl.viewModelOf
import org.koin.core.module.dsl.singleOf
import org.koin.dsl.bind

@ExperimentalSerializationApi
@ExperimentalCoroutinesApi
Expand Down Expand Up @@ -69,31 +71,29 @@ class InventoryApplication
@OptIn(InternalCoroutinesApi::class)
private fun registerDependencies() : Module {
return module {
// ** DO NOT listen to the NO cast needed warnings - removing the as statement will
// ** result in the application not functioning correctly
single { MockAuthenticationService() as AuthenticationService }
single { ReplicatorServiceDb(get(), this@InventoryApplication) as ReplicatorService }
single { UserProfileRepository(this@InventoryApplication) as KeyValueRepository }
single { WarehouseRepositoryDb(this@InventoryApplication) as WarehouseRepository }
single { ProjectRepositoryDb(this@InventoryApplication, get(), get(), get(), get()) as ProjectRepository }
single { StockItemRepositoryDb(this@InventoryApplication) as StockItemRepository }
single { AuditRepositoryDb(this@InventoryApplication, get()) as AuditRepository }
singleOf(::DatabaseManager)
singleOf(::MockAuthenticationService) bind AuthenticationService::class
singleOf(::ReplicatorServiceDb) bind ReplicatorService::class
singleOf(::UserProfileRepository) bind KeyValueRepository::class
singleOf(::WarehouseRepositoryDb) bind WarehouseRepository::class
singleOf(::ProjectRepositoryDb) bind ProjectRepository::class
singleOf(::StockItemRepositoryDb) bind StockItemRepository::class
singleOf(::AuditRepositoryDb) bind AuditRepository::class

viewModel { MainViewModel(get(), get(), WeakReference(this@InventoryApplication)) }
viewModel { LoginViewModel(get(), get(), WeakReference(this@InventoryApplication)) }
viewModel { ProjectListViewModel(get(), get()) }
viewModel { ProjectEditorViewModel(get()) }
viewModel { AuditListViewModel(get())}
viewModel { AuditEditorViewModel(get()) as AuditEditorViewModel}

viewModel { WarehouseSelectionViewModel(get(), get()) }
viewModel { StockItemSelectionViewModel(get(), get()) }
viewModel { UserProfileViewModel(get(), get(), WeakReference(this@InventoryApplication)) }
viewModel { DeveloperViewModel(get()) }
viewModel { DevDatabaseInfoViewModel(get(), get(), get(), get(), get(), get()) }
viewModel { ReplicatorViewModel(get())}
viewModel { ReplicatorConfigViewModel(get())}
viewModelOf(::MainViewModel)
viewModelOf(::LoginViewModel)
viewModelOf(::ProjectListViewModel)
viewModelOf(::ProjectEditorViewModel)
viewModelOf(::AuditListViewModel)
viewModelOf(::AuditEditorViewModel)

viewModelOf(::WarehouseSelectionViewModel)
viewModelOf(::StockItemSelectionViewModel)
viewModelOf(::UserProfileViewModel)
viewModelOf(::DeveloperViewModel)
viewModelOf(::DevDatabaseInfoViewModel)
viewModelOf(::ReplicatorViewModel)
viewModelOf(::ReplicatorConfigViewModel)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@ package com.couchbase.learningpath.data

import android.content.Context
import com.couchbase.learningpath.models.User
import com.couchbase.learningpath.util.Singleton
import com.couchbase.lite.*
import java.io.File
import java.io.FileOutputStream
import java.util.zip.ZipEntry
import java.util.zip.ZipInputStream

class DatabaseManager private constructor(private val context: Context) {
class DatabaseManager(private val context: Context) {

var inventoryDatabase: Database? = null
var warehouseDatabase: Database? = null
Expand Down Expand Up @@ -253,6 +252,4 @@ class DatabaseManager private constructor(private val context: Context) {
stream.close()
}
}

companion object : Singleton<DatabaseManager, Context>(::DatabaseManager)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@

package com.couchbase.learningpath.data.audits

import android.content.Context
import android.util.Log
import com.couchbase.learningpath.data.DatabaseManager
import com.couchbase.learningpath.models.Audit
import com.couchbase.learningpath.models.AuditDao
import com.couchbase.learningpath.models.Project
import com.couchbase.learningpath.models.StockItem
import com.couchbase.learningpath.services.AuthenticationService
import com.couchbase.lite.*
Expand All @@ -23,15 +21,13 @@ import java.util.*

@OptIn(ExperimentalCoroutinesApi::class)
class AuditRepositoryDb(
var context: Context,
private val authenticationService: AuthenticationService
private val authenticationService: AuthenticationService,
private val databaseManager: DatabaseManager
) : AuditRepository {

private val databaseResources: DatabaseManager = DatabaseManager.getInstance(context)

override fun getAuditsByProjectId(projectId: String): Flow<List<Audit>>? {
try {
val db = databaseResources.inventoryDatabase
val db = databaseManager.inventoryDatabase
val team = authenticationService.getCurrentUser().team
db?.let { database ->
val query =
Expand All @@ -58,7 +54,7 @@ class AuditRepositoryDb(
override suspend fun get(projectId: String, auditId: String): Audit {
return withContext(Dispatchers.IO) {
try {
val db = databaseResources.inventoryDatabase
val db = databaseManager.inventoryDatabase
db?.let { database ->
val doc = database.getDocument(auditId)
doc?.let { document ->
Expand Down Expand Up @@ -89,7 +85,7 @@ class AuditRepositoryDb(
override suspend fun save(document: Audit) {
return withContext(Dispatchers.IO) {
try {
val db = databaseResources.inventoryDatabase
val db = databaseManager.inventoryDatabase
db?.let { database ->
val json = Json.encodeToString(document)
val doc = MutableDocument(document.auditId, json)
Expand All @@ -108,7 +104,7 @@ class AuditRepositoryDb(
) {
return withContext(Dispatchers.IO) {
try {
val db = databaseResources.inventoryDatabase
val db = databaseManager.inventoryDatabase
val audit = get(projectId, auditId)
audit.stockItem = stockItem
audit.notes = "Found item ${stockItem.name} - ${stockItem.description} in warehouse"
Expand Down Expand Up @@ -139,7 +135,7 @@ class AuditRepositoryDb(
return withContext(Dispatchers.IO) {
var result = false
try {
val db = databaseResources.inventoryDatabase
val db = databaseManager.inventoryDatabase
db?.let { database ->
val doc = database.getDocument(documentId)
doc?.let { document ->
Expand All @@ -158,7 +154,7 @@ class AuditRepositoryDb(
return withContext(Dispatchers.IO) {
var count = 0
try {
val db = DatabaseManager.getInstance(context).inventoryDatabase
val db = databaseManager.inventoryDatabase
db?.let { database ->
val query =
database.createQuery("SELECT COUNT(*) AS count FROM _ AS item WHERE documentType=\"audit\"") // 1
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.couchbase.learningpath.data.project

import android.content.Context
import android.util.Log
import com.couchbase.lite.*
import kotlinx.coroutines.Dispatchers
Expand All @@ -17,7 +16,6 @@ import java.text.SimpleDateFormat
import java.util.*

import com.couchbase.learningpath.data.DatabaseManager
import com.couchbase.learningpath.data.audits.AuditRepository
import com.couchbase.learningpath.data.stockItem.StockItemRepository
import com.couchbase.learningpath.data.warehouse.WarehouseRepository
import com.couchbase.learningpath.models.Audit
Expand All @@ -30,23 +28,22 @@ import kotlinx.serialization.ExperimentalSerializationApi
@ExperimentalCoroutinesApi
@ExperimentalSerializationApi
class ProjectRepositoryDb(
private val context: Context,
private val authenticationService: AuthenticationService,
private val auditRepository: AuditRepository,
private val warehouseRepository: WarehouseRepository,
private val stockItemRepository: StockItemRepository,
private val databaseManager: DatabaseManager
) : ProjectRepository {
private val projectDocumentType = "project"
private val auditDocumentType = "audit"

override val databaseName: String
get() = DatabaseManager.getInstance(context).currentInventoryDatabaseName
get() = databaseManager.currentInventoryDatabaseName

//live query demo of returning project documents

override fun getDocuments(team: String): Flow<List<Project>> {
try {
val db = DatabaseManager.getInstance(context).inventoryDatabase
val db = databaseManager.inventoryDatabase
// NOTE - the as method is a also a keyword in Kotlin, so it must be escaped using
// `as` - this will probably break intellisense, so it will act like the where
// method isn't available work around is to do your entire statement without the as
Expand Down Expand Up @@ -92,7 +89,7 @@ class ProjectRepositoryDb(
override suspend fun get(documentId: String): Project {
return withContext(Dispatchers.IO) {
try {
val db = DatabaseManager.getInstance(context).inventoryDatabase
val db = databaseManager.inventoryDatabase
db?.let { database ->
val doc = database.getDocument(documentId)
doc?.let { document ->
Expand Down Expand Up @@ -136,7 +133,7 @@ class ProjectRepositoryDb(
override suspend fun updateProjectWarehouse(projectId: String, warehouse: Warehouse) {
return withContext(Dispatchers.IO) {
try {
val db = DatabaseManager.getInstance(context).inventoryDatabase
val db = databaseManager.inventoryDatabase
val project = get(projectId)
project.warehouse = warehouse
db?.let { database ->
Expand All @@ -153,7 +150,7 @@ class ProjectRepositoryDb(
override suspend fun save(document: Project) {
return withContext(Dispatchers.IO) {
try {
val db = DatabaseManager.getInstance(context).inventoryDatabase
val db = databaseManager.inventoryDatabase
db?.let { database ->
val json = Json.encodeToString(document)
val doc = MutableDocument(document.projectId, json)
Expand All @@ -173,7 +170,7 @@ class ProjectRepositoryDb(
return withContext(Dispatchers.IO) {
var result = false
try {
val db = DatabaseManager.getInstance(context).inventoryDatabase
val db = databaseManager.inventoryDatabase
db?.let { database ->
val projectDoc = database.getDocument(documentId)
projectDoc?.let { document ->
Expand All @@ -192,7 +189,7 @@ class ProjectRepositoryDb(
return withContext(Dispatchers.IO) {
var count = 0
try {
val db = DatabaseManager.getInstance(context).inventoryDatabase
val db = databaseManager.inventoryDatabase
db?.let { database ->
val query = QueryBuilder // 1
.select(
Expand Down Expand Up @@ -223,7 +220,7 @@ class ProjectRepositoryDb(
val stockItemsCount = stockItems.count() - 1 // <5>

if (warehouseCount > 0 && stockItemsCount > 0) {
val db = DatabaseManager.getInstance(context).inventoryDatabase
val db = databaseManager.inventoryDatabase
db?.let { database ->
// batch operations for saving multiple documents
// this is a faster way to process groups of documents at once
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@

package com.couchbase.learningpath.data.stockItem

import android.content.Context
import android.util.Log
import androidx.compose.ui.text.toLowerCase
import com.couchbase.learningpath.data.DatabaseManager
import com.couchbase.learningpath.models.StockItem
import com.couchbase.learningpath.models.StockItemDao
Expand All @@ -16,21 +14,20 @@ import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json

class StockItemRepositoryDb(
var context: Context
private val databaseManager: DatabaseManager
) : StockItemRepository {
private val databaseResources: DatabaseManager = DatabaseManager.getInstance(context)
private val documentType = "item"

override val databaseName: () -> String? =
{ DatabaseManager.getInstance(context).warehouseDatabase?.name }
{ databaseManager.warehouseDatabase?.name }
override val databaseLocation: () -> String? =
{ DatabaseManager.getInstance(context).warehouseDatabase?.path }
{ databaseManager.warehouseDatabase?.path }

override suspend fun get(): List<StockItem> {
return withContext(Dispatchers.IO) {
val stockItems = mutableListOf<StockItem>()
try {
val db = databaseResources.warehouseDatabase
val db = databaseManager.warehouseDatabase
db?.let { database ->
val query =
database.createQuery("SELECT * FROM _ AS item WHERE documentType=\"$documentType\"")
Expand All @@ -51,7 +48,7 @@ class StockItemRepositoryDb(
return withContext(Dispatchers.IO) {
var count = 0
try {
val db = DatabaseManager.getInstance(context).warehouseDatabase
val db = databaseManager.warehouseDatabase
db?.let { database ->
val query =
database.createQuery("SELECT COUNT(*) AS count FROM _ AS item WHERE documentType=\"$documentType\"") // 1
Expand All @@ -72,7 +69,7 @@ class StockItemRepositoryDb(
return withContext(Dispatchers.IO) {
val stockItems = mutableListOf<StockItem>()
try {
val db = databaseResources.warehouseDatabase
val db = databaseManager.warehouseDatabase
db?.let { database ->
var queryString =
"SELECT * FROM _ as item WHERE documentType=\"item\" AND lower(name) LIKE ('%' || \$parameterName || '%')" // 1
Expand Down
Loading