From 3b3582bc0eabec9f2a8b3bb0d13b077c6725b821 Mon Sep 17 00:00:00 2001 From: deviantbadge <deviantbadge21@gmail.com> Date: Wed, 7 Nov 2018 19:03:51 +0300 Subject: [PATCH 1/2] Lecture practice --- lecture07/src/main/resources/sql/data/data.sql | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lecture07/src/main/resources/sql/data/data.sql b/lecture07/src/main/resources/sql/data/data.sql index 281e97bf..b1554760 100644 --- a/lecture07/src/main/resources/sql/data/data.sql +++ b/lecture07/src/main/resources/sql/data/data.sql @@ -13,3 +13,6 @@ select * from chat.message where time > '2017-03-25'; + +select * +from chat.user; \ No newline at end of file From 49a6406fe3b27ffa22e75c440d9d7cdedb86eec0 Mon Sep 17 00:00:00 2001 From: deviantbadge <deviantbadge21@gmail.com> Date: Tue, 13 Nov 2018 00:37:54 +0300 Subject: [PATCH 2/2] Add Dao implementation + several tests --- lecture07/build.gradle.kts | 3 +- .../io/rybalkinsd/kotlinbootcamp/Main.kt | 4 ++ .../io/rybalkinsd/kotlinbootcamp/dao/Dao.kt | 5 +- .../kotlinbootcamp/dao/MessageDao.kt | 37 ++++++++++-- .../rybalkinsd/kotlinbootcamp/dao/UserDao.kt | 34 +++++++++-- .../rybalkinsd/kotlinbootcamp/dao/database.kt | 2 +- .../kotlinbootcamp/db/DbConnector.kt | 7 +-- .../kotlinbootcamp/model/modelExt.kt | 11 +++- .../src/main/resources/sql/data/data.sql | 9 ++- .../kotlinbootcamp/dao/MessageDaoTest.kt | 8 +-- .../kotlinbootcamp/dao/UserDaoTest.kt | 18 +++--- .../practice/ChatMessageDaoTest.kt | 50 ++++++++++------ .../practice/ChatUserDaoTest.kt | 59 ++++++++++--------- 13 files changed, 169 insertions(+), 78 deletions(-) create mode 100644 lecture07/src/main/kotlin/io/rybalkinsd/kotlinbootcamp/Main.kt diff --git a/lecture07/build.gradle.kts b/lecture07/build.gradle.kts index 8303c09e..f8a0952d 100644 --- a/lecture07/build.gradle.kts +++ b/lecture07/build.gradle.kts @@ -36,9 +36,10 @@ dependencies { compile(spring("web")) compile(spring("actuator")) - testCompile("junit", "junit", "4.12") + testCompile("org.testng", "testng", "6.14.3") testCompile(spring("test")) + ktlint("com.github.shyiko", "ktlint", "0.28.0") } diff --git a/lecture07/src/main/kotlin/io/rybalkinsd/kotlinbootcamp/Main.kt b/lecture07/src/main/kotlin/io/rybalkinsd/kotlinbootcamp/Main.kt new file mode 100644 index 00000000..9aa13aad --- /dev/null +++ b/lecture07/src/main/kotlin/io/rybalkinsd/kotlinbootcamp/Main.kt @@ -0,0 +1,4 @@ +package io.rybalkinsd.kotlinbootcamp + +fun main() { +} \ No newline at end of file diff --git a/lecture07/src/main/kotlin/io/rybalkinsd/kotlinbootcamp/dao/Dao.kt b/lecture07/src/main/kotlin/io/rybalkinsd/kotlinbootcamp/dao/Dao.kt index f8265734..f34cf141 100644 --- a/lecture07/src/main/kotlin/io/rybalkinsd/kotlinbootcamp/dao/Dao.kt +++ b/lecture07/src/main/kotlin/io/rybalkinsd/kotlinbootcamp/dao/Dao.kt @@ -1,5 +1,6 @@ package io.rybalkinsd.kotlinbootcamp.dao +import org.jetbrains.exposed.sql.Op interface Dao<T> { /** @@ -10,7 +11,7 @@ interface Dao<T> { /** * SELECT * ... WHERE cond0 AND ... AND condN */ - fun getAllWhere(vararg conditions: String): List<T> + fun getAllWhere(vararg where: Op<Boolean>): List<T> /** * INSERT INTO ... @@ -21,5 +22,5 @@ interface Dao<T> { * SELECT * from ... WHERE id= * @return Optional.empty() if nothing found */ - fun findById(id: Int): T? = getAllWhere("id=$id").firstOrNull() + fun findById(id: Int): T } diff --git a/lecture07/src/main/kotlin/io/rybalkinsd/kotlinbootcamp/dao/MessageDao.kt b/lecture07/src/main/kotlin/io/rybalkinsd/kotlinbootcamp/dao/MessageDao.kt index 63b3ac36..5e4106cb 100644 --- a/lecture07/src/main/kotlin/io/rybalkinsd/kotlinbootcamp/dao/MessageDao.kt +++ b/lecture07/src/main/kotlin/io/rybalkinsd/kotlinbootcamp/dao/MessageDao.kt @@ -1,17 +1,44 @@ package io.rybalkinsd.kotlinbootcamp.dao import io.rybalkinsd.kotlinbootcamp.model.Message +import io.rybalkinsd.kotlinbootcamp.model.toMessage +import org.jetbrains.exposed.sql.Op +import org.jetbrains.exposed.sql.ResultRow +import org.jetbrains.exposed.sql.and +import org.jetbrains.exposed.sql.insert +import org.jetbrains.exposed.sql.select +import org.jetbrains.exposed.sql.selectAll +import org.jetbrains.exposed.sql.transactions.transaction class MessageDao : Dao<Message> { + override fun findById(id: Int) = transaction { + Messages.select { Messages.id eq id } + .firstOrNull() + ?.toMessage() + ?: throw IllegalStateException("Message with $id not found in database") + } + override val all: List<Message> - get() = TODO("not implemented") + get() = transaction { + Messages.selectAll() + .toList() + .map(ResultRow::toMessage) + } - override fun getAllWhere(vararg conditions: String): List<Message> { - TODO("not implemented") + override fun getAllWhere(vararg where: Op<Boolean>): List<Message> = transaction { + Messages.select(where.reduce { resultExpr, condition -> resultExpr and condition }) + .toList() + .map(ResultRow::toMessage) } override fun insert(t: Message) { - TODO("not implemented") + transaction { + Messages.insert { + it[id] = t.id + it[user] = t.user.id + it[time] = t.timestamp + it[value] = t.value + } + } } - } diff --git a/lecture07/src/main/kotlin/io/rybalkinsd/kotlinbootcamp/dao/UserDao.kt b/lecture07/src/main/kotlin/io/rybalkinsd/kotlinbootcamp/dao/UserDao.kt index 319d1802..6d815c87 100644 --- a/lecture07/src/main/kotlin/io/rybalkinsd/kotlinbootcamp/dao/UserDao.kt +++ b/lecture07/src/main/kotlin/io/rybalkinsd/kotlinbootcamp/dao/UserDao.kt @@ -1,16 +1,42 @@ package io.rybalkinsd.kotlinbootcamp.dao import io.rybalkinsd.kotlinbootcamp.model.User +import io.rybalkinsd.kotlinbootcamp.model.toUser +import org.jetbrains.exposed.sql.Op +import org.jetbrains.exposed.sql.ResultRow +import org.jetbrains.exposed.sql.and +import org.jetbrains.exposed.sql.insert +import org.jetbrains.exposed.sql.select +import org.jetbrains.exposed.sql.selectAll +import org.jetbrains.exposed.sql.transactions.transaction class UserDao : Dao<User> { + override fun findById(id: Int) = transaction { + Users.select { Users.id eq id } + .firstOrNull() + ?.toUser() + ?: throw IllegalStateException("User with $id not found in database") + } + override val all: List<User> - get() = TODO("not implemented") + get() = transaction { + Users.selectAll() + .toList() + .map(ResultRow::toUser) + } - override fun getAllWhere(vararg conditions: String): List<User> { - TODO("not implemented") + override fun getAllWhere(vararg where: Op<Boolean>) = transaction { + Users.select(where.reduce { resultExpr, condition -> resultExpr and condition }) + .toList() + .map(ResultRow::toUser) } override fun insert(t: User) { - TODO("not implemented") + transaction { + Users.insert { + it[id] = t.id + it[login] = t.login + } + } } } diff --git a/lecture07/src/main/kotlin/io/rybalkinsd/kotlinbootcamp/dao/database.kt b/lecture07/src/main/kotlin/io/rybalkinsd/kotlinbootcamp/dao/database.kt index 17778d1d..5ce75f8a 100644 --- a/lecture07/src/main/kotlin/io/rybalkinsd/kotlinbootcamp/dao/database.kt +++ b/lecture07/src/main/kotlin/io/rybalkinsd/kotlinbootcamp/dao/database.kt @@ -12,4 +12,4 @@ object Messages : Table("chat.message") { val user = integer("user") references Users.id val time = datetime("time") val value = text("value") -} \ No newline at end of file +} diff --git a/lecture07/src/main/kotlin/io/rybalkinsd/kotlinbootcamp/db/DbConnector.kt b/lecture07/src/main/kotlin/io/rybalkinsd/kotlinbootcamp/db/DbConnector.kt index 243d89be..6ccaca83 100644 --- a/lecture07/src/main/kotlin/io/rybalkinsd/kotlinbootcamp/db/DbConnector.kt +++ b/lecture07/src/main/kotlin/io/rybalkinsd/kotlinbootcamp/db/DbConnector.kt @@ -3,15 +3,14 @@ package io.rybalkinsd.kotlinbootcamp.db import io.rybalkinsd.kotlinbootcamp.util.logger import org.jetbrains.exposed.sql.Database - object DbConnector { private val log = logger() private val host = "54.224.37.210" private val port = 5432 - private val dbName = "chatdb_atom49" - private val user = "atom49" - private val password = "atom49" + private val dbName = "chatdb_atom6" + private val user = "atom6" + private val password = "atom6" init { Database.connect( diff --git a/lecture07/src/main/kotlin/io/rybalkinsd/kotlinbootcamp/model/modelExt.kt b/lecture07/src/main/kotlin/io/rybalkinsd/kotlinbootcamp/model/modelExt.kt index 3508344c..208ca68f 100644 --- a/lecture07/src/main/kotlin/io/rybalkinsd/kotlinbootcamp/model/modelExt.kt +++ b/lecture07/src/main/kotlin/io/rybalkinsd/kotlinbootcamp/model/modelExt.kt @@ -1,6 +1,15 @@ package io.rybalkinsd.kotlinbootcamp.model +import io.rybalkinsd.kotlinbootcamp.dao.Messages +import io.rybalkinsd.kotlinbootcamp.dao.UserDao import io.rybalkinsd.kotlinbootcamp.dao.Users import org.jetbrains.exposed.sql.ResultRow -internal fun ResultRow.toUser() = User(this[Users.id], this[Users.login]) \ No newline at end of file +internal fun ResultRow.toUser() = User(this[Users.id], this[Users.login]) + +internal fun ResultRow.toMessage() = Message( + this[Messages.id], + UserDao().findById(this[Messages.user]), + this[Messages.time], + this[Messages.value] +) diff --git a/lecture07/src/main/resources/sql/data/data.sql b/lecture07/src/main/resources/sql/data/data.sql index b1554760..be6659b5 100644 --- a/lecture07/src/main/resources/sql/data/data.sql +++ b/lecture07/src/main/resources/sql/data/data.sql @@ -14,5 +14,10 @@ from chat.message where time > '2017-03-25'; -select * -from chat.user; \ No newline at end of file +select login, value +from chat.user, chat.message +where "user"=44; + +select value, chat.user.login +from chat.message +left join chat.user on chat.message.user = chat.user.id; \ No newline at end of file diff --git a/lecture07/src/test/kotlin/io/rybalkinsd/kotlinbootcamp/dao/MessageDaoTest.kt b/lecture07/src/test/kotlin/io/rybalkinsd/kotlinbootcamp/dao/MessageDaoTest.kt index 0abfd7c2..e2bbc9e8 100644 --- a/lecture07/src/test/kotlin/io/rybalkinsd/kotlinbootcamp/dao/MessageDaoTest.kt +++ b/lecture07/src/test/kotlin/io/rybalkinsd/kotlinbootcamp/dao/MessageDaoTest.kt @@ -6,8 +6,9 @@ import org.jetbrains.exposed.sql.addLogger import org.jetbrains.exposed.sql.insert import org.jetbrains.exposed.sql.transactions.transaction import org.joda.time.DateTime -import org.junit.Test +import org.testng.annotations.Test +@Test(enabled = false) class MessageDaoTest { @Test @@ -18,10 +19,9 @@ class MessageDaoTest { addLogger(StdOutSqlLogger) Messages.insert { - it[id] = 0 - it[user] = 42 + it[user] = 44 it[time] = DateTime.now() - it[value] = "My first message" + it[value] = "My first haha" } } } diff --git a/lecture07/src/test/kotlin/io/rybalkinsd/kotlinbootcamp/dao/UserDaoTest.kt b/lecture07/src/test/kotlin/io/rybalkinsd/kotlinbootcamp/dao/UserDaoTest.kt index 2fea86e9..bf522706 100644 --- a/lecture07/src/test/kotlin/io/rybalkinsd/kotlinbootcamp/dao/UserDaoTest.kt +++ b/lecture07/src/test/kotlin/io/rybalkinsd/kotlinbootcamp/dao/UserDaoTest.kt @@ -2,17 +2,19 @@ package io.rybalkinsd.kotlinbootcamp.dao import io.rybalkinsd.kotlinbootcamp.db.DbConnector import io.rybalkinsd.kotlinbootcamp.model.toUser +import org.jetbrains.exposed.sql.ResultRow import org.jetbrains.exposed.sql.StdOutSqlLogger import org.jetbrains.exposed.sql.addLogger import org.jetbrains.exposed.sql.insert import org.jetbrains.exposed.sql.selectAll import org.jetbrains.exposed.sql.transactions.transaction -import org.junit.Before -import org.junit.Test +import org.testng.annotations.BeforeClass +import org.testng.annotations.Test +@Test(enabled = false) class UserDaoTest { - @Before + @BeforeClass fun setUp() { DbConnector } @@ -23,7 +25,7 @@ class UserDaoTest { addLogger(StdOutSqlLogger) val id = Users.insert { - it[id] = 44 + it[id] = 1 it[login] = "login44" } get Users.id @@ -32,17 +34,13 @@ class UserDaoTest { } @Test - fun `select * from User`() { + fun `select from User`() { transaction { addLogger(StdOutSqlLogger) - val users = Users.selectAll().map { - it.toUser() - } + val users = Users.selectAll().map(ResultRow::toUser) println(users) } } - - } \ No newline at end of file diff --git a/lecture07/src/test/kotlin/io/rybalkinsd/kotlinbootcamp/practice/ChatMessageDaoTest.kt b/lecture07/src/test/kotlin/io/rybalkinsd/kotlinbootcamp/practice/ChatMessageDaoTest.kt index 31f0dafd..7f5c91a8 100644 --- a/lecture07/src/test/kotlin/io/rybalkinsd/kotlinbootcamp/practice/ChatMessageDaoTest.kt +++ b/lecture07/src/test/kotlin/io/rybalkinsd/kotlinbootcamp/practice/ChatMessageDaoTest.kt @@ -1,37 +1,53 @@ package io.rybalkinsd.kotlinbootcamp.practice import io.rybalkinsd.kotlinbootcamp.dao.MessageDao +import io.rybalkinsd.kotlinbootcamp.dao.Messages import io.rybalkinsd.kotlinbootcamp.db.DbConnector import io.rybalkinsd.kotlinbootcamp.model.Message -import junit.framework.TestCase.assertTrue -import org.junit.Before -import org.junit.Ignore -import org.junit.Test +import io.rybalkinsd.kotlinbootcamp.practice.ChatUserDaoTest.Companion.admin +import org.assertj.core.api.Assertions +import org.assertj.core.api.Assertions.assertThat +import org.jetbrains.exposed.sql.Op +import org.joda.time.DateTime +import org.testng.annotations.BeforeClass +import org.testng.annotations.Test - -@Ignore class ChatMessageDaoTest { val messageDao = MessageDao() - @Before + @BeforeClass fun setUp() { DbConnector } @Test - fun `select * from message`() { - assertTrue(messageDao.all.isNotEmpty()) - } - - @Test - fun `insert message`() { + fun insertMessage() { val before = messagesNumber() - messageDao.insert(dummyMessage()) + messageDao.insert(dummyMessage(before)) val after = messagesNumber() - assertTrue(before + 1 >= after) + assertThat(before + 1).isEqualTo(after) + } + + @Test(dependsOnMethods = ["insertMessage"]) + fun selectAll() { + assertThat(messageDao.all) + .isNotEmpty + } + + @Test(dependsOnMethods = ["selectAll"]) + fun getMessageById() { + val id = messageDao.all.firstOrNull()?.id + ?: return Assertions.fail("Failed to load id from database") + assertThat(messageDao.findById(id).id).isEqualTo(id) + } + + @Test(dependsOnMethods = ["insertMessage"]) + fun getHelloMessage() { + assertThat(messageDao.getAllWhere(Op.build { Messages.value like "Hello %" })) + .isNotEmpty } - fun messagesNumber(): Long = TODO() - fun dummyMessage(): Message = TODO() + private fun messagesNumber() = messageDao.all.size + private fun dummyMessage(messageAmunt: Int) = Message(messageAmunt, admin, DateTime(0), "Hello guys") } \ No newline at end of file diff --git a/lecture07/src/test/kotlin/io/rybalkinsd/kotlinbootcamp/practice/ChatUserDaoTest.kt b/lecture07/src/test/kotlin/io/rybalkinsd/kotlinbootcamp/practice/ChatUserDaoTest.kt index 4d740400..3e522a13 100644 --- a/lecture07/src/test/kotlin/io/rybalkinsd/kotlinbootcamp/practice/ChatUserDaoTest.kt +++ b/lecture07/src/test/kotlin/io/rybalkinsd/kotlinbootcamp/practice/ChatUserDaoTest.kt @@ -1,53 +1,58 @@ package io.rybalkinsd.kotlinbootcamp.practice import io.rybalkinsd.kotlinbootcamp.dao.UserDao +import io.rybalkinsd.kotlinbootcamp.dao.Users import io.rybalkinsd.kotlinbootcamp.db.DbConnector import io.rybalkinsd.kotlinbootcamp.model.User -import junit.framework.TestCase -import org.junit.Assert.assertTrue -import org.junit.Before -import org.junit.Ignore -import org.junit.Test -import kotlin.random.Random +import org.assertj.core.api.Assertions +import org.assertj.core.api.Assertions.assertThat +import org.jetbrains.exposed.sql.Op +import org.testng.annotations.BeforeClass +import org.testng.annotations.Test /** * Created by sergey on 3/25/17. */ -@Ignore class ChatUserDaoTest { + companion object { + val admin = User(0, "admin") + } + val userDao = UserDao() - @Before + @BeforeClass fun setUp() { DbConnector } - @Test - fun getAllTest() { - assertTrue(userDao.all.isNotEmpty()) - } - @Test fun insertTest() { val before = userNumber() - userDao.insert(dummyUser()) + userDao.insert(dummyUser(before)) val after = userNumber() - TestCase.assertTrue(before + 1 >= after) + assertThat(before + 1).isEqualTo(after) } - @Test - fun `find lol`() { - userDao.insert(User(Random.nextInt(), "Lolita")) - val lols = userDao.getAllWhere("login like 'Lol%'") - - assertTrue( - lols.asSequence() - .map { it.login } - .any { it.startsWith("Lol") } - ) + @Test(dependsOnMethods = ["insertTest"]) + fun getAllTest() { + assertThat(userDao.all) + .isNotEmpty } - fun userNumber(): Long = TODO() - fun dummyUser(): User = TODO() + @Test(dependsOnMethods = ["getAllTest"]) + fun getByIdTest() { + val id = userDao.all.firstOrNull()?.id + ?: return Assertions.fail("Failed to load id from database") + assertThat(userDao.findById(id).id).isEqualTo(id) + } + + @Test(dependsOnMethods = ["insertTest"]) + fun getAngel() { + val users = userDao.getAllWhere(Op.build { Users.login like "angel *" }) + assertThat(users) + .allMatch { user -> user.login.startsWith("angel ") } + } + fun userNumber() = userDao.all.size + fun dummyUser(userAmount: Int) = User(userAmount, "angel $userAmount") } \ No newline at end of file