Can filter article by author
This commit is contained in:
@@ -2,6 +2,7 @@ package fr.dcproject.repository
|
|||||||
|
|
||||||
import fr.postgresjson.connexion.Paginated
|
import fr.postgresjson.connexion.Paginated
|
||||||
import fr.postgresjson.connexion.Requester
|
import fr.postgresjson.connexion.Requester
|
||||||
|
import fr.postgresjson.entity.Parameter
|
||||||
import fr.postgresjson.repository.RepositoryI
|
import fr.postgresjson.repository.RepositoryI
|
||||||
import fr.postgresjson.repository.RepositoryI.Direction
|
import fr.postgresjson.repository.RepositoryI.Direction
|
||||||
import net.pearx.kasechange.toSnakeCase
|
import net.pearx.kasechange.toSnakeCase
|
||||||
@@ -25,7 +26,8 @@ class Article(override var requester: Requester) : RepositoryI {
|
|||||||
limit: Int = 50,
|
limit: Int = 50,
|
||||||
sort: String? = null,
|
sort: String? = null,
|
||||||
direction: Direction? = null,
|
direction: Direction? = null,
|
||||||
search: String? = null
|
search: String? = null,
|
||||||
|
filter: Filter = Filter()
|
||||||
): Paginated<ArticleEntity> {
|
): Paginated<ArticleEntity> {
|
||||||
return requester
|
return requester
|
||||||
.getFunction("find_articles")
|
.getFunction("find_articles")
|
||||||
@@ -33,7 +35,8 @@ class Article(override var requester: Requester) : RepositoryI {
|
|||||||
page, limit,
|
page, limit,
|
||||||
"sort" to sort?.toSnakeCase(),
|
"sort" to sort?.toSnakeCase(),
|
||||||
"direction" to direction,
|
"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")
|
.getFunction("upsert_article")
|
||||||
.selectOne("resource" to article)
|
.selectOne("resource" to article)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class Filter(
|
||||||
|
val createdById: String? = null
|
||||||
|
) : Parameter
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package fr.dcproject.routes
|
package fr.dcproject.routes
|
||||||
|
|
||||||
import fr.dcproject.citizen
|
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.CREATE
|
||||||
import fr.dcproject.security.voter.ArticleVoter.Action.VIEW
|
import fr.dcproject.security.voter.ArticleVoter.Action.VIEW
|
||||||
import fr.dcproject.security.voter.assertCan
|
import fr.dcproject.security.voter.assertCan
|
||||||
@@ -19,7 +20,7 @@ import fr.dcproject.repository.Article as ArticleRepository
|
|||||||
|
|
||||||
@KtorExperimentalLocationsAPI
|
@KtorExperimentalLocationsAPI
|
||||||
object ArticlesPaths {
|
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 page: Int = if (page < 1) 1 else page
|
||||||
val limit: Int = if (limit > 50) 50 else if (limit < 1) 1 else limit
|
val limit: Int = if (limit > 50) 50 else if (limit < 1) 1 else limit
|
||||||
}
|
}
|
||||||
@@ -34,7 +35,7 @@ object ArticlesPaths {
|
|||||||
@KtorExperimentalLocationsAPI
|
@KtorExperimentalLocationsAPI
|
||||||
fun Route.article(repo: ArticleRepository) {
|
fun Route.article(repo: ArticleRepository) {
|
||||||
get<ArticlesPaths.ArticlesRequest> {
|
get<ArticlesPaths.ArticlesRequest> {
|
||||||
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)
|
assertCan(VIEW, articles.result)
|
||||||
call.respond(articles)
|
call.respond(articles)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -211,6 +211,7 @@ paths:
|
|||||||
- $ref: '#/components/parameters/articleSort'
|
- $ref: '#/components/parameters/articleSort'
|
||||||
- $ref: '#/components/parameters/direction'
|
- $ref: '#/components/parameters/direction'
|
||||||
- $ref: '#/components/parameters/search'
|
- $ref: '#/components/parameters/search'
|
||||||
|
- $ref: '#/components/parameters/createdBy'
|
||||||
responses:
|
responses:
|
||||||
200:
|
200:
|
||||||
description: The Article objects
|
description: The Article objects
|
||||||
@@ -752,6 +753,15 @@ components:
|
|||||||
required: false
|
required: false
|
||||||
schema:
|
schema:
|
||||||
type: string
|
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:
|
citizen:
|
||||||
name: citizen
|
name: citizen
|
||||||
@@ -798,6 +808,7 @@ components:
|
|||||||
type: http
|
type: http
|
||||||
scheme: bearer
|
scheme: bearer
|
||||||
description: call /login to get token
|
description: call /login to get token
|
||||||
|
bearerFormat: JWT
|
||||||
|
|
||||||
schemas:
|
schemas:
|
||||||
UUID:
|
UUID:
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
create or replace function find_articles(
|
create or replace function find_articles(
|
||||||
_search text default null,
|
_search text default null,
|
||||||
|
_filter json default '{}',
|
||||||
direction text default 'desc',
|
direction text default 'desc',
|
||||||
sort text default 'created_at',
|
sort text default 'created_at',
|
||||||
"limit" int default 50,
|
"limit" int default 50,
|
||||||
@@ -9,7 +10,13 @@ create or replace function find_articles(
|
|||||||
) language plpgsql as
|
) language plpgsql as
|
||||||
$$
|
$$
|
||||||
begin
|
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
|
into resource, total
|
||||||
from (
|
from (
|
||||||
select
|
select
|
||||||
@@ -22,9 +29,12 @@ begin
|
|||||||
_search is null
|
_search is null
|
||||||
or _search = ''
|
or _search = ''
|
||||||
or a ==> dsl.multi_match('{title^3, content, description, tags}', _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
|
order by
|
||||||
|
_score desc,
|
||||||
case direction when 'asc' then
|
case direction when 'asc' then
|
||||||
case sort
|
case sort
|
||||||
when 'title' then a.title
|
when 'title' then a.title
|
||||||
@@ -49,4 +59,4 @@ begin
|
|||||||
end;
|
end;
|
||||||
$$;
|
$$;
|
||||||
|
|
||||||
-- drop function if exists find_articles(text, text, text, int, int);
|
-- drop function if exists find_articles(text, json, text, text, int, int);
|
||||||
|
|||||||
Reference in New Issue
Block a user