Compare commits

...

15 Commits

10 changed files with 109 additions and 26 deletions

View File

@@ -1,5 +1,29 @@
# Changelog
## 0.9.24
* `Ktor`:
* `Common`:
* New extension fun `MPPFile#input`
## 0.9.23
* `Repos`:
* `Exposed`:
* New property `ExposedRepo#selectAll` to retrieve all the rows in the table
## 0.9.22
* `Ktor`:
* `Server`:
* Now `createKtorServer` fun is fully customizable
## 0.9.21
* `Repos`:
* `Exposed`:
* fixes in `AbstractExposedWriteCRUDRepo`
## 0.9.20
* `Repos`:

View File

@@ -14,5 +14,5 @@ crypto_js_version=4.1.1
# Project data
group=dev.inmo
version=0.9.20
android_code_version=110
version=0.9.24
android_code_version=114

View File

@@ -39,6 +39,7 @@ kt-coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", vers
kt-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "kt-coroutines" }
ktor-io = { module = "io.ktor:ktor-io", version.ref = "ktor" }
ktor-client = { module = "io.ktor:ktor-client-core", version.ref = "ktor" }
ktor-client-java = { module = "io.ktor:ktor-client-java", version.ref = "ktor" }
ktor-server = { module = "io.ktor:ktor-server", version.ref = "ktor" }

View File

@@ -14,6 +14,7 @@ kotlin {
api libs.kt.serialization.cbor
api libs.klock
api libs.uuid
api libs.ktor.io
}
}
}

View File

@@ -0,0 +1,6 @@
package dev.inmo.micro_utils.ktor.common
import dev.inmo.micro_utils.common.MPPFile
import io.ktor.utils.io.core.Input
expect fun MPPFile.input(): Input

View File

@@ -0,0 +1,7 @@
package dev.inmo.micro_utils.ktor.common
import dev.inmo.micro_utils.common.*
import io.ktor.utils.io.core.ByteReadPacket
import io.ktor.utils.io.core.Input
actual fun MPPFile.input(): Input = ByteReadPacket(readBytes())

View File

@@ -0,0 +1,7 @@
package dev.inmo.micro_utils.ktor.common
import dev.inmo.micro_utils.common.MPPFile
import io.ktor.utils.io.core.Input
import io.ktor.utils.io.streams.asInput
actual fun MPPFile.input(): Input = inputStream().asInput()

View File

@@ -3,6 +3,7 @@ package dev.inmo.micro_utils.ktor.server
import dev.inmo.micro_utils.ktor.server.configurators.KtorApplicationConfigurator
import io.ktor.application.Application
import io.ktor.server.cio.CIO
import io.ktor.server.cio.CIOApplicationEngine
import io.ktor.server.engine.*
import kotlin.random.Random
@@ -10,17 +11,21 @@ fun <TEngine : ApplicationEngine, TConfiguration : ApplicationEngine.Configurati
engine: ApplicationEngineFactory<TEngine, TConfiguration>,
host: String = "localhost",
port: Int = Random.nextInt(1024, 65535),
additionalEngineEnvironmentConfigurator: ApplicationEngineEnvironmentBuilder.() -> Unit = {},
additionalConfigurationConfigurator: TConfiguration.() -> Unit = {},
block: Application.() -> Unit
): TEngine {
val env = applicationEngineEnvironment {
): TEngine = embeddedServer(
engine,
applicationEngineEnvironment {
module(block)
connector {
this@connector.host = host
this@connector.port = port
this.host = host
this.port = port
}
}
return embeddedServer(engine, env)
}
additionalEngineEnvironmentConfigurator()
},
additionalConfigurationConfigurator
)
/**
* Create server with [CIO] server engine without starting of it
@@ -30,18 +35,31 @@ fun <TEngine : ApplicationEngine, TConfiguration : ApplicationEngine.Configurati
fun createKtorServer(
host: String = "localhost",
port: Int = Random.nextInt(1024, 65535),
additionalEngineEnvironmentConfigurator: ApplicationEngineEnvironmentBuilder.() -> Unit = {},
additionalConfigurationConfigurator: CIOApplicationEngine.Configuration.() -> Unit = {},
block: Application.() -> Unit
): ApplicationEngine = createKtorServer(CIO, host, port, block)
): CIOApplicationEngine = createKtorServer(
CIO,
host,
port,
additionalEngineEnvironmentConfigurator,
additionalConfigurationConfigurator,
block
)
fun <TEngine : ApplicationEngine, TConfiguration : ApplicationEngine.Configuration> createKtorServer(
engine: ApplicationEngineFactory<TEngine, TConfiguration>,
host: String = "localhost",
port: Int = Random.nextInt(1024, 65535),
additionalEngineEnvironmentConfigurator: ApplicationEngineEnvironmentBuilder.() -> Unit = {},
additionalConfigurationConfigurator: TConfiguration.() -> Unit = {},
configurators: List<KtorApplicationConfigurator>
): TEngine = createKtorServer(
engine,
host,
port
port,
additionalEngineEnvironmentConfigurator,
additionalConfigurationConfigurator
) {
configurators.forEach { it.apply { configure() } }
}
@@ -54,5 +72,7 @@ fun <TEngine : ApplicationEngine, TConfiguration : ApplicationEngine.Configurati
fun createKtorServer(
host: String = "localhost",
port: Int = Random.nextInt(1024, 65535),
configurators: List<KtorApplicationConfigurator>
): ApplicationEngine = createKtorServer(CIO, host, port, configurators)
configurators: List<KtorApplicationConfigurator>,
additionalEngineEnvironmentConfigurator: ApplicationEngineEnvironmentBuilder.() -> Unit = {},
additionalConfigurationConfigurator: CIOApplicationEngine.Configuration.() -> Unit = {},
): ApplicationEngine = createKtorServer(CIO, host, port, additionalEngineEnvironmentConfigurator, additionalConfigurationConfigurator, configurators)

View File

@@ -17,13 +17,19 @@ abstract class AbstractExposedWriteCRUDRepo<ObjectType, IdType, InputValueType>(
ExposedCRUDRepo<ObjectType, IdType>,
WriteStandardCRUDRepo<ObjectType, IdType, InputValueType>
{
protected val newObjectsChannel = MutableSharedFlow<ObjectType>(replyCacheInFlows, flowsChannelsSize)
protected val updateObjectsChannel = MutableSharedFlow<ObjectType>(replyCacheInFlows, flowsChannelsSize)
protected val deleteObjectsIdsChannel = MutableSharedFlow<IdType>(replyCacheInFlows, flowsChannelsSize)
protected val _newObjectsFlow = MutableSharedFlow<ObjectType>(replyCacheInFlows, flowsChannelsSize)
protected val _updatedObjectsFlow = MutableSharedFlow<ObjectType>(replyCacheInFlows, flowsChannelsSize)
protected val _deletedObjectsIdsFlow = MutableSharedFlow<IdType>(replyCacheInFlows, flowsChannelsSize)
@Deprecated("Renamed", ReplaceWith("_newObjectsFlow"))
protected val newObjectsChannel = _newObjectsFlow
@Deprecated("Renamed", ReplaceWith("_updatedObjectsFlow"))
protected val updateObjectsChannel = _updatedObjectsFlow
@Deprecated("Renamed", ReplaceWith("_deletedObjectsIdsFlow"))
protected val deleteObjectsIdsChannel = _deletedObjectsIdsFlow
override val newObjectsFlow: Flow<ObjectType> = newObjectsChannel.asSharedFlow()
override val updatedObjectsFlow: Flow<ObjectType> = updateObjectsChannel.asSharedFlow()
override val deletedObjectsIdsFlow: Flow<IdType> = deleteObjectsIdsChannel.asSharedFlow()
override val newObjectsFlow: Flow<ObjectType> = _newObjectsFlow.asSharedFlow()
override val updatedObjectsFlow: Flow<ObjectType> = _updatedObjectsFlow.asSharedFlow()
override val deletedObjectsIdsFlow: Flow<IdType> = _deletedObjectsIdsFlow.asSharedFlow()
protected abstract fun InsertStatement<Number>.asObject(value: InputValueType): ObjectType
abstract val selectByIds: SqlExpressionBuilder.(List<IdType>) -> Op<Boolean>
@@ -43,7 +49,7 @@ abstract class AbstractExposedWriteCRUDRepo<ObjectType, IdType, InputValueType>(
return transaction(db = database) {
values.map { value -> createWithoutNotification(value) }
}.onEach {
newObjectsChannel.emit(it)
_newObjectsFlow.emit(it)
}
}
@@ -74,7 +80,7 @@ abstract class AbstractExposedWriteCRUDRepo<ObjectType, IdType, InputValueType>(
onBeforeUpdate(listOf(id to value))
return updateWithoutNotification(id, value).also {
if (it != null) {
updateObjectsChannel.emit(it)
_updatedObjectsFlow.emit(it)
}
}
}
@@ -85,16 +91,25 @@ abstract class AbstractExposedWriteCRUDRepo<ObjectType, IdType, InputValueType>(
values.map { (id, value) -> updateWithoutNotification(id, value) }
}.filterNotNull()
).onEach {
updateObjectsChannel.emit(it)
_updatedObjectsFlow.emit(it)
}
}
protected open suspend fun onBeforeDelete(ids: List<IdType>) {}
override suspend fun deleteById(ids: List<IdType>) {
onBeforeDelete(ids)
transaction(db = database) {
deleteWhere(null, null) {
val deleted = deleteWhere(null, null) {
selectByIds(ids)
}
if (deleted == ids.size) {
ids
} else {
ids.filter {
select { selectById(it) }.limit(1).none()
}
}
}.forEach {
_deletedObjectsIdsFlow.emit(it)
}
}
}

View File

@@ -1,8 +1,10 @@
package dev.inmo.micro_utils.repos.exposed
import dev.inmo.micro_utils.repos.Repo
import org.jetbrains.exposed.sql.Database
import org.jetbrains.exposed.sql.*
interface ExposedRepo : Repo {
interface ExposedRepo : Repo, FieldSet {
val database: Database
}
val selectAll: Transaction.() -> Query
get() = { (this@ExposedRepo as FieldSet).selectAll() }
}