Files
Starlight_Lancher/packages/app-lib/migrations/20260803120000_instance-content-ownership.sql

193 lines
5.3 KiB
SQL

ALTER TABLE instance_content_sets
ADD COLUMN revision INTEGER NOT NULL DEFAULT 0;
ALTER TABLE instance_content_entries
ADD COLUMN ownership_kind TEXT NOT NULL DEFAULT 'user_added'
CHECK (ownership_kind IN ('pack_managed', 'user_added'));
UPDATE instance_content_entries AS entry
SET ownership_kind = 'pack_managed'
WHERE EXISTS (
SELECT 1
FROM instance_links link
WHERE link.instance_id = entry.instance_id
AND (
(link.link_kind IN ('modrinth_modpack', 'server_project_modpack')
AND entry.source_kind = 'modrinth_modpack')
OR (link.link_kind = 'curseforge_modpack'
AND entry.source_kind = 'curseforge')
OR (link.link_kind = 'imported_modpack'
AND entry.source_kind IN (
'imported_modpack',
'modrinth_modpack',
'curseforge'
))
)
);
CREATE INDEX instance_content_entries_ownership_kind
ON instance_content_entries(content_set_id, ownership_kind);
CREATE TABLE instance_pack_members (
id TEXT NOT NULL,
content_set_id TEXT NOT NULL,
content_entry_id TEXT NULL,
member_key TEXT NOT NULL,
project_type TEXT NOT NULL,
expected_relative_path TEXT NOT NULL,
provider TEXT NULL,
provider_project_id TEXT NULL,
provider_release_id TEXT NULL,
required INTEGER NOT NULL DEFAULT 1,
expected_sha1 TEXT NULL,
expected_size INTEGER NULL,
expected_fingerprint INTEGER NULL,
materialization_state TEXT NOT NULL DEFAULT 'present',
override_kind TEXT NOT NULL DEFAULT 'none',
reconciled INTEGER NOT NULL DEFAULT 1,
created_at INTEGER NOT NULL,
modified_at INTEGER NOT NULL,
PRIMARY KEY (id),
UNIQUE (content_set_id, member_key),
FOREIGN KEY (content_set_id)
REFERENCES instance_content_sets(id)
ON DELETE CASCADE,
FOREIGN KEY (content_entry_id)
REFERENCES instance_content_entries(id)
ON DELETE SET NULL,
CHECK (provider IS NULL OR provider IN ('modrinth', 'curseforge')),
CHECK (required IN (0, 1)),
CHECK (materialization_state IN (
'present',
'pending_manual',
'missing',
'removed'
)),
CHECK (override_kind IN ('none', 'disabled', 'removed', 'version')),
CHECK (reconciled IN (0, 1))
);
CREATE INDEX instance_pack_members_content_set
ON instance_pack_members(content_set_id);
CREATE INDEX instance_pack_members_content_entry
ON instance_pack_members(content_entry_id);
CREATE INDEX instance_pack_members_provider
ON instance_pack_members(provider, provider_project_id, provider_release_id);
CREATE INDEX instance_pack_members_state
ON instance_pack_members(content_set_id, materialization_state);
INSERT INTO instance_pack_members (
id,
content_set_id,
content_entry_id,
member_key,
project_type,
expected_relative_path,
provider,
provider_project_id,
provider_release_id,
required,
expected_sha1,
expected_size,
expected_fingerprint,
materialization_state,
override_kind,
reconciled,
created_at,
modified_at
)
SELECT
'pack-member:' || entry.id,
entry.content_set_id,
entry.id,
CASE
WHEN origin.provider IS NOT NULL THEN
origin.provider || ':' || origin.provider_project_id || ':' || entry.project_type
ELSE 'path:' || lower(replace(file.relative_path, '\\', '/'))
END,
entry.project_type,
file.relative_path,
origin.provider,
origin.provider_project_id,
origin.provider_release_id,
CASE
WHEN entry.server_requirement = 'optional'
AND entry.client_requirement = 'optional'
THEN 0
ELSE 1
END,
file.sha1,
file.size,
NULL,
CASE WHEN file.missing = 1 THEN 'missing' ELSE 'present' END,
CASE
WHEN entry.enabled = 0 OR file.enabled = 0 THEN 'disabled'
ELSE 'none'
END,
CASE
WHEN link.link_kind = 'curseforge_modpack' THEN 0
ELSE 1
END,
entry.added_at,
entry.modified_at
FROM instance_content_entries entry
INNER JOIN instance_files file ON file.id = entry.file_id
INNER JOIN instance_links link ON link.instance_id = entry.instance_id
LEFT JOIN instance_content_provider_refs origin
ON origin.content_entry_id = entry.id
AND origin.is_origin = 1
WHERE entry.ownership_kind = 'pack_managed';
CREATE TABLE instance_pending_manual_downloads (
id TEXT NOT NULL,
instance_id TEXT NOT NULL,
pack_member_id TEXT NULL,
content_entry_id TEXT NULL,
operation_kind TEXT NOT NULL,
operation_target_id TEXT NULL,
project_type TEXT NOT NULL,
provider TEXT NOT NULL,
provider_project_id TEXT NOT NULL,
provider_release_id TEXT NOT NULL,
file_name TEXT NOT NULL,
website_url TEXT NULL,
target_relative_path TEXT NOT NULL,
expected_sha1 TEXT NULL,
expected_size INTEGER NULL,
expected_fingerprint INTEGER NULL,
state TEXT NOT NULL DEFAULT 'waiting',
context JSONB NOT NULL DEFAULT '{}',
created_at INTEGER NOT NULL,
modified_at INTEGER NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (instance_id) REFERENCES instances(id) ON DELETE CASCADE,
FOREIGN KEY (pack_member_id)
REFERENCES instance_pack_members(id)
ON DELETE CASCADE,
FOREIGN KEY (content_entry_id)
REFERENCES instance_content_entries(id)
ON DELETE SET NULL,
CHECK (provider IN ('modrinth', 'curseforge')),
CHECK (operation_kind IN (
'pack_install',
'pack_update',
'content_install',
'content_update'
)),
CHECK (state IN ('waiting', 'matched', 'imported', 'error', 'cancelled'))
);
CREATE UNIQUE INDEX instance_pending_manual_download_identity
ON instance_pending_manual_downloads(
instance_id,
operation_kind,
provider,
provider_project_id,
provider_release_id
)
WHERE state IN ('waiting', 'matched');
CREATE INDEX instance_pending_manual_downloads_instance_state
ON instance_pending_manual_downloads(instance_id, state);