#29 Implement Workgroup (create query)

Create SQL query to get/set workgroup
Add workgroup to article query
This commit is contained in:
2020-03-12 12:38:32 +01:00
parent fb3278fa47
commit 491ca13284
17 changed files with 264 additions and 12 deletions

View File

@@ -1,7 +1,5 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Fixtures on Test" type="DatabaseScript" folderName="SQL TEST">
<script-file value="$PROJECT_DIR$/src/main/resources/sql/migrations/0000-init_schema.down.sql" />
<script-file value="$PROJECT_DIR$/src/main/resources/sql/migrations/0000-init_schema.up.sql" />
<script-file value="$PROJECT_DIR$/src/main/resources/sql/fixtures/01-user.sql" />
<script-file value="$PROJECT_DIR$/src/main/resources/sql/fixtures/02-citizen.sql" />
<script-file value="$PROJECT_DIR$/src/main/resources/sql/fixtures/03-workgroup.sql" />
@@ -13,6 +11,8 @@
<script-file value="$PROJECT_DIR$/src/main/resources/sql/fixtures/09-opinion.sql" />
<script-mode>FILE</script-mode>
<data-source id="a9a6d0e9-327d-4e7d-9b93-3cb6f7948866" namespace="database/&quot;test&quot;/schema/&quot;public&quot;" />
<method v="2" />
<method v="2">
<option name="RunConfigurationTask" enabled="true" run_configuration_name="Reset Test database" run_configuration_type="DatabaseScript" />
</method>
</configuration>
</component>

View File

@@ -1,7 +1,5 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Test All SQL" type="DatabaseScript" folderName="SQL TEST" editBeforeRun="true">
<script-file value="$PROJECT_DIR$/src/main/resources/sql/migrations/0000-init_schema.down.sql" />
<script-file value="$PROJECT_DIR$/src/main/resources/sql/migrations/0000-init_schema.up.sql" />
<script-file value="$PROJECT_DIR$/src/main/resources/sql/functions/article/find_article_by_id.sql" />
<script-file value="$PROJECT_DIR$/src/main/resources/sql/functions/article/find_articles.sql" />
<script-file value="$PROJECT_DIR$/src/main/resources/sql/functions/article/find_articles_versions_by_id.sql" />
@@ -55,6 +53,10 @@
<script-file value="$PROJECT_DIR$/src/main/resources/sql/functions/opinion/find_opinion_choices.sql" />
<script-file value="$PROJECT_DIR$/src/main/resources/sql/functions/opinion/find_opinion_by_id.sql" />
<script-file value="$PROJECT_DIR$/src/main/resources/sql/functions/opinion/upsert_opinion.sql" />
<script-file value="$PROJECT_DIR$/src/main/resources/sql/functions/workgroup/find_workgroup_by_id.sql" />
<script-file value="$PROJECT_DIR$/src/main/resources/sql/functions/workgroup/find_workgroups.sql" />
<script-file value="$PROJECT_DIR$/src/main/resources/sql/functions/workgroup/upsert_workgroup.sql" />
<script-file value="$PROJECT_DIR$/src/main/resources/sql/functions/workgroup/find_workgroup_members.sql" />
<script-file value="$PROJECT_DIR$/src/test/sql/user.sql" />
<script-file value="$PROJECT_DIR$/src/test/sql/citizen.sql" />
<script-file value="$PROJECT_DIR$/src/test/sql/article.sql" />
@@ -63,8 +65,11 @@
<script-file value="$PROJECT_DIR$/src/test/sql/follow.sql" />
<script-file value="$PROJECT_DIR$/src/test/sql/vote.sql" />
<script-file value="$PROJECT_DIR$/src/test/sql/opinion.sql" />
<script-file value="$PROJECT_DIR$/src/test/sql/workgroup.sql" />
<script-mode>FILE</script-mode>
<data-source id="a9a6d0e9-327d-4e7d-9b93-3cb6f7948866" namespace="database/&quot;test&quot;/schema/&quot;public&quot;" />
<method v="2" />
<method v="2">
<option name="RunConfigurationTask" enabled="true" run_configuration_name="Reset Test database" run_configuration_type="DatabaseScript" />
</method>
</configuration>
</component>

View File

@@ -11,7 +11,7 @@
<script-mode>FILE</script-mode>
<data-source id="a9a6d0e9-327d-4e7d-9b93-3cb6f7948866" namespace="database/&quot;test&quot;/schema/&quot;public&quot;" />
<method v="2">
<option name="RunConfigurationTask" enabled="true" />
<option name="RunConfigurationTask" enabled="true" run_configuration_name="Reset Test database" run_configuration_type="DatabaseScript" />
</method>
</configuration>
</component>

View File

@@ -13,7 +13,7 @@
<script-mode>FILE</script-mode>
<data-source id="a9a6d0e9-327d-4e7d-9b93-3cb6f7948866" namespace="database/&quot;test&quot;/schema/&quot;public&quot;" />
<method v="2">
<option name="RunConfigurationTask" enabled="true" />
<option name="RunConfigurationTask" enabled="true" run_configuration_name="Reset Test database" run_configuration_type="DatabaseScript" />
</method>
</configuration>
</component>

View File

@@ -0,0 +1,31 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Workgroup test" type="JUnit" factoryName="JUnit" show_console_on_std_err="true">
<output_file path="$PROJECT_DIR$/var/log/test/out.log" is_save="true" />
<module name="dcproject.test" />
<useClassPathOnly />
<extension name="coverage" sample_coverage="false">
<pattern>
<option name="PATTERN" value="fr.dcproject.*" />
<option name="ENABLED" value="true" />
</pattern>
</extension>
<option name="PACKAGE_NAME" value="" />
<option name="MAIN_CLASS_NAME" value="RunCucumberTest" />
<option name="METHOD_NAME" value="" />
<option name="TEST_OBJECT" value="class" />
<option name="VM_PARAMETERS" value="-ea -Dcucumber.filter.tags=&quot;@workgroup&quot;" />
<option name="PARAMETERS" value="" />
<option name="TEST_SEARCH_SCOPE">
<value defaultName="wholeProject" />
</option>
<envs>
<env name="SEND_GRID_KEY" value="$SEND_GRID_KEY$" />
</envs>
<dir value="$PROJECT_DIR$" />
<tag value="!online" />
<method v="2">
<option name="Make" enabled="true" />
<option name="RunConfigurationTask" enabled="true" run_configuration_name="Test Workgroup" run_configuration_type="DatabaseScript" />
</method>
</configuration>
</component>

View File

@@ -9,15 +9,17 @@ declare
}
$tags$;
_citizen_count int = (select count(z) from citizen z);
_workgroup_count int = (select count(w) from workgroup w);
begin
delete from article_relations;
delete from article;
insert into article (id, version_id, created_by_id, title, anonymous, content, description, tags, created_at, draft)
insert into article (id, version_id, created_by_id, workgroup_id, title, anonymous, content, description, tags, created_at, draft)
select
uuid_in(md5('article'||row_number() over ())::cstring),
uuid_in(md5('article_v'||row_number() over () % (_citizen_count / 2))::cstring),
z.id,
case when row_number() over () % 2 = 0 then w.id end,
'title' || row_number() over (),
row_number() over () % 3 = 0,
'content' || row_number() over (),
@@ -25,7 +27,8 @@ begin
_tags[(row_number() over () % 5):(row_number() over () % 9)],
now() + (row_number() over () * interval '7 minute 3 second'),
(row_number() over () % 7) = 0
from citizen z;
from (select *, row_number() over () rn from citizen z) z
join (select *, row_number() over () % _workgroup_count rn from workgroup) w using (rn);
insert into article_relations (source_id, target_id, created_by_id, comment)
select

View File

@@ -8,6 +8,7 @@ begin
select
a.*,
find_citizen_by_id(a.created_by_id) as created_by,
find_workgroup_by_id(a.workgroup_id) as workgroup,
count_vote(a.id) as votes,
count_opinion(a.id) as opinions
into resource

View File

@@ -22,6 +22,7 @@ begin
select
a.*,
find_citizen_by_id(a.created_by_id) as created_by,
find_workgroup_by_id(a.workgroup_id) as workgroup,
count_vote(a.id) as votes,
count_opinion(a.id) as opinions,
zdb.score(a.ctid) _score

View File

@@ -15,6 +15,7 @@ begin
select
a.*,
find_citizen_by_id(a.created_by_id) as created_by,
find_workgroup_by_id(a.workgroup_id) as workgroup,
count_vote(a.id) as votes
from article as a
where a.version_id = _version_id

View File

@@ -8,6 +8,7 @@ begin
select
a.*,
find_citizen_by_id(a.created_by_id) as created_by,
find_workgroup_by_id(a.workgroup_id) as workgroup,
count_vote(a.id) as votes
into resource
from article as a

View File

@@ -19,6 +19,8 @@ begin
if (_existing_draft_id is not null) then
update article a2 set
created_by_id = (resource#>>'{created_by, id}')::uuid,
workgroup_id = (resource#>>'{workgroup, id}')::uuid,
title = a.title,
anonymous = a.anonymous,
content = a.content,
@@ -29,12 +31,13 @@ begin
where a2.id = (_existing_draft_id)::uuid
returning a2.id into new_id;
else
insert into article (id, version_id, created_by_id, title, anonymous, content, description, tags, draft)
insert into article (id, version_id, created_by_id, workgroup_id, title, anonymous, content, description, tags, draft)
select
case when _id_exist then uuid_generate_v4()
else coalesce(id, uuid_generate_v4()) end,
coalesce(version_id, uuid_generate_v4()),
(resource#>>'{created_by, id}')::uuid,
(resource#>>'{workgroup, id}')::uuid,
title,
anonymous,
content,

View File

@@ -0,0 +1,22 @@
create or replace function find_workgroup_by_id(in id uuid, out resource json) language plpgsql as
$$
declare
_id alias for id;
begin
select to_json(t)
from (
select
w.*,
find_citizen_by_id(w.created_by_id) as created_by,
find_citizen_by_id(w.owner_id) as owner
into resource
from workgroup as w
left join citizen_in_workgroup ciw on w.id = ciw.workgroup_id
where w.id = _id
and deleted_at is null
) as t;
end;
$$;
-- drop function if exists find_workgroup_by_id(uuid, out json);
-- select * from find_workgroup_by_id('d011ad4c-fa1b-40a3-593b-7816479ff33b')

View File

@@ -0,0 +1,59 @@
create or replace function find_workgroups(
_search text default null,
_filter json default '{}',
direction text default 'desc',
sort text default 'created_at',
"limit" int default 50,
"offset" int default 0,
out resource json,
out total int
) language plpgsql as
$$
begin
select json_agg(t), (
select count(id)
from workgroup w
where deleted_at is null
and (_search is null or _search = '' or w ==> dsl.multi_match('{name^3, description}', _search))
and (_filter->>'created_by_id' is null or w.created_by_id = (_filter->>'created_by_id')::uuid)
)
into resource, total
from (
select
w.*,
find_citizen_by_id(w.created_by_id) as created_by,
find_citizen_by_id(w.owner_id) as owner,
zdb.score(w.ctid) _score
from workgroup as w
where deleted_at is null
and (
_search is null
or _search = ''
or w ==> dsl.multi_match('{name^3, description}', _search)
)
and (_filter->>'created_by_id' is null or w.created_by_id = (_filter->>'created_by_id')::uuid)
order by
_score desc,
case direction when 'asc' then
case sort
when 'name' then w.name
when 'created_at' then w.created_at::text
else null
end
end,
case direction when 'desc' then
case sort
when 'title' then w.name
when 'created_at' then w.created_at::text
end
end
desc,
w.created_at desc
limit "limit" offset "offset"
) as t;
end;
$$;
-- drop function if exists find_workgroups(text, json, text, text, int, int);
-- select * from find_workgroups('49', "limit" := 2)

View File

@@ -0,0 +1,29 @@
create or replace function upsert_workgroup(inout resource json)
language plpgsql as
$$
declare
new_id uuid = coalesce((resource->>'id')::uuid, uuid_generate_v4());
begin
insert into workgroup (id, created_by_id, name, description, anonymous, logo, owner_id)
select
new_id,
(resource#>>'{created_by, id}')::uuid,
name,
description,
anonymous,
logo,
(resource#>>'{owner, id}')::uuid
from json_populate_record(null::workgroup, resource)
on conflict (id) do update set
name = excluded.name,
description = excluded.description,
anonymous = excluded.anonymous,
logo = excluded.logo,
owner_id = excluded.owner_id;
select find_workgroup_by_id(new_id) into resource;
end;
$$;
-- drop procedure if exists upsert_workgroup(inout json);

View File

@@ -27,6 +27,7 @@ create table workgroup
id uuid default uuid_generate_v4() not null primary key,
created_at timestamptz default now() not null,
updated_at timestamptz default now() not null check ( updated_at >= created_at ),
deleted_at timestamptz null check ( deleted_at is null or deleted_at >= updated_at ),
created_by_id uuid not null references citizen (id),
name varchar(128) not null,
description text null,
@@ -194,6 +195,7 @@ create table article
id uuid default uuid_generate_v4() not null primary key,
created_at timestamptz default now() not null,
created_by_id uuid not null references citizen (id),
workgroup_id uuid null references workgroup (id),
version_id uuid default uuid_generate_v4() not null,
version_number int not null,
title text not null check ( length(title) < 128 ),
@@ -740,4 +742,25 @@ create index citizen_idx
using zombodb ((citizen.*))
with (alias ='citizen_idx');
reindex index citizen_idx;
reindex index citizen_idx;
-- INDEX workgroup table
select zdb.define_field_mapping('workgroup', 'name', '{
"type": "text",
"analyzer": "name_analyzer",
"search_analyzer": "name_analyzer"
}');
select zdb.define_field_mapping('workgroup', 'description', '{
"type": "text",
"analyzer": "fr_analyzer",
"search_analyzer": "fr_analyzer"
}');
create index workgroup_idx
on workgroup
using zombodb ((workgroup.*))
with (alias ='workgroup_idx');
reindex index workgroup_idx;

View File

@@ -0,0 +1,29 @@
create or replace function fixture_workgroup(in name text default 'vert', _citizen_id uuid default fixture_citizen(), out _article_id uuid)
language plpgsql as
$$
declare
created_workgroup json;
begin
if (name = 'vert') then
created_workgroup = '{
"name": "Le groupe des vert",
"description": "test",
"anonymous": false
}';
elseif (name = 'rouge') then
created_workgroup = '{
"name": "Le groupe des rouge",
"description": "test",
"anonymous": false
}';
end if;
created_workgroup := jsonb_set(created_workgroup::jsonb, '{created_by}'::text[], jsonb_build_object('id', _citizen_id::text), true)::json;
created_workgroup := jsonb_set(created_workgroup::jsonb, '{owner}'::text[], jsonb_build_object('id', _citizen_id::text), true)::json;
assert created_workgroup#>>'{created_by, id}' = _citizen_id::text, format('citizenId in workgroup must be the same as citizen, %s != %s', created_workgroup#>>'{created_by, id}', _citizen_id::text);
-- upsert workgroup
select upsert_workgroup(created_workgroup) into created_workgroup;
assert created_workgroup->>'description' is not null, 'description should not be null';
end;
$$

View File

@@ -0,0 +1,44 @@
do
$$
declare
_citizen_id uuid := fixture_citizen();
created_workgroup json := '{
"name": "Le groupe des vert",
"description": "test",
"anonymous": false
}';
created_workgroup_2 json := '{
"name": "hello",
"description": "super",
"anonymous": false
}';
selected_workgroup json;
selected_workgroup_2 json;
begin
created_workgroup := jsonb_set(created_workgroup::jsonb, '{created_by}'::text[], jsonb_build_object('id', _citizen_id::text), true)::json;
created_workgroup := jsonb_set(created_workgroup::jsonb, '{owner}'::text[], jsonb_build_object('id', _citizen_id::text), true)::json;
assert created_workgroup#>>'{created_by, id}' = _citizen_id::text, format('citizenId in workgroup must be the same as citizen, %s != %s', created_workgroup#>>'{created_by, id}', _citizen_id::text);
-- upsert workgroup
select upsert_workgroup(created_workgroup) into created_workgroup;
assert created_workgroup->>'description' is not null, 'description should not be null';
assert (created_workgroup->>'name') = 'Le groupe des vert', format('name must be equal to "Le groupe des vert", %s instead', created_workgroup->>'name');
-- insert another workgroup
created_workgroup_2 := jsonb_set(created_workgroup_2::jsonb, '{created_by}'::text[], jsonb_build_object('id', _citizen_id::text), true)::json;
created_workgroup_2 := jsonb_set(created_workgroup_2::jsonb, '{owner}'::text[], jsonb_build_object('id', _citizen_id::text), true)::json;
assert created_workgroup_2#>>'{created_by, id}' = _citizen_id::text, format('citizenId in workgroup must be the same as citizen, %s != %s', created_workgroup_2#>>'{created_by, id}', _citizen_id::text);
select upsert_workgroup(created_workgroup_2) into created_workgroup_2;
-- get workgroup by id and check the name
select find_workgroup_by_id((created_workgroup->>'id')::uuid) into selected_workgroup;
assert selected_workgroup->>'name' = 'Le groupe des vert', format('name must be "Le groupe des vert", %s', selected_workgroup->>'name');
-- search workgroups and check the name
select (w.resource->0) into selected_workgroup from find_workgroups('Le groupe des vert', "limit" := 1) w;
assert (selected_workgroup->>'name') = 'Le groupe des vert', format('name must be "Le groupe des vert" instead of : %s', (selected_workgroup->>'name'));
rollback;
raise notice 'workgroup test pass';
end
$$;