+
+
+
\ No newline at end of file
diff --git a/src/main/resources/openApi.yaml b/src/main/resources/openApi.yaml
index 42dc61a..aea5f0c 100644
--- a/src/main/resources/openApi.yaml
+++ b/src/main/resources/openApi.yaml
@@ -1029,6 +1029,7 @@ components:
- $ref: '#/components/schemas/CreatedAt'
- $ref: '#/components/schemas/lastVersion'
- $ref: '#/components/schemas/Votable'
+ - $ref: '#/components/schemas/Opinionable'
ArticleRequest:
$ref: '#/components/schemas/ArticleBase'
@@ -1210,6 +1211,15 @@ components:
properties:
votes:
$ref: '#/components/schemas/VoteAggregation'
+ Opinionable:
+ type: object
+ properties:
+ opinions:
+ type: string
+ additionalProperties: true
+ example:
+ Opinion1: 1
+ Opinion2: 55
diff --git a/src/main/resources/sql/fixtures/09-opinion.sql b/src/main/resources/sql/fixtures/09-opinion.sql
new file mode 100644
index 0000000..6b7278a
--- /dev/null
+++ b/src/main/resources/sql/fixtures/09-opinion.sql
@@ -0,0 +1,29 @@
+do
+$$
+declare
+ article_count int = (select count(*) from article);
+ _citizensIds uuid[] = (select array_agg(id) from citizen);
+begin
+ delete from opinion_on_article;
+ delete from opinion_list;
+
+ insert into opinion_list (id, name, target)
+ select uuid_in(md5('opinion_list'||row_number() over ())::cstring), 'Opinion'||row_number() over (), 'article'
+ from generate_series(0,20);
+
+ for i in 0..9 loop
+ insert into opinion_on_article (id, created_by_id, target_id, opinion)
+ select
+ uuid_in(md5('opinion_on_article'||rn+(article_count*i))::cstring),
+ z.id,
+ a.id,
+ uuid_in(md5('opinion_list'||((rn+i) % 5 +1))::cstring)
+ from (select *, row_number() over ()+i+5 % 5 rn from citizen) z
+ join (select *, row_number() over () rn from article) a using (rn);
+ end loop;
+
+ raise notice '% opinion inserted', (select count(*) from opinion_on_article);
+
+ raise notice 'opinions fixtures done';
+end;
+$$;
diff --git a/src/main/resources/sql/functions/article/find_article_by_id.sql b/src/main/resources/sql/functions/article/find_article_by_id.sql
index 01f5964..f2e714d 100644
--- a/src/main/resources/sql/functions/article/find_article_by_id.sql
+++ b/src/main/resources/sql/functions/article/find_article_by_id.sql
@@ -8,7 +8,8 @@ begin
select
a.*,
find_citizen_by_id(a.created_by_id) as created_by,
- count_vote(a.id) as votes
+ count_vote(a.id) as votes,
+ count_opinion(a.id) as opinions
into resource
from article as a
where a.id = _id
diff --git a/src/main/resources/sql/functions/article/find_articles.sql b/src/main/resources/sql/functions/article/find_articles.sql
index 10b7e1b..cd9e5e0 100644
--- a/src/main/resources/sql/functions/article/find_articles.sql
+++ b/src/main/resources/sql/functions/article/find_articles.sql
@@ -23,6 +23,7 @@ begin
a.*,
find_citizen_by_id(a.created_by_id) as created_by,
count_vote(a.id) as votes,
+ count_opinion(a.id) as opinions,
zdb.score(a.ctid) _score
from article as a
where (
@@ -60,3 +61,4 @@ end;
$$;
-- drop function if exists find_articles(text, json, text, text, int, int);
+-- select find_article_by_id('d91aa0cd-61d6-83cc-41bb-8d5656e130f7');
\ No newline at end of file
diff --git a/src/main/resources/sql/functions/opinion/count_opinion.sql b/src/main/resources/sql/functions/opinion/count_opinion.sql
index dccfb4a..fae0cd1 100644
--- a/src/main/resources/sql/functions/opinion/count_opinion.sql
+++ b/src/main/resources/sql/functions/opinion/count_opinion.sql
@@ -3,7 +3,7 @@ create or replace function count_opinion(_target_id uuid, out resource json)
$$
declare
agg jsonb;
- empty jsonb = '[]'::jsonb;
+ empty jsonb = '{}'::jsonb;
begin
select jsonb_object_agg(t.label, t.total)
into agg
@@ -18,10 +18,10 @@ begin
order by ol.name
) t;
- resource = empty || coalesce(agg, empty);
+ resource = coalesce(agg, empty);
end;
$$;
-- drop function if exists count_opinion(uuid);
--- select * from count_opinion('ced1563f-ecf5-4f11-8518-8aeceff3c13a');
\ No newline at end of file
+-- select * from count_opinion('d91aa0cd-61d6-83cc-41bb-8d5656e130f7');
\ No newline at end of file
diff --git a/src/main/resources/sql/functions/opinion/find_citizen_opinions_by_target_id.sql b/src/main/resources/sql/functions/opinion/find_citizen_opinions_by_target_id.sql
new file mode 100644
index 0000000..ff415ae
--- /dev/null
+++ b/src/main/resources/sql/functions/opinion/find_citizen_opinions_by_target_id.sql
@@ -0,0 +1,28 @@
+create or replace function find_citizen_opinions_by_target_id(
+ _citizen_id uuid,
+ _id uuid,
+ out resource json
+) language plpgsql as
+$$
+begin
+ select
+ json_agg(t)
+ into resource
+ from (
+ select
+ o.*,
+ ol.name
+ from opinion as o
+ join opinion_list ol on o.opinion = ol.id
+
+ where target_id = _id
+ and created_by_id = _citizen_id
+
+ order by
+ ol.name
+ limit 100
+ ) as t;
+end;
+$$;
+
+-- drop function if exists find_citizen_votes_by_target_ids(uuid, uuid[], regclass);
diff --git a/src/main/resources/sql/functions/opinion/find_citizen_opinions_by_target_ids.sql b/src/main/resources/sql/functions/opinion/find_citizen_opinions_by_target_ids.sql
new file mode 100644
index 0000000..48e28ba
--- /dev/null
+++ b/src/main/resources/sql/functions/opinion/find_citizen_opinions_by_target_ids.sql
@@ -0,0 +1,18 @@
+create or replace function find_citizen_opinions_by_target_ids(
+ _citizen_id uuid,
+ _ids uuid[],
+ out resource json
+) language plpgsql as
+$$
+begin
+ select
+ jsonb_agg(find_citizen_opinions_by_target_id(_citizen_id, o)) into resource
+ from unnest(_ids) o
+
+ order by
+ _ids
+ limit 100;
+end;
+$$;
+
+-- drop function if exists find_citizen_votes_by_target_ids(uuid, uuid[], regclass);
diff --git a/src/test/sql/opinion.sql b/src/test/sql/opinion.sql
index f8d2abe..bba6e80 100644
--- a/src/test/sql/opinion.sql
+++ b/src/test/sql/opinion.sql
@@ -76,6 +76,22 @@ begin
assert (select count(*) = 1 from opinion_on_article), 'opinion must be inserted';
assert (select opinion = opinion1 from opinion_on_article limit 1), 'opinion must be inserted';
+ assert(select (a#>>'{opinions, Opinion1}')::int = 1
+ from find_article_by_id((created_article->>'id')::uuid) a), 'the article must be have a opinion';
+
+ assert(
+ select (o#>>'{0, name}') = 'Opinion1'
+ from find_citizen_opinions_by_target_id(_citizen_id, (created_article->>'id')::uuid) o),
+ 'The opinion must have a name';
+
+ raise notice '%', (
+ select o
+ from find_citizen_opinions_by_target_ids(_citizen_id, array[(created_article->>'id')::uuid]) o);
+
+ assert(
+ select (o#>>'{0, 0, name}') = 'Opinion1'
+ from find_citizen_opinions_by_target_ids(_citizen_id, array[(created_article->>'id')::uuid]) o),
+ 'The first opinion must have a name';
-- delete vote and context
delete from opinion;
@@ -85,5 +101,5 @@ begin
delete from "user";
raise notice 'opinion test pass';
-end;
+end
$$;