196 lines
5.6 KiB
PL/PgSQL
196 lines
5.6 KiB
PL/PgSQL
create table if not exists public.page_refs (
|
|
id uuid primary key default gen_random_uuid(),
|
|
workspace_id uuid not null references public.workspaces(id) on delete cascade,
|
|
source_page_id uuid not null references public.documents(id) on delete cascade,
|
|
source_block_id text,
|
|
target_page_id uuid not null references public.documents(id) on delete cascade,
|
|
alias text,
|
|
display_mode text not null default 'inline' check (display_mode in ('inline','embed')),
|
|
is_previewable boolean not null default true,
|
|
created_by uuid not null references public.profiles(id) on delete cascade,
|
|
created_at timestamptz not null default timezone('utc', now()),
|
|
updated_at timestamptz not null default timezone('utc', now())
|
|
);
|
|
|
|
create index if not exists page_refs_target_idx on public.page_refs (workspace_id, target_page_id, display_mode);
|
|
create index if not exists page_refs_source_idx on public.page_refs (workspace_id, source_page_id);
|
|
create index if not exists page_refs_recent_idx on public.page_refs (workspace_id, updated_at desc);
|
|
|
|
create unique index if not exists page_refs_unique_block_ref
|
|
on public.page_refs (workspace_id, source_page_id, coalesce(source_block_id, ''), target_page_id, display_mode);
|
|
|
|
create or replace function public.set_page_refs_updated_at()
|
|
returns trigger
|
|
language plpgsql
|
|
security invoker
|
|
as $$
|
|
begin
|
|
new.updated_at := timezone('utc', now());
|
|
return new;
|
|
end;
|
|
$$;
|
|
|
|
drop trigger if exists set_page_refs_updated_at on public.page_refs;
|
|
create trigger set_page_refs_updated_at
|
|
before update on public.page_refs
|
|
for each row
|
|
execute procedure public.set_page_refs_updated_at();
|
|
|
|
alter table public.page_refs enable row level security;
|
|
|
|
drop policy if exists "Select refs within workspace" on public.page_refs;
|
|
create policy "Select refs within workspace"
|
|
on public.page_refs
|
|
for select
|
|
using (
|
|
exists (
|
|
select 1
|
|
from public.workspace_members wm
|
|
where wm.workspace_id = page_refs.workspace_id
|
|
and wm.user_id = auth.uid()
|
|
)
|
|
);
|
|
|
|
drop policy if exists "Insert refs within workspace" on public.page_refs;
|
|
create policy "Insert refs within workspace"
|
|
on public.page_refs
|
|
for insert
|
|
with check (
|
|
exists (
|
|
select 1
|
|
from public.workspace_members wm
|
|
where wm.workspace_id = page_refs.workspace_id
|
|
and wm.user_id = auth.uid()
|
|
)
|
|
);
|
|
|
|
drop policy if exists "Update refs ownership" on public.page_refs;
|
|
create policy "Update refs ownership"
|
|
on public.page_refs
|
|
for update
|
|
using (
|
|
exists (
|
|
select 1
|
|
from public.workspace_members wm
|
|
where wm.workspace_id = page_refs.workspace_id
|
|
and wm.user_id = auth.uid()
|
|
)
|
|
)
|
|
with check (
|
|
exists (
|
|
select 1
|
|
from public.workspace_members wm
|
|
where wm.workspace_id = page_refs.workspace_id
|
|
and wm.user_id = auth.uid()
|
|
)
|
|
);
|
|
|
|
create or replace function public.record_page_ref(
|
|
p_workspace_id uuid,
|
|
p_source_page_id uuid,
|
|
p_source_block_id text,
|
|
p_target_page_id uuid,
|
|
p_alias text,
|
|
p_display_mode text default 'inline',
|
|
p_is_previewable boolean default true,
|
|
p_created_by uuid default auth.uid()
|
|
)
|
|
returns public.page_refs
|
|
language plpgsql
|
|
security definer
|
|
set search_path = public
|
|
as $$
|
|
declare
|
|
v_existing public.page_refs%rowtype;
|
|
v_mode text := coalesce(nullif(p_display_mode, ''), 'inline');
|
|
begin
|
|
select *
|
|
into v_existing
|
|
from public.page_refs
|
|
where workspace_id = p_workspace_id
|
|
and source_page_id = p_source_page_id
|
|
and target_page_id = p_target_page_id
|
|
and coalesce(source_block_id, '') = coalesce(p_source_block_id, '')
|
|
and display_mode = v_mode
|
|
limit 1;
|
|
|
|
if found then
|
|
update public.page_refs
|
|
set alias = coalesce(p_alias, public.page_refs.alias),
|
|
is_previewable = coalesce(p_is_previewable, public.page_refs.is_previewable),
|
|
updated_at = timezone('utc', now())
|
|
where id = v_existing.id
|
|
returning * into v_existing;
|
|
|
|
return v_existing;
|
|
end if;
|
|
|
|
insert into public.page_refs (
|
|
workspace_id,
|
|
source_page_id,
|
|
source_block_id,
|
|
target_page_id,
|
|
alias,
|
|
display_mode,
|
|
is_previewable,
|
|
created_by
|
|
)
|
|
values (
|
|
p_workspace_id,
|
|
p_source_page_id,
|
|
p_source_block_id,
|
|
p_target_page_id,
|
|
p_alias,
|
|
v_mode,
|
|
coalesce(p_is_previewable, true),
|
|
coalesce(p_created_by, auth.uid())
|
|
)
|
|
returning * into v_existing;
|
|
|
|
return v_existing;
|
|
end;
|
|
$$;
|
|
|
|
create or replace function public.list_backlinks(
|
|
p_workspace_id uuid,
|
|
p_target_page_id uuid,
|
|
p_limit integer default 50,
|
|
p_offset integer default 0
|
|
)
|
|
returns table (
|
|
id uuid,
|
|
source_page_id uuid,
|
|
source_block_id text,
|
|
alias text,
|
|
display_mode text,
|
|
is_previewable boolean,
|
|
created_at timestamptz,
|
|
updated_at timestamptz,
|
|
source_title text,
|
|
workspace_id uuid
|
|
)
|
|
language sql
|
|
security definer
|
|
set search_path = public
|
|
as $$
|
|
select
|
|
r.id,
|
|
r.source_page_id,
|
|
r.source_block_id,
|
|
r.alias,
|
|
r.display_mode,
|
|
r.is_previewable,
|
|
r.created_at,
|
|
r.updated_at,
|
|
d.title as source_title,
|
|
r.workspace_id
|
|
from public.page_refs r
|
|
join public.documents d on d.id = r.source_page_id
|
|
where r.workspace_id = p_workspace_id
|
|
and r.target_page_id = p_target_page_id
|
|
and d.workspace_id = p_workspace_id
|
|
order by r.updated_at desc
|
|
limit greatest(p_limit, 1)
|
|
offset greatest(p_offset, 0);
|
|
$$;
|