core/core/api/src/jvmMain/kotlin/dev/inmo/postssystem/core/content/api/business/content_adapters/binary/FilesStoreRepoAdapter.kt

80 lines
2.6 KiB
Kotlin

package dev.inmo.postssystem.core.content.api.business.content_adapters.binary
import dev.inmo.micro_utils.coroutines.doOutsideOfCoroutine
import dev.inmo.micro_utils.coroutines.safelyWithoutExceptions
import dev.inmo.micro_utils.pagination.*
import dev.inmo.micro_utils.repos.KeyValueRepo
import dev.inmo.micro_utils.repos.set
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import java.io.File
class FilesStoreRepoAdapter(
private val filesRepo: KeyValueRepo<String, File>,
private val temporalFilesFolder: File
) : KeyValueRepo<String, ByteArray> {
private val File.asByteArray
get() = readBytes()
override val onNewValue: Flow<Pair<String, ByteArray>> = filesRepo.onNewValue.map { (filename, file) ->
filename to file.asByteArray
}
override val onValueRemoved: Flow<String> = filesRepo.onValueRemoved
init {
temporalFilesFolder.mkdirs()
}
override suspend fun contains(key: String): Boolean = filesRepo.contains(key)
override suspend fun count(): Long = filesRepo.count()
override suspend fun get(k: String): ByteArray? = filesRepo.get(k) ?.asByteArray
override suspend fun keys(
v: ByteArray,
pagination: Pagination,
reversed: Boolean
): PaginationResult<String> = emptyPaginationResult()
override suspend fun keys(
pagination: Pagination,
reversed: Boolean
): PaginationResult<String> = filesRepo.keys(pagination, reversed)
override suspend fun set(toSet: Map<String, ByteArray>) {
supervisorScope {
toSet.map { (filename, bytes) ->
launch {
safelyWithoutExceptions {
val file = File(temporalFilesFolder, filename).also {
it.delete()
doOutsideOfCoroutine {
it.createNewFile()
it.writeBytes(bytes)
}
}
filesRepo.set(filename, file)
doOutsideOfCoroutine { file.delete() }
}
}
}
}.joinAll()
}
override suspend fun unset(toUnset: List<String>) = filesRepo.unset(toUnset)
override suspend fun values(
pagination: Pagination,
reversed: Boolean
): PaginationResult<ByteArray> = filesRepo.values(pagination, reversed).let {
PaginationResult(
it.page,
it.pagesNumber,
it.results.map { it.readBytes() },
it.size
)
}
}