Files
Starlight_Lancher/packages/app-lib/migrations/20260728110000_reconcile_provider_qualified_content.sql

188 lines
5.0 KiB
SQL

ALTER TABLE instance_content_provider_refs
RENAME TO instance_content_provider_refs_single_legacy;
DROP INDEX IF EXISTS instance_content_provider_refs_project;
DROP INDEX IF EXISTS instance_content_provider_refs_release;
DROP INDEX IF EXISTS instance_content_provider_refs_origin;
DROP INDEX IF EXISTS instance_content_provider_refs_identity;
CREATE TABLE instance_content_provider_refs (
id INTEGER PRIMARY KEY AUTOINCREMENT,
content_entry_id TEXT NOT NULL,
provider TEXT NOT NULL,
provider_project_id TEXT NOT NULL,
provider_release_id TEXT NULL,
is_origin INTEGER NOT NULL DEFAULT 0,
FOREIGN KEY (content_entry_id)
REFERENCES instance_content_entries(id)
ON DELETE CASCADE,
CHECK (provider IN ('modrinth', 'curseforge')),
CHECK (is_origin IN (0, 1))
);
CREATE INDEX instance_content_provider_refs_project
ON instance_content_provider_refs(provider, provider_project_id);
CREATE INDEX instance_content_provider_refs_release
ON instance_content_provider_refs(provider, provider_release_id);
CREATE UNIQUE INDEX instance_content_provider_refs_identity
ON instance_content_provider_refs(
content_entry_id,
provider,
provider_project_id,
COALESCE(provider_release_id, '')
);
CREATE UNIQUE INDEX instance_content_provider_refs_origin
ON instance_content_provider_refs(content_entry_id)
WHERE is_origin = 1;
INSERT OR IGNORE INTO instance_content_provider_refs (
content_entry_id,
provider,
provider_project_id,
provider_release_id,
is_origin
)
SELECT
content_entry_id,
provider,
provider_project_id,
provider_release_id,
is_origin
FROM instance_content_provider_refs_single_legacy
WHERE length(trim(provider_project_id)) > 0
AND (
(
provider = 'modrinth'
AND (
provider_release_id IS NULL
OR length(trim(provider_release_id)) > 0
)
)
OR (
provider = 'curseforge'
AND provider_project_id NOT GLOB '*[^0-9]*'
AND CAST(provider_project_id AS INTEGER) > 0
AND (
provider_release_id IS NULL
OR (
provider_release_id NOT GLOB '*[^0-9]*'
AND CAST(provider_release_id AS INTEGER) > 0
)
)
)
);
UPDATE instance_content_provider_refs
SET is_origin = 0
WHERE content_entry_id IN (
SELECT id
FROM instance_content_entries
WHERE source_kind = 'curseforge'
);
INSERT OR IGNORE INTO instance_content_provider_refs (
content_entry_id,
provider,
provider_project_id,
provider_release_id,
is_origin
)
SELECT
ref.content_entry_id,
'curseforge',
ref.provider_project_id,
ref.provider_release_id,
0
FROM instance_content_provider_refs ref
INNER JOIN instance_content_entries entry
ON entry.id = ref.content_entry_id
WHERE entry.source_kind = 'curseforge'
AND ref.provider = 'modrinth'
AND ref.provider_project_id NOT GLOB '*[^0-9]*'
AND CAST(ref.provider_project_id AS INTEGER) > 0
AND (
ref.provider_release_id IS NULL
OR (
ref.provider_release_id NOT GLOB '*[^0-9]*'
AND CAST(ref.provider_release_id AS INTEGER) > 0
)
)
AND NOT EXISTS (
SELECT 1
FROM instance_content_provider_refs existing
WHERE existing.content_entry_id = ref.content_entry_id
AND existing.provider = 'curseforge'
)
AND ref.id = (
SELECT MIN(candidate.id)
FROM instance_content_provider_refs candidate
WHERE candidate.content_entry_id = ref.content_entry_id
AND candidate.provider = 'modrinth'
AND candidate.provider_project_id NOT GLOB '*[^0-9]*'
AND CAST(candidate.provider_project_id AS INTEGER) > 0
AND (
candidate.provider_release_id IS NULL
OR (
candidate.provider_release_id NOT GLOB '*[^0-9]*'
AND CAST(candidate.provider_release_id AS INTEGER) > 0
)
)
);
UPDATE instance_content_provider_refs
SET is_origin = 1
WHERE id IN (
SELECT MIN(ref.id)
FROM instance_content_provider_refs ref
INNER JOIN instance_content_entries entry
ON entry.id = ref.content_entry_id
WHERE entry.source_kind = 'curseforge'
AND ref.provider = 'curseforge'
GROUP BY ref.content_entry_id
);
DELETE FROM instance_content_provider_refs
WHERE provider = 'modrinth'
AND content_entry_id IN (
SELECT id
FROM instance_content_entries
WHERE source_kind = 'curseforge'
)
AND NOT EXISTS (
SELECT 1
FROM instance_content_entries entry
INNER JOIN instance_files file ON file.id = entry.file_id
INNER JOIN cache
ON cache.data_type = 'file_hash'
AND json_extract(
CASE WHEN json_valid(cache.data) THEN cache.data ELSE '{}' END,
'$.path'
) =
entry.instance_id || '/' || file.relative_path
WHERE entry.id = instance_content_provider_refs.content_entry_id
AND json_extract(
CASE WHEN json_valid(cache.data) THEN cache.data ELSE '{}' END,
'$.project_id'
) =
instance_content_provider_refs.provider_project_id
AND json_extract(
CASE WHEN json_valid(cache.data) THEN cache.data ELSE '{}' END,
'$.version_id'
) IS
instance_content_provider_refs.provider_release_id
);
DELETE FROM instance_content_update_checks
WHERE provider = 'modrinth'
AND content_entry_id IN (
SELECT id
FROM instance_content_entries
WHERE source_kind = 'curseforge'
);
DROP TABLE instance_content_provider_refs_single_legacy;