feature #6: implement PostArticle route

fix upsert_article function
This commit is contained in:
2019-07-31 13:05:41 +02:00
parent ea835d8e9a
commit 3bf7ee1d13
9 changed files with 72 additions and 31 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,6 +1,3 @@
import org.jetbrains.kotlin.gradle.dsl.Coroutines
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
val ktor_version: String by project val ktor_version: String by project
val kotlin_version: String by project val kotlin_version: String by project
val logback_version: String by project val logback_version: String by project
@@ -35,6 +32,9 @@ dependencies {
compile("io.ktor:ktor-auth-jwt:$ktor_version") compile("io.ktor:ktor-auth-jwt:$ktor_version")
compile("io.ktor:ktor-gson:$ktor_version") compile("io.ktor:ktor-gson:$ktor_version")
compile("org.koin:koin-ktor:$koinVersion") compile("org.koin:koin-ktor:$koinVersion")
compile("io.ktor:ktor-jackson:$ktor_version")
compile("com.fasterxml.jackson.module:jackson-module-kotlin:2.9.9")
compile("com.fasterxml.jackson.datatype:jackson-datatype-joda:2.9.9")
compile("fr.postgresjson:postgresjson:$postgresjson_version") compile("fr.postgresjson:postgresjson:$postgresjson_version")
testCompile("io.ktor:ktor-server-tests:$ktor_version") testCompile("io.ktor:ktor-server-tests:$ktor_version")
} }

View File

@@ -1,4 +1,4 @@
create or replace procedure upsert_article(inout resource json) create or replace function upsert_article(inout resource json)
language plpgsql as language plpgsql as
$$ $$
declare declare
@@ -6,7 +6,7 @@ declare
begin begin
insert into article (version_id, created_by_id, title, annonymous, content, description, tags) insert into article (version_id, created_by_id, title, annonymous, content, description, tags)
select select
version_id, coalesce(version_id, uuid_generate_v4()),
(resource#>>'{created_by, id}')::uuid, (resource#>>'{created_by, id}')::uuid,
title, title,
annonymous, annonymous,

View File

@@ -1,13 +1,20 @@
package fr.dcproject package fr.dcproject
import com.fasterxml.jackson.core.util.DefaultIndenter
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter
import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.databind.PropertyNamingStrategy
import com.fasterxml.jackson.databind.SerializationFeature
import com.fasterxml.jackson.datatype.joda.JodaModule
import fr.dcproject.entity.Article import fr.dcproject.entity.Article
import fr.dcproject.routes.article import fr.dcproject.routes.article
import io.ktor.application.Application import io.ktor.application.Application
import io.ktor.application.install import io.ktor.application.install
import io.ktor.auth.Authentication import io.ktor.auth.Authentication
import io.ktor.features.AutoHeadResponse
import io.ktor.features.ContentNegotiation import io.ktor.features.ContentNegotiation
import io.ktor.features.DataConversion import io.ktor.features.DataConversion
import io.ktor.gson.gson import io.ktor.jackson.jackson
import io.ktor.locations.KtorExperimentalLocationsAPI import io.ktor.locations.KtorExperimentalLocationsAPI
import io.ktor.locations.Locations import io.ktor.locations.Locations
import io.ktor.routing.Routing import io.ktor.routing.Routing
@@ -57,12 +64,25 @@ fun Application.module() {
install(Authentication) { install(Authentication) {
} }
install(AutoHeadResponse)
install(ContentNegotiation) { install(ContentNegotiation) {
gson { // TODO move to postgresJson lib
jackson {
propertyNamingStrategy = PropertyNamingStrategy.SNAKE_CASE
registerModule(JodaModule())
disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
configure(SerializationFeature.INDENT_OUTPUT, true)
setDefaultPrettyPrinter(DefaultPrettyPrinter().apply {
indentArraysWith(DefaultPrettyPrinter.FixedSpaceIndenter.instance)
indentObjectsWith(DefaultIndenter(" ", "\n"))
})
} }
} }
install(Routing) { install(Routing) {
article() article(get())
} }
} }

View File

@@ -4,13 +4,13 @@ import java.util.*
class Article( class Article(
id: UUID, id: UUID?,
var versionId: UUID, var versionId: UUID?,
var versionNumber: Int, var versionNumber: Int?,
var title: String, var title: String?,
var annonymous: Boolean, var annonymous: Boolean?,
var content: String, var content: String?,
var description: String, var description: String?,
var tags: List<String> var tags: List<String>
): ):
UuidEntity(id), UuidEntity(id),

View File

@@ -7,7 +7,7 @@ import java.util.*
class User( class User(
id: UUID?, id: UUID?,
var username: String, var username: String?,
var blockedAt: DateTime?, var blockedAt: DateTime?,
override var createdAt: DateTime?, override var createdAt: DateTime?,
override var updatedAt: DateTime? override var updatedAt: DateTime?

View File

@@ -4,11 +4,10 @@ import fr.postgresjson.connexion.Requester
import fr.postgresjson.entity.EntitiesCollections import fr.postgresjson.entity.EntitiesCollections
import fr.postgresjson.repository.RepositoryI import fr.postgresjson.repository.RepositoryI
import java.util.* import java.util.*
import kotlin.reflect.KClass
import fr.dcproject.entity.Article as ArticleEntity import fr.dcproject.entity.Article as ArticleEntity
class Article(override var requester: Requester) : RepositoryI<ArticleEntity> { class Article(override var requester: Requester) : RepositoryI<ArticleEntity> {
override val entityName: KClass<fr.dcproject.entity.Article> = ArticleEntity::class override val entityName = ArticleEntity::class
fun findById(id: UUID): ArticleEntity? { fun findById(id: UUID): ArticleEntity? {
val function = requester.getFunction("find_article_by_id") val function = requester.getFunction("find_article_by_id")
@@ -19,4 +18,12 @@ class Article(override var requester: Requester) : RepositoryI<ArticleEntity> {
else -> e else -> e
} }
} }
fun upsert(article: ArticleEntity): ArticleEntity? {
return requester
.getFunction("upsert_article")
.selectOne<ArticleEntity>("resource" to article)?.also {
EntitiesCollections().set(it)
}
}
} }

View File

@@ -5,15 +5,25 @@ import fr.postgresjson.serializer.serialize
import io.ktor.application.call import io.ktor.application.call
import io.ktor.locations.KtorExperimentalLocationsAPI import io.ktor.locations.KtorExperimentalLocationsAPI
import io.ktor.locations.get import io.ktor.locations.get
import io.ktor.locations.post
import io.ktor.request.receive
import io.ktor.response.respond
import io.ktor.response.respondText import io.ktor.response.respondText
import io.ktor.routing.Route import io.ktor.routing.Route
import fr.dcproject.entity.Article as ArticleEntity
import fr.dcproject.repository.Article as ArticleRepository
@KtorExperimentalLocationsAPI @KtorExperimentalLocationsAPI
fun Route.article() { fun Route.article(repo: ArticleRepository) {
get<Paths.ArticlesRequest> { get<Paths.ArticlesRequest> {
call.respondText("todo") call.respondText("todo")
} }
get<Paths.ArticleRequest> { get<Paths.ArticleRequest> {
call.respondText(it.article.serialize()) call.respondText(it.article.serialize())
} }
post<Paths.PostArticleRequest>() {
val article = call.receive<ArticleEntity>()
repo.upsert(article)
call.respond(article)
}
} }