49 lines
1.7 KiB
PL/PgSQL
49 lines
1.7 KiB
PL/PgSQL
-- Ensure storage objects for all artefacts are removed when a file is deleted
|
|
-- by deleting the entire "cabinet_id/file_id" directory prefix in Storage.
|
|
|
|
-- Helper to delete all objects under a prefix
|
|
create or replace function public._delete_storage_prefix(p_bucket text, p_prefix text)
|
|
returns void
|
|
language plpgsql security definer
|
|
set search_path to 'public', 'storage'
|
|
as $$
|
|
begin
|
|
if p_bucket is null or p_prefix is null then
|
|
return;
|
|
end if;
|
|
-- Delete any objects whose name starts with the prefix + '/'
|
|
delete from storage.objects where bucket_id = p_bucket and name like p_prefix || '/%';
|
|
-- In case an object exists exactly at the prefix (rare but safe)
|
|
delete from storage.objects where bucket_id = p_bucket and name = p_prefix;
|
|
end
|
|
$$;
|
|
|
|
-- Update file-level GC to also delete the parent directory prefix (cabinet_id/file_id)
|
|
create or replace function public._storage_gc_sql()
|
|
returns trigger
|
|
language plpgsql security definer
|
|
set search_path to 'public', 'storage'
|
|
as $$
|
|
declare
|
|
v_prefix text;
|
|
begin
|
|
-- Derive directory prefix from the file path by removing the last segment (filename)
|
|
-- Example: 'cabinet_id/file_id/filename.ext' -> 'cabinet_id/file_id'
|
|
v_prefix := regexp_replace(old.path, '/[^/]+$', '');
|
|
|
|
if tg_op = 'DELETE' then
|
|
-- Delete the original object and any artefacts under the file's directory
|
|
perform public._delete_storage_objects(old.bucket, old.path);
|
|
perform public._delete_storage_prefix(old.bucket, v_prefix);
|
|
elsif tg_op = 'UPDATE' then
|
|
if (old.bucket is distinct from new.bucket) or (old.path is distinct from new.path) then
|
|
perform public._delete_storage_objects(old.bucket, old.path);
|
|
perform public._delete_storage_prefix(old.bucket, v_prefix);
|
|
end if;
|
|
end if;
|
|
return null;
|
|
end
|
|
$$;
|
|
|
|
|