|
| 1 | +\set ON_ERROR_STOP on |
| 2 | + |
| 3 | +CREATE TEMP TABLE migration_preflight_issues ( |
| 4 | + severity text NOT NULL, |
| 5 | + check_name text NOT NULL, |
| 6 | + detail text NOT NULL |
| 7 | +); |
| 8 | + |
| 9 | +INSERT INTO migration_preflight_issues(severity, check_name, detail) |
| 10 | +SELECT 'blocker', 'required_schema', format('missing schema %s', schema_name) |
| 11 | +FROM (VALUES ('mledb'), ('sprocket'), ('mledb_bridge')) AS required(schema_name) |
| 12 | +WHERE NOT EXISTS ( |
| 13 | + SELECT 1 |
| 14 | + FROM information_schema.schemata s |
| 15 | + WHERE s.schema_name = required.schema_name |
| 16 | +); |
| 17 | + |
| 18 | +INSERT INTO migration_preflight_issues(severity, check_name, detail) |
| 19 | +SELECT 'blocker', 'required_table', format('missing table %s.%s', schema_name, table_name) |
| 20 | +FROM ( |
| 21 | + VALUES |
| 22 | + ('mledb', 'division'), |
| 23 | + ('mledb', 'team'), |
| 24 | + ('mledb', 'team_branding'), |
| 25 | + ('mledb', 'player'), |
| 26 | + ('mledb', 'season'), |
| 27 | + ('mledb', 'match'), |
| 28 | + ('mledb', 'fixture'), |
| 29 | + ('mledb', 'series'), |
| 30 | + ('sprocket', 'organization'), |
| 31 | + ('sprocket', 'organization_profile'), |
| 32 | + ('sprocket', 'game'), |
| 33 | + ('sprocket', 'game_mode'), |
| 34 | + ('sprocket', 'franchise'), |
| 35 | + ('sprocket', 'franchise_profile'), |
| 36 | + ('sprocket', 'game_skill_group'), |
| 37 | + ('sprocket', 'team'), |
| 38 | + ('sprocket', 'user'), |
| 39 | + ('sprocket', 'user_profile'), |
| 40 | + ('sprocket', 'user_authentication_account'), |
| 41 | + ('sprocket', 'member'), |
| 42 | + ('sprocket', 'member_profile'), |
| 43 | + ('sprocket', 'player'), |
| 44 | + ('sprocket', 'schedule_group'), |
| 45 | + ('sprocket', 'schedule_fixture'), |
| 46 | + ('sprocket', 'match_parent'), |
| 47 | + ('sprocket', 'match'), |
| 48 | + ('mledb_bridge', 'division_to_franchise_group'), |
| 49 | + ('mledb_bridge', 'team_to_franchise'), |
| 50 | + ('mledb_bridge', 'league_to_skill_group'), |
| 51 | + ('mledb_bridge', 'player_to_user'), |
| 52 | + ('mledb_bridge', 'player_to_player'), |
| 53 | + ('mledb_bridge', 'season_to_schedule_group'), |
| 54 | + ('mledb_bridge', 'match_to_schedule_group'), |
| 55 | + ('mledb_bridge', 'fixture_to_fixture'), |
| 56 | + ('mledb_bridge', 'series_to_match_parent') |
| 57 | +) AS required(schema_name, table_name) |
| 58 | +WHERE NOT EXISTS ( |
| 59 | + SELECT 1 |
| 60 | + FROM information_schema.tables t |
| 61 | + WHERE t.table_schema = required.schema_name |
| 62 | + AND t.table_name = required.table_name |
| 63 | +); |
| 64 | + |
| 65 | +TABLE migration_preflight_issues |
| 66 | +ORDER BY CASE severity WHEN 'blocker' THEN 0 ELSE 1 END, check_name, detail; |
| 67 | + |
| 68 | +DO $$ |
| 69 | +DECLARE |
| 70 | + structural_blocker_count int; |
| 71 | +BEGIN |
| 72 | + SELECT count(*) INTO structural_blocker_count |
| 73 | + FROM migration_preflight_issues |
| 74 | + WHERE severity = 'blocker' |
| 75 | + AND check_name IN ('required_schema', 'required_table'); |
| 76 | + |
| 77 | + IF structural_blocker_count > 0 THEN |
| 78 | + RAISE EXCEPTION 'mledb -> sprocket preflight found % structural blocker(s)', structural_blocker_count; |
| 79 | + END IF; |
| 80 | +END; |
| 81 | +$$; |
| 82 | + |
| 83 | +INSERT INTO migration_preflight_issues(severity, check_name, detail) |
| 84 | +SELECT 'blocker', 'duplicate_discord_id', format('discord_id %s appears %s times in mledb.player', discord_id, count(*)) |
| 85 | +FROM mledb.player |
| 86 | +WHERE nullif(discord_id, '') IS NOT NULL |
| 87 | +GROUP BY discord_id |
| 88 | +HAVING count(*) > 1; |
| 89 | + |
| 90 | +INSERT INTO migration_preflight_issues(severity, check_name, detail) |
| 91 | +SELECT 'blocker', 'duplicate_player_name', format('player name %s appears %s times in mledb.player', name, count(*)) |
| 92 | +FROM mledb.player |
| 93 | +GROUP BY name |
| 94 | +HAVING count(*) > 1; |
| 95 | + |
| 96 | +INSERT INTO migration_preflight_issues(severity, check_name, detail) |
| 97 | +SELECT 'blocker', 'fixture_missing_team_bridge_source', format('fixture %s references missing team home=%s away=%s', f.id, f.home_name, f.away_name) |
| 98 | +FROM mledb.fixture f |
| 99 | +LEFT JOIN mledb.team ht ON ht.name = f.home_name |
| 100 | +LEFT JOIN mledb.team at ON at.name = f.away_name |
| 101 | +WHERE ht.name IS NULL OR at.name IS NULL; |
| 102 | + |
| 103 | +INSERT INTO migration_preflight_issues(severity, check_name, detail) |
| 104 | +SELECT 'blocker', 'series_unknown_league', format('series %s has unsupported league %s', id, league) |
| 105 | +FROM mledb.series |
| 106 | +WHERE fixture_id IS NOT NULL |
| 107 | + AND league NOT IN ('FOUNDATION', 'ACADEMY', 'CHAMPION', 'MASTER', 'PREMIER'); |
| 108 | + |
| 109 | +INSERT INTO migration_preflight_issues(severity, check_name, detail) |
| 110 | +SELECT 'blocker', 'series_unknown_mode', format('series %s has unsupported mode %s', id, mode) |
| 111 | +FROM mledb.series |
| 112 | +WHERE fixture_id IS NOT NULL |
| 113 | + AND mode NOT IN ('DOUBLES', 'STANDARD'); |
| 114 | + |
| 115 | +INSERT INTO migration_preflight_issues(severity, check_name, detail) |
| 116 | +SELECT 'blocker', 'player_unknown_league', format('player %s (%s) has unsupported league %s', id, name, league) |
| 117 | +FROM mledb.player |
| 118 | +WHERE league NOT IN ('FOUNDATION', 'ACADEMY', 'CHAMPION', 'MASTER', 'PREMIER', 'UNKNOWN'); |
| 119 | + |
| 120 | +INSERT INTO migration_preflight_issues(severity, check_name, detail) |
| 121 | +SELECT 'warning', 'bridge_table_not_empty', format('%s.%s already contains %s rows', table_schema, table_name, row_count) |
| 122 | +FROM ( |
| 123 | + SELECT 'mledb_bridge'::text AS table_schema, 'division_to_franchise_group'::text AS table_name, count(*)::bigint AS row_count FROM mledb_bridge.division_to_franchise_group |
| 124 | + UNION ALL SELECT 'mledb_bridge', 'team_to_franchise', count(*) FROM mledb_bridge.team_to_franchise |
| 125 | + UNION ALL SELECT 'mledb_bridge', 'league_to_skill_group', count(*) FROM mledb_bridge.league_to_skill_group |
| 126 | + UNION ALL SELECT 'mledb_bridge', 'player_to_user', count(*) FROM mledb_bridge.player_to_user |
| 127 | + UNION ALL SELECT 'mledb_bridge', 'player_to_player', count(*) FROM mledb_bridge.player_to_player |
| 128 | + UNION ALL SELECT 'mledb_bridge', 'season_to_schedule_group', count(*) FROM mledb_bridge.season_to_schedule_group |
| 129 | + UNION ALL SELECT 'mledb_bridge', 'match_to_schedule_group', count(*) FROM mledb_bridge.match_to_schedule_group |
| 130 | + UNION ALL SELECT 'mledb_bridge', 'fixture_to_fixture', count(*) FROM mledb_bridge.fixture_to_fixture |
| 131 | + UNION ALL SELECT 'mledb_bridge', 'series_to_match_parent', count(*) FROM mledb_bridge.series_to_match_parent |
| 132 | +) bridge_counts |
| 133 | +WHERE row_count > 0; |
| 134 | + |
| 135 | +TABLE migration_preflight_issues |
| 136 | +ORDER BY CASE severity WHEN 'blocker' THEN 0 ELSE 1 END, check_name, detail; |
| 137 | + |
| 138 | +DO $$ |
| 139 | +DECLARE |
| 140 | + blocker_count int; |
| 141 | +BEGIN |
| 142 | + SELECT count(*) INTO blocker_count |
| 143 | + FROM migration_preflight_issues |
| 144 | + WHERE severity = 'blocker'; |
| 145 | + |
| 146 | + IF blocker_count > 0 THEN |
| 147 | + RAISE EXCEPTION 'mledb -> sprocket preflight found % blocker(s)', blocker_count; |
| 148 | + END IF; |
| 149 | +END; |
| 150 | +$$; |
0 commit comments