Compare commits

...

12 Commits
0.2.0 ... 0.2.1

15 changed files with 160 additions and 74 deletions

View File

@@ -1,5 +1,13 @@
# Changelog
## 0.2.1
* `Pagination`
* `Common`:
* Extension `Pagination#reverse` has been added
* Factory `PaginationByIndexes`
* Shortcut `calculatePagesNumber` with reversed parameters
## 0.2.0
* `Repos`
@@ -10,6 +18,7 @@
* `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`
@@ -20,6 +29,7 @@
* Changed incoming types to `ColumnAllocator`
* `open` instead of `abstract`
* `OneToMany`:
* `tableName` parameter
* Class `AbstractExposedReadOneToManyKeyValueRepo`
* Renamed to `ExposedReadOneToManyKeyValueRepo`
* Changed incoming arguments order

View File

@@ -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
View 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

View File

@@ -1,8 +1,11 @@
private String getCurrentVersionChangelog() {
OutputStream changelogDataOS = new ByteArrayOutputStream()
exec {
commandLine 'chmod', "+x", './changelog_parser.sh'
}
exec {
standardOutput = changelogDataOS
commandLine './changelog_info_retriever', "$library_version", 'CHANGELOG.md'
commandLine './changelog_parser.sh', "${project.version}", 'CHANGELOG.md'
}
return changelogDataOS.toString().trim()
@@ -18,9 +21,9 @@ if (new File(projectDir, "secret.gradle").exists()) {
owner "InsanusMokrassar"
repo "MicroUtils"
tagName "$library_version"
releaseName "$library_version"
targetCommitish "$library_version"
tagName "${project.version}"
releaseName "${project.version}"
targetCommitish "${project.version}"
body getCurrentVersionChangelog()
}

View File

@@ -19,4 +19,4 @@ github_release_plugin_version=2.2.12
uuidVersion=0.2.2
group=dev.inmo
version=0.2.0
version=0.2.1

View File

@@ -43,6 +43,11 @@ val Pagination.lastIndex: Int
fun calculatePagesNumber(datasetSize: Long, pageSize: Int): Int {
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]
*/

View File

@@ -27,7 +27,21 @@ data class SimplePagination(
override val size: Int
) : Pagination
/**
* Factory for [SimplePagination]
*/
fun Pagination(
page: Int,
size: Int
) = 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)
}

View File

@@ -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())

View File

@@ -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
}
}
}
}

View File

@@ -12,11 +12,13 @@ import org.jetbrains.exposed.sql.transactions.transaction
open class ExposedKeyValueRepo<Key, Value>(
database: Database,
keyColumnAllocator: ColumnAllocator<Key>,
valueColumnAllocator: ColumnAllocator<Value>
valueColumnAllocator: ColumnAllocator<Value>,
tableName: String? = null
) : StandardKeyValueRepo<Key, Value>, ExposedReadKeyValueRepo<Key, Value>(
database,
keyColumnAllocator,
valueColumnAllocator
valueColumnAllocator,
tableName
) {
private val onNewValueChannel = BroadcastChannel<Pair<Key, Value>>(Channel.BUFFERED)
private val onValueRemovedChannel = BroadcastChannel<Key>(Channel.BUFFERED)
@@ -24,8 +26,6 @@ open class ExposedKeyValueRepo<Key, Value>(
override val onNewValue: Flow<Pair<Key, Value>> = onNewValueChannel.asFlow()
override val onValueRemoved: Flow<Key> = onValueRemovedChannel.asFlow()
init { initTable() }
override suspend fun set(k: Key, v: Value) {
transaction(database) {
if (select { keyColumn.eq(k) }.limit(1).any()) {

View File

@@ -10,13 +10,12 @@ open class ExposedReadKeyValueRepo<Key, Value>(
override val database: Database,
keyColumnAllocator: ColumnAllocator<Key>,
valueColumnAllocator: ColumnAllocator<Value>,
) : ReadStandardKeyValueRepo<Key, Value>, ExposedRepo, 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)
init { initTable() }
override suspend fun get(k: Key): Value? = transaction(database) {
select { keyColumn.eq(k) }.limit(1).firstOrNull() ?.getOrNull(valueColumn)
}

View File

@@ -11,11 +11,13 @@ import org.jetbrains.exposed.sql.transactions.transaction
open class ExposedOneToManyKeyValueRepo<Key, Value>(
database: Database,
keyColumnAllocator: ColumnAllocator<Key>,
valueColumnAllocator: ColumnAllocator<Value>
valueColumnAllocator: ColumnAllocator<Value>,
tableName: String? = null
) : OneToManyKeyValueRepo<Key, Value>, ExposedReadOneToManyKeyValueRepo<Key, Value>(
database,
keyColumnAllocator,
valueColumnAllocator
valueColumnAllocator,
tableName
) {
protected val _onNewValue: BroadcastFlow<Pair<Key, Value>> = BroadcastFlow()
override val onNewValue: Flow<Pair<Key, Value>>
@@ -27,8 +29,6 @@ open class ExposedOneToManyKeyValueRepo<Key, Value>(
override val onDataCleared: Flow<Key>
get() = _onDataCleared
init { initTable() }
override suspend fun add(k: Key, v: Value) {
transaction(database) {
insert {

View File

@@ -9,8 +9,9 @@ import org.jetbrains.exposed.sql.transactions.transaction
open class ExposedReadOneToManyKeyValueRepo<Key, Value>(
override val database: Database,
keyColumnAllocator: ColumnAllocator<Key>,
valueColumnAllocator: ColumnAllocator<Value>
) : ReadOneToManyKeyValueRepo<Key, Value>, ExposedRepo, Table() {
valueColumnAllocator: ColumnAllocator<Value>,
tableName: String? = null
) : ReadOneToManyKeyValueRepo<Key, Value>, ExposedRepo, Table(tableName ?: "") {
protected val keyColumn: Column<Key> = keyColumnAllocator()
protected val valueColumn: Column<Value> = valueColumnAllocator()

View File

@@ -2,6 +2,8 @@ package dev.inmo.micro_utils.repos
import dev.inmo.micro_utils.coroutines.BroadcastFlow
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
class ReadMapKeyValueRepo<Key, Value>(
@@ -13,31 +15,27 @@ class ReadMapKeyValueRepo<Key, Value>(
pagination: Pagination,
reversed: Boolean
): PaginationResult<Value> {
val firstIndex: Int = if (reversed) {
val size = map.size
(size - pagination.lastIndex).let { if (it < 0) 0 else it }
} else {
pagination.firstIndex
val values = map.values
val actualPagination = if (reversed) pagination.reverse(values.size) else pagination
return values.paginate(actualPagination).let {
if (reversed) {
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> {
val firstIndex: Int = if (reversed) {
val size = map.size
(size - pagination.lastIndex).let { if (it < 0) 0 else it }
} else {
pagination.firstIndex
val keys = map.keys
val actualPagination = if (reversed) pagination.reverse(keys.size) else pagination
return keys.paginate(actualPagination).let {
if (reversed) {
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)

View File

@@ -3,6 +3,7 @@ package dev.inmo.micro_utils.repos
import dev.inmo.micro_utils.coroutines.BroadcastFlow
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
class MapReadOneToManyKeyValueRepo<Key, Value>(
@@ -13,8 +14,7 @@ class MapReadOneToManyKeyValueRepo<Key, Value>(
return list.paginate(
if (reversed) {
val firstIndex = (map.size - pagination.lastIndex).let { if (it < 0) 0 else it }
SimplePagination(firstIndex, pagination.size)
pagination.reverse(list.size)
} else {
pagination
}
@@ -22,17 +22,15 @@ class MapReadOneToManyKeyValueRepo<Key, Value>(
}
override suspend fun keys(pagination: Pagination, reversed: Boolean): PaginationResult<Key> {
val firstIndex: Int = if (reversed) {
val size = map.size
(size - pagination.lastIndex).let { if (it < 0) 0 else it }
} else {
pagination.firstIndex
val keys = map.keys
val actualPagination = if (reversed) pagination.reverse(keys.size) else pagination
return keys.paginate(actualPagination).let {
if (reversed) {
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)