diff --git a/migrations/2025-01-19-212212_issues-to-tasks/down.sql b/migrations/2025-01-19-212212_issues-to-tasks/down.sql new file mode 100644 index 0000000..2c4803c --- /dev/null +++ b/migrations/2025-01-19-212212_issues-to-tasks/down.sql @@ -0,0 +1,7 @@ +DELETE FROM tasks +WHERE type = 'dev' + AND id IN (SELECT id FROM issues); + +DELETE FROM users_projects_roles +WHERE role_id = 2 + AND user_id IN (SELECT DISTINCT assignee_id FROM issues WHERE assignee_id IS NOT NULL); diff --git a/migrations/2025-01-19-212212_issues-to-tasks/up.sql b/migrations/2025-01-19-212212_issues-to-tasks/up.sql new file mode 100644 index 0000000..e892177 --- /dev/null +++ b/migrations/2025-01-19-212212_issues-to-tasks/up.sql @@ -0,0 +1,60 @@ +-- Migrate issues to tasks + +INSERT INTO tasks ( + id, + number, + repository_id, + title, + description, + labels, + open, + is_certified, + assignee_user_id, + issue_created_at, + issue_closed_at, + created_at, + updated_at, + type, + status, + url +) +SELECT + i.id, + i.number, + i.repository_id, + i.title, + i.description, + i.labels, + i.open, + COALESCE(i.certified, false) AS is_certified, + i.assignee_id AS assignee_user_id, + i.issue_created_at, + i.issue_closed_at, + i.created_at, + i.updated_at, + 'dev' AS type, + CASE + WHEN i.open = TRUE AND i.assignee_id IS NULL THEN 'open' + WHEN i.open = TRUE AND i.assignee_id IS NOT NULL THEN 'in-progress' + WHEN i.open = FALSE THEN 'completed' + END AS status, + CONCAT( + 'https://github.com/', + r.slug, + '/issues/', + i.number + ) AS url +FROM + issues i +JOIN + repositories r +ON + i.repository_id = r.id; + +-- add CONTRIBUTOR role + +INSERT INTO users_projects_roles (user_id, role_id) +SELECT DISTINCT assignee_id AS user_id, 2 AS role_id +FROM issues +WHERE assignee_id IS NOT NULL +ON CONFLICT (user_id, project_id, role_id) DO NOTHING; diff --git a/migrations/2025-01-19-215731_contributor-role/down.sql b/migrations/2025-01-19-215731_contributor-role/down.sql new file mode 100644 index 0000000..dd524fe --- /dev/null +++ b/migrations/2025-01-19-215731_contributor-role/down.sql @@ -0,0 +1,2 @@ +DROP TRIGGER IF EXISTS trigger_assign_role_to_user ON tasks; +DROP FUNCTION IF EXISTS assign_role_to_user; diff --git a/migrations/2025-01-19-215731_contributor-role/up.sql b/migrations/2025-01-19-215731_contributor-role/up.sql new file mode 100644 index 0000000..c0bab5a --- /dev/null +++ b/migrations/2025-01-19-215731_contributor-role/up.sql @@ -0,0 +1,21 @@ +CREATE OR REPLACE FUNCTION assign_role_to_user() +RETURNS TRIGGER AS $$ +BEGIN + IF NEW.assignee_user_id IS NOT NULL THEN + INSERT INTO users_projects_roles (user_id, role_id) + SELECT NEW.assignee_user_id, 2 + WHERE NOT EXISTS ( + SELECT 1 + FROM users_projects_roles + WHERE user_id = NEW.assignee_user_id + AND role_id = 2 + ); + END IF; + RETURN NEW; +END; +$$ LANGUAGE plpgsql; + +CREATE TRIGGER trigger_assign_role_to_user +AFTER INSERT OR UPDATE OF assignee_user_id ON tasks +FOR EACH ROW +EXECUTE FUNCTION assign_role_to_user(); diff --git a/migrations/2025-01-19-223138_tasks-status/down.sql b/migrations/2025-01-19-223138_tasks-status/down.sql new file mode 100644 index 0000000..61a86fe --- /dev/null +++ b/migrations/2025-01-19-223138_tasks-status/down.sql @@ -0,0 +1,2 @@ +DROP TRIGGER IF EXISTS update_task_status_trigger ON tasks; +DROP FUNCTION IF EXISTS update_task_status; \ No newline at end of file diff --git a/migrations/2025-01-19-223138_tasks-status/up.sql b/migrations/2025-01-19-223138_tasks-status/up.sql new file mode 100644 index 0000000..6393bd4 --- /dev/null +++ b/migrations/2025-01-19-223138_tasks-status/up.sql @@ -0,0 +1,16 @@ + +CREATE OR REPLACE FUNCTION update_task_status() RETURNS TRIGGER AS $$ +BEGIN + NEW.status := CASE + WHEN NEW.open = TRUE AND NEW.assignee_user_id IS NULL THEN 'open' + WHEN NEW.open = TRUE AND NEW.assignee_user_id IS NOT NULL THEN 'in-progress' + WHEN NEW.open = FALSE THEN 'completed' + END; + RETURN NEW; +END; +$$ LANGUAGE plpgsql; + +CREATE TRIGGER update_task_status_trigger +BEFORE INSERT OR UPDATE ON tasks +FOR EACH ROW +EXECUTE FUNCTION update_task_status(); \ No newline at end of file diff --git a/migrations/2025-01-27-234215_add_unique_constraint_to_tasks/down.sql b/migrations/2025-01-27-234215_add_unique_constraint_to_tasks/down.sql new file mode 100644 index 0000000..7f14109 --- /dev/null +++ b/migrations/2025-01-27-234215_add_unique_constraint_to_tasks/down.sql @@ -0,0 +1,2 @@ +ALTER TABLE tasks +DROP CONSTRAINT tasks_repo_number_unique; diff --git a/migrations/2025-01-27-234215_add_unique_constraint_to_tasks/up.sql b/migrations/2025-01-27-234215_add_unique_constraint_to_tasks/up.sql new file mode 100644 index 0000000..de54584 --- /dev/null +++ b/migrations/2025-01-27-234215_add_unique_constraint_to_tasks/up.sql @@ -0,0 +1,2 @@ +ALTER TABLE tasks +ADD CONSTRAINT tasks_repo_number_unique UNIQUE (repository_id, number); diff --git a/migrations/2025-01-29-212647_repository-id/down.sql b/migrations/2025-01-29-212647_repository-id/down.sql new file mode 100644 index 0000000..a3b0aa8 --- /dev/null +++ b/migrations/2025-01-29-212647_repository-id/down.sql @@ -0,0 +1,3 @@ + +ALTER TABLE tasks + DROP CONSTRAINT tasks_repository_id_fkey; diff --git a/migrations/2025-01-29-212647_repository-id/up.sql b/migrations/2025-01-29-212647_repository-id/up.sql new file mode 100644 index 0000000..f2d97f0 --- /dev/null +++ b/migrations/2025-01-29-212647_repository-id/up.sql @@ -0,0 +1,6 @@ + +ALTER TABLE tasks + ADD CONSTRAINT tasks_repository_id_fkey + FOREIGN KEY (repository_id) + REFERENCES repositories(id) + ON DELETE CASCADE; \ No newline at end of file diff --git a/migrations/2025-01-29-212911_project-id/down.sql b/migrations/2025-01-29-212911_project-id/down.sql new file mode 100644 index 0000000..dec2645 --- /dev/null +++ b/migrations/2025-01-29-212911_project-id/down.sql @@ -0,0 +1,8 @@ + +DROP TRIGGER IF EXISTS trigger_set_project_id ON tasks; +DROP FUNCTION IF EXISTS set_project_id_from_repository; +ALTER TABLE tasks + DROP CONSTRAINT tasks_repository_id_fkey; + +ALTER TABLE repositories + DROP CONSTRAINT unique_id_project_id; diff --git a/migrations/2025-01-29-212911_project-id/up.sql b/migrations/2025-01-29-212911_project-id/up.sql new file mode 100644 index 0000000..52a14c0 --- /dev/null +++ b/migrations/2025-01-29-212911_project-id/up.sql @@ -0,0 +1,16 @@ +ALTER TABLE repositories + ADD CONSTRAINT unique_id_project_id UNIQUE (id, project_id); + +CREATE OR REPLACE FUNCTION set_project_id_from_repository() +RETURNS TRIGGER AS $$ +BEGIN + NEW.project_id := (SELECT project_id FROM repositories WHERE id = NEW.repository_id); + RETURN NEW; +END; +$$ LANGUAGE plpgsql; + +CREATE TRIGGER trigger_set_project_id +BEFORE INSERT OR UPDATE ON tasks +FOR EACH ROW +WHEN (NEW.repository_id IS NOT NULL AND NEW.project_id IS NULL) +EXECUTE FUNCTION set_project_id_from_repository(); \ No newline at end of file diff --git a/src/schema.rs b/src/schema.rs index c900f27..70ce5cf 100644 --- a/src/schema.rs +++ b/src/schema.rs @@ -28,6 +28,18 @@ diesel::table! { } } +diesel::table! { + milestones (id) { + id -> Int4, + slug -> Text, + name -> Text, + url -> Nullable, + project_id -> Int4, + created_at -> Timestamptz, + updated_at -> Nullable, + } +} + diesel::table! { projects (id) { id -> Int4, @@ -155,8 +167,10 @@ diesel::table! { diesel::joinable!(issues -> repositories (repository_id)); diesel::joinable!(issues -> users (assignee_id)); +diesel::joinable!(milestones -> projects (project_id)); diesel::joinable!(repositories -> projects (project_id)); diesel::joinable!(tasks -> projects (project_id)); +diesel::joinable!(tasks -> repositories (repository_id)); diesel::joinable!(tasks_votes -> tasks (task_id)); diesel::joinable!(tasks_votes -> users (user_id)); diesel::joinable!(team_memberships -> teams (team_id)); @@ -168,6 +182,7 @@ diesel::joinable!(users_projects_roles -> users (user_id)); diesel::allow_tables_to_appear_in_same_query!( issues, languages, + milestones, projects, repositories, roles,