diff --git a/gradle.properties b/gradle.properties index 1759e8f..31a7499 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,6 +8,6 @@ android.enableJetifier=true # Project data -group=project_group +group=dev.inmo version=0.0.1 android_code_version=1 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index de17777..44b7760 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -3,6 +3,10 @@ kotlin = "1.7.10" kotlin-serialization = "1.4.0-RC" +plagubot = "2.1.0" +tgbotapi = "3.1.1" +microutils = "0.12.1" + dexcount = "3.1.0" junit_version = "4.12" test_ext_junit_version = "1.1.3" @@ -24,6 +28,11 @@ kotlin-test-js = { module = "org.jetbrains.kotlin:kotlin-test-js", version.ref = android-test-junit = { module = "androidx.test.ext:junit", version.ref = "test_ext_junit_version" } android-test-espresso-core = { module = "androidx.test.espresso:espresso-core", version.ref = "espresso_core" } +tgbotapi = { module = "dev.inmo:tgbotapi", version.ref = "tgbotapi" } +plagubot-plugin = { module = "dev.inmo:plagubot.plugin", version.ref = "plagubot" } +microutils-repos-common = { module = "dev.inmo:micro_utils.repos.common", version.ref = "microutils" } +microutils-repos-exposed = { module = "dev.inmo:micro_utils.repos.exposed", version.ref = "microutils" } + # buildscript classpaths android-tools-build = { module = "com.android.tools.build:gradle", version.ref = "android-gradle-plugin" } diff --git a/lib/build.gradle b/lib/build.gradle deleted file mode 100644 index 8a22926..0000000 --- a/lib/build.gradle +++ /dev/null @@ -1,8 +0,0 @@ -plugins { - id "org.jetbrains.kotlin.multiplatform" - id "org.jetbrains.kotlin.plugin.serialization" - id "com.android.library" -} - -apply from: "$mppProjectWithSerializationPresetPath" - diff --git a/lib/src/commonMain/kotlin/project_group/Library.kt b/lib/src/commonMain/kotlin/project_group/Library.kt deleted file mode 100644 index 424d112..0000000 --- a/lib/src/commonMain/kotlin/project_group/Library.kt +++ /dev/null @@ -1,7 +0,0 @@ -package project_group - -class Library { - fun someLibraryMethod(): Boolean { - return true - } -} diff --git a/lib/src/commonTest/kotlin/project_group/LibraryTest.kt b/lib/src/commonTest/kotlin/project_group/LibraryTest.kt deleted file mode 100644 index 84b573a..0000000 --- a/lib/src/commonTest/kotlin/project_group/LibraryTest.kt +++ /dev/null @@ -1,14 +0,0 @@ -/* - * This Kotlin source file was generated by the Gradle 'init' task. - */ -package project_group - -import kotlin.test.Test -import kotlin.test.assertTrue - -class LibraryTest { - @Test fun testSomeLibraryMethod() { - val classUnderTest = Library() - assertTrue(classUnderTest.someLibraryMethod(), "someLibraryMethod should return 'true'") - } -} diff --git a/lib/src/main/AndroidManifest.xml b/lib/src/main/AndroidManifest.xml deleted file mode 100644 index 03c9554..0000000 --- a/lib/src/main/AndroidManifest.xml +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/posts/build.gradle b/posts/build.gradle new file mode 100644 index 0000000..1b0a1a6 --- /dev/null +++ b/posts/build.gradle @@ -0,0 +1,24 @@ +plugins { + id "org.jetbrains.kotlin.multiplatform" + id "org.jetbrains.kotlin.plugin.serialization" + id "com.android.library" +} + +apply from: "$mppProjectWithSerializationPresetPath" + +kotlin { + sourceSets { + commonMain { + dependencies { + api libs.tgbotapi + api libs.microutils.repos.common + } + } + jvmMain { + dependencies { + api libs.microutils.repos.exposed + api libs.plagubot.plugin + } + } + } +} diff --git a/posts/src/commonMain/kotlin/PackageInfo.kt b/posts/src/commonMain/kotlin/PackageInfo.kt new file mode 100644 index 0000000..51daf7a --- /dev/null +++ b/posts/src/commonMain/kotlin/PackageInfo.kt @@ -0,0 +1 @@ +package dev.inmo.plaguposter.posts diff --git a/posts/src/commonMain/kotlin/models/Post.kt b/posts/src/commonMain/kotlin/models/Post.kt new file mode 100644 index 0000000..0e97632 --- /dev/null +++ b/posts/src/commonMain/kotlin/models/Post.kt @@ -0,0 +1,20 @@ +package dev.inmo.plaguposter.posts.models + +import dev.inmo.tgbotapi.types.ChatId +import kotlinx.serialization.Serializable + +@Serializable +sealed interface Post { + val content: List +} + +@Serializable +data class NewPost( + override val content: List +) : Post + +@Serializable +data class RegisteredPost( + val id: PostId, + override val content: List +) : Post diff --git a/posts/src/commonMain/kotlin/models/PostContentInfo.kt b/posts/src/commonMain/kotlin/models/PostContentInfo.kt new file mode 100644 index 0000000..7a572d5 --- /dev/null +++ b/posts/src/commonMain/kotlin/models/PostContentInfo.kt @@ -0,0 +1,13 @@ +package dev.inmo.plaguposter.posts.models + +import dev.inmo.tgbotapi.types.ChatId +import dev.inmo.tgbotapi.types.MessageIdentifier +import kotlinx.serialization.Serializable + +@Serializable +data class PostContentInfo( + val chatId: ChatId, + val messageId: MessageIdentifier, + val group: String?, + val order: Int +) diff --git a/posts/src/commonMain/kotlin/models/PostId.kt b/posts/src/commonMain/kotlin/models/PostId.kt new file mode 100644 index 0000000..806d412 --- /dev/null +++ b/posts/src/commonMain/kotlin/models/PostId.kt @@ -0,0 +1,10 @@ +package dev.inmo.plaguposter.posts.models + +import kotlinx.serialization.Serializable +import kotlin.jvm.JvmInline + +@Serializable +@JvmInline +value class PostId( + val string: String +) diff --git a/posts/src/commonMain/kotlin/repo/PostsRepo.kt b/posts/src/commonMain/kotlin/repo/PostsRepo.kt new file mode 100644 index 0000000..b22c7aa --- /dev/null +++ b/posts/src/commonMain/kotlin/repo/PostsRepo.kt @@ -0,0 +1,7 @@ +package dev.inmo.plaguposter.posts.repo + +import dev.inmo.micro_utils.repos.CRUDRepo +import dev.inmo.plaguposter.posts.models.* + +interface PostsRepo : CRUDRepo, ReadPostsRepo, WritePostsRepo { +} diff --git a/posts/src/commonMain/kotlin/repo/ReadPostsRepo.kt b/posts/src/commonMain/kotlin/repo/ReadPostsRepo.kt new file mode 100644 index 0000000..83c9200 --- /dev/null +++ b/posts/src/commonMain/kotlin/repo/ReadPostsRepo.kt @@ -0,0 +1,6 @@ +package dev.inmo.plaguposter.posts.repo + +import dev.inmo.micro_utils.repos.ReadCRUDRepo +import dev.inmo.plaguposter.posts.models.* + +interface ReadPostsRepo : ReadCRUDRepo diff --git a/posts/src/commonMain/kotlin/repo/WritePostsRepo.kt b/posts/src/commonMain/kotlin/repo/WritePostsRepo.kt new file mode 100644 index 0000000..c9f1be4 --- /dev/null +++ b/posts/src/commonMain/kotlin/repo/WritePostsRepo.kt @@ -0,0 +1,7 @@ +package dev.inmo.plaguposter.posts.repo + +import dev.inmo.micro_utils.repos.ReadCRUDRepo +import dev.inmo.micro_utils.repos.WriteCRUDRepo +import dev.inmo.plaguposter.posts.models.* + +interface WritePostsRepo : WriteCRUDRepo diff --git a/posts/src/jvmMain/kotlin/Plugin.kt b/posts/src/jvmMain/kotlin/Plugin.kt new file mode 100644 index 0000000..f420db5 --- /dev/null +++ b/posts/src/jvmMain/kotlin/Plugin.kt @@ -0,0 +1,12 @@ +package dev.inmo.plaguposter.posts + +import dev.inmo.plagubot.Plugin +import kotlinx.serialization.json.JsonObject +import org.jetbrains.exposed.sql.Database +import org.koin.core.module.Module + +object Plugin : Plugin { + override fun Module.setupDI(database: Database, params: JsonObject) { + TODO("Not yet implemented") + } +} diff --git a/posts/src/jvmMain/kotlin/exposed/ExposedContentInfoRepo.kt b/posts/src/jvmMain/kotlin/exposed/ExposedContentInfoRepo.kt new file mode 100644 index 0000000..7eaeed2 --- /dev/null +++ b/posts/src/jvmMain/kotlin/exposed/ExposedContentInfoRepo.kt @@ -0,0 +1,35 @@ +package dev.inmo.plaguposter.posts.exposed + +import com.benasher44.uuid.uuid4 +import dev.inmo.micro_utils.repos.KeyValuesRepo +import dev.inmo.micro_utils.repos.exposed.* +import dev.inmo.plaguposter.posts.models.* +import dev.inmo.plaguposter.posts.repo.PostsRepo +import dev.inmo.tgbotapi.types.ChatId +import org.jetbrains.exposed.sql.* +import org.jetbrains.exposed.sql.statements.InsertStatement +import org.jetbrains.exposed.sql.statements.UpdateStatement +import sun.security.pkcs.ContentInfo + +internal class ExposedContentInfoRepo( + override val database: Database, + postIdColumnReference: Column +) : ExposedRepo, Table(name = "posts_content") { + val postIdColumn = (text("post_id") references postIdColumnReference).index() + val chatIdColumn = long("chat_id") + val messageIdColumn = long("message_id") + val groupColumn = text("group").nullable() + val orderColumn = integer("order") + + val ResultRow.asObject + get() = PostContentInfo( + ChatId(get(chatIdColumn)), + get(messageIdColumn), + get(groupColumn), + get(orderColumn) + ) + + init { + initTable() + } +} diff --git a/posts/src/jvmMain/kotlin/exposed/ExposedPostsRepo.kt b/posts/src/jvmMain/kotlin/exposed/ExposedPostsRepo.kt new file mode 100644 index 0000000..e733caa --- /dev/null +++ b/posts/src/jvmMain/kotlin/exposed/ExposedPostsRepo.kt @@ -0,0 +1,86 @@ +package dev.inmo.plaguposter.posts.exposed + +import com.benasher44.uuid.uuid4 +import dev.inmo.micro_utils.repos.KeyValuesRepo +import dev.inmo.micro_utils.repos.exposed.AbstractExposedCRUDRepo +import dev.inmo.plaguposter.posts.models.* +import dev.inmo.plaguposter.posts.repo.PostsRepo +import kotlinx.serialization.json.Json +import org.jetbrains.exposed.sql.* +import org.jetbrains.exposed.sql.statements.InsertStatement +import org.jetbrains.exposed.sql.statements.UpdateStatement + +class ExposedPostsRepo( + override val database: Database, + json: Json +) : PostsRepo, AbstractExposedCRUDRepo( + tableName = "posts" +) { + val idColumn = text("id").clientDefault { uuid4().toString() } + + private val contentRepo by lazy { + ExposedContentInfoRepo( + database, + idColumn + ) + } + + override val primaryKey: PrimaryKey? = PrimaryKey(idColumn) + + override val selectById: SqlExpressionBuilder.(PostId) -> Op = { idColumn.eq(it.string) } + override val selectByIds: SqlExpressionBuilder.(List) -> Op = { idColumn.inList(it.map { it.string }) } + override val ResultRow.asObject: RegisteredPost + get() { + val id = PostId(get(idColumn)) + return RegisteredPost( + id, + with(contentRepo) { + select { postIdColumn.eq(id.string) }.map { + it.asObject + } + } + ) + } + + override fun InsertStatement.asObject(value: NewPost): RegisteredPost { + val id = PostId(get(idColumn)) + + with(contentRepo) { + value.content.forEach { contentInfo -> + insert { + it[postIdColumn] = id.string + it[chatIdColumn] = contentInfo.chatId.chatId + it[messageIdColumn] = contentInfo.messageId + it[groupColumn] = contentInfo.group + it[orderColumn] = contentInfo.order + } + } + } + + return RegisteredPost( + id, + with(contentRepo) { + select { postIdColumn.eq(id.string) }.map { + it.asObject + } + } + ) + } + + override fun update(id: PostId, value: NewPost, it: UpdateStatement) { + with(contentRepo) { + deleteWhere { postIdColumn.eq(id.string) } + value.content.forEach { contentInfo -> + insert { + it[postIdColumn] = id.string + it[chatIdColumn] = contentInfo.chatId.chatId + it[messageIdColumn] = contentInfo.messageId + it[groupColumn] = contentInfo.group + it[orderColumn] = contentInfo.order + } + } + } + } + + override fun insert(value: NewPost, it: InsertStatement) {} +} diff --git a/posts/src/main/AndroidManifest.xml b/posts/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7bbd57b --- /dev/null +++ b/posts/src/main/AndroidManifest.xml @@ -0,0 +1 @@ + diff --git a/settings.gradle b/settings.gradle index 4e2023f..b8e2f35 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,7 +1,7 @@ -rootProject.name = 'project_name' +rootProject.name = 'plaguposter' String[] includes = [ - ":lib" + ":posts" ]