|
| 1 | +DO LANGUAGE plpgsql $$ |
| 2 | +DECLARE |
| 3 | + VAR_env_field_id INT; |
| 4 | + VAR_env_field_enum_id INT := 4; -- Known available ID for a new enum type |
| 5 | +BEGIN |
| 6 | + |
| 7 | +-- Define a new loader field for environment |
| 8 | +INSERT INTO loader_field_enums (id, enum_name, ordering, hidable) |
| 9 | + VALUES (VAR_env_field_enum_id, 'environment', NULL, TRUE); |
| 10 | + |
| 11 | +INSERT INTO loader_field_enum_values (enum_id, value, ordering, created, metadata) |
| 12 | + VALUES |
| 13 | + -- Must be installed on both client and (integrated) server |
| 14 | + (VAR_env_field_enum_id, 'client_and_server', NULL, NOW(), NULL), |
| 15 | + -- Must be installed only on the client |
| 16 | + (VAR_env_field_enum_id, 'client_only', NULL, NOW(), NULL), |
| 17 | + -- Must be installed on the client, may be installed on a (integrated) server. To be displayed as a |
| 18 | + -- client mod |
| 19 | + (VAR_env_field_enum_id, 'client_only_server_optional', NULL, NOW(), NULL), |
| 20 | + -- Must be installed only on the integrated singleplayer server. To be displayed as a server mod for |
| 21 | + -- singleplayer exclusively |
| 22 | + (VAR_env_field_enum_id, 'singleplayer_only', NULL, NOW(), NULL), |
| 23 | + -- Must be installed only on a (integrated) server |
| 24 | + (VAR_env_field_enum_id, 'server_only', NULL, NOW(), NULL), |
| 25 | + -- Must be installed on the server, may be installed on the client. To be displayed as a |
| 26 | + -- singleplayer-compatible server mod |
| 27 | + (VAR_env_field_enum_id, 'server_only_client_optional', NULL, NOW(), NULL), |
| 28 | + -- Must be installed only on a dedicated multiplayer server (not the integrated singleplayer server). |
| 29 | + -- To be displayed as an server mod for multiplayer exclusively |
| 30 | + (VAR_env_field_enum_id, 'dedicated_server_only', NULL, NOW(), NULL), |
| 31 | + -- Can be installed on both client and server, with no strong preference for either. To be displayed |
| 32 | + -- as both a client and server mod |
| 33 | + (VAR_env_field_enum_id, 'client_or_server', NULL, NOW(), NULL), |
| 34 | + -- Can be installed on both client and server, with a preference for being installed on both. To be |
| 35 | + -- displayed as a client and server mod |
| 36 | + (VAR_env_field_enum_id, 'client_or_server_prefers_both', NULL, NOW(), NULL), |
| 37 | + (VAR_env_field_enum_id, 'unknown', NULL, NOW(), NULL); |
| 38 | + |
| 39 | +INSERT INTO loader_fields (field, field_type, enum_type, optional) |
| 40 | + VALUES ('environment', 'enum', VAR_env_field_enum_id, FALSE) |
| 41 | + RETURNING id INTO VAR_env_field_id; |
| 42 | + |
| 43 | +-- Update version_fields to have the new environment field, initializing it from the |
| 44 | +-- values of the previous fields |
| 45 | +INSERT INTO version_fields (version_id, field_id, enum_value) |
| 46 | + SELECT vf.version_id, VAR_env_field_id, ( |
| 47 | + SELECT id |
| 48 | + FROM loader_field_enum_values |
| 49 | + WHERE enum_id = VAR_env_field_enum_id |
| 50 | + AND value = ( |
| 51 | + CASE jsonb_object_agg(lf.field, vf.int_value) |
| 52 | + WHEN '{ "server_only": 0, "singleplayer": 0, "client_and_server": 0, "client_only": 1 }'::jsonb THEN 'client_only' |
| 53 | + WHEN '{ "server_only": 0, "singleplayer": 0, "client_and_server": 1, "client_only": 0 }'::jsonb THEN 'client_and_server' |
| 54 | + WHEN '{ "server_only": 0, "singleplayer": 0, "client_and_server": 1, "client_only": 1 }'::jsonb THEN 'client_only_server_optional' |
| 55 | + WHEN '{ "server_only": 0, "singleplayer": 1, "client_and_server": 0, "client_only": 0 }'::jsonb THEN 'singleplayer_only' |
| 56 | + WHEN '{ "server_only": 0, "singleplayer": 1, "client_and_server": 0, "client_only": 1 }'::jsonb THEN 'client_only' |
| 57 | + WHEN '{ "server_only": 0, "singleplayer": 1, "client_and_server": 1, "client_only": 0 }'::jsonb THEN 'client_and_server' |
| 58 | + WHEN '{ "server_only": 0, "singleplayer": 1, "client_and_server": 1, "client_only": 1 }'::jsonb THEN 'client_only_server_optional' |
| 59 | + WHEN '{ "server_only": 1, "singleplayer": 0, "client_and_server": 0, "client_only": 0 }'::jsonb THEN 'server_only' |
| 60 | + WHEN '{ "server_only": 1, "singleplayer": 0, "client_and_server": 0, "client_only": 1 }'::jsonb THEN 'client_or_server' |
| 61 | + WHEN '{ "server_only": 1, "singleplayer": 0, "client_and_server": 1, "client_only": 0 }'::jsonb THEN 'server_only_client_optional' |
| 62 | + WHEN '{ "server_only": 1, "singleplayer": 0, "client_and_server": 1, "client_only": 1 }'::jsonb THEN 'client_or_server_prefers_both' |
| 63 | + WHEN '{ "server_only": 1, "singleplayer": 1, "client_and_server": 0, "client_only": 0 }'::jsonb THEN 'server_only' |
| 64 | + WHEN '{ "server_only": 1, "singleplayer": 1, "client_and_server": 0, "client_only": 1 }'::jsonb THEN 'client_or_server' |
| 65 | + WHEN '{ "server_only": 1, "singleplayer": 1, "client_and_server": 1, "client_only": 0 }'::jsonb THEN 'server_only_client_optional' |
| 66 | + WHEN '{ "server_only": 1, "singleplayer": 1, "client_and_server": 1, "client_only": 1 }'::jsonb THEN 'client_or_server_prefers_both' |
| 67 | + ELSE 'unknown' |
| 68 | + END |
| 69 | + ) |
| 70 | + ) |
| 71 | + FROM version_fields vf |
| 72 | + JOIN loader_fields lf ON vf.field_id = lf.id |
| 73 | + WHERE lf.field IN ('server_only', 'singleplayer', 'client_and_server', 'client_only') |
| 74 | + GROUP BY vf.version_id |
| 75 | + HAVING COUNT(DISTINCT lf.field) = VAR_env_field_enum_id; |
| 76 | + |
| 77 | +-- Clean up old fields from the project versions |
| 78 | +DELETE FROM version_fields |
| 79 | + WHERE field_id IN ( |
| 80 | + SELECT id |
| 81 | + FROM loader_fields |
| 82 | + WHERE field IN ('server_only', 'singleplayer', 'client_and_server', 'client_only') |
| 83 | + ); |
| 84 | + |
| 85 | +-- Switch loader fields definitions on the available loaders to use the new environment field |
| 86 | +ALTER TABLE loader_fields_loaders DROP CONSTRAINT unique_loader_field; |
| 87 | +ALTER TABLE loader_fields_loaders DROP CONSTRAINT loader_fields_loaders_pkey; |
| 88 | + |
| 89 | +UPDATE loader_fields_loaders |
| 90 | + SET loader_field_id = VAR_env_field_id |
| 91 | + WHERE loader_field_id IN ( |
| 92 | + SELECT id |
| 93 | + FROM loader_fields |
| 94 | + WHERE field IN ('server_only', 'singleplayer', 'client_and_server', 'client_only') |
| 95 | + ); |
| 96 | + |
| 97 | +-- Remove duplicate (loader_id, loader_field_id) pairs that may have been created due to several |
| 98 | +-- old fields being converted to a single new field |
| 99 | +DELETE FROM loader_fields_loaders |
| 100 | + WHERE ctid NOT IN ( |
| 101 | + SELECT MIN(ctid) |
| 102 | + FROM loader_fields_loaders |
| 103 | + GROUP BY loader_id, loader_field_id |
| 104 | + ); |
| 105 | + |
| 106 | +-- Having both a PK and UNIQUE constraint for the same columns is redundant, so only restore the PK |
| 107 | +ALTER TABLE loader_fields_loaders ADD PRIMARY KEY (loader_id, loader_field_id); |
| 108 | + |
| 109 | +-- Finally, remove the old loader fields |
| 110 | +DELETE FROM loader_fields |
| 111 | + WHERE field IN ('server_only', 'singleplayer', 'client_and_server', 'client_only'); |
| 112 | + |
| 113 | +END; |
| 114 | +$$ |
0 commit comments