|
| 1 | +-- +goose Up |
| 2 | +-- +goose NO TRANSACTION |
| 3 | + |
| 4 | + |
| 5 | +-- This table is a rebuildable cache, not a source of truth: every write is an |
| 6 | +-- idempotent recompute from the canonical query. |
| 7 | +-- +goose StatementBegin |
| 8 | +CREATE TABLE IF NOT EXISTS "public"."template_default_builds" ( |
| 9 | + template_id TEXT PRIMARY KEY REFERENCES "public"."envs"(id) ON DELETE CASCADE, |
| 10 | + team_id UUID NOT NULL, |
| 11 | + build_id UUID, |
| 12 | + vcpu BIGINT NOT NULL DEFAULT 0, |
| 13 | + ram_mb BIGINT NOT NULL DEFAULT 0, |
| 14 | + total_disk_size_mb BIGINT, |
| 15 | + build_created_at TIMESTAMPTZ, |
| 16 | + name_sort_key TEXT NOT NULL DEFAULT '', |
| 17 | + created_at TIMESTAMPTZ NOT NULL DEFAULT now(), |
| 18 | + updated_at TIMESTAMPTZ NOT NULL DEFAULT now() |
| 19 | +); |
| 20 | +-- +goose StatementEnd |
| 21 | + |
| 22 | +-- Backfill existing templates in batches to avoid long-held locks |
| 23 | +-- Idempotent (ON CONFLICT DO NOTHING), so the migration can be re-run safely. |
| 24 | +-- +goose StatementBegin |
| 25 | +CREATE OR REPLACE PROCEDURE backfill_template_default_builds() AS $$ |
| 26 | +DECLARE |
| 27 | + last_id TEXT := ''; |
| 28 | + batch_max TEXT; |
| 29 | +BEGIN |
| 30 | + LOOP |
| 31 | + SELECT max(id) INTO batch_max |
| 32 | + FROM ( |
| 33 | + SELECT e.id |
| 34 | + FROM "public"."envs" e |
| 35 | + WHERE e.source = 'template' AND e.id > last_id |
| 36 | + ORDER BY e.id |
| 37 | + LIMIT 10000 |
| 38 | + ) batch; |
| 39 | + |
| 40 | + EXIT WHEN batch_max IS NULL; |
| 41 | + |
| 42 | + INSERT INTO "public"."template_default_builds" |
| 43 | + (template_id, team_id, build_id, vcpu, ram_mb, total_disk_size_mb, build_created_at, name_sort_key) |
| 44 | + SELECT |
| 45 | + e.id, |
| 46 | + e.team_id, |
| 47 | + b.build_id, |
| 48 | + COALESCE(b.vcpu, 0), |
| 49 | + COALESCE(b.ram_mb, 0), |
| 50 | + b.total_disk_size_mb, |
| 51 | + b.build_created_at, |
| 52 | + COALESCE(a.name_sort_key, '') |
| 53 | + FROM "public"."envs" e |
| 54 | + LEFT JOIN LATERAL ( |
| 55 | + SELECT |
| 56 | + eb.id AS build_id, |
| 57 | + eb.vcpu, |
| 58 | + eb.ram_mb, |
| 59 | + eb.total_disk_size_mb, |
| 60 | + eb.created_at AS build_created_at |
| 61 | + FROM "public"."env_build_assignments" ba |
| 62 | + JOIN "public"."env_builds" eb ON eb.id = ba.build_id |
| 63 | + WHERE ba.env_id = e.id AND ba.tag = 'default' AND eb.status_group = 'ready' |
| 64 | + ORDER BY ba.created_at DESC |
| 65 | + LIMIT 1 |
| 66 | + ) b ON TRUE |
| 67 | + LEFT JOIN LATERAL ( |
| 68 | + SELECT MIN(CASE WHEN namespace IS NOT NULL THEN namespace || '/' || alias ELSE alias END) AS name_sort_key |
| 69 | + FROM "public"."env_aliases" |
| 70 | + WHERE env_id = e.id |
| 71 | + ) a ON TRUE |
| 72 | + WHERE e.source = 'template' AND e.id > last_id AND e.id <= batch_max |
| 73 | + ON CONFLICT (template_id) DO NOTHING; |
| 74 | + |
| 75 | + last_id := batch_max; |
| 76 | + COMMIT; |
| 77 | + RAISE NOTICE 'backfill_template_default_builds: processed up to id %, sleeping 2s before next batch...', batch_max; |
| 78 | + PERFORM pg_sleep(2); |
| 79 | + END LOOP; |
| 80 | +END; |
| 81 | +$$ LANGUAGE plpgsql; |
| 82 | +-- +goose StatementEnd |
| 83 | + |
| 84 | +CALL backfill_template_default_builds(); |
| 85 | +DROP PROCEDURE backfill_template_default_builds(); |
| 86 | + |
| 87 | +CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_template_default_builds_team_name |
| 88 | + ON "public"."template_default_builds" (team_id, name_sort_key, template_id); |
| 89 | + |
| 90 | +CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_template_default_builds_team_vcpu |
| 91 | + ON "public"."template_default_builds" (team_id, vcpu, template_id); |
| 92 | + |
| 93 | +CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_template_default_builds_team_ram |
| 94 | + ON "public"."template_default_builds" (team_id, ram_mb, template_id); |
| 95 | + |
| 96 | +CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_template_default_builds_build_id |
| 97 | + ON "public"."template_default_builds" (build_id); |
| 98 | + |
| 99 | +-- +goose Down |
| 100 | +-- +goose NO TRANSACTION |
| 101 | + |
| 102 | +-- +goose StatementBegin |
| 103 | +DROP TABLE IF EXISTS "public"."template_default_builds"; |
| 104 | +-- +goose StatementEnd |
0 commit comments