Merge pull request #52 from InsanusMokrassar/0.4.29

0.4.29
This commit is contained in:
InsanusMokrassar 2021-03-05 20:45:34 +06:00 committed by GitHub
commit e0cc780887
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 114 additions and 78 deletions

View File

@ -1,16 +0,0 @@
name: Build
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Build with Gradle
run: ./gradlew build

24
.github/workflows/packages_push.yml vendored Normal file
View File

@ -0,0 +1,24 @@
name: Publish package to GitHub Packages
on: [push]
jobs:
publishing:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Rewrite version
run: |
branch="`echo "${{ github.ref }}" | grep -o "[^/]*$"`"
cat gradle.properties | sed -e "s/^version=\([0-9\.]*\)/version=\1-branch_$branch-build${{ github.run_number }}/" > gradle.properties.tmp
rm gradle.properties
mv gradle.properties.tmp gradle.properties
- name: Build
run: ./gradlew build
- name: Publish
run: ./gradlew --no-parallel publishAllPublicationsToGithubPackagesRepository -x signJsPublication -x signJvmPublication -x signKotlinMultiplatformPublication -x signMetadataPublication -x signAndroidDebugPublication -x signAndroidReleasePublication -x signKotlinMultiplatformPublication
env:
GITHUBPACKAGES_USER: ${{ github.actor }}
GITHUBPACKAGES_PASSWORD: ${{ secrets.GITHUB_TOKEN }}

View File

@ -1,5 +1,16 @@
# Changelog
## 0.4.29
* `Versions`:
* `Coroutines`: `1.4.2` -> `1.4.3`
* `Repos`:
* `Common`
* `Android`:
* New `blockingReadableTransaction`/`blockingWritableTransaction`
* Android databases realizations now use blocking transactions where it is possible
* Several improvements in transactions work
## 0.4.28
* `Versions`:

View File

@ -7,7 +7,7 @@ android.useAndroidX=true
android.enableJetifier=true
kotlin_version=1.4.31
kotlin_coroutines_version=1.4.2
kotlin_coroutines_version=1.4.3
kotlin_serialisation_core_version=1.1.0
kotlin_exposed_version=0.29.1
@ -44,5 +44,5 @@ dokka_version=1.4.20
# Project data
group=dev.inmo
version=0.4.28
android_code_version=32
version=0.4.29
android_code_version=33

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View File

@ -1 +0,0 @@
{"bintrayConfig":{"repo":"MicroUtils","packageName":"${project.name}","packageVcs":"https://github.com/InsanusMokrassar/MicroUtils","autoPublish":true,"overridePublish":true},"licenses":[{"id":"Apache-2.0","title":"Apache Software License 2.0","url":"https://git.inmo.dev/InsanusMokrassar/MicroUtils_mirror/src/master/LICENSE"}],"mavenConfig":{"name":"${project.name}","description":"It is set of projects with micro tools for avoiding of routines coding","url":"https://git.inmo.dev/InsanusMokrassar/MicroUtils_mirror","vcsUrl":"ssh://git@git.inmo.dev:8322/InsanusMokrassar/MicroUtils_mirror.git","includeGpgSigning":true,"publishToMavenCentral":true,"developers":[{"id":"InsanusMokrassar","name":"Aleksei Ovsiannikov","eMail":"ovsyannikov.alexey95@gmail.com"},{"id":"000Sanya","name":"Syrov Aleksandr","eMail":"000sanya.000sanya@gmail.com"}]}}

View File

@ -12,11 +12,11 @@ publishing {
pom {
description = "It is set of projects with micro tools for avoiding of routines coding"
name = "${project.name}"
url = "https://git.inmo.dev/InsanusMokrassar/MicroUtils_mirror"
url = "https://github.com/InsanusMokrassar/MicroUtils/"
scm {
developerConnection = "scm:git:[fetch=]ssh://git@git.inmo.dev:8322/InsanusMokrassar/MicroUtils_mirror.git[push=]ssh://git@git.inmo.dev:8322/InsanusMokrassar/MicroUtils_mirror.git"
url = "ssh://git@git.inmo.dev:8322/InsanusMokrassar/MicroUtils_mirror.git"
developerConnection = "scm:git:[fetch=]https://github.com/InsanusMokrassar/MicroUtils.git[push=]https://github.com/InsanusMokrassar/MicroUtils.git"
url = "https://github.com/InsanusMokrassar/MicroUtils.git"
}
developers {
@ -40,33 +40,33 @@ publishing {
license {
name = "Apache Software License 2.0"
url = "https://git.inmo.dev/InsanusMokrassar/MicroUtils_mirror/src/master/LICENSE"
url = "https://github.com/InsanusMokrassar/MicroUtils/blob/master/LICENSE"
}
}
}
repositories {
maven {
name = "bintray"
url = uri("https://api.bintray.com/maven/${project.hasProperty('BINTRAY_USER') ? project.property('BINTRAY_USER') : System.getenv('BINTRAY_USER')}/MicroUtils/${project.name}/;publish=1;override=1")
credentials {
username = project.hasProperty('BINTRAY_USER') ? project.property('BINTRAY_USER') : System.getenv('BINTRAY_USER')
password = project.hasProperty('BINTRAY_KEY') ? project.property('BINTRAY_KEY') : System.getenv('BINTRAY_KEY')
if ((project.hasProperty('GITHUBPACKAGES_USER') || System.getenv('GITHUBPACKAGES_USER') != null) && (project.hasProperty('GITHUBPACKAGES_PASSWORD') || System.getenv('GITHUBPACKAGES_PASSWORD') != null)) {
maven {
name = "GithubPackages"
url = uri("https://maven.pkg.github.com/InsanusMokrassar/MicroUtils")
credentials {
username = project.hasProperty('GITHUBPACKAGES_USER') ? project.property('GITHUBPACKAGES_USER') : System.getenv('GITHUBPACKAGES_USER')
password = project.hasProperty('GITHUBPACKAGES_PASSWORD') ? project.property('GITHUBPACKAGES_PASSWORD') : System.getenv('GITHUBPACKAGES_PASSWORD')
}
}
}
maven {
name = "sonatype"
url = uri("https://oss.sonatype.org/service/local/staging/deploy/maven2/")
credentials {
username = project.hasProperty('SONATYPE_USER') ? project.property('SONATYPE_USER') : System.getenv('SONATYPE_USER')
password = project.hasProperty('SONATYPE_PASSWORD') ? project.property('SONATYPE_PASSWORD') : System.getenv('SONATYPE_PASSWORD')
if ((project.hasProperty('SONATYPE_USER') || System.getenv('SONATYPE_USER') != null) && (project.hasProperty('SONATYPE_PASSWORD') || System.getenv('SONATYPE_PASSWORD') != null)) {
maven {
name = "sonatype"
url = uri("https://oss.sonatype.org/service/local/staging/deploy/maven2/")
credentials {
username = project.hasProperty('SONATYPE_USER') ? project.property('SONATYPE_USER') : System.getenv('SONATYPE_USER')
password = project.hasProperty('SONATYPE_PASSWORD') ? project.property('SONATYPE_PASSWORD') : System.getenv('SONATYPE_PASSWORD')
}
}
}
}
}
}

1
publish.kpsb Normal file
View File

@ -0,0 +1 @@
{"licenses":[{"id":"Apache-2.0","title":"Apache Software License 2.0","url":"https://github.com/InsanusMokrassar/MicroUtils/blob/master/LICENSE"}],"mavenConfig":{"name":"${project.name}","description":"It is set of projects with micro tools for avoiding of routines coding","url":"https://github.com/InsanusMokrassar/MicroUtils/","vcsUrl":"https://github.com/InsanusMokrassar/MicroUtils.git","includeGpgSigning":true,"developers":[{"id":"InsanusMokrassar","name":"Aleksei Ovsiannikov","eMail":"ovsyannikov.alexey95@gmail.com"},{"id":"000Sanya","name":"Syrov Aleksandr","eMail":"000sanya.000sanya@gmail.com"}],"repositories":[{"name":"GithubPackages","url":"https://maven.pkg.github.com/InsanusMokrassar/MicroUtils"},{"name":"sonatype","url":"https://oss.sonatype.org/service/local/staging/deploy/maven2/"}]}}

View File

@ -32,7 +32,9 @@ private object ContextsPool {
suspend fun <T> use(block: suspend (CoroutineContext) -> T): T = acquireContext().let {
try {
block(it)
safely {
block(it)
}
} finally {
freeContext(it)
}
@ -48,11 +50,12 @@ class TransactionContext(
}
suspend fun <T> SQLiteDatabase.transaction(block: suspend SQLiteDatabase.() -> T): T {
return coroutineContext[TransactionContext] ?.let {
withContext(it.databaseContext) {
coroutineContext[TransactionContext] ?.let {
return withContext(it.databaseContext) {
block()
}
} ?: ContextsPool.use { context ->
}
return ContextsPool.use { context ->
withContext(TransactionContext(context) + context) {
beginTransaction()
safely(
@ -70,18 +73,18 @@ suspend fun <T> SQLiteDatabase.transaction(block: suspend SQLiteDatabase.() -> T
}
}
inline fun <T> SQLiteDatabase.inlineTransaction(block: SQLiteDatabase.() -> T): T {
inline fun <T> SQLiteDatabase.inlineTransaction(crossinline block: SQLiteDatabase.() -> T): T {
return when {
inTransaction() -> block()
else -> {
beginTransaction()
try {
block().also {
setTransactionSuccessful()
}
block().also { setTransactionSuccessful() }
} finally {
endTransaction()
}
}
}
}
fun <T> SQLiteDatabase.blockingTransaction(block: SQLiteDatabase.() -> T): T = inlineTransaction(block)

View File

@ -31,6 +31,20 @@ class StandardSQLHelper(
suspend fun <T> readableTransaction(block: suspend SQLiteDatabase.() -> T): T = sqlOpenHelper.readableTransaction(block)
}
fun <T> SQLiteOpenHelper.blockingWritableTransaction(block: SQLiteDatabase.() -> T): T {
return writableDatabase.blockingTransaction(block)
}
fun <T> SQLiteOpenHelper.blockingReadableTransaction(block: SQLiteDatabase.() -> T): T {
return readableDatabase.blockingTransaction(block)
}
fun <T> StandardSQLHelper.blockingWritableTransaction(block: SQLiteDatabase.() -> T): T {
return sqlOpenHelper.blockingWritableTransaction(block)
}
fun <T> StandardSQLHelper.blockingReadableTransaction(block: SQLiteDatabase.() -> T): T {
return sqlOpenHelper.blockingReadableTransaction(block)
}
suspend fun <T> SQLiteOpenHelper.writableTransaction(block: suspend SQLiteDatabase.() -> T): T {
return writableDatabase.transaction(block)
}

View File

@ -20,7 +20,7 @@ abstract class AbstractAndroidCRUDRepo<ObjectType, IdType>(
it.count
}.toLong()
override suspend fun contains(id: IdType): Boolean = helper.readableTransaction {
override suspend fun contains(id: IdType): Boolean = helper.blockingReadableTransaction {
select(
tableName,
null,

View File

@ -19,9 +19,10 @@ abstract class AbstractMutableAndroidCRUDRepo<ObjectType, IdType, InputValueType
protected abstract suspend fun InputValueType.asContentValues(id: IdType? = null): ContentValues
override suspend fun create(values: List<InputValueType>): List<ObjectType> {
val indexes = helper.writableTransaction {
values.map {
insert(tableName, null, it.asContentValues())
val valuesContentValues = values.map { it.asContentValues() }
val indexes = helper.blockingWritableTransaction {
valuesContentValues.map {
insert(tableName, null, it)
}
}
return helper.readableTransaction {
@ -47,7 +48,7 @@ abstract class AbstractMutableAndroidCRUDRepo<ObjectType, IdType, InputValueType
override suspend fun deleteById(ids: List<IdType>) {
val deleted = mutableListOf<IdType>()
helper.writableTransaction {
helper.blockingWritableTransaction {
ids.forEach { id ->
delete(tableName, "$idColumnName=?", arrayOf(id.asId)).also {
if (it > 0) {
@ -64,7 +65,7 @@ abstract class AbstractMutableAndroidCRUDRepo<ObjectType, IdType, InputValueType
override suspend fun update(id: IdType, value: InputValueType): ObjectType? {
val asContentValues = value.asContentValues(id)
if (asContentValues.keySet().isNotEmpty()) {
helper.writableTransaction {
helper.blockingWritableTransaction {
update(
tableName,
asContentValues,
@ -79,11 +80,12 @@ abstract class AbstractMutableAndroidCRUDRepo<ObjectType, IdType, InputValueType
}
override suspend fun update(values: List<UpdatedValuePair<IdType, InputValueType>>): List<ObjectType> {
val contentValues = values.map { (id, value) -> id to value.asContentValues(id) }
helper.writableTransaction {
values.forEach { (id, value) ->
contentValues.forEach { (id, contentValues) ->
update(
tableName,
value.asContentValues(id),
contentValues,
"$idColumnName=?",
arrayOf(id.asId)
)
@ -98,5 +100,5 @@ abstract class AbstractMutableAndroidCRUDRepo<ObjectType, IdType, InputValueType
}
}
override suspend fun count(): Long = helper.readableTransaction { select(tableName).use { it.count.toLong() } }
override suspend fun count(): Long = helper.blockingReadableTransaction { select(tableName).use { it.count.toLong() } }
}

View File

@ -42,21 +42,19 @@ class OneToManyAndroidRepo<Key, Value>(
private fun String.asKey(): Key = internalSerialFormat.decodeFromString(keySerializer, this)
init {
runBlocking(DatabaseCoroutineContext) {
helper.writableTransaction {
createTable(
tableName,
internalId to internalIdType,
idColumnName to ColumnType.Text.NOT_NULLABLE,
valueColumnName to ColumnType.Text.NULLABLE
)
}
helper.blockingWritableTransaction {
createTable(
tableName,
internalId to internalIdType,
idColumnName to ColumnType.Text.NOT_NULLABLE,
valueColumnName to ColumnType.Text.NULLABLE
)
}
}
override suspend fun add(toAdd: Map<Key, List<Value>>) {
val added = mutableListOf<Pair<Key, Value>>()
helper.writableTransaction {
helper.blockingWritableTransaction {
toAdd.forEach { (k, values) ->
values.forEach { v ->
insert(
@ -78,7 +76,7 @@ class OneToManyAndroidRepo<Key, Value>(
}
override suspend fun clear(k: Key) {
helper.writableTransaction {
helper.blockingWritableTransaction {
delete(tableName, "$idColumnName=?", arrayOf(k.asId()))
}.also {
if (it > 0) {
@ -88,7 +86,7 @@ class OneToManyAndroidRepo<Key, Value>(
}
override suspend fun set(toSet: Map<Key, List<Value>>) {
val (clearedKeys, inserted) = helper.writableTransaction {
val (clearedKeys, inserted) = helper.blockingWritableTransaction {
toSet.mapNotNull { (k, _) ->
if (delete(tableName, "$idColumnName=?", arrayOf(k.asId())) > 0) {
k
@ -110,13 +108,13 @@ class OneToManyAndroidRepo<Key, Value>(
inserted.forEach { newPair -> _onNewValue.emit(newPair) }
}
override suspend fun contains(k: Key): Boolean = helper.readableTransaction {
override suspend fun contains(k: Key): Boolean = helper.blockingReadableTransaction {
select(tableName, selection = "$idColumnName=?", selectionArgs = arrayOf(k.asId()), limit = FirstPagePagination(1).limitClause()).use {
it.count > 0
}
}
override suspend fun contains(k: Key, v: Value): Boolean = helper.readableTransaction {
override suspend fun contains(k: Key, v: Value): Boolean = helper.blockingReadableTransaction {
select(
tableName,
selection = "$idColumnName=? AND $valueColumnName=?",
@ -127,7 +125,7 @@ class OneToManyAndroidRepo<Key, Value>(
}
}
override suspend fun count(): Long =helper.readableTransaction {
override suspend fun count(): Long =helper.blockingReadableTransaction {
select(
tableName
).use {
@ -135,7 +133,7 @@ class OneToManyAndroidRepo<Key, Value>(
}
}.toLong()
override suspend fun count(k: Key): Long = helper.readableTransaction {
override suspend fun count(k: Key): Long = helper.blockingReadableTransaction {
select(tableName, selection = "$idColumnName=?", selectionArgs = arrayOf(k.asId()), limit = FirstPagePagination(1).limitClause()).use {
it.count
}
@ -147,7 +145,7 @@ class OneToManyAndroidRepo<Key, Value>(
reversed: Boolean
): PaginationResult<Value> = count(k).let { count ->
val resultPagination = pagination.let { if (reversed) pagination.reverse(count) else pagination }
helper.readableTransaction {
helper.blockingReadableTransaction {
select(
tableName,
selection = "$idColumnName=?",
@ -173,7 +171,7 @@ class OneToManyAndroidRepo<Key, Value>(
reversed: Boolean
): PaginationResult<Key> = count().let { count ->
val resultPagination = pagination.let { if (reversed) pagination.reverse(count) else pagination }
helper.readableTransaction {
helper.blockingReadableTransaction {
select(
tableName,
limit = resultPagination.limitClause()
@ -198,7 +196,7 @@ class OneToManyAndroidRepo<Key, Value>(
reversed: Boolean
): PaginationResult<Key> = count().let { count ->
val resultPagination = pagination.let { if (reversed) pagination.reverse(count) else pagination }
helper.readableTransaction {
helper.blockingReadableTransaction {
select(
tableName,
selection = "$valueColumnName=?",
@ -220,7 +218,7 @@ class OneToManyAndroidRepo<Key, Value>(
}
override suspend fun remove(toRemove: Map<Key, List<Value>>) {
helper.writableTransaction {
helper.blockingWritableTransaction {
toRemove.flatMap { (k, vs) ->
vs.mapNotNullA { v ->
if (delete(tableName, "$idColumnName=? AND $valueColumnName=?", arrayOf(k.asId(), v.asValue())) > 0) {