fixes
This commit is contained in:
parent
3baf6cc3c6
commit
43f148bf4b
@ -20,3 +20,8 @@ fun Query.paginate(with: Pagination, orderBy: Pair<Expression<*>, SortOrder>? =
|
||||
it
|
||||
}
|
||||
}
|
||||
|
||||
fun Query.paginate(with: Pagination, orderBy: Expression<*>?, reversed: Boolean = false) = paginate(
|
||||
with,
|
||||
orderBy ?.let { it to if (reversed) SortOrder.DESC else SortOrder.ASC }
|
||||
)
|
||||
|
@ -0,0 +1,13 @@
|
||||
package com.insanusmokrassar.postssystem.utils.repos.exposed
|
||||
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
|
||||
abstract class AbstractExposedCRUDRepo<ObjectType, IdType, InputValueType>(
|
||||
flowsChannelsSize: Int = Channel.BUFFERED,
|
||||
databaseName: String = ""
|
||||
) :
|
||||
AbstractExposedWriteCRUDRepo<ObjectType, IdType, InputValueType>(
|
||||
flowsChannelsSize,
|
||||
databaseName
|
||||
),
|
||||
ExposedCRUDRepo<ObjectType, IdType>
|
@ -0,0 +1,39 @@
|
||||
package com.insanusmokrassar.postssystem.utils.repos.exposed
|
||||
|
||||
import com.insanusmokrassar.postssystem.exposed.commons.paginate
|
||||
import com.insanusmokrassar.postssystem.utils.repos.ReadStandardCRUDRepo
|
||||
import com.insanusmokrassar.postssystem.utils.repos.pagination.*
|
||||
import org.jetbrains.exposed.sql.Table
|
||||
import org.jetbrains.exposed.sql.select
|
||||
import org.jetbrains.exposed.sql.selectAll
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
|
||||
abstract class AbstractExposedReadCRUDRepo<ObjectType, IdType>(
|
||||
tableName: String
|
||||
) :
|
||||
ReadStandardCRUDRepo<ObjectType, IdType>,
|
||||
ExposedCRUDRepo<ObjectType, IdType>,
|
||||
Table(tableName)
|
||||
{
|
||||
override suspend fun getByPagination(pagination: Pagination): PaginationResult<ObjectType> {
|
||||
return transaction(database) {
|
||||
selectAll().paginate(pagination).map {
|
||||
it.asObject
|
||||
}.createPaginationResult(
|
||||
pagination,
|
||||
selectAll().count()
|
||||
)
|
||||
}
|
||||
}
|
||||
override suspend fun getById(id: IdType): ObjectType? {
|
||||
return transaction(database) {
|
||||
select {
|
||||
selectById(id)
|
||||
}.limit(1).firstOrNull() ?.asObject
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun contains(id: IdType): Boolean = transaction(database) {
|
||||
select { selectById(id) }.limit(1).any()
|
||||
}
|
||||
}
|
@ -0,0 +1,105 @@
|
||||
package com.insanusmokrassar.postssystem.utils.repos.exposed
|
||||
|
||||
import com.insanusmokrassar.postssystem.utils.repos.UpdatedValuePair
|
||||
import com.insanusmokrassar.postssystem.utils.repos.WriteStandardCRUDRepo
|
||||
import kotlinx.coroutines.channels.BroadcastChannel
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.asFlow
|
||||
import org.jetbrains.exposed.sql.*
|
||||
import org.jetbrains.exposed.sql.statements.InsertStatement
|
||||
import org.jetbrains.exposed.sql.statements.UpdateStatement
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
|
||||
abstract class AbstractExposedWriteCRUDRepo<ObjectType, IdType, InputValueType>(
|
||||
flowsChannelsSize: Int = 64,
|
||||
databaseName: String = ""
|
||||
) :
|
||||
AbstractExposedReadCRUDRepo<ObjectType, IdType>(databaseName),
|
||||
ExposedCRUDRepo<ObjectType, IdType>,
|
||||
WriteStandardCRUDRepo<ObjectType, IdType, InputValueType>
|
||||
{
|
||||
protected val newObjectsChannel = BroadcastChannel<ObjectType>(flowsChannelsSize)
|
||||
protected val updateObjectsChannel = BroadcastChannel<ObjectType>(flowsChannelsSize)
|
||||
protected val deleteObjectsIdsChannel = BroadcastChannel<IdType>(flowsChannelsSize)
|
||||
|
||||
override val newObjectsFlow: Flow<ObjectType> = newObjectsChannel.asFlow()
|
||||
override val updatedObjectsFlow: Flow<ObjectType> = updateObjectsChannel.asFlow()
|
||||
override val deletedObjectsIdsFlow: Flow<IdType> = deleteObjectsIdsChannel.asFlow()
|
||||
|
||||
abstract val InsertStatement<Number>.asObject: ObjectType
|
||||
abstract val selectByIds: SqlExpressionBuilder.(Array<out IdType>) -> Op<Boolean>
|
||||
|
||||
protected abstract fun insert(value: InputValueType, it: InsertStatement<Number>)
|
||||
protected abstract fun update(id: IdType, value: InputValueType, it: UpdateStatement)
|
||||
|
||||
protected open suspend fun onBeforeCreate(vararg value: InputValueType) {}
|
||||
private fun createWithoutNotification(value: InputValueType): ObjectType {
|
||||
return transaction(database) {
|
||||
insert { insert(value, it) }.asObject
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun create(vararg values: InputValueType): List<ObjectType> {
|
||||
onBeforeCreate(*values)
|
||||
return transaction(database) {
|
||||
values.map { value -> createWithoutNotification(value) }
|
||||
}.also {
|
||||
it.forEach {
|
||||
newObjectsChannel.send(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected open suspend fun onBeforeUpdate(vararg value: UpdatedValuePair<IdType, InputValueType>) {}
|
||||
private fun updateWithoutNotification(id: IdType, value: InputValueType): ObjectType? {
|
||||
return transaction(database) {
|
||||
update(
|
||||
{
|
||||
selectById(this, id)
|
||||
}
|
||||
) {
|
||||
update(id, value, it)
|
||||
}
|
||||
}.let {
|
||||
if (it > 0) {
|
||||
select {
|
||||
selectById(this, id)
|
||||
}.limit(1).firstOrNull() ?.asObject
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun update(id: IdType, value: InputValueType): ObjectType? {
|
||||
onBeforeUpdate(id to value)
|
||||
return updateWithoutNotification(id, value).also {
|
||||
if (it != null) {
|
||||
updateObjectsChannel.send(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
override suspend fun update(vararg values: UpdatedValuePair<IdType, InputValueType>): List<ObjectType> {
|
||||
onBeforeUpdate(*values)
|
||||
return (
|
||||
transaction(database) {
|
||||
values.map { (id, value) -> updateWithoutNotification(id, value) }
|
||||
}.filter {
|
||||
it != null
|
||||
} as List<ObjectType>
|
||||
).also {
|
||||
it.forEach {
|
||||
updateObjectsChannel.send(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
protected open suspend fun onBeforeDelete(vararg ids: IdType) {}
|
||||
override suspend fun deleteById(vararg ids: IdType) {
|
||||
onBeforeDelete(*ids)
|
||||
transaction(database) {
|
||||
deleteWhere(null, null) {
|
||||
selectByIds(ids)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package com.insanusmokrassar.postssystem.utils.repos.exposed
|
||||
|
||||
import org.jetbrains.exposed.sql.Database
|
||||
import org.jetbrains.exposed.sql.Op
|
||||
import org.jetbrains.exposed.sql.ResultRow
|
||||
import org.jetbrains.exposed.sql.SqlExpressionBuilder
|
||||
|
||||
interface ExposedCRUDRepo<ObjectType, IdType> {
|
||||
val database: Database
|
||||
|
||||
val ResultRow.asObject: ObjectType
|
||||
val selectById: SqlExpressionBuilder.(IdType) -> Op<Boolean>
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package com.insanusmokrassar.postssystem.utils.repos.exposed
|
||||
|
||||
import org.jetbrains.exposed.sql.Database
|
||||
import org.jetbrains.exposed.sql.SchemaUtils
|
||||
import org.jetbrains.exposed.sql.Table
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
|
||||
fun Table.initTable(database: Database) {
|
||||
transaction(database) { SchemaUtils.createMissingTablesAndColumns(this@initTable) }
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package com.insanusmokrassar.postssystem.utils.repos.exposed.onetomany
|
||||
|
||||
import com.insanusmokrassar.budgetmanager.core.utils.repo.onetomany.AbstractOneToManyExposedReadKeyValueRepo
|
||||
import com.insanusmokrassar.budgetmanager.core.utils.repo.onetomany.ColumnAllocator
|
||||
import com.insanusmokrassar.postssystem.utils.repos.OneToManyKeyValueRepo
|
||||
import org.jetbrains.exposed.sql.*
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
|
||||
abstract class AbstractOneToManyExposedKeyValueRepo<Key, Value>(
|
||||
keyColumnAllocator: ColumnAllocator<Key>,
|
||||
valueColumnAllocator: ColumnAllocator<Value>,
|
||||
database: Database
|
||||
) : OneToManyKeyValueRepo<Key, Value>, AbstractOneToManyExposedReadKeyValueRepo<Key, Value>(
|
||||
keyColumnAllocator,
|
||||
valueColumnAllocator,
|
||||
database
|
||||
) {
|
||||
override suspend fun add(k: Key, v: Value) {
|
||||
transaction(database) {
|
||||
insert {
|
||||
it[keyColumn] = k
|
||||
it[valueColumn] = v
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun remove(k: Key, v: Value) {
|
||||
transaction(database) { deleteWhere { keyColumn.eq(k).and(valueColumn.eq(v)) } }
|
||||
}
|
||||
|
||||
override suspend fun clear(k: Key) {
|
||||
transaction(database) { deleteWhere { keyColumn.eq(k) } }
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package com.insanusmokrassar.budgetmanager.core.utils.repo.onetomany
|
||||
|
||||
import com.insanusmokrassar.postssystem.exposed.commons.paginate
|
||||
import com.insanusmokrassar.postssystem.utils.repos.OneToManyReadKeyValueRepo
|
||||
import com.insanusmokrassar.postssystem.utils.repos.pagination.*
|
||||
import org.jetbrains.exposed.sql.*
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
|
||||
typealias ColumnAllocator<T> = Table.() -> Column<T>
|
||||
|
||||
abstract class AbstractOneToManyExposedReadKeyValueRepo<Key, Value>(
|
||||
keyColumnAllocator: ColumnAllocator<Key>,
|
||||
valueColumnAllocator: ColumnAllocator<Value>,
|
||||
protected val database: Database
|
||||
) : OneToManyReadKeyValueRepo<Key, Value>, Table() {
|
||||
protected val keyColumn: Column<Key> = keyColumnAllocator()
|
||||
protected val valueColumn: Column<Value> = valueColumnAllocator()
|
||||
|
||||
override suspend fun count(k: Key): Long = transaction(database) { select { keyColumn.eq(k) }.count() }
|
||||
|
||||
override suspend fun count(): Long = transaction(database) { selectAll().count() }
|
||||
|
||||
override suspend fun get(
|
||||
k: Key,
|
||||
pagination: Pagination,
|
||||
reversed: Boolean
|
||||
): PaginationResult<Value> = transaction(database) {
|
||||
select { keyColumn.eq(k) }.paginate(pagination, keyColumn, reversed).map { it[valueColumn] }
|
||||
}.createPaginationResult(
|
||||
pagination,
|
||||
count(k)
|
||||
)
|
||||
|
||||
override suspend fun keys(pagination: Pagination, reversed: Boolean): PaginationResult<Key> = transaction(database) {
|
||||
selectAll().paginate(pagination, keyColumn, reversed).map { it[keyColumn] }
|
||||
}.createPaginationResult(
|
||||
pagination,
|
||||
count()
|
||||
)
|
||||
|
||||
override suspend fun contains(k: Key): Boolean = transaction(database) {
|
||||
select { keyColumn.eq(k) }.limit(1).any()
|
||||
}
|
||||
|
||||
override suspend fun contains(k: Key, v: Value): Boolean = transaction(database) {
|
||||
select { keyColumn.eq(k).and(valueColumn.eq(v)) }.limit(1).any()
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user