#4 #20
18
resources/functions/article/find_article_by_id.sql
Normal file
18
resources/functions/article/find_article_by_id.sql
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
create or replace function find_article_by_id(in id uuid, out resource json) language plpgsql as
|
||||||
|
$$
|
||||||
|
declare
|
||||||
|
_id alias for id;
|
||||||
|
begin
|
||||||
|
select to_json(t)
|
||||||
|
from (
|
||||||
|
select
|
||||||
|
a.*,
|
||||||
|
find_citizen_by_id(a.created_by_id) as created_by
|
||||||
|
into resource
|
||||||
|
from article as a
|
||||||
|
where a.id = _id
|
||||||
|
) as t;
|
||||||
|
end;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
-- drop function if exists find_article_by_id(uuid, out json);
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
create or replace function find_last_article_by_version_id(in version_id uuid, out resource json) language plpgsql as
|
||||||
|
$$
|
||||||
|
declare
|
||||||
|
_version_id alias for version_id;
|
||||||
|
begin
|
||||||
|
select to_json(t)
|
||||||
|
from (
|
||||||
|
select
|
||||||
|
a.*,
|
||||||
|
find_citizen_by_id(a.created_by_id) as created_by
|
||||||
|
into resource
|
||||||
|
from article as a
|
||||||
|
where a.version_id = _version_id
|
||||||
|
order by a.version_number desc
|
||||||
|
limit 1
|
||||||
|
) as t;
|
||||||
|
end;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
-- drop function if exists find_last_article_by_version_id(uuid, inout json);
|
||||||
23
resources/functions/article/upsert_article.sql
Normal file
23
resources/functions/article/upsert_article.sql
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
create or replace procedure upsert_article(inout resource json)
|
||||||
|
language plpgsql as
|
||||||
|
$$
|
||||||
|
declare
|
||||||
|
new_id uuid;
|
||||||
|
begin
|
||||||
|
insert into article (version_id, created_by_id, title, annonymous, content, description, tags)
|
||||||
|
select
|
||||||
|
version_id,
|
||||||
|
(resource#>>'{created_by, id}')::uuid,
|
||||||
|
title,
|
||||||
|
annonymous,
|
||||||
|
content,
|
||||||
|
description,
|
||||||
|
tags
|
||||||
|
from json_populate_record(null::article, resource)
|
||||||
|
returning id into new_id;
|
||||||
|
|
||||||
|
select find_article_by_id(new_id) into resource;
|
||||||
|
end;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
-- drop procedure if exists upsert_article(inout json);
|
||||||
@@ -7,7 +7,7 @@ begin
|
|||||||
from (
|
from (
|
||||||
select
|
select
|
||||||
z.*,
|
z.*,
|
||||||
find_user_by_id(z.user_id)
|
find_user_by_id(z.user_id) as "user"
|
||||||
from citizen as z
|
from citizen as z
|
||||||
where z.id = _id
|
where z.id = _id
|
||||||
) as t;
|
) as t;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ begin
|
|||||||
from (
|
from (
|
||||||
select
|
select
|
||||||
z.*,
|
z.*,
|
||||||
find_user_by_id(z.user_id)
|
find_user_by_id(z.user_id) as "user"
|
||||||
from citizen as z
|
from citizen as z
|
||||||
where z.user_id = _user_id
|
where z.user_id = _user_id
|
||||||
) as t;
|
) as t;
|
||||||
|
|||||||
@@ -21,10 +21,7 @@ begin
|
|||||||
follow_annonymous = excluded.follow_annonymous
|
follow_annonymous = excluded.follow_annonymous
|
||||||
returning id into new_id;
|
returning id into new_id;
|
||||||
|
|
||||||
select to_json(z)
|
select find_citizen_by_id(new_id) into resource;
|
||||||
into resource
|
|
||||||
from citizen as z
|
|
||||||
where z.id = new_id;
|
|
||||||
end;
|
end;
|
||||||
$$;
|
$$;
|
||||||
|
|
||||||
|
|||||||
@@ -9,4 +9,4 @@ begin
|
|||||||
end;
|
end;
|
||||||
$$;
|
$$;
|
||||||
|
|
||||||
-- drop function if exists find_user_by_id(uuid, inout json);
|
-- drop function if exists find_user_by_id(uuid, out json);
|
||||||
@@ -11,9 +11,7 @@ begin
|
|||||||
from json_populate_record(null::"user", resource)
|
from json_populate_record(null::"user", resource)
|
||||||
returning id into new_id;
|
returning id into new_id;
|
||||||
|
|
||||||
select to_json(u) into resource
|
select find_user_by_id(new_id) into resource;
|
||||||
from "user" as u
|
|
||||||
where u.id = new_id;
|
|
||||||
end;
|
end;
|
||||||
$$;
|
$$;
|
||||||
|
|
||||||
|
|||||||
@@ -52,13 +52,28 @@ create table moderator
|
|||||||
user_id uuid not null references "user" (id)
|
user_id uuid not null references "user" (id)
|
||||||
);
|
);
|
||||||
|
|
||||||
-- Article & Contitution
|
-- Article & Constitution
|
||||||
|
|
||||||
create or replace function generate_version_number(tablename regclass, version_id uuid) returns int
|
create or replace function generate_version_number(tablename regclass, version_id uuid, out generated_number int)
|
||||||
language plpgsql as
|
language plpgsql as
|
||||||
$$
|
$$
|
||||||
|
declare
|
||||||
|
_version_id alias for version_id;
|
||||||
begin
|
begin
|
||||||
return random(); -- TODO
|
if (tablename = 'article'::regclass) then
|
||||||
|
select version_number+1
|
||||||
|
into generated_number
|
||||||
|
from article as t
|
||||||
|
where t.version_id = _version_id
|
||||||
|
order by version_number
|
||||||
|
limit 1;
|
||||||
|
else
|
||||||
|
raise exception '% is not implemented', tablename::text;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
if not found then
|
||||||
|
generated_number := 1;
|
||||||
|
end if;
|
||||||
end;
|
end;
|
||||||
$$;
|
$$;
|
||||||
|
|
||||||
@@ -67,6 +82,7 @@ create or replace function set_version_number() returns trigger
|
|||||||
$$
|
$$
|
||||||
begin
|
begin
|
||||||
new.version_number = generate_version_number(tg_table_name::regclass, new.version_id);
|
new.version_number = generate_version_number(tg_table_name::regclass, new.version_id);
|
||||||
|
return new;
|
||||||
end;
|
end;
|
||||||
$$;
|
$$;
|
||||||
|
|
||||||
@@ -76,18 +92,20 @@ create table article
|
|||||||
created_at timestamptz default now() not null,
|
created_at timestamptz default now() not null,
|
||||||
created_by_id uuid not null references citizen (id),
|
created_by_id uuid not null references citizen (id),
|
||||||
version_id uuid default uuid_generate_v4() not null,
|
version_id uuid default uuid_generate_v4() not null,
|
||||||
version_number int not null unique,
|
version_number int not null,
|
||||||
title text not null,
|
title text not null,
|
||||||
annonymous boolean default false not null,
|
annonymous boolean default false not null,
|
||||||
content text not null check ( content != '' ),
|
content text not null check ( content != '' ),
|
||||||
description text,
|
description text,
|
||||||
tags varchar(32)[] default '{}' not null
|
tags varchar(32)[] default '{}' not null,
|
||||||
|
unique (version_id, version_number)
|
||||||
);
|
);
|
||||||
|
|
||||||
create trigger generate_version_number_trigger
|
create trigger generate_version_number_trigger
|
||||||
before insert
|
before insert
|
||||||
on article
|
on article
|
||||||
execute procedure set_version_number();
|
for each row
|
||||||
|
execute function set_version_number();
|
||||||
|
|
||||||
create table constitution
|
create table constitution
|
||||||
(
|
(
|
||||||
|
|||||||
53
resources/tests/article.sql
Normal file
53
resources/tests/article.sql
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
do
|
||||||
|
$$
|
||||||
|
declare
|
||||||
|
created_user json := '{"username": "george", "plain_password": "azerty"}';
|
||||||
|
_user_id uuid;
|
||||||
|
_citizen_id uuid;
|
||||||
|
created_citizen json := '{"name": {"first_name":"George", "last_name":"MICHEL"}, "birthday": "2001-01-01"}';
|
||||||
|
created_article json := '{"version_id":"933b6a1b-50c9-42b6-989f-c02a57814ef9", "title": "Love the world", "annonymous": false, "content": "bla bal bla", "tags": ["love", "test"]}';
|
||||||
|
selected_article json;
|
||||||
|
begin
|
||||||
|
-- insert user for context
|
||||||
|
call insert_user(created_user);
|
||||||
|
_user_id := created_user->>'id';
|
||||||
|
created_citizen := jsonb_set(created_citizen::jsonb, '{user}'::text[], jsonb_build_object('id', _user_id::text), true)::json;
|
||||||
|
assert created_citizen#>>'{user, id}' = _user_id::text, format('userId in citizen must be the same as user, %s = %s', created_citizen#>>'{user, id}', _user_id::text);
|
||||||
|
|
||||||
|
-- insert new citizen for context
|
||||||
|
call upsert_citizen(created_citizen);
|
||||||
|
_citizen_id := created_citizen->>'id';
|
||||||
|
created_article := jsonb_set(created_article::jsonb, '{created_by}'::text[], jsonb_build_object('id', _citizen_id::text), true)::json;
|
||||||
|
assert created_article#>>'{created_by, id}' = _citizen_id::text, format('citizenId in article must be the same as citizen, %s != %s', created_article#>>'{created_by, id}', _citizen_id::text);
|
||||||
|
|
||||||
|
-- upsert article
|
||||||
|
call upsert_article(created_article);
|
||||||
|
assert created_article->>'version_id' is not null, 'version_id should not be null';
|
||||||
|
assert (created_article->>'version_number')::int = 1, format('version_number must be equal to 1, %s instead', created_article->>'version_number');
|
||||||
|
-- try tu create new version
|
||||||
|
call upsert_article(created_article);
|
||||||
|
assert (created_article->>'version_number')::int = 2, format('version_number must be equal to 2, %s instead', created_article->>'version_number');
|
||||||
|
|
||||||
|
-- get article by id and check the title
|
||||||
|
select find_article_by_id((created_article->>'id')::uuid) into selected_article;
|
||||||
|
assert selected_article->>'title' = 'Love the world', format('title must be "Love the world", %s', selected_article->>'title');
|
||||||
|
|
||||||
|
-- get article by version_id and check the title
|
||||||
|
select find_last_article_by_version_id((created_article->>'version_id')::uuid) into selected_article;
|
||||||
|
assert selected_article->>'title' = 'Love the world', format('title must be "Love the world", %s', selected_article->>'title');
|
||||||
|
assert (selected_article->>'version_number')::int = 2, format('version_id must be 2, %s instead', selected_article->>'version_number');
|
||||||
|
-- check if user id is returned
|
||||||
|
assert (selected_article#>>'{created_by, user, id}')::uuid = _user_id, format('user_id must be %s instead of %s', _user_id, (selected_article#>>'{created_by, user, id}')::uuid);
|
||||||
|
|
||||||
|
-- delete article and context
|
||||||
|
delete from article;
|
||||||
|
delete from citizen;
|
||||||
|
delete from "user";
|
||||||
|
|
||||||
|
-- check if find by id return null if article not exist
|
||||||
|
select find_citizen_by_user_id((created_citizen->>'id')::uuid) into selected_article;
|
||||||
|
assert selected_article is null, format('article must be null if not exist, %s', selected_article);
|
||||||
|
|
||||||
|
raise notice 'article test pass';
|
||||||
|
end;
|
||||||
|
$$;
|
||||||
@@ -8,7 +8,7 @@ begin
|
|||||||
-- Insert user and check if username and password is correct
|
-- Insert user and check if username and password is correct
|
||||||
call insert_user(created_user);
|
call insert_user(created_user);
|
||||||
assert created_user->>'username' = 'george', 'username must be george';
|
assert created_user->>'username' = 'george', 'username must be george';
|
||||||
assert created_user->>'password' is not null, 'password must be generated';
|
assert created_user->>'password' is null, 'password must not be returned';
|
||||||
|
|
||||||
-- get user by there id and check the username is correct
|
-- get user by there id and check the username is correct
|
||||||
select find_user_by_id((created_user->>'id')::uuid) into selected_user;
|
select find_user_by_id((created_user->>'id')::uuid) into selected_user;
|
||||||
|
|||||||
Reference in New Issue
Block a user