74 lines
2.6 KiB
Kotlin
74 lines
2.6 KiB
Kotlin
package dev.inmo.postssystem.features.files.common
|
|
|
|
import com.benasher44.uuid.uuid4
|
|
import dev.inmo.postssystem.features.files.common.storage.WriteFilesStorage
|
|
import dev.inmo.micro_utils.repos.*
|
|
import io.ktor.utils.io.core.copyTo
|
|
import io.ktor.utils.io.streams.asOutput
|
|
import kotlinx.coroutines.flow.*
|
|
import java.io.File
|
|
|
|
class WriteDistFilesStorage(
|
|
private val filesFolder: File,
|
|
private val metasKeyValueRepo: WriteKeyValueRepo<FileId, MetaFileInfo>
|
|
) : WriteFilesStorage {
|
|
private val FileId.file
|
|
get() = File(filesFolder, string)
|
|
|
|
private val _deletedObjectsIdsFlow = MutableSharedFlow<FileId>()
|
|
private val _newObjectsFlow = MutableSharedFlow<FullFileInfoStorageWrapper>()
|
|
private val _updatedObjectsFlow = MutableSharedFlow<FullFileInfoStorageWrapper>()
|
|
override val deletedObjectsIdsFlow: Flow<FileId> = _deletedObjectsIdsFlow.asSharedFlow()
|
|
override val newObjectsFlow: Flow<FullFileInfoStorageWrapper> = _newObjectsFlow.asSharedFlow()
|
|
override val updatedObjectsFlow: Flow<FullFileInfoStorageWrapper> = _updatedObjectsFlow.asSharedFlow()
|
|
|
|
init {
|
|
if (!filesFolder.exists()) {
|
|
filesFolder.mkdirs()
|
|
} else {
|
|
require(filesFolder.isDirectory) { "$filesFolder must be a directory" }
|
|
}
|
|
}
|
|
|
|
override suspend fun create(values: List<FullFileInfo>): List<FullFileInfoStorageWrapper> = values.map {
|
|
var newId: FileId
|
|
var file: File
|
|
do {
|
|
newId = FileId(uuid4().toString())
|
|
file = newId.file
|
|
} while (file.exists())
|
|
metasKeyValueRepo.set(newId, it.toMetaFileInfo())
|
|
it.inputProvider().copyTo(file.outputStream().asOutput())
|
|
FullFileInfoStorageWrapper(newId, it)
|
|
}
|
|
|
|
override suspend fun deleteById(ids: List<FileId>) {
|
|
ids.forEach {
|
|
if (it.file.delete()) {
|
|
metasKeyValueRepo.unset(it)
|
|
_deletedObjectsIdsFlow.emit(it)
|
|
}
|
|
}
|
|
}
|
|
|
|
override suspend fun update(
|
|
id: FileId,
|
|
value: FullFileInfo
|
|
): FullFileInfoStorageWrapper? {
|
|
val file = id.file.takeIf { it.exists() } ?: return null
|
|
value.inputProvider().copyTo(file.outputStream().asOutput())
|
|
val result = FullFileInfoStorageWrapper(id, value.copy())
|
|
|
|
metasKeyValueRepo.set(id, value.toMetaFileInfo())
|
|
_updatedObjectsFlow.emit(result)
|
|
|
|
return result
|
|
}
|
|
|
|
override suspend fun update(
|
|
values: List<UpdatedValuePair<FileId, FullFileInfo>>
|
|
): List<FullFileInfoStorageWrapper> = values.mapNotNull { (id, file) ->
|
|
update(id, file)
|
|
}
|
|
}
|