From 5b4d878f8a3a014368a68709229ebc5cacd6d59e Mon Sep 17 00:00:00 2001 From: Fabrice Lecomte Date: Tue, 22 Oct 2019 11:00:27 +0200 Subject: [PATCH] Can filter article by author --- .../kotlin/fr/dcproject/repository/Article.kt | 11 +++++++++-- src/main/kotlin/fr/dcproject/routes/Article.kt | 5 +++-- src/main/resources/openApi.yaml | 11 +++++++++++ .../sql/functions/article/find_articles.sql | 16 +++++++++++++--- 4 files changed, 36 insertions(+), 7 deletions(-) diff --git a/src/main/kotlin/fr/dcproject/repository/Article.kt b/src/main/kotlin/fr/dcproject/repository/Article.kt index 1fe061b..315d6a4 100644 --- a/src/main/kotlin/fr/dcproject/repository/Article.kt +++ b/src/main/kotlin/fr/dcproject/repository/Article.kt @@ -2,6 +2,7 @@ package fr.dcproject.repository import fr.postgresjson.connexion.Paginated import fr.postgresjson.connexion.Requester +import fr.postgresjson.entity.Parameter import fr.postgresjson.repository.RepositoryI import fr.postgresjson.repository.RepositoryI.Direction import net.pearx.kasechange.toSnakeCase @@ -25,7 +26,8 @@ class Article(override var requester: Requester) : RepositoryI { limit: Int = 50, sort: String? = null, direction: Direction? = null, - search: String? = null + search: String? = null, + filter: Filter = Filter() ): Paginated { return requester .getFunction("find_articles") @@ -33,7 +35,8 @@ class Article(override var requester: Requester) : RepositoryI { page, limit, "sort" to sort?.toSnakeCase(), "direction" to direction, - "search" to search + "search" to search, + "filter" to filter ) } @@ -42,4 +45,8 @@ class Article(override var requester: Requester) : RepositoryI { .getFunction("upsert_article") .selectOne("resource" to article) } + + class Filter( + val createdById: String? = null + ) : Parameter } diff --git a/src/main/kotlin/fr/dcproject/routes/Article.kt b/src/main/kotlin/fr/dcproject/routes/Article.kt index d52eaa7..4b66d65 100644 --- a/src/main/kotlin/fr/dcproject/routes/Article.kt +++ b/src/main/kotlin/fr/dcproject/routes/Article.kt @@ -1,6 +1,7 @@ package fr.dcproject.routes import fr.dcproject.citizen +import fr.dcproject.repository.Article.Filter import fr.dcproject.security.voter.ArticleVoter.Action.CREATE import fr.dcproject.security.voter.ArticleVoter.Action.VIEW import fr.dcproject.security.voter.assertCan @@ -19,7 +20,7 @@ import fr.dcproject.repository.Article as ArticleRepository @KtorExperimentalLocationsAPI object ArticlesPaths { - @Location("/articles") class ArticlesRequest(page: Int = 1, limit: Int = 50, val sort: String? = null, val direction: RepositoryI.Direction? = null, val search: String? = null) { + @Location("/articles") class ArticlesRequest(page: Int = 1, limit: Int = 50, val sort: String? = null, val direction: RepositoryI.Direction? = null, val search: String? = null, val createdBy: String? = null) { val page: Int = if (page < 1) 1 else page val limit: Int = if (limit > 50) 50 else if (limit < 1) 1 else limit } @@ -34,7 +35,7 @@ object ArticlesPaths { @KtorExperimentalLocationsAPI fun Route.article(repo: ArticleRepository) { get { - val articles = repo.find(it.page, it.limit, it.sort, it.direction, it.search) + val articles = repo.find(it.page, it.limit, it.sort, it.direction, it.search, Filter(createdById = it.createdBy)) assertCan(VIEW, articles.result) call.respond(articles) } diff --git a/src/main/resources/openApi.yaml b/src/main/resources/openApi.yaml index 084a002..f92524d 100644 --- a/src/main/resources/openApi.yaml +++ b/src/main/resources/openApi.yaml @@ -211,6 +211,7 @@ paths: - $ref: '#/components/parameters/articleSort' - $ref: '#/components/parameters/direction' - $ref: '#/components/parameters/search' + - $ref: '#/components/parameters/createdBy' responses: 200: description: The Article objects @@ -752,6 +753,15 @@ components: required: false schema: type: string + createdBy: + name: createdBy + in: query + description: filter by Author + example: 4d673bfa-eaef-4290-b52f-85a9c8a7eba5 + required: false + schema: + type: string + format: uuid citizen: name: citizen @@ -798,6 +808,7 @@ components: type: http scheme: bearer description: call /login to get token + bearerFormat: JWT schemas: UUID: diff --git a/src/main/resources/sql/functions/article/find_articles.sql b/src/main/resources/sql/functions/article/find_articles.sql index 5a33be3..10b7e1b 100644 --- a/src/main/resources/sql/functions/article/find_articles.sql +++ b/src/main/resources/sql/functions/article/find_articles.sql @@ -1,5 +1,6 @@ create or replace function find_articles( _search text default null, + _filter json default '{}', direction text default 'desc', sort text default 'created_at', "limit" int default 50, @@ -9,7 +10,13 @@ create or replace function find_articles( ) language plpgsql as $$ begin - select json_agg(t), (select count(id) from article a where (_search is null or _search = '' or a ==> dsl.multi_match('{title^3, content, description, tags}', _search)) and a.last_version = true) + select json_agg(t), ( + select count(id) + from article a + where (_search is null or _search = '' or a ==> dsl.multi_match('{title^3, content, description, tags}', _search)) + and (_filter->>'created_by_id' is null or a.created_by_id = (_filter->>'created_by_id')::uuid) + and a.last_version = true + ) into resource, total from ( select @@ -22,9 +29,12 @@ begin _search is null or _search = '' or a ==> dsl.multi_match('{title^3, content, description, tags}', _search) - ) and a.last_version = true + ) + and (_filter->>'created_by_id' is null or a.created_by_id = (_filter->>'created_by_id')::uuid) + and a.last_version = true order by + _score desc, case direction when 'asc' then case sort when 'title' then a.title @@ -49,4 +59,4 @@ begin end; $$; --- drop function if exists find_articles(text, text, text, int, int); +-- drop function if exists find_articles(text, json, text, text, int, int);