mirror of
https://github.com/penpot/penpot.git
synced 2025-05-10 06:56:37 +02:00
♻️ Refactor migrations.
This commit is contained in:
parent
1b598e2f6d
commit
dda6a96407
25 changed files with 75 additions and 70 deletions
|
@ -18,97 +18,73 @@
|
|||
(def +migrations+
|
||||
{:name "uxbox-main"
|
||||
:steps
|
||||
[{:desc "Add initial extensions and functions."
|
||||
:name "0001-add-extensions"
|
||||
:fn (mg/resource "migrations/0001-add-extensions.sql")}
|
||||
[{:name "0001-add-extensions"
|
||||
:fn (mg/resource "app/migrations/sql/0001-add-extensions.sql")}
|
||||
|
||||
{:desc "Add profile related tables"
|
||||
:name "0002-add-profile-tables"
|
||||
:fn (mg/resource "migrations/0002-add-profile-tables.sql")}
|
||||
{:name "0002-add-profile-tables"
|
||||
:fn (mg/resource "app/migrations/sql/0002-add-profile-tables.sql")}
|
||||
|
||||
{:desc "Add project related tables"
|
||||
:name "0003-add-project-tables"
|
||||
:fn (mg/resource "migrations/0003-add-project-tables.sql")}
|
||||
{:name "0003-add-project-tables"
|
||||
:fn (mg/resource "app/migrations/sql/0003-add-project-tables.sql")}
|
||||
|
||||
{:desc "Add tasks related tables"
|
||||
:name "0004-add-tasks-tables"
|
||||
:fn (mg/resource "migrations/0004-add-tasks-tables.sql")}
|
||||
{:name "0004-add-tasks-tables"
|
||||
:fn (mg/resource "app/migrations/sql/0004-add-tasks-tables.sql")}
|
||||
|
||||
{:desc "Add libraries related tables"
|
||||
:name "0005-add-libraries-tables"
|
||||
:fn (mg/resource "migrations/0005-add-libraries-tables.sql")}
|
||||
{:name "0005-add-libraries-tables"
|
||||
:fn (mg/resource "app/migrations/sql/0005-add-libraries-tables.sql")}
|
||||
|
||||
{:desc "Add presence related tables"
|
||||
:name "0006-add-presence-tables"
|
||||
:fn (mg/resource "migrations/0006-add-presence-tables.sql")}
|
||||
{:name "0006-add-presence-tables"
|
||||
:fn (mg/resource "app/migrations/sql/0006-add-presence-tables.sql")}
|
||||
|
||||
{:desc "Drop version field from page table."
|
||||
:name "0007-drop-version-field-from-page-table"
|
||||
:fn (mg/resource "migrations/0007-drop-version-field-from-page-table.sql")}
|
||||
{:name "0007-drop-version-field-from-page-table"
|
||||
:fn (mg/resource "app/migrations/sql/0007-drop-version-field-from-page-table.sql")}
|
||||
|
||||
{:desc "Add generic token related tables."
|
||||
:name "0008-add-generic-token-table"
|
||||
:fn (mg/resource "migrations/0008-add-generic-token-table.sql")}
|
||||
{:name "0008-add-generic-token-table"
|
||||
:fn (mg/resource "app/migrations/sql/0008-add-generic-token-table.sql")}
|
||||
|
||||
{:desc "Drop the profile_email table"
|
||||
:name "0009-drop-profile-email-table"
|
||||
:fn (mg/resource "migrations/0009-drop-profile-email-table.sql")}
|
||||
{:name "0009-drop-profile-email-table"
|
||||
:fn (mg/resource "app/migrations/sql/0009-drop-profile-email-table.sql")}
|
||||
|
||||
{:desc "Add new HTTP session table"
|
||||
:name "0010-add-http-session-table"
|
||||
:fn (mg/resource "migrations/0010-add-http-session-table.sql")}
|
||||
{:name "0010-add-http-session-table"
|
||||
:fn (mg/resource "app/migrations/sql/0010-add-http-session-table.sql")}
|
||||
|
||||
{:desc "Add session_id field to page_change table"
|
||||
:name "0011-add-session-id-field-to-page-change-table"
|
||||
:fn (mg/resource "migrations/0011-add-session-id-field-to-page-change-table.sql")}
|
||||
{:name "0011-add-session-id-field-to-page-change-table"
|
||||
:fn (mg/resource "app/migrations/sql/0011-add-session-id-field-to-page-change-table.sql")}
|
||||
|
||||
{:desc "Make libraries linked to a file"
|
||||
:name "0012-make-libraries-linked-to-a-file"
|
||||
:fn (mg/resource "migrations/0012-make-libraries-linked-to-a-file.sql")}
|
||||
{:name "0012-make-libraries-linked-to-a-file"
|
||||
:fn (mg/resource "app/migrations/sql/0012-make-libraries-linked-to-a-file.sql")}
|
||||
|
||||
{:desc "Mark files shareable"
|
||||
:name "0013-mark-files-shareable"
|
||||
:fn (mg/resource "migrations/0013-mark-files-shareable.sql")}
|
||||
{:name "0013-mark-files-shareable"
|
||||
:fn (mg/resource "app/migrations/sql/0013-mark-files-shareable.sql")}
|
||||
|
||||
{:desc "Refactor media storage"
|
||||
:name "0014-refactor-media-storage.sql"
|
||||
:fn (mg/resource "migrations/0014-refactor-media-storage.sql")}
|
||||
{:name "0014-refactor-media-storage.sql"
|
||||
:fn (mg/resource "app/migrations/sql/0014-refactor-media-storage.sql")}
|
||||
|
||||
{:desc "Improve and partition task related tables"
|
||||
:name "0015-improve-tasks-tables"
|
||||
:fn (mg/resource "migrations/0015-improve-tasks-tables.sql")}
|
||||
{:name "0015-improve-tasks-tables"
|
||||
:fn (mg/resource "app/migrations/sql/0015-improve-tasks-tables.sql")}
|
||||
|
||||
{:desc "Truncate & alter tokens tables"
|
||||
:name "0016-truncate-and-alter-tokens-table"
|
||||
:fn (mg/resource "migrations/0016-truncate-and-alter-tokens-table.sql")}
|
||||
{:name "0016-truncate-and-alter-tokens-table"
|
||||
:fn (mg/resource "app/migrations/sql/0016-truncate-and-alter-tokens-table.sql")}
|
||||
|
||||
{:desc "Link files to libraries"
|
||||
:name "0017-link-files-to-libraries"
|
||||
:fn (mg/resource "migrations/0017-link-files-to-libraries.sql")}
|
||||
{:name "0017-link-files-to-libraries"
|
||||
:fn (mg/resource "app/migrations/sql/0017-link-files-to-libraries.sql")}
|
||||
|
||||
{:desc "Add file triming triggers"
|
||||
:name "0018-add-file-trimming-triggers"
|
||||
:fn (mg/resource "migrations/0018-add-file-trimming-triggers.sql")}
|
||||
{:name "0018-add-file-trimming-triggers"
|
||||
:fn (mg/resource "app/migrations/sql/0018-add-file-trimming-triggers.sql")}
|
||||
|
||||
{:desc "Improve scheduled task tables"
|
||||
:name "0019-add-improved-scheduled-tasks"
|
||||
:fn (mg/resource "migrations/0019-add-improved-scheduled-tasks.sql")}
|
||||
{:name "0019-add-improved-scheduled-tasks"
|
||||
:fn (mg/resource "app/migrations/sql/0019-add-improved-scheduled-tasks.sql")}
|
||||
|
||||
{:desc "Minor fixes to media object"
|
||||
:name "0020-minor-fixes-to-media-object"
|
||||
:fn (mg/resource "migrations/0020-minor-fixes-to-media-object.sql")}
|
||||
{:name "0020-minor-fixes-to-media-object"
|
||||
:fn (mg/resource "app/migrations/sql/0020-minor-fixes-to-media-object.sql")}
|
||||
|
||||
{:desc "Improve http session tables"
|
||||
:name "0021-http-session-improvements"
|
||||
:fn (mg/resource "migrations/0021-http-session-improvements.sql")}
|
||||
{:name "0021-http-session-improvements"
|
||||
:fn (mg/resource "app/migrations/sql/0021-http-session-improvements.sql")}
|
||||
|
||||
{:desc "Refactor pages and files"
|
||||
:name "0022-page-file-refactor"
|
||||
:fn (mg/resource "migrations/0022-page-file-refactor.sql")}
|
||||
{:name "0022-page-file-refactor"
|
||||
:fn (mg/resource "app/migrations/sql/0022-page-file-refactor.sql")}
|
||||
|
||||
|
||||
{:desc "Adapt old pages and files to new format"
|
||||
:name "0023-adapt-old-pages-and-files"
|
||||
{:name "0023-adapt-old-pages-and-files"
|
||||
:fn mg0023/migrate}
|
||||
]})
|
||||
|
||||
|
|
26
backend/src/app/migrations/sql/0001-add-extensions.sql
Normal file
26
backend/src/app/migrations/sql/0001-add-extensions.sql
Normal file
|
@ -0,0 +1,26 @@
|
|||
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
||||
CREATE EXTENSION IF NOT EXISTS "pgcrypto";
|
||||
|
||||
CREATE FUNCTION update_modified_at()
|
||||
RETURNS TRIGGER AS $updt$
|
||||
BEGIN
|
||||
NEW.modified_at := clock_timestamp();
|
||||
RETURN NEW;
|
||||
END;
|
||||
$updt$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE TABLE pending_to_delete (
|
||||
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
type text NOT NULL,
|
||||
data jsonb NOT NULL
|
||||
);
|
||||
|
||||
CREATE FUNCTION handle_delete()
|
||||
RETURNS TRIGGER AS $pagechange$
|
||||
BEGIN
|
||||
INSERT INTO pending_to_delete (type, data)
|
||||
VALUES (TG_TABLE_NAME, row_to_json(OLD));
|
||||
RETURN OLD;
|
||||
END;
|
||||
$pagechange$ LANGUAGE plpgsql;
|
150
backend/src/app/migrations/sql/0002-add-profile-tables.sql
Normal file
150
backend/src/app/migrations/sql/0002-add-profile-tables.sql
Normal file
|
@ -0,0 +1,150 @@
|
|||
CREATE TABLE profile (
|
||||
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
|
||||
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
modified_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
deleted_at timestamptz NULL,
|
||||
|
||||
fullname text NOT NULL DEFAULT '',
|
||||
email text NOT NULL,
|
||||
photo text NOT NULL,
|
||||
password text NOT NULL,
|
||||
|
||||
lang text NULL,
|
||||
theme text NULL,
|
||||
is_demo boolean NOT NULL DEFAULT false
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX profile__email__idx
|
||||
ON profile (email)
|
||||
WHERE deleted_at IS null;
|
||||
|
||||
CREATE INDEX profile__is_demo
|
||||
ON profile (is_demo)
|
||||
WHERE deleted_at IS null
|
||||
AND is_demo IS true;
|
||||
|
||||
INSERT INTO profile (id, fullname, email, photo, password)
|
||||
VALUES ('00000000-0000-0000-0000-000000000000'::uuid,
|
||||
'System Profile',
|
||||
'system@uxbox.io',
|
||||
'',
|
||||
'!');
|
||||
|
||||
|
||||
--- NOTE: this table is deleted in the next migrations
|
||||
|
||||
CREATE TABLE profile_email (
|
||||
profile_id uuid NOT NULL REFERENCES profile(id) ON DELETE CASCADE,
|
||||
|
||||
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
verified_at timestamptz NULL DEFAULT NULL,
|
||||
|
||||
email text NOT NULL,
|
||||
|
||||
is_main boolean NOT NULL DEFAULT false,
|
||||
is_verified boolean NOT NULL DEFAULT false
|
||||
);
|
||||
|
||||
CREATE INDEX profile_email__profile_id__idx
|
||||
ON profile_email (profile_id);
|
||||
|
||||
CREATE UNIQUE INDEX profile_email__email__idx
|
||||
ON profile_email (email);
|
||||
|
||||
|
||||
|
||||
CREATE TABLE team (
|
||||
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
|
||||
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
modified_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
deleted_at timestamptz NULL,
|
||||
|
||||
name text NOT NULL,
|
||||
photo text NOT NULL,
|
||||
|
||||
is_default boolean NOT NULL DEFAULT false
|
||||
);
|
||||
|
||||
CREATE TRIGGER team__modified_at__tgr
|
||||
BEFORE UPDATE ON team
|
||||
FOR EACH ROW EXECUTE PROCEDURE update_modified_at();
|
||||
|
||||
INSERT INTO team (id, name, photo, is_default)
|
||||
VALUES ('00000000-0000-0000-0000-000000000000'::uuid,
|
||||
'System Team',
|
||||
'',
|
||||
true);
|
||||
|
||||
|
||||
|
||||
CREATE TABLE team_profile_rel (
|
||||
team_id uuid NOT NULL REFERENCES team(id) ON DELETE CASCADE,
|
||||
profile_id uuid NOT NULL REFERENCES profile(id) ON DELETE RESTRICT,
|
||||
|
||||
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
modified_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
|
||||
is_admin boolean DEFAULT false,
|
||||
is_owner boolean DEFAULT false,
|
||||
can_edit boolean DEFAULT false,
|
||||
|
||||
PRIMARY KEY (team_id, profile_id)
|
||||
);
|
||||
|
||||
COMMENT ON TABLE team_profile_rel
|
||||
IS 'Relation between teams and profiles (NM)';
|
||||
|
||||
CREATE TRIGGER team_profile_rel__modified_at__tgr
|
||||
BEFORE UPDATE ON team_profile_rel
|
||||
FOR EACH ROW EXECUTE PROCEDURE update_modified_at();
|
||||
|
||||
|
||||
|
||||
CREATE TABLE profile_attr (
|
||||
profile_id uuid NOT NULL REFERENCES profile(id) ON DELETE CASCADE,
|
||||
|
||||
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
modified_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
|
||||
key text NOT NULL,
|
||||
val bytea NOT NULL,
|
||||
|
||||
PRIMARY KEY (key, profile_id)
|
||||
);
|
||||
|
||||
CREATE INDEX profile_attr__profile_id__idx
|
||||
ON profile_attr(profile_id);
|
||||
|
||||
CREATE TRIGGER profile_attr__modified_at__tgr
|
||||
BEFORE UPDATE ON profile_attr
|
||||
FOR EACH ROW EXECUTE PROCEDURE update_modified_at();
|
||||
|
||||
|
||||
--- NOTE: this table is removed in the following migrations
|
||||
|
||||
CREATE TABLE password_recovery_token (
|
||||
profile_id uuid NOT NULL REFERENCES profile(id) ON DELETE CASCADE,
|
||||
token text NOT NULL,
|
||||
|
||||
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
used_at timestamptz NULL,
|
||||
|
||||
PRIMARY KEY (profile_id, token)
|
||||
);
|
||||
|
||||
|
||||
|
||||
CREATE TABLE session (
|
||||
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
|
||||
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
modified_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
|
||||
profile_id uuid REFERENCES profile(id) ON DELETE CASCADE,
|
||||
user_agent text NULL
|
||||
);
|
||||
|
||||
CREATE INDEX session__profile_id__idx
|
||||
ON session(profile_id);
|
220
backend/src/app/migrations/sql/0003-add-project-tables.sql
Normal file
220
backend/src/app/migrations/sql/0003-add-project-tables.sql
Normal file
|
@ -0,0 +1,220 @@
|
|||
CREATE TABLE project (
|
||||
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
team_id uuid NOT NULL REFERENCES team(id) ON DELETE CASCADE,
|
||||
|
||||
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
modified_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
deleted_at timestamptz DEFAULT NULL,
|
||||
|
||||
is_default boolean NOT NULL DEFAULT false,
|
||||
|
||||
name text NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX project__team_id__idx
|
||||
ON project(team_id);
|
||||
|
||||
CREATE TABLE project_profile_rel (
|
||||
profile_id uuid NOT NULL REFERENCES profile(id) ON DELETE CASCADE,
|
||||
project_id uuid NOT NULL REFERENCES project(id) ON DELETE CASCADE,
|
||||
|
||||
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
modified_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
|
||||
is_owner boolean DEFAULT false,
|
||||
is_admin boolean DEFAULT false,
|
||||
can_edit boolean DEFAULT false,
|
||||
|
||||
PRIMARY KEY (profile_id, project_id)
|
||||
);
|
||||
|
||||
COMMENT ON TABLE project_profile_rel
|
||||
IS 'Relation between projects and profiles (NM)';
|
||||
|
||||
CREATE INDEX project_profile_rel__profile_id__idx
|
||||
ON project_profile_rel(profile_id);
|
||||
|
||||
CREATE INDEX project_profile_rel__project_id__idx
|
||||
ON project_profile_rel(project_id);
|
||||
|
||||
|
||||
CREATE TABLE file (
|
||||
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
project_id uuid NOT NULL REFERENCES project(id) ON DELETE CASCADE,
|
||||
|
||||
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
modified_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
deleted_at timestamptz DEFAULT NULL,
|
||||
|
||||
name text NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE file_profile_rel (
|
||||
file_id uuid NOT NULL REFERENCES file(id) ON DELETE CASCADE,
|
||||
profile_id uuid NOT NULL REFERENCES profile(id) ON DELETE CASCADE,
|
||||
|
||||
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
modified_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
|
||||
is_owner boolean DEFAULT false,
|
||||
is_admin boolean DEFAULT false,
|
||||
can_edit boolean DEFAULT false,
|
||||
|
||||
PRIMARY KEY (file_id, profile_id)
|
||||
);
|
||||
|
||||
COMMENT ON TABLE file_profile_rel
|
||||
IS 'Relation between files and profiles (NM)';
|
||||
|
||||
CREATE INDEX file_profile_rel__profile_id__idx
|
||||
ON file_profile_rel(profile_id);
|
||||
|
||||
CREATE INDEX file_profile_rel__file_id__idx
|
||||
ON file_profile_rel(file_id);
|
||||
|
||||
CREATE TRIGGER file_profile_rel__modified_at__tgr
|
||||
BEFORE UPDATE ON file_profile_rel
|
||||
FOR EACH ROW EXECUTE PROCEDURE update_modified_at();
|
||||
|
||||
CREATE TABLE file_image (
|
||||
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
file_id uuid NOT NULL REFERENCES file(id) ON DELETE CASCADE,
|
||||
|
||||
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
modified_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
deleted_at timestamptz DEFAULT NULL,
|
||||
|
||||
name text NOT NULL,
|
||||
|
||||
path text NOT NULL,
|
||||
width int NOT NULL,
|
||||
height int NOT NULL,
|
||||
mtype text NOT NULL,
|
||||
|
||||
thumb_path text NOT NULL,
|
||||
thumb_width int NOT NULL,
|
||||
thumb_height int NOT NULL,
|
||||
thumb_quality int NOT NULL,
|
||||
thumb_mtype text NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX file_image__file_id__idx
|
||||
ON file_image(file_id);
|
||||
|
||||
CREATE TRIGGER file_image__modified_at__tgr
|
||||
BEFORE UPDATE ON file_image
|
||||
FOR EACH ROW EXECUTE PROCEDURE update_modified_at();
|
||||
|
||||
CREATE TRIGGER file_image__on_delete__tgr
|
||||
AFTER DELETE ON file_image
|
||||
FOR EACH ROW EXECUTE PROCEDURE handle_delete();
|
||||
|
||||
|
||||
|
||||
CREATE TABLE page (
|
||||
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
file_id uuid NOT NULL REFERENCES file(id) ON DELETE CASCADE,
|
||||
|
||||
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
modified_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
deleted_at timestamptz DEFAULT NULL,
|
||||
|
||||
version bigint NOT NULL DEFAULT 0,
|
||||
revn bigint NOT NULL DEFAULT 0,
|
||||
|
||||
share_token text NULL DEFAULT NULL,
|
||||
|
||||
ordering smallint NOT NULL,
|
||||
|
||||
name text NOT NULL,
|
||||
data bytea NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX page__file_id__idx
|
||||
ON page(file_id);
|
||||
|
||||
ALTER TABLE page
|
||||
ALTER COLUMN data SET STORAGE EXTERNAL,
|
||||
ALTER COLUMN share_token SET STORAGE PLAIN;
|
||||
|
||||
CREATE FUNCTION handle_page_update()
|
||||
RETURNS TRIGGER AS $pagechange$
|
||||
DECLARE
|
||||
current_dt timestamptz := clock_timestamp();
|
||||
proj_id uuid;
|
||||
BEGIN
|
||||
NEW.modified_at := current_dt;
|
||||
|
||||
UPDATE file
|
||||
SET modified_at = current_dt
|
||||
WHERE id = OLD.file_id
|
||||
RETURNING project_id
|
||||
INTO STRICT proj_id;
|
||||
|
||||
--- Update projects modified_at attribute when a
|
||||
--- page of that project is modified.
|
||||
UPDATE project
|
||||
SET modified_at = current_dt
|
||||
WHERE id = proj_id;
|
||||
|
||||
RETURN NEW;
|
||||
END;
|
||||
$pagechange$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE TRIGGER page__on_update__tgr
|
||||
BEFORE UPDATE ON page
|
||||
FOR EACH ROW EXECUTE PROCEDURE handle_page_update();
|
||||
|
||||
|
||||
CREATE TABLE page_version (
|
||||
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
|
||||
page_id uuid NOT NULL REFERENCES page(id) ON DELETE CASCADE,
|
||||
profile_id uuid NULL REFERENCES profile(id) ON DELETE SET NULL,
|
||||
|
||||
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
modified_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
deleted_at timestamptz DEFAULT NULL,
|
||||
|
||||
version bigint NOT NULL DEFAULT 0,
|
||||
|
||||
label text NOT NULL DEFAULT '',
|
||||
data bytea NOT NULL,
|
||||
|
||||
changes bytea NULL DEFAULT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX page_version__profile_id__idx
|
||||
ON page_version(profile_id);
|
||||
|
||||
CREATE INDEX page_version__page_id__idx
|
||||
ON page_version(page_id);
|
||||
|
||||
CREATE TRIGGER page_version__modified_at__tgr
|
||||
BEFORE UPDATE ON page_version
|
||||
FOR EACH ROW EXECUTE PROCEDURE update_modified_at();
|
||||
|
||||
|
||||
|
||||
CREATE TABLE page_change (
|
||||
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
page_id uuid NOT NULL REFERENCES page(id) ON DELETE CASCADE,
|
||||
|
||||
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
modified_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
|
||||
revn bigint NOT NULL DEFAULT 0,
|
||||
|
||||
label text NOT NULL DEFAULT '',
|
||||
data bytea NOT NULL,
|
||||
|
||||
changes bytea NULL DEFAULT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX page_change__page_id__idx
|
||||
ON page_change(page_id);
|
||||
|
||||
CREATE TRIGGER page_change__modified_at__tgr
|
||||
BEFORE UPDATE ON page_change
|
||||
FOR EACH ROW EXECUTE PROCEDURE update_modified_at();
|
||||
|
40
backend/src/app/migrations/sql/0004-add-tasks-tables.sql
Normal file
40
backend/src/app/migrations/sql/0004-add-tasks-tables.sql
Normal file
|
@ -0,0 +1,40 @@
|
|||
CREATE TABLE task (
|
||||
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
|
||||
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
modified_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
completed_at timestamptz NULL DEFAULT NULL,
|
||||
scheduled_at timestamptz NOT NULL,
|
||||
priority smallint DEFAULT 100,
|
||||
|
||||
queue text NOT NULL,
|
||||
|
||||
name text NOT NULL,
|
||||
props bytea NOT NULL,
|
||||
|
||||
error text NULL DEFAULT NULL,
|
||||
|
||||
retry_num smallint NOT NULL DEFAULT 0,
|
||||
status text NOT NULL DEFAULT 'new'
|
||||
);
|
||||
|
||||
CREATE INDEX task__scheduled_at__queue__idx
|
||||
ON task (scheduled_at, queue);
|
||||
|
||||
CREATE TRIGGER task__modified_at__tgr
|
||||
BEFORE UPDATE ON task
|
||||
FOR EACH ROW EXECUTE PROCEDURE update_modified_at();
|
||||
|
||||
CREATE TABLE scheduled_task (
|
||||
id text PRIMARY KEY,
|
||||
|
||||
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
modified_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
executed_at timestamptz NULL DEFAULT NULL,
|
||||
|
||||
cron_expr text NOT NULL
|
||||
);
|
||||
|
||||
CREATE TRIGGER scheduled_task__modified_at__tgr
|
||||
BEFORE UPDATE ON scheduled_task
|
||||
FOR EACH ROW EXECUTE PROCEDURE update_modified_at();
|
136
backend/src/app/migrations/sql/0005-add-libraries-tables.sql
Normal file
136
backend/src/app/migrations/sql/0005-add-libraries-tables.sql
Normal file
|
@ -0,0 +1,136 @@
|
|||
CREATE TABLE image_library (
|
||||
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
team_id uuid NOT NULL REFERENCES team(id) ON DELETE CASCADE,
|
||||
|
||||
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
modified_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
deleted_at timestamptz DEFAULT NULL,
|
||||
|
||||
name text NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX image_library__team_id__idx
|
||||
ON image_library(team_id);
|
||||
|
||||
CREATE TRIGGER image_library__modified_at__tgr
|
||||
BEFORE UPDATE ON image_library
|
||||
FOR EACH ROW EXECUTE PROCEDURE update_modified_at();
|
||||
|
||||
|
||||
|
||||
CREATE TABLE image (
|
||||
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
library_id uuid NOT NULL REFERENCES image_library(id) ON DELETE CASCADE,
|
||||
|
||||
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
modified_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
deleted_at timestamptz DEFAULT NULL,
|
||||
|
||||
name text NOT NULL,
|
||||
|
||||
path text NOT NULL,
|
||||
width int NOT NULL,
|
||||
height int NOT NULL,
|
||||
mtype text NOT NULL,
|
||||
|
||||
thumb_path text NOT NULL,
|
||||
thumb_width int NOT NULL,
|
||||
thumb_height int NOT NULL,
|
||||
thumb_quality int NOT NULL,
|
||||
thumb_mtype text NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX image__library_id__idx
|
||||
ON image(library_id);
|
||||
|
||||
CREATE TRIGGER image__modified_at__tgr
|
||||
BEFORE UPDATE ON image
|
||||
FOR EACH ROW EXECUTE PROCEDURE update_modified_at();
|
||||
|
||||
CREATE TRIGGER image__on_delete__tgr
|
||||
AFTER DELETE ON image
|
||||
FOR EACH ROW EXECUTE PROCEDURE handle_delete();
|
||||
|
||||
|
||||
|
||||
CREATE TABLE icon_library (
|
||||
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
team_id uuid NOT NULL REFERENCES team(id) ON DELETE CASCADE,
|
||||
|
||||
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
modified_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
deleted_at timestamptz DEFAULT NULL,
|
||||
|
||||
name text NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX icon_colection__team_id__idx
|
||||
ON icon_library (team_id);
|
||||
|
||||
CREATE TRIGGER icon_library__modified_at__tgr
|
||||
BEFORE UPDATE ON icon_library
|
||||
FOR EACH ROW EXECUTE PROCEDURE update_modified_at();
|
||||
|
||||
|
||||
|
||||
CREATE TABLE icon (
|
||||
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
library_id uuid REFERENCES icon_library(id) ON DELETE CASCADE,
|
||||
|
||||
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
modified_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
deleted_at timestamptz DEFAULT NULL,
|
||||
|
||||
|
||||
name text NOT NULL,
|
||||
content text NOT NULL,
|
||||
metadata bytea NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX icon__library_id__idx
|
||||
ON icon(library_id);
|
||||
|
||||
CREATE TRIGGER icon__modified_at__tgr
|
||||
BEFORE UPDATE ON icon
|
||||
FOR EACH ROW EXECUTE PROCEDURE update_modified_at();
|
||||
|
||||
|
||||
|
||||
CREATE TABLE color_library (
|
||||
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
team_id uuid NOT NULL REFERENCES team(id) ON DELETE CASCADE,
|
||||
|
||||
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
modified_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
deleted_at timestamptz DEFAULT NULL,
|
||||
|
||||
name text NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX color_colection__team_id__idx
|
||||
ON color_library (team_id);
|
||||
|
||||
CREATE TRIGGER color_library__modified_at__tgr
|
||||
BEFORE UPDATE ON color_library
|
||||
FOR EACH ROW EXECUTE PROCEDURE update_modified_at();
|
||||
|
||||
|
||||
|
||||
CREATE TABLE color (
|
||||
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
library_id uuid REFERENCES color_library(id) ON DELETE CASCADE,
|
||||
|
||||
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
modified_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
deleted_at timestamptz DEFAULT NULL,
|
||||
|
||||
name text NOT NULL,
|
||||
content text NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX color__library_id__idx
|
||||
ON color(library_id);
|
||||
|
||||
CREATE TRIGGER color__modified_at__tgr
|
||||
BEFORE UPDATE ON color
|
||||
FOR EACH ROW EXECUTE PROCEDURE update_modified_at();
|
|
@ -0,0 +1,9 @@
|
|||
CREATE TABLE presence (
|
||||
file_id uuid NOT NULL REFERENCES file(id) ON DELETE CASCADE,
|
||||
profile_id uuid NOT NULL REFERENCES profile(id) ON DELETE CASCADE,
|
||||
session_id uuid NOT NULL,
|
||||
|
||||
updated_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
|
||||
PRIMARY KEY (file_id, session_id, profile_id)
|
||||
);
|
|
@ -0,0 +1,2 @@
|
|||
ALTER TABLE page
|
||||
DROP COLUMN version;
|
|
@ -0,0 +1,14 @@
|
|||
--- Delete previously token related tables
|
||||
|
||||
DROP TABLE password_recovery_token;
|
||||
|
||||
--- Create a new generic table for store tokens.
|
||||
|
||||
CREATE TABLE generic_token (
|
||||
token text PRIMARY KEY,
|
||||
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
valid_until timestamptz NOT NULL,
|
||||
content bytea NOT NULL
|
||||
);
|
||||
|
||||
COMMENT ON TABLE generic_token IS 'Table for generic tokens storage';
|
|
@ -0,0 +1,6 @@
|
|||
DROP INDEX profile_email__profile_id__idx;
|
||||
DROP INDEX profile_email__email__idx;
|
||||
DROP TABLE profile_email;
|
||||
|
||||
ALTER TABLE profile
|
||||
ADD COLUMN pending_email text NULL;
|
|
@ -0,0 +1,14 @@
|
|||
DROP TABLE session;
|
||||
|
||||
CREATE TABLE http_session (
|
||||
id text PRIMARY KEY,
|
||||
|
||||
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
modified_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
|
||||
profile_id uuid REFERENCES profile(id) ON DELETE CASCADE,
|
||||
user_agent text NULL
|
||||
);
|
||||
|
||||
CREATE INDEX http_session__profile_id__idx
|
||||
ON http_session(profile_id);
|
|
@ -0,0 +1,2 @@
|
|||
ALTER TABLE page_change
|
||||
ADD COLUMN session_id uuid DEFAULT NULL;
|
|
@ -0,0 +1,21 @@
|
|||
TRUNCATE TABLE color;
|
||||
TRUNCATE TABLE color_library CASCADE;
|
||||
TRUNCATE TABLE image;
|
||||
TRUNCATE TABLE image_library CASCADE;
|
||||
TRUNCATE TABLE icon;
|
||||
TRUNCATE TABLE icon_library CASCADE;
|
||||
|
||||
ALTER TABLE color
|
||||
DROP COLUMN library_id,
|
||||
ADD COLUMN file_id uuid NOT NULL REFERENCES file(id) ON DELETE CASCADE;
|
||||
|
||||
CREATE INDEX color__file_id__idx
|
||||
ON color(file_id);
|
||||
|
||||
ALTER TABLE image
|
||||
DROP COLUMN library_id,
|
||||
ADD COLUMN file_id uuid NOT NULL REFERENCES file(id) ON DELETE CASCADE;
|
||||
|
||||
CREATE INDEX image__file_id__idx
|
||||
ON image(file_id);
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
ALTER TABLE file
|
||||
ADD COLUMN is_shared BOOLEAN NOT NULL DEFAULT false;
|
||||
|
||||
UPDATE file
|
||||
SET is_shared = true
|
||||
WHERE project_id IN (SELECT id
|
||||
FROM project
|
||||
WHERE team_id = uuid_nil());
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
ALTER TABLE image
|
||||
RENAME TO media_object;
|
||||
|
||||
ALTER TABLE media_object
|
||||
ADD COLUMN is_local boolean NOT NULL DEFAULT false;
|
||||
|
||||
INSERT INTO media_object
|
||||
(id, file_id, created_at, modified_at, deleted_at, name, path,
|
||||
width, height, mtype, thumb_path, thumb_width, thumb_height,
|
||||
thumb_quality, thumb_mtype, is_local)
|
||||
(SELECT id, file_id, created_at, modified_at, deleted_at, name, path,
|
||||
width, height, mtype, thumb_path, thumb_width, thumb_height,
|
||||
thumb_quality, thumb_mtype, true
|
||||
FROM file_image);
|
||||
|
||||
CREATE TABLE media_thumbnail (
|
||||
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
media_object_id uuid NOT NULL REFERENCES media_object(id) ON DELETE CASCADE,
|
||||
mtype text NOT NULL,
|
||||
path text NOT NULL,
|
||||
width int NOT NULL,
|
||||
height int NOT NULL,
|
||||
quality int NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX media_thumbnail__media_object_id__idx
|
||||
ON media_thumbnail(media_object_id);
|
||||
|
||||
INSERT INTO media_thumbnail
|
||||
(media_object_id, mtype, path, width, height, quality)
|
||||
(SELECT id, thumb_mtype, thumb_path, thumb_width, thumb_height, thumb_quality
|
||||
FROM media_object);
|
||||
|
||||
ALTER TABLE media_object
|
||||
DROP COLUMN thumb_mtype,
|
||||
DROP COLUMN thumb_path,
|
||||
DROP COLUMN thumb_width,
|
||||
DROP COLUMN thumb_height,
|
||||
DROP COLUMN thumb_quality;
|
||||
|
||||
DROP TABLE color_library;
|
||||
DROP TABLE icon;
|
||||
DROP TABLE icon_library;
|
||||
DROP TABLE image_library;
|
||||
DROP TABLE file_image;
|
||||
|
29
backend/src/app/migrations/sql/0015-improve-tasks-tables.sql
Normal file
29
backend/src/app/migrations/sql/0015-improve-tasks-tables.sql
Normal file
|
@ -0,0 +1,29 @@
|
|||
DROP TABLE task;
|
||||
|
||||
CREATE TABLE task (
|
||||
id uuid DEFAULT uuid_generate_v4(),
|
||||
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
modified_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
completed_at timestamptz NULL DEFAULT NULL,
|
||||
scheduled_at timestamptz NOT NULL,
|
||||
priority smallint DEFAULT 100,
|
||||
|
||||
queue text NOT NULL,
|
||||
|
||||
name text NOT NULL,
|
||||
props jsonb NOT NULL,
|
||||
|
||||
error text NULL DEFAULT NULL,
|
||||
retry_num smallint NOT NULL DEFAULT 0,
|
||||
max_retries smallint NOT NULL DEFAULT 3,
|
||||
status text NOT NULL DEFAULT 'new',
|
||||
|
||||
PRIMARY KEY (id, status)
|
||||
) PARTITION BY list(status);
|
||||
|
||||
CREATE TABLE task_completed partition OF task FOR VALUES IN ('completed', 'failed');
|
||||
CREATE TABLE task_default partition OF task default;
|
||||
|
||||
CREATE INDEX task__scheduled_at__queue__idx
|
||||
ON task (scheduled_at, queue)
|
||||
WHERE status = 'new' or status = 'retry';
|
|
@ -0,0 +1,3 @@
|
|||
delete from generic_token;
|
||||
alter table generic_token drop column content;
|
||||
alter table generic_token add column content jsonb not null;
|
|
@ -0,0 +1,15 @@
|
|||
CREATE TABLE file_library_rel (
|
||||
file_id uuid NOT NULL REFERENCES file(id) ON DELETE CASCADE,
|
||||
library_file_id uuid NOT NULL REFERENCES file(id) ON DELETE RESTRICT,
|
||||
|
||||
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
|
||||
PRIMARY KEY (file_id, library_file_id)
|
||||
);
|
||||
|
||||
COMMENT ON TABLE file_library_rel
|
||||
IS 'Relation between files and the shared library files they use (NM)';
|
||||
|
||||
CREATE INDEX file_library_rel__file_id__idx
|
||||
ON file_library_rel(file_id);
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
ALTER TABLE file
|
||||
ADD COLUMN has_media_trimmed boolean DEFAULT false;
|
||||
|
||||
CREATE INDEX file__modified_at__has_media_trimed__idx
|
||||
ON file(modified_at)
|
||||
WHERE has_media_trimmed IS false;
|
||||
|
||||
CREATE FUNCTION on_media_object_insert()
|
||||
RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
UPDATE file
|
||||
SET has_media_trimmed = false,
|
||||
modified_at = now()
|
||||
WHERE id = NEW.file_id;
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE TRIGGER media_object__insert__tgr
|
||||
AFTER INSERT ON media_object
|
||||
FOR EACH ROW EXECUTE PROCEDURE on_media_object_insert();
|
||||
|
||||
CREATE TRIGGER media_thumbnail__on_delete__tgr
|
||||
AFTER DELETE ON media_thumbnail
|
||||
FOR EACH ROW EXECUTE PROCEDURE handle_delete();
|
|
@ -0,0 +1,24 @@
|
|||
DROP TABLE scheduled_task;
|
||||
|
||||
CREATE TABLE scheduled_task (
|
||||
id text PRIMARY KEY,
|
||||
|
||||
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
modified_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
|
||||
cron_expr text NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE scheduled_task_history (
|
||||
id uuid DEFAULT uuid_generate_v4(),
|
||||
task_id text NOT NULL REFERENCES scheduled_task(id),
|
||||
|
||||
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
is_error boolean NOT NULL DEFAULT false,
|
||||
reason text NULL DEFAULT NULL,
|
||||
|
||||
PRIMARY KEY (id, created_at)
|
||||
);
|
||||
|
||||
CREATE INDEX scheduled_task_history__task_id__idx
|
||||
ON scheduled_task_history(task_id);
|
|
@ -0,0 +1,8 @@
|
|||
alter table media_object drop column modified_at;
|
||||
alter index image_pkey rename to media_object_pkey;
|
||||
alter index image__file_id__idx rename to media_bject__file_id__idx;
|
||||
alter table media_object rename constraint image_file_id_fkey to media_object_file_id_fkey;
|
||||
alter trigger image__on_delete__tgr on media_object rename to media_object__on_delete__tgr;
|
||||
drop trigger image__modified_at__tgr on media_object;
|
||||
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
alter table http_session drop constraint http_session_pkey;
|
||||
alter table http_session add primary key (id, profile_id);
|
||||
alter table http_session drop column modified_at;
|
||||
drop index http_session__profile_id__idx;
|
48
backend/src/app/migrations/sql/0022-page-file-refactor.sql
Normal file
48
backend/src/app/migrations/sql/0022-page-file-refactor.sql
Normal file
|
@ -0,0 +1,48 @@
|
|||
ALTER TABLE file
|
||||
ADD COLUMN revn bigint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN data bytea NULL;
|
||||
|
||||
CREATE TABLE file_change (
|
||||
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
file_id uuid NOT NULL REFERENCES file(id) ON DELETE CASCADE,
|
||||
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
session_id uuid NULL DEFAULT NULL,
|
||||
revn bigint NOT NULL DEFAULT 0,
|
||||
data bytea NOT NULL,
|
||||
changes bytea NULL DEFAULT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE file_share_token (
|
||||
file_id uuid NOT NULL REFERENCES file(id) ON DELETE CASCADE,
|
||||
page_id uuid NOT NULL,
|
||||
token text NOT NULL,
|
||||
|
||||
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
|
||||
PRIMARY KEY (file_id, token)
|
||||
);
|
||||
|
||||
CREATE INDEX page_change_file_id_idx
|
||||
ON file_change(file_id);
|
||||
|
||||
CREATE FUNCTION handle_file_update()
|
||||
RETURNS TRIGGER AS $pagechange$
|
||||
DECLARE
|
||||
current_dt timestamptz := clock_timestamp();
|
||||
BEGIN
|
||||
NEW.modified_at := current_dt;
|
||||
|
||||
--- Update projects modified_at attribute when a
|
||||
--- page of that project is modified.
|
||||
UPDATE project
|
||||
SET modified_at = current_dt
|
||||
WHERE id = OLD.project_id;
|
||||
|
||||
RETURN NEW;
|
||||
END;
|
||||
$pagechange$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE TRIGGER file_on_update_tgr
|
||||
BEFORE UPDATE ON file
|
||||
FOR EACH ROW EXECUTE PROCEDURE handle_file_update();
|
||||
|
|
@ -13,7 +13,7 @@
|
|||
[next.jdbc :as jdbc]))
|
||||
|
||||
(s/def ::name string?)
|
||||
(s/def ::step (s/keys :req-un [::name ::desc ::fn]))
|
||||
(s/def ::step (s/keys :req-un [::name ::fn]))
|
||||
(s/def ::steps (s/every ::step :kind vector?))
|
||||
(s/def ::migrations
|
||||
(s/keys :req-un [::name ::steps]))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue