ALTER TABLE artifact ADD COLUMN repository_id int; ALTER TABLE artifact ADD COLUMN media_type varchar(255); ALTER TABLE artifact ADD COLUMN manifest_media_type varchar(255); ALTER TABLE artifact ADD COLUMN size bigint; ALTER TABLE artifact ADD COLUMN extra_attrs text; ALTER TABLE artifact ADD COLUMN annotations jsonb; ALTER TABLE artifact RENAME COLUMN kind TO type; ALTER TABLE artifact DROP COLUMN creation_time; /*set the media type*/ UPDATE artifact AS art SET type='IMAGE', repository_id=repo.repository_id, manifest_media_type=blob.content_type, media_type=( CASE /*v2 manifest*/ WHEN blob.content_type='application/vnd.docker.distribution.manifest.v2+json' THEN 'application/vnd.docker.container.image.v1+json' /*manifest list*/ WHEN blob.content_type='application/vnd.docker.distribution.manifest.list.v2+json' THEN 'application/vnd.docker.distribution.manifest.list.v2+json' /*v1 manifest*/ ELSE 'application/vnd.docker.distribution.manifest.v1+prettyjws' END ) FROM repository AS repo, blob AS blob WHERE art.repo=repo.name AND art.digest=blob.digest; ALTER TABLE artifact ALTER COLUMN repository_id SET NOT NULL; ALTER TABLE artifact ALTER COLUMN media_type SET NOT NULL; ALTER TABLE artifact ALTER COLUMN manifest_media_type SET NOT NULL; ALTER TABLE artifact RENAME COLUMN repo TO repository_name; CREATE TABLE tag ( id SERIAL PRIMARY KEY NOT NULL, repository_id int NOT NULL, artifact_id int NOT NULL, name varchar(255) NOT NULL, push_time timestamp default CURRENT_TIMESTAMP, pull_time timestamp, FOREIGN KEY (artifact_id) REFERENCES artifact(id), CONSTRAINT unique_tag UNIQUE (repository_id, name) ); /*move the tag in the table artifact into table tag*/ INSERT INTO tag (artifact_id, repository_id, name, push_time, pull_time) SELECT ordered_art.id, art.repository_id, art.tag, art.push_time, art.pull_time FROM artifact AS art JOIN ( /*the tag references the first artifact that with the same digest*/ SELECT id, repository_name, digest, row_number() OVER (PARTITION BY repository_name, digest ORDER BY id) AS seq FROM artifact ) AS ordered_art ON art.repository_name=ordered_art.repository_name AND art.digest=ordered_art.digest WHERE ordered_art.seq=1; ALTER TABLE artifact DROP COLUMN tag; /*TODO: remove this after insert the repository_name when create artifact*/ ALTER TABLE artifact ALTER COLUMN repository_name DROP NOT NULL; /*remove the duplicate artifact rows*/ DELETE FROM artifact WHERE id NOT IN ( SELECT artifact_id FROM tag ); ALTER TABLE artifact ADD CONSTRAINT unique_artifact UNIQUE (repository_id, digest); /*set artifact size*/ UPDATE artifact SET size=s.size FROM ( SELECT art.digest, sum(blob.size) AS size FROM artifact AS art, artifact_blob AS ref, blob AS blob WHERE art.digest=ref.digest_af AND ref.digest_blob=blob.digest GROUP BY art.digest ) AS s WHERE artifact.digest=s.digest; /* artifact_reference records the child artifact referenced by parent artifact */ CREATE TABLE artifact_reference ( id SERIAL PRIMARY KEY NOT NULL, parent_id int NOT NULL, child_id int NOT NULL, platform varchar(255), FOREIGN KEY (parent_id) REFERENCES artifact(id), FOREIGN KEY (child_id) REFERENCES artifact(id), CONSTRAINT unique_reference UNIQUE (parent_id, child_id) ); /* artifact_trash records deleted artifact */ CREATE TABLE artifact_trash ( id SERIAL PRIMARY KEY NOT NULL, media_type varchar(255) NOT NULL, manifest_media_type varchar(255) NOT NULL, repository_name varchar(255) NOT NULL, digest varchar(255) NOT NULL, creation_time timestamp default CURRENT_TIMESTAMP, CONSTRAINT unique_artifact_trash UNIQUE (repository_name, digest) ); /* TODO upgrade: how about keep the table "harbor_resource_label" only for helm v2 chart and use the new table for artifact label reference? */ /* label_reference records the labels added to the artifact */ CREATE TABLE label_reference ( id SERIAL PRIMARY KEY NOT NULL, label_id int NOT NULL, artifact_id int NOT NULL, creation_time timestamp default CURRENT_TIMESTAMP, update_time timestamp default CURRENT_TIMESTAMP, FOREIGN KEY (label_id) REFERENCES harbor_label(id), FOREIGN KEY (artifact_id) REFERENCES artifact(id), CONSTRAINT unique_label_reference UNIQUE (label_id,artifact_id) ); /* TODO remove this table after clean up code that related with the old artifact model */ CREATE TABLE artifact_2 ( id SERIAL PRIMARY KEY NOT NULL, project_id int NOT NULL, repo varchar(255) NOT NULL, tag varchar(255) NOT NULL, /* digest of manifest */ digest varchar(255) NOT NULL, /* kind of artifact, image, chart, etc.. */ kind varchar(255) NOT NULL, creation_time timestamp default CURRENT_TIMESTAMP, pull_time timestamp, push_time timestamp, CONSTRAINT unique_artifact_2 UNIQUE (project_id, repo, tag) );