♻️ Refactor migrations.

This commit is contained in:
Andrey Antukh 2020-09-21 15:58:56 +02:00 committed by Alonso Torres
parent 1b598e2f6d
commit dda6a96407
25 changed files with 75 additions and 70 deletions

View file

@ -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}
]})

View 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;

View 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);

View 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();

View 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();

View 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();

View file

@ -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)
);

View file

@ -0,0 +1,2 @@
ALTER TABLE page
DROP COLUMN version;

View file

@ -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';

View file

@ -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;

View file

@ -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);

View file

@ -0,0 +1,2 @@
ALTER TABLE page_change
ADD COLUMN session_id uuid DEFAULT NULL;

View file

@ -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);

View file

@ -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());

View file

@ -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;

View 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';

View file

@ -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;

View file

@ -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);

View file

@ -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();

View file

@ -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);

View file

@ -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;

View file

@ -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;

View 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();

View file

@ -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]))