mirror of
https://github.com/InsanusMokrassar/MicroUtils.git
synced 2025-09-21 08:19:24 +00:00
Compare commits
24 Commits
Author | SHA1 | Date | |
---|---|---|---|
418af7874d | |||
4972cc9daa | |||
ff905e1491 | |||
64b0184a17 | |||
97cbe44fb5 | |||
452d8778c5 | |||
02ad1a748e | |||
c5a32e2b1b | |||
d34c5d845a | |||
82b39baada | |||
712ed06b69 | |||
3365c63e07 | |||
702300f761 | |||
efcaa08b70 | |||
7f7369b3a8 | |||
45a9a95888 | |||
90c1731bd1 | |||
893fd1ac07 | |||
9cac05f98b | |||
3babc94842 | |||
87230d010c | |||
f8a8808508 | |||
f44174b5b3 | |||
f6eb339cd0 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -10,3 +10,5 @@ build/
|
|||||||
out/
|
out/
|
||||||
|
|
||||||
secret.gradle
|
secret.gradle
|
||||||
|
|
||||||
|
publishing.sh
|
||||||
|
47
CHANGELOG.md
47
CHANGELOG.md
@@ -1,10 +1,46 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## 0.1.0
|
## 0.2.1
|
||||||
|
|
||||||
Inited :)
|
* `Pagination`
|
||||||
|
* `Common`:
|
||||||
|
* Extension `Pagination#reverse` has been added
|
||||||
|
* Factory `PaginationByIndexes`
|
||||||
|
* Shortcut `calculatePagesNumber` with reversed parameters
|
||||||
|
|
||||||
### 0.1.1
|
## 0.2.0
|
||||||
|
|
||||||
|
* `Repos`
|
||||||
|
* `Exposed`
|
||||||
|
* Now this project depend on `micro_utils.coroutines`
|
||||||
|
* Typealias `ColumnAllocator` has been replaced to root exposed package
|
||||||
|
* Interface `ExposedRepo` has been added
|
||||||
|
* `ExposedCRUDRepo` now extends `ExposedRepo` instead of simple `Repo`
|
||||||
|
* New extension `initTable` for classes which are `Table` and `ExposedRepo` at the same time
|
||||||
|
* `KeyValue`:
|
||||||
|
* `tableName` parameter
|
||||||
|
* Class `AbstractExposedReadKeyValueRepo`
|
||||||
|
* Renamed to `ExposedReadKeyValueRepo`
|
||||||
|
* Changed incoming types to `ColumnAllocator`
|
||||||
|
* `open` instead of `abstract`
|
||||||
|
* Implements `ExposedRepo`
|
||||||
|
* Class `AbstractExposedKeyValueRepo`
|
||||||
|
* Renamed to `ExposedKeyValueRepo`
|
||||||
|
* Changed incoming types to `ColumnAllocator`
|
||||||
|
* `open` instead of `abstract`
|
||||||
|
* `OneToMany`:
|
||||||
|
* `tableName` parameter
|
||||||
|
* Class `AbstractExposedReadOneToManyKeyValueRepo`
|
||||||
|
* Renamed to `ExposedReadOneToManyKeyValueRepo`
|
||||||
|
* Changed incoming arguments order
|
||||||
|
* Implements `ExposedRepo`
|
||||||
|
* Class `AbstractExposedOneToManyKeyValueRepo`
|
||||||
|
* Renamed to `ExposedKeyValueRepo`
|
||||||
|
* Changed incoming arguments order
|
||||||
|
* `open` instead of `abstract`
|
||||||
|
* Release for every `Flow` in parent interfaces
|
||||||
|
|
||||||
|
## 0.1.1
|
||||||
|
|
||||||
* `Versions`:
|
* `Versions`:
|
||||||
* `kotlinx.serialization`: `1.0.0-RC2` -> `1.0.0`
|
* `kotlinx.serialization`: `1.0.0-RC2` -> `1.0.0`
|
||||||
@@ -39,3 +75,8 @@ Inited :)
|
|||||||
* `MapCRUDRepo` class as implementation of `StandardCRUDRepo` on top of `MutableMap` has been added
|
* `MapCRUDRepo` class as implementation of `StandardCRUDRepo` on top of `MutableMap` has been added
|
||||||
* `MapKeyValueRepo` class as implementation of `StandardKeyValueRepo` on top of `MutableMap` has been added
|
* `MapKeyValueRepo` class as implementation of `StandardKeyValueRepo` on top of `MutableMap` has been added
|
||||||
* `MapOneToManyKeyValueRepo` class as implementation of `OneToManyKeyValueRepo` on top of `MutableMap` has been added
|
* `MapOneToManyKeyValueRepo` class as implementation of `OneToManyKeyValueRepo` on top of `MutableMap` has been added
|
||||||
|
|
||||||
|
|
||||||
|
## 0.1.0
|
||||||
|
|
||||||
|
Inited :)
|
12
build.gradle
12
build.gradle
@@ -14,11 +14,13 @@ buildscript {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
allprojects {
|
||||||
mavenLocal()
|
repositories {
|
||||||
jcenter()
|
mavenLocal()
|
||||||
mavenCentral()
|
jcenter()
|
||||||
maven { url "https://kotlin.bintray.com/kotlinx" }
|
mavenCentral()
|
||||||
|
maven { url "https://kotlin.bintray.com/kotlinx" }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
apply from: "./extensions.gradle"
|
apply from: "./extensions.gradle"
|
||||||
|
@@ -1,24 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
function parse() {
|
|
||||||
version=$1
|
|
||||||
|
|
||||||
while IFS= read -r line && [ -z "`echo $line | grep -e "^#\+ $version"`" ]
|
|
||||||
do
|
|
||||||
: # do nothing
|
|
||||||
done
|
|
||||||
|
|
||||||
while IFS= read -r line && [ -z "`echo $line | grep -e "^#\+"`" ]
|
|
||||||
do
|
|
||||||
echo "$line"
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
version=$1
|
|
||||||
file=$2
|
|
||||||
|
|
||||||
if [ -n "$file" ]; then
|
|
||||||
parse $version < "$file"
|
|
||||||
else
|
|
||||||
parse $version
|
|
||||||
fi
|
|
24
changelog_parser.sh
Executable file
24
changelog_parser.sh
Executable file
@@ -0,0 +1,24 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
function parse() {
|
||||||
|
version="$1"
|
||||||
|
|
||||||
|
while IFS= read -r line && [ -z "`echo "$line" | grep -e "^#\+ $version"`" ]
|
||||||
|
do
|
||||||
|
: # do nothing
|
||||||
|
done
|
||||||
|
|
||||||
|
while IFS= read -r line && [ -z "`echo "$line" | grep -e "^#\+"`" ]
|
||||||
|
do
|
||||||
|
echo "$line"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
version="$1"
|
||||||
|
file="$2"
|
||||||
|
|
||||||
|
if [ -n "$file" ]; then
|
||||||
|
parse "$version" < "$file"
|
||||||
|
else
|
||||||
|
parse "$version"
|
||||||
|
fi
|
@@ -1,8 +1,11 @@
|
|||||||
private String getCurrentVersionChangelog() {
|
private String getCurrentVersionChangelog() {
|
||||||
OutputStream changelogDataOS = new ByteArrayOutputStream()
|
OutputStream changelogDataOS = new ByteArrayOutputStream()
|
||||||
|
exec {
|
||||||
|
commandLine 'chmod', "+x", './changelog_parser.sh'
|
||||||
|
}
|
||||||
exec {
|
exec {
|
||||||
standardOutput = changelogDataOS
|
standardOutput = changelogDataOS
|
||||||
commandLine './changelog_info_retriever', "$library_version", 'CHANGELOG.md'
|
commandLine './changelog_parser.sh', "${project.version}", 'CHANGELOG.md'
|
||||||
}
|
}
|
||||||
|
|
||||||
return changelogDataOS.toString().trim()
|
return changelogDataOS.toString().trim()
|
||||||
@@ -18,9 +21,9 @@ if (new File(projectDir, "secret.gradle").exists()) {
|
|||||||
owner "InsanusMokrassar"
|
owner "InsanusMokrassar"
|
||||||
repo "MicroUtils"
|
repo "MicroUtils"
|
||||||
|
|
||||||
tagName "$library_version"
|
tagName "${project.version}"
|
||||||
releaseName "$library_version"
|
releaseName "${project.version}"
|
||||||
targetCommitish "$library_version"
|
targetCommitish "${project.version}"
|
||||||
|
|
||||||
body getCurrentVersionChangelog()
|
body getCurrentVersionChangelog()
|
||||||
}
|
}
|
||||||
|
@@ -19,4 +19,4 @@ github_release_plugin_version=2.2.12
|
|||||||
uuidVersion=0.2.2
|
uuidVersion=0.2.2
|
||||||
|
|
||||||
group=dev.inmo
|
group=dev.inmo
|
||||||
version=0.1.1
|
version=0.2.1
|
||||||
|
@@ -3,13 +3,6 @@ project.group = "$group"
|
|||||||
|
|
||||||
apply from: "$publishGradlePath"
|
apply from: "$publishGradlePath"
|
||||||
|
|
||||||
repositories {
|
|
||||||
jcenter()
|
|
||||||
mavenCentral()
|
|
||||||
maven { url "https://kotlin.bintray.com/kotlinx" }
|
|
||||||
mavenLocal()
|
|
||||||
}
|
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
jvm()
|
jvm()
|
||||||
|
|
||||||
|
@@ -3,13 +3,6 @@ project.group = "$group"
|
|||||||
|
|
||||||
apply from: "$publishGradlePath"
|
apply from: "$publishGradlePath"
|
||||||
|
|
||||||
repositories {
|
|
||||||
jcenter()
|
|
||||||
mavenCentral()
|
|
||||||
maven { url "https://kotlin.bintray.com/kotlinx" }
|
|
||||||
mavenLocal()
|
|
||||||
}
|
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
jvm()
|
jvm()
|
||||||
js (BOTH) {
|
js (BOTH) {
|
||||||
|
@@ -43,6 +43,11 @@ val Pagination.lastIndex: Int
|
|||||||
fun calculatePagesNumber(datasetSize: Long, pageSize: Int): Int {
|
fun calculatePagesNumber(datasetSize: Long, pageSize: Int): Int {
|
||||||
return ceil(datasetSize.toDouble() / pageSize).toInt()
|
return ceil(datasetSize.toDouble() / pageSize).toInt()
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Calculates pages count for given [datasetSize]. As a fact, it is shortcut for [calculatePagesNumber]
|
||||||
|
* @return calculated page number which can be correctly used in [PaginationResult] as [PaginationResult.page] value
|
||||||
|
*/
|
||||||
|
fun calculatePagesNumber(pageSize: Int, datasetSize: Long): Int = calculatePagesNumber(datasetSize, pageSize)
|
||||||
/**
|
/**
|
||||||
* Calculates pages count for given [datasetSize]
|
* Calculates pages count for given [datasetSize]
|
||||||
*/
|
*/
|
||||||
|
@@ -27,7 +27,21 @@ data class SimplePagination(
|
|||||||
override val size: Int
|
override val size: Int
|
||||||
) : Pagination
|
) : Pagination
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Factory for [SimplePagination]
|
||||||
|
*/
|
||||||
fun Pagination(
|
fun Pagination(
|
||||||
page: Int,
|
page: Int,
|
||||||
size: Int
|
size: Int
|
||||||
) = SimplePagination(page, size)
|
) = SimplePagination(page, size)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param firstIndex Inclusive first index of pagination
|
||||||
|
* @param lastIndex INCLUSIVE last index of pagination (last index of object covered by result [SimplePagination])
|
||||||
|
*/
|
||||||
|
fun PaginationByIndexes(
|
||||||
|
firstIndex: Int,
|
||||||
|
lastIndex: Int
|
||||||
|
) = maxOf(0, (lastIndex - firstIndex + 1)).let { size ->
|
||||||
|
Pagination(calculatePage(firstIndex, size), size)
|
||||||
|
}
|
||||||
|
@@ -0,0 +1,34 @@
|
|||||||
|
package dev.inmo.micro_utils.pagination.utils
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.pagination.*
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Example:
|
||||||
|
*
|
||||||
|
* * `|__f__l_______________________|` will be transformed to `|_______________________f__l__|`
|
||||||
|
* * `|__f__l_|` will be transformed to `|__f__l_|`
|
||||||
|
*
|
||||||
|
* @return Reversed version of this [Pagination]
|
||||||
|
*/
|
||||||
|
fun Pagination.reverse(objectsCount: Long): SimplePagination {
|
||||||
|
val firstIndex = (objectsCount - (this.lastIndex + 1)).let {
|
||||||
|
when {
|
||||||
|
it < 0 -> it
|
||||||
|
it > objectsCount -> objectsCount
|
||||||
|
else -> it
|
||||||
|
}
|
||||||
|
}.toInt()
|
||||||
|
val lastIndex = (objectsCount - (this.firstIndex + 1)).let {
|
||||||
|
when {
|
||||||
|
it < 0 -> it
|
||||||
|
it > objectsCount -> objectsCount
|
||||||
|
else -> it
|
||||||
|
}
|
||||||
|
}.toInt()
|
||||||
|
return PaginationByIndexes(firstIndex, lastIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shortcut for [reverse]
|
||||||
|
*/
|
||||||
|
fun Pagination.reverse(objectsCount: Int) = reverse(objectsCount.toLong())
|
@@ -0,0 +1,24 @@
|
|||||||
|
package dev.inmo.micro_utils.pagination.utils
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.pagination.*
|
||||||
|
import kotlin.test.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
class PaginationReversingTests {
|
||||||
|
@Test
|
||||||
|
fun testThatCommonCaseWorksOk() {
|
||||||
|
val pageSize = 2
|
||||||
|
val collectionSize = 8
|
||||||
|
val pages = calculatePage(collectionSize, pageSize)
|
||||||
|
|
||||||
|
doWithPagination(FirstPagePagination(pageSize)) {
|
||||||
|
val reversed = it.reverse(collectionSize.toLong())
|
||||||
|
assertEquals(Pagination(calculatePage(collectionSize - it.firstIndex - it.size, it.size), it.size), reversed)
|
||||||
|
if (it.page < pages) {
|
||||||
|
it.nextPage()
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -9,6 +9,7 @@ kotlin {
|
|||||||
sourceSets {
|
sourceSets {
|
||||||
commonMain {
|
commonMain {
|
||||||
dependencies {
|
dependencies {
|
||||||
|
api internalProject("micro_utils.coroutines")
|
||||||
api internalProject("micro_utils.repos.common")
|
api internalProject("micro_utils.repos.common")
|
||||||
api internalProject("micro_utils.pagination.exposed")
|
api internalProject("micro_utils.pagination.exposed")
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,6 @@
|
|||||||
|
package dev.inmo.micro_utils.repos.exposed
|
||||||
|
|
||||||
|
import org.jetbrains.exposed.sql.Column
|
||||||
|
import org.jetbrains.exposed.sql.Table
|
||||||
|
|
||||||
|
typealias ColumnAllocator<T> = Table.() -> Column<T>
|
@@ -3,9 +3,7 @@ package dev.inmo.micro_utils.repos.exposed
|
|||||||
import dev.inmo.micro_utils.repos.Repo
|
import dev.inmo.micro_utils.repos.Repo
|
||||||
import org.jetbrains.exposed.sql.*
|
import org.jetbrains.exposed.sql.*
|
||||||
|
|
||||||
interface ExposedCRUDRepo<ObjectType, IdType> : Repo {
|
interface ExposedCRUDRepo<ObjectType, IdType> : ExposedRepo {
|
||||||
val database: Database
|
|
||||||
|
|
||||||
val ResultRow.asObject: ObjectType
|
val ResultRow.asObject: ObjectType
|
||||||
val selectById: SqlExpressionBuilder.(IdType) -> Op<Boolean>
|
val selectById: SqlExpressionBuilder.(IdType) -> Op<Boolean>
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,8 @@
|
|||||||
|
package dev.inmo.micro_utils.repos.exposed
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.repos.Repo
|
||||||
|
import org.jetbrains.exposed.sql.Database
|
||||||
|
|
||||||
|
interface ExposedRepo : Repo {
|
||||||
|
val database: Database
|
||||||
|
}
|
@@ -6,3 +6,5 @@ import org.jetbrains.exposed.sql.transactions.transaction
|
|||||||
fun Table.initTable(database: Database) {
|
fun Table.initTable(database: Database) {
|
||||||
transaction(database) { SchemaUtils.createMissingTablesAndColumns(this@initTable) }
|
transaction(database) { SchemaUtils.createMissingTablesAndColumns(this@initTable) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun <T> T.initTable() where T: ExposedRepo, T: Table = initTable(database)
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
package dev.inmo.micro_utils.repos.exposed.keyvalue
|
package dev.inmo.micro_utils.repos.exposed.keyvalue
|
||||||
|
|
||||||
import dev.inmo.micro_utils.repos.StandardKeyValueRepo
|
import dev.inmo.micro_utils.repos.StandardKeyValueRepo
|
||||||
|
import dev.inmo.micro_utils.repos.exposed.*
|
||||||
import kotlinx.coroutines.channels.BroadcastChannel
|
import kotlinx.coroutines.channels.BroadcastChannel
|
||||||
import kotlinx.coroutines.channels.Channel
|
import kotlinx.coroutines.channels.Channel
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
@@ -8,14 +9,16 @@ import kotlinx.coroutines.flow.asFlow
|
|||||||
import org.jetbrains.exposed.sql.*
|
import org.jetbrains.exposed.sql.*
|
||||||
import org.jetbrains.exposed.sql.transactions.transaction
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
|
|
||||||
abstract class AbstractExposedKeyValueRepo<Key, Value>(
|
open class ExposedKeyValueRepo<Key, Value>(
|
||||||
database: Database,
|
database: Database,
|
||||||
keyColumn: Column<Key>,
|
keyColumnAllocator: ColumnAllocator<Key>,
|
||||||
valueColumn: Column<Value>
|
valueColumnAllocator: ColumnAllocator<Value>,
|
||||||
) : StandardKeyValueRepo<Key, Value>, AbstractExposedReadKeyValueRepo<Key, Value>(
|
tableName: String? = null
|
||||||
|
) : StandardKeyValueRepo<Key, Value>, ExposedReadKeyValueRepo<Key, Value>(
|
||||||
database,
|
database,
|
||||||
keyColumn,
|
keyColumnAllocator,
|
||||||
valueColumn
|
valueColumnAllocator,
|
||||||
|
tableName
|
||||||
) {
|
) {
|
||||||
private val onNewValueChannel = BroadcastChannel<Pair<Key, Value>>(Channel.BUFFERED)
|
private val onNewValueChannel = BroadcastChannel<Pair<Key, Value>>(Channel.BUFFERED)
|
||||||
private val onValueRemovedChannel = BroadcastChannel<Key>(Channel.BUFFERED)
|
private val onValueRemovedChannel = BroadcastChannel<Key>(Channel.BUFFERED)
|
||||||
@@ -46,3 +49,6 @@ abstract class AbstractExposedKeyValueRepo<Key, Value>(
|
|||||||
onValueRemovedChannel.send(k)
|
onValueRemovedChannel.send(k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated("Renamed", ReplaceWith("ExposedKeyValueRepo", "dev.inmo.micro_utils.repos.exposed.keyvalue.ExposedKeyValueRepo"))
|
||||||
|
typealias AbstractExposedKeyValueRepo<Key, Value> = ExposedKeyValueRepo<Key, Value>
|
@@ -2,14 +2,18 @@ package dev.inmo.micro_utils.repos.exposed.keyvalue
|
|||||||
|
|
||||||
import dev.inmo.micro_utils.pagination.*
|
import dev.inmo.micro_utils.pagination.*
|
||||||
import dev.inmo.micro_utils.repos.ReadStandardKeyValueRepo
|
import dev.inmo.micro_utils.repos.ReadStandardKeyValueRepo
|
||||||
|
import dev.inmo.micro_utils.repos.exposed.*
|
||||||
import org.jetbrains.exposed.sql.*
|
import org.jetbrains.exposed.sql.*
|
||||||
import org.jetbrains.exposed.sql.transactions.transaction
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
|
|
||||||
abstract class AbstractExposedReadKeyValueRepo<Key, Value>(
|
open class ExposedReadKeyValueRepo<Key, Value>(
|
||||||
protected val database: Database,
|
override val database: Database,
|
||||||
protected val keyColumn: Column<Key>,
|
keyColumnAllocator: ColumnAllocator<Key>,
|
||||||
protected val valueColumn: Column<Value>
|
valueColumnAllocator: ColumnAllocator<Value>,
|
||||||
) : ReadStandardKeyValueRepo<Key, Value>, Table() {
|
tableName: String? = null
|
||||||
|
) : ReadStandardKeyValueRepo<Key, Value>, ExposedRepo, Table(tableName ?: "") {
|
||||||
|
protected val keyColumn: Column<Key> = keyColumnAllocator()
|
||||||
|
protected val valueColumn: Column<Value> = valueColumnAllocator()
|
||||||
override val primaryKey: PrimaryKey = PrimaryKey(keyColumn, valueColumn)
|
override val primaryKey: PrimaryKey = PrimaryKey(keyColumn, valueColumn)
|
||||||
|
|
||||||
override suspend fun get(k: Key): Value? = transaction(database) {
|
override suspend fun get(k: Key): Value? = transaction(database) {
|
||||||
@@ -34,3 +38,6 @@ abstract class AbstractExposedReadKeyValueRepo<Key, Value>(
|
|||||||
}
|
}
|
||||||
}.createPaginationResult(pagination, count())
|
}.createPaginationResult(pagination, count())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated("Renamed", ReplaceWith("ExposedReadKeyValueRepo", "dev.inmo.micro_utils.repos.exposed.keyvalue.ExposedReadKeyValueRepo"))
|
||||||
|
typealias AbstractExposedReadKeyValueRepo<Key, Value> = ExposedReadKeyValueRepo<Key, Value>
|
@@ -1,35 +0,0 @@
|
|||||||
package dev.inmo.micro_utils.repos.exposed.onetomany
|
|
||||||
|
|
||||||
import dev.inmo.micro_utils.repos.OneToManyKeyValueRepo
|
|
||||||
import org.jetbrains.exposed.sql.*
|
|
||||||
import org.jetbrains.exposed.sql.transactions.transaction
|
|
||||||
|
|
||||||
abstract class AbstractExposedOneToManyKeyValueRepo<Key, Value>(
|
|
||||||
keyColumnAllocator: ColumnAllocator<Key>,
|
|
||||||
valueColumnAllocator: ColumnAllocator<Value>,
|
|
||||||
database: Database
|
|
||||||
) : OneToManyKeyValueRepo<Key, Value>, AbstractExposedReadOneToManyKeyValueRepo<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) } }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated("Renamed", ReplaceWith("AbstractExposedOneToManyKeyValueRepo", "dev.inmo.micro_utils.repos.exposed.onetomany.AbstractExposedOneToManyKeyValueRepo"))
|
|
||||||
typealias AbstractOneToManyExposedKeyValueRepo<Key, Value> = AbstractExposedOneToManyKeyValueRepo<Key, Value>
|
|
@@ -0,0 +1,58 @@
|
|||||||
|
package dev.inmo.micro_utils.repos.exposed.onetomany
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.coroutines.BroadcastFlow
|
||||||
|
import dev.inmo.micro_utils.repos.OneToManyKeyValueRepo
|
||||||
|
import dev.inmo.micro_utils.repos.exposed.ColumnAllocator
|
||||||
|
import dev.inmo.micro_utils.repos.exposed.initTable
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import org.jetbrains.exposed.sql.*
|
||||||
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
|
|
||||||
|
open class ExposedOneToManyKeyValueRepo<Key, Value>(
|
||||||
|
database: Database,
|
||||||
|
keyColumnAllocator: ColumnAllocator<Key>,
|
||||||
|
valueColumnAllocator: ColumnAllocator<Value>,
|
||||||
|
tableName: String? = null
|
||||||
|
) : OneToManyKeyValueRepo<Key, Value>, ExposedReadOneToManyKeyValueRepo<Key, Value>(
|
||||||
|
database,
|
||||||
|
keyColumnAllocator,
|
||||||
|
valueColumnAllocator,
|
||||||
|
tableName
|
||||||
|
) {
|
||||||
|
protected val _onNewValue: BroadcastFlow<Pair<Key, Value>> = BroadcastFlow()
|
||||||
|
override val onNewValue: Flow<Pair<Key, Value>>
|
||||||
|
get() = _onNewValue
|
||||||
|
protected val _onValueRemoved: BroadcastFlow<Pair<Key, Value>> = BroadcastFlow()
|
||||||
|
override val onValueRemoved: Flow<Pair<Key, Value>>
|
||||||
|
get() = _onValueRemoved
|
||||||
|
protected val _onDataCleared: BroadcastFlow<Key> = BroadcastFlow()
|
||||||
|
override val onDataCleared: Flow<Key>
|
||||||
|
get() = _onDataCleared
|
||||||
|
|
||||||
|
override suspend fun add(k: Key, v: Value) {
|
||||||
|
transaction(database) {
|
||||||
|
insert {
|
||||||
|
it[keyColumn] = k
|
||||||
|
it[valueColumn] = v
|
||||||
|
}
|
||||||
|
}.also { _onNewValue.send(k to v) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun remove(k: Key, v: Value) {
|
||||||
|
transaction(database) {
|
||||||
|
deleteWhere { keyColumn.eq(k).and(valueColumn.eq(v)) }
|
||||||
|
}.also { _onValueRemoved.send(k to v) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun clear(k: Key) {
|
||||||
|
transaction(database) {
|
||||||
|
deleteWhere { keyColumn.eq(k) }
|
||||||
|
}.also { _onDataCleared.send(k) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated("Renamed", ReplaceWith("ExposedOneToManyKeyValueRepo", "dev.inmo.micro_utils.repos.exposed.onetomany.ExposedOneToManyKeyValueRepo"))
|
||||||
|
typealias AbstractOneToManyExposedKeyValueRepo<Key, Value> = ExposedOneToManyKeyValueRepo<Key, Value>
|
||||||
|
|
||||||
|
@Deprecated("Renamed", ReplaceWith("ExposedOneToManyKeyValueRepo", "dev.inmo.micro_utils.repos.exposed.onetomany.ExposedOneToManyKeyValueRepo"))
|
||||||
|
typealias AbstractExposedOneToManyKeyValueRepo<Key, Value> = ExposedOneToManyKeyValueRepo<Key, Value>
|
@@ -2,19 +2,21 @@ package dev.inmo.micro_utils.repos.exposed.onetomany
|
|||||||
|
|
||||||
import dev.inmo.micro_utils.pagination.*
|
import dev.inmo.micro_utils.pagination.*
|
||||||
import dev.inmo.micro_utils.repos.ReadOneToManyKeyValueRepo
|
import dev.inmo.micro_utils.repos.ReadOneToManyKeyValueRepo
|
||||||
|
import dev.inmo.micro_utils.repos.exposed.*
|
||||||
import org.jetbrains.exposed.sql.*
|
import org.jetbrains.exposed.sql.*
|
||||||
import org.jetbrains.exposed.sql.transactions.transaction
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
|
|
||||||
typealias ColumnAllocator<T> = Table.() -> Column<T>
|
open class ExposedReadOneToManyKeyValueRepo<Key, Value>(
|
||||||
|
override val database: Database,
|
||||||
abstract class AbstractExposedReadOneToManyKeyValueRepo<Key, Value>(
|
|
||||||
keyColumnAllocator: ColumnAllocator<Key>,
|
keyColumnAllocator: ColumnAllocator<Key>,
|
||||||
valueColumnAllocator: ColumnAllocator<Value>,
|
valueColumnAllocator: ColumnAllocator<Value>,
|
||||||
protected val database: Database
|
tableName: String? = null
|
||||||
) : ReadOneToManyKeyValueRepo<Key, Value>, Table() {
|
) : ReadOneToManyKeyValueRepo<Key, Value>, ExposedRepo, Table(tableName ?: "") {
|
||||||
protected val keyColumn: Column<Key> = keyColumnAllocator()
|
protected val keyColumn: Column<Key> = keyColumnAllocator()
|
||||||
protected val valueColumn: Column<Value> = valueColumnAllocator()
|
protected val valueColumn: Column<Value> = valueColumnAllocator()
|
||||||
|
|
||||||
|
init { initTable() }
|
||||||
|
|
||||||
override suspend fun count(k: Key): Long = transaction(database) { select { keyColumn.eq(k) }.count() }
|
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 count(): Long = transaction(database) { selectAll().count() }
|
||||||
@@ -46,5 +48,8 @@ abstract class AbstractExposedReadOneToManyKeyValueRepo<Key, Value>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated("Renamed", ReplaceWith("AbstractExposedReadOneToManyKeyValueRepo", "dev.inmo.micro_utils.repos.exposed.onetomany.AbstractExposedReadOneToManyKeyValueRepo"))
|
@Deprecated("Renamed", ReplaceWith("ExposedReadOneToManyKeyValueRepo", "dev.inmo.micro_utils.repos.exposed.onetomany.ExposedReadOneToManyKeyValueRepo"))
|
||||||
typealias AbstractOneToManyExposedReadKeyValueRepo<Key, Value> = AbstractExposedReadOneToManyKeyValueRepo<Key, Value>
|
typealias AbstractOneToManyExposedReadKeyValueRepo<Key, Value> = ExposedReadOneToManyKeyValueRepo<Key, Value>
|
||||||
|
|
||||||
|
@Deprecated("Renamed", ReplaceWith("ExposedReadOneToManyKeyValueRepo", "dev.inmo.micro_utils.repos.exposed.onetomany.ExposedReadOneToManyKeyValueRepo"))
|
||||||
|
typealias AbstractExposedReadOneToManyKeyValueRepo<Key, Value> = ExposedReadOneToManyKeyValueRepo<Key, Value>
|
@@ -2,6 +2,8 @@ package dev.inmo.micro_utils.repos
|
|||||||
|
|
||||||
import dev.inmo.micro_utils.coroutines.BroadcastFlow
|
import dev.inmo.micro_utils.coroutines.BroadcastFlow
|
||||||
import dev.inmo.micro_utils.pagination.*
|
import dev.inmo.micro_utils.pagination.*
|
||||||
|
import dev.inmo.micro_utils.pagination.utils.paginate
|
||||||
|
import dev.inmo.micro_utils.pagination.utils.reverse
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
class ReadMapKeyValueRepo<Key, Value>(
|
class ReadMapKeyValueRepo<Key, Value>(
|
||||||
@@ -13,31 +15,27 @@ class ReadMapKeyValueRepo<Key, Value>(
|
|||||||
pagination: Pagination,
|
pagination: Pagination,
|
||||||
reversed: Boolean
|
reversed: Boolean
|
||||||
): PaginationResult<Value> {
|
): PaginationResult<Value> {
|
||||||
val firstIndex: Int = if (reversed) {
|
val values = map.values
|
||||||
val size = map.size
|
val actualPagination = if (reversed) pagination.reverse(values.size) else pagination
|
||||||
(size - pagination.lastIndex).let { if (it < 0) 0 else it }
|
return values.paginate(actualPagination).let {
|
||||||
} else {
|
if (reversed) {
|
||||||
pagination.firstIndex
|
it.copy(results = it.results.reversed())
|
||||||
|
} else {
|
||||||
|
it
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return map.keys.drop(firstIndex).take(pagination.size).mapNotNull { map[it] }.createPaginationResult(
|
|
||||||
firstIndex,
|
|
||||||
count()
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun keys(pagination: Pagination, reversed: Boolean): PaginationResult<Key> {
|
override suspend fun keys(pagination: Pagination, reversed: Boolean): PaginationResult<Key> {
|
||||||
val firstIndex: Int = if (reversed) {
|
val keys = map.keys
|
||||||
val size = map.size
|
val actualPagination = if (reversed) pagination.reverse(keys.size) else pagination
|
||||||
(size - pagination.lastIndex).let { if (it < 0) 0 else it }
|
return keys.paginate(actualPagination).let {
|
||||||
} else {
|
if (reversed) {
|
||||||
pagination.firstIndex
|
it.copy(results = it.results.reversed())
|
||||||
|
} else {
|
||||||
|
it
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return map.keys.drop(firstIndex).take(pagination.size).createPaginationResult(
|
|
||||||
firstIndex,
|
|
||||||
count()
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun contains(key: Key): Boolean = map.containsKey(key)
|
override suspend fun contains(key: Key): Boolean = map.containsKey(key)
|
||||||
|
@@ -3,6 +3,7 @@ package dev.inmo.micro_utils.repos
|
|||||||
import dev.inmo.micro_utils.coroutines.BroadcastFlow
|
import dev.inmo.micro_utils.coroutines.BroadcastFlow
|
||||||
import dev.inmo.micro_utils.pagination.*
|
import dev.inmo.micro_utils.pagination.*
|
||||||
import dev.inmo.micro_utils.pagination.utils.paginate
|
import dev.inmo.micro_utils.pagination.utils.paginate
|
||||||
|
import dev.inmo.micro_utils.pagination.utils.reverse
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
class MapReadOneToManyKeyValueRepo<Key, Value>(
|
class MapReadOneToManyKeyValueRepo<Key, Value>(
|
||||||
@@ -13,8 +14,7 @@ class MapReadOneToManyKeyValueRepo<Key, Value>(
|
|||||||
|
|
||||||
return list.paginate(
|
return list.paginate(
|
||||||
if (reversed) {
|
if (reversed) {
|
||||||
val firstIndex = (map.size - pagination.lastIndex).let { if (it < 0) 0 else it }
|
pagination.reverse(list.size)
|
||||||
SimplePagination(firstIndex, pagination.size)
|
|
||||||
} else {
|
} else {
|
||||||
pagination
|
pagination
|
||||||
}
|
}
|
||||||
@@ -22,17 +22,15 @@ class MapReadOneToManyKeyValueRepo<Key, Value>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun keys(pagination: Pagination, reversed: Boolean): PaginationResult<Key> {
|
override suspend fun keys(pagination: Pagination, reversed: Boolean): PaginationResult<Key> {
|
||||||
val firstIndex: Int = if (reversed) {
|
val keys = map.keys
|
||||||
val size = map.size
|
val actualPagination = if (reversed) pagination.reverse(keys.size) else pagination
|
||||||
(size - pagination.lastIndex).let { if (it < 0) 0 else it }
|
return keys.paginate(actualPagination).let {
|
||||||
} else {
|
if (reversed) {
|
||||||
pagination.firstIndex
|
it.copy(results = it.results.reversed())
|
||||||
|
} else {
|
||||||
|
it
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return map.keys.drop(firstIndex).take(pagination.size).createPaginationResult(
|
|
||||||
firstIndex,
|
|
||||||
count()
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun contains(k: Key): Boolean = map.containsKey(k)
|
override suspend fun contains(k: Key): Boolean = map.containsKey(k)
|
||||||
|
Reference in New Issue
Block a user