Coverage Summary for Class: DbManager (cloud.mindbox.mobile_sdk.managers)
| Class |
Method, %
|
Branch, %
|
Line, %
|
Instruction, %
|
| DbManager |
15.4%
(2/13)
|
0%
(0/6)
|
13%
(3/23)
|
11.9%
(18/151)
|
| DbManager$addEventToQueue$1 |
100%
(1/1)
|
50%
(1/2)
|
85.7%
(6/7)
|
60%
(21/35)
|
| DbManager$getConfigurations$1 |
100%
(1/1)
|
50%
(1/2)
|
100%
(3/3)
|
85.7%
(18/21)
|
| DbManager$getEvents$1 |
0%
(0/1)
|
|
0%
(0/1)
|
0%
(0/25)
|
| DbManager$getFilteredEvents$1 |
0%
(0/1)
|
0%
(0/2)
|
0%
(0/5)
|
0%
(0/33)
|
| DbManager$getFilteredEvents$1$1 |
0%
(0/1)
|
|
0%
(0/1)
|
0%
(0/15)
|
| DbManager$getFilteredEvents$1$invoke$$inlined$sortedBy$1 |
0%
(0/1)
|
|
| DbManager$init$1 |
0%
(0/1)
|
0%
(0/2)
|
0%
(0/2)
|
0%
(0/9)
|
| DbManager$isTooOld$1 |
0%
(0/1)
|
0%
(0/2)
|
0%
(0/1)
|
0%
(0/13)
|
| DbManager$removeEventFromQueue$1 |
0%
(0/1)
|
0%
(0/2)
|
0%
(0/5)
|
0%
(0/52)
|
| DbManager$removeEventsFromQueue$1 |
0%
(0/1)
|
0%
(0/2)
|
0%
(0/3)
|
0%
(0/47)
|
| DbManager$saveConfigurations$1 |
0%
(0/1)
|
0%
(0/2)
|
0%
(0/5)
|
0%
(0/19)
|
| Total |
16.7%
(4/24)
|
9.1%
(2/22)
|
21.4%
(12/56)
|
13.6%
(57/420)
|
package cloud.mindbox.mobile_sdk.managers
import android.content.Context
import cloud.mindbox.mobile_sdk.logger.MindboxLoggerImpl
import cloud.mindbox.mobile_sdk.models.Configuration
import cloud.mindbox.mobile_sdk.models.Event
import cloud.mindbox.mobile_sdk.repository.MindboxDatabase
import cloud.mindbox.mobile_sdk.services.BackgroundWorkManager
import cloud.mindbox.mobile_sdk.utils.LoggingExceptionHandler
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.launch
internal object DbManager {
const val EVENTS_TABLE_NAME = "mindbox_events_table"
const val CONFIGURATION_TABLE_NAME = "mindbox_configuration_table"
private const val MAX_EVENT_LIST_SIZE = 10000
private const val HALF_YEAR_IN_MILLISECONDS: Long = 15552000000L
private const val DELAY_FOR_SEND_IN_BACKGROUND = 120_000
@Volatile
private lateinit var mindboxDb: MindboxDatabase
fun init(context: Context) = LoggingExceptionHandler.runCatching {
if (!this::mindboxDb.isInitialized) {
mindboxDb = MindboxDatabase.getInstance(context)
}
}
fun addEventToQueue(context: Context, event: Event) = LoggingExceptionHandler.runCatching {
try {
mindboxDb.eventsDao().insert(event)
MindboxLoggerImpl.d(this, "Event ${event.eventType.operation} was added to queue")
} catch (exception: RuntimeException) {
MindboxLoggerImpl.e(
this,
"Error writing object to the database: ${event.body}",
exception,
)
}
BackgroundWorkManager.startOneTimeService(context)
}
fun getFilteredEvents(): List<Event> = LoggingExceptionHandler.runCatching(
defaultValue = listOf(),
) {
val events = getEvents().sortedBy(Event::enqueueTimestamp)
val resultEvents = filterEvents(events)
if (events.size > resultEvents.size) {
CoroutineScope(Dispatchers.IO).launch { removeEventsFromQueue(events - resultEvents) }
}
resultEvents
}
fun getFilteredEventsForBackgroundSend() = System.currentTimeMillis().let { time ->
getFilteredEvents().filter { time - it.enqueueTimestamp > DELAY_FOR_SEND_IN_BACKGROUND }
}
fun removeEventFromQueue(event: Event) = LoggingExceptionHandler.runCatching {
try {
synchronized(this) { mindboxDb.eventsDao().delete(event.transactionId) }
MindboxLoggerImpl.d(
this,
"Event ${event.eventType.operation};${event.transactionId} was deleted from queue",
)
} catch (exception: RuntimeException) {
MindboxLoggerImpl.e(this, "Error deleting item from database", exception)
}
}
private fun removeEventsFromQueue(events: List<Event>) = LoggingExceptionHandler.runCatching {
try {
synchronized(this) { mindboxDb.eventsDao().deleteEvents(events) }
MindboxLoggerImpl.d(this, "${events.size} events were deleted from queue")
} catch (exception: RuntimeException) {
MindboxLoggerImpl.e(this, "Error deleting items from database", exception)
}
}
fun saveConfigurations(configuration: Configuration) = LoggingExceptionHandler.runCatching {
try {
mindboxDb.configurationDao().insert(configuration)
} catch (exception: RuntimeException) {
MindboxLoggerImpl.e(
this,
"Error writing object configuration to the database",
exception,
)
}
}
fun getConfigurations(): Configuration? = LoggingExceptionHandler.runCatching(
defaultValue = null,
) {
try {
mindboxDb.configurationDao().get()
} catch (exception: RuntimeException) {
// invalid data in case of exception
MindboxLoggerImpl.e(this, "Error reading from database", exception)
null
}
}
fun listenConfigurations(): Flow<Configuration> {
return try {
mindboxDb.configurationDao().listenConfiguration()
} catch (e: RuntimeException) {
MindboxLoggerImpl.e(this, "Error reading from database", e)
flowOf(null)
}.filterNotNull()
}
private fun getEvents(): List<Event> = LoggingExceptionHandler.runCatching(
defaultValue = listOf(),
) {
synchronized(this) { mindboxDb.eventsDao().getAll() }
}
fun removeAllEventsFromQueue() {
try {
mindboxDb.eventsDao().deleteAll()
} catch (exception: RuntimeException) {
// invalid data in case of exception
MindboxLoggerImpl.e(this, "Error reading from database", exception)
}
}
private fun filterEvents(events: List<Event>): List<Event> {
val time = System.currentTimeMillis()
val filteredEvents = events.filterNot { it.isTooOld(time) }
return filteredEvents.takeLast(MAX_EVENT_LIST_SIZE)
}
private fun Event.isTooOld(
timeNow: Long,
): Boolean = LoggingExceptionHandler.runCatching(defaultValue = false) {
timeNow - this.enqueueTimestamp >= HALF_YEAR_IN_MILLISECONDS
}
}