diff --git a/.github/workflows/gradle_build.yml b/.github/workflows/gradle_build.yml deleted file mode 100644 index ceab9f27349..00000000000 --- a/.github/workflows/gradle_build.yml +++ /dev/null @@ -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 diff --git a/.github/workflows/packages_push.yml b/.github/workflows/packages_push.yml new file mode 100644 index 00000000000..23d3b54dbfd --- /dev/null +++ b/.github/workflows/packages_push.yml @@ -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 }} diff --git a/CHANGELOG.md b/CHANGELOG.md index dd6045f7252..68b45fce871 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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`: diff --git a/gradle.properties b/gradle.properties index 5bac5c44c53..d5678b771ac 100644 --- a/gradle.properties +++ b/gradle.properties @@ -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 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 28ff446a215..442d9132ea3 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -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 diff --git a/pubconf.kpsb b/pubconf.kpsb deleted file mode 100644 index 0269aaeea96..00000000000 --- a/pubconf.kpsb +++ /dev/null @@ -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"}]}} \ No newline at end of file diff --git a/publish.gradle b/publish.gradle index 7b5bc5fafb8..53ad96d9e30 100644 --- a/publish.gradle +++ b/publish.gradle @@ -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') + } } } - } - } } diff --git a/publish.kpsb b/publish.kpsb new file mode 100644 index 00000000000..775a054a27c --- /dev/null +++ b/publish.kpsb @@ -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/"}]}} \ No newline at end of file diff --git a/repos/common/src/main/kotlin/dev/inmo/micro_utils/repos/DatabaseTransactions.kt b/repos/common/src/main/kotlin/dev/inmo/micro_utils/repos/DatabaseTransactions.kt index 6d7821d20ca..b5ab920e1c1 100644 --- a/repos/common/src/main/kotlin/dev/inmo/micro_utils/repos/DatabaseTransactions.kt +++ b/repos/common/src/main/kotlin/dev/inmo/micro_utils/repos/DatabaseTransactions.kt @@ -32,7 +32,9 @@ private object ContextsPool { suspend fun 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 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 SQLiteDatabase.transaction(block: suspend SQLiteDatabase.() -> T } } -inline fun SQLiteDatabase.inlineTransaction(block: SQLiteDatabase.() -> T): T { +inline fun SQLiteDatabase.inlineTransaction(crossinline block: SQLiteDatabase.() -> T): T { return when { inTransaction() -> block() else -> { beginTransaction() try { - block().also { - setTransactionSuccessful() - } + block().also { setTransactionSuccessful() } } finally { endTransaction() } } } } + +fun SQLiteDatabase.blockingTransaction(block: SQLiteDatabase.() -> T): T = inlineTransaction(block) diff --git a/repos/common/src/main/kotlin/dev/inmo/micro_utils/repos/StandardSQLHelper.kt b/repos/common/src/main/kotlin/dev/inmo/micro_utils/repos/StandardSQLHelper.kt index 591778d2a87..8979680cefe 100644 --- a/repos/common/src/main/kotlin/dev/inmo/micro_utils/repos/StandardSQLHelper.kt +++ b/repos/common/src/main/kotlin/dev/inmo/micro_utils/repos/StandardSQLHelper.kt @@ -31,6 +31,20 @@ class StandardSQLHelper( suspend fun readableTransaction(block: suspend SQLiteDatabase.() -> T): T = sqlOpenHelper.readableTransaction(block) } +fun SQLiteOpenHelper.blockingWritableTransaction(block: SQLiteDatabase.() -> T): T { + return writableDatabase.blockingTransaction(block) +} +fun SQLiteOpenHelper.blockingReadableTransaction(block: SQLiteDatabase.() -> T): T { + return readableDatabase.blockingTransaction(block) +} + +fun StandardSQLHelper.blockingWritableTransaction(block: SQLiteDatabase.() -> T): T { + return sqlOpenHelper.blockingWritableTransaction(block) +} +fun StandardSQLHelper.blockingReadableTransaction(block: SQLiteDatabase.() -> T): T { + return sqlOpenHelper.blockingReadableTransaction(block) +} + suspend fun SQLiteOpenHelper.writableTransaction(block: suspend SQLiteDatabase.() -> T): T { return writableDatabase.transaction(block) } diff --git a/repos/common/src/main/kotlin/dev/inmo/micro_utils/repos/crud/AbstractAndroidCRUDRepo.kt b/repos/common/src/main/kotlin/dev/inmo/micro_utils/repos/crud/AbstractAndroidCRUDRepo.kt index bd1109b71ea..64440100acf 100644 --- a/repos/common/src/main/kotlin/dev/inmo/micro_utils/repos/crud/AbstractAndroidCRUDRepo.kt +++ b/repos/common/src/main/kotlin/dev/inmo/micro_utils/repos/crud/AbstractAndroidCRUDRepo.kt @@ -20,7 +20,7 @@ abstract class AbstractAndroidCRUDRepo( it.count }.toLong() - override suspend fun contains(id: IdType): Boolean = helper.readableTransaction { + override suspend fun contains(id: IdType): Boolean = helper.blockingReadableTransaction { select( tableName, null, diff --git a/repos/common/src/main/kotlin/dev/inmo/micro_utils/repos/crud/AbstractMutableAndroidCRUDRepo.kt b/repos/common/src/main/kotlin/dev/inmo/micro_utils/repos/crud/AbstractMutableAndroidCRUDRepo.kt index 3da89678146..b433ecf9da5 100644 --- a/repos/common/src/main/kotlin/dev/inmo/micro_utils/repos/crud/AbstractMutableAndroidCRUDRepo.kt +++ b/repos/common/src/main/kotlin/dev/inmo/micro_utils/repos/crud/AbstractMutableAndroidCRUDRepo.kt @@ -19,9 +19,10 @@ abstract class AbstractMutableAndroidCRUDRepo): List { - 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) { val deleted = mutableListOf() - helper.writableTransaction { + helper.blockingWritableTransaction { ids.forEach { id -> delete(tableName, "$idColumnName=?", arrayOf(id.asId)).also { if (it > 0) { @@ -64,7 +65,7 @@ abstract class AbstractMutableAndroidCRUDRepo>): List { + 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( 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>) { val added = mutableListOf>() - helper.writableTransaction { + helper.blockingWritableTransaction { toAdd.forEach { (k, values) -> values.forEach { v -> insert( @@ -78,7 +76,7 @@ class OneToManyAndroidRepo( } 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( } override suspend fun set(toSet: Map>) { - 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( 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( } } - override suspend fun count(): Long =helper.readableTransaction { + override suspend fun count(): Long =helper.blockingReadableTransaction { select( tableName ).use { @@ -135,7 +133,7 @@ class OneToManyAndroidRepo( } }.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( reversed: Boolean ): PaginationResult = 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( reversed: Boolean ): PaginationResult = 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( reversed: Boolean ): PaginationResult = 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( } override suspend fun remove(toRemove: Map>) { - helper.writableTransaction { + helper.blockingWritableTransaction { toRemove.flatMap { (k, vs) -> vs.mapNotNullA { v -> if (delete(tableName, "$idColumnName=? AND $valueColumnName=?", arrayOf(k.asId(), v.asValue())) > 0) {