diff --git a/sql/upgrades/115.sql b/sql/upgrades/115.sql new file mode 100644 index 00000000..7e35f60f --- /dev/null +++ b/sql/upgrades/115.sql @@ -0,0 +1,161 @@ +-- SWH DB schema upgrade +-- from_version: 114 +-- to_version: 115 +-- description: Add snapshot models + +insert into dbversion(version, release, description) + values(115, now(), 'Work In Progress'); + +CREATE SEQUENCE snapshot_branch_object_id_seq + START WITH 1 + INCREMENT BY 1 + NO MAXVALUE + NO MINVALUE + CACHE 1; + +CREATE SEQUENCE snapshot_object_id_seq + START WITH 1 + INCREMENT BY 1 + NO MAXVALUE + NO MINVALUE + CACHE 1; + +CREATE TYPE snapshot_target AS ENUM ( + 'content', + 'directory', + 'revision', + 'release', + 'snapshot', + 'alias' +); + +CREATE TYPE snapshot_result AS ( + snapshot_id sha1_git, + name bytea, + target bytea, + target_type snapshot_target +); + +CREATE TABLE snapshot ( + object_id bigint DEFAULT nextval('snapshot_object_id_seq'::regclass) NOT NULL, + id sha1_git +); + +CREATE TABLE snapshot_branch ( + object_id bigint DEFAULT nextval('snapshot_branch_object_id_seq'::regclass) NOT NULL, + name bytea NOT NULL, + target bytea, + target_type snapshot_target +); + +CREATE TABLE snapshot_branches ( + snapshot_id bigint NOT NULL, + branch_id bigint NOT NULL +); + +ALTER TABLE occurrence_history + ADD COLUMN snapshot_branch_id bigint; + +ALTER TABLE origin_visit + ADD COLUMN snapshot_id bigint; + +COMMENT ON COLUMN origin_visit.snapshot_id IS 'id of the snapshot associated with the visit'; + +ALTER SEQUENCE snapshot_branch_object_id_seq + OWNED BY snapshot_branch.object_id; + +ALTER SEQUENCE snapshot_object_id_seq + OWNED BY snapshot.object_id; + +CREATE OR REPLACE FUNCTION swh_mktemp_snapshot_branch() RETURNS void + LANGUAGE sql + AS $$ + create temporary table tmp_snapshot_branch ( + name bytea not null, + target bytea, + target_type snapshot_target + ) on commit drop; +$$; + +CREATE OR REPLACE FUNCTION swh_snapshot_add(origin bigint, visit bigint, snapshot_id sha1_git) RETURNS void + LANGUAGE plpgsql + AS $$ +declare + snapshot_object_id snapshot.object_id%type; +begin + select object_id from snapshot where id = snapshot_id into snapshot_object_id; + if snapshot_object_id is null then + insert into snapshot (id) values (snapshot_id) returning object_id into snapshot_object_id; + with all_branches(name, target_type, target) as ( + select name, target_type, target from tmp_snapshot_branch + ), inserted as ( + insert into snapshot_branch (name, target_type, target) + select name, target_type, target from all_branches + on conflict do nothing + returning object_id + ) + insert into snapshot_branches (snapshot_id, branch_id) + select snapshot_object_id, object_id as branch_id from inserted + union all + select snapshot_object_id, object_id as branch_id + from all_branches ab + join snapshot_branch sb + on sb.name = ab.name + and sb.target_type is not distinct from ab.target_type + and sb.target is not distinct from ab.target; + end if; + update origin_visit ov + set snapshot_id = snapshot_object_id + where ov.origin=swh_snapshot_add.origin and ov.visit=swh_snapshot_add.visit; +end; +$$; + +CREATE OR REPLACE FUNCTION swh_snapshot_get_by_id(id sha1_git) RETURNS SETOF snapshot_result + LANGUAGE sql STABLE + AS $$ + select + swh_snapshot_get_by_id.id as snapshot_id, name, target, target_type + from snapshot_branches + inner join snapshot_branch on snapshot_branches.branch_id = snapshot_branch.object_id + where snapshot_id = (select object_id from snapshot where snapshot.id = swh_snapshot_get_by_id.id) +$$; + +CREATE OR REPLACE FUNCTION swh_snapshot_get_by_origin_visit(origin_id bigint, visit_id bigint) RETURNS sha1_git + LANGUAGE sql STABLE + AS $$ + select snapshot.id + from origin_visit + left join snapshot + on snapshot.object_id = origin_visit.snapshot_id + where origin_visit.origin=origin_id and origin_visit.visit=visit_id; +$$; + +ALTER TABLE snapshot + ADD CONSTRAINT snapshot_pkey PRIMARY KEY (object_id); + +ALTER TABLE snapshot_branch + ADD CONSTRAINT snapshot_branch_pkey PRIMARY KEY (object_id); + +ALTER TABLE snapshot_branches + ADD CONSTRAINT snapshot_branches_pkey PRIMARY KEY (snapshot_id, branch_id); + +ALTER TABLE origin_visit + ADD CONSTRAINT origin_visit_snapshot_id_fkey FOREIGN KEY (snapshot_id) REFERENCES snapshot(object_id); + +ALTER TABLE snapshot_branch + ADD CONSTRAINT snapshot_branch_target_check CHECK (((target_type IS NULL) = (target IS NULL))); + +ALTER TABLE snapshot_branch + ADD CONSTRAINT snapshot_target_check CHECK (((target_type <> ALL (ARRAY['content'::snapshot_target, 'directory'::snapshot_target, 'revision'::snapshot_target, 'release'::snapshot_target, 'snapshot'::snapshot_target])) OR (length(target) = 20))); + +ALTER TABLE snapshot_branches + ADD CONSTRAINT snapshot_branches_branch_id_fkey FOREIGN KEY (branch_id) REFERENCES snapshot_branch(object_id); + +ALTER TABLE snapshot_branches + ADD CONSTRAINT snapshot_branches_snapshot_id_fkey FOREIGN KEY (snapshot_id) REFERENCES snapshot(object_id); + +CREATE UNIQUE INDEX snapshot_id_idx ON snapshot USING btree (id); + +CREATE UNIQUE INDEX snapshot_branch_name_idx ON snapshot_branch USING btree (name) WHERE ((target_type IS NULL) AND (target IS NULL)); + +CREATE UNIQUE INDEX snapshot_branch_target_type_target_name_idx ON snapshot_branch USING btree (target_type, target, name);