Files
breadcrumb-the-shire/db/updates/2026-03-14-user-bookmarks.sql
2026-03-14 21:45:58 +01:00

109 lines
3.6 KiB
SQL

-- Replace user_saved_filters with global bookmark system.
-- Hard cut: existing saved filters are removed and not migrated.
-- Hard cut: bookmark-level icons are removed; icons live on groups only.
-- Idempotent: safe to run multiple times.
DROP TABLE IF EXISTS `user_saved_filters`;
CREATE TABLE IF NOT EXISTS `user_bookmark_groups` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` INT UNSIGNED NOT NULL,
`name` VARCHAR(100) NOT NULL,
`icon` VARCHAR(40) NOT NULL DEFAULT 'bi-folder',
`sort_order` SMALLINT UNSIGNED NOT NULL DEFAULT 0,
`created` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`modified` DATETIME NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_ubg_user_sort` (`user_id`, `sort_order`),
CONSTRAINT `fk_ubg_user` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE IF NOT EXISTS `user_bookmarks` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` INT UNSIGNED NOT NULL,
`group_id` INT UNSIGNED NULL,
`name` VARCHAR(120) NOT NULL,
`url` VARCHAR(500) NOT NULL,
`sort_order` SMALLINT UNSIGNED NOT NULL DEFAULT 0,
`created` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`modified` DATETIME NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uniq_ub_user_url` (`user_id`, `url`),
KEY `idx_ub_user_sort` (`user_id`, `sort_order`),
KEY `idx_ub_group` (`group_id`),
CONSTRAINT `fk_ub_user` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE,
CONSTRAINT `fk_ub_group` FOREIGN KEY (`group_id`) REFERENCES `user_bookmark_groups` (`id`) ON DELETE SET NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
SET @ubg_icon_exists = (
SELECT COUNT(*)
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'user_bookmark_groups'
AND COLUMN_NAME = 'icon'
);
SET @sql = IF(@ubg_icon_exists = 0,
'ALTER TABLE `user_bookmark_groups` ADD COLUMN `icon` VARCHAR(40) NOT NULL DEFAULT ''bi-folder'' AFTER `name`',
'SELECT 1'
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
UPDATE `user_bookmark_groups`
SET `icon` = 'bi-folder'
WHERE `icon` IS NULL OR TRIM(`icon`) = '';
SET @ub_icon_exists = (
SELECT COUNT(*)
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'user_bookmarks'
AND COLUMN_NAME = 'icon'
);
SET @sql = IF(@ub_icon_exists > 0,
'ALTER TABLE `user_bookmarks` DROP COLUMN `icon`',
'SELECT 1'
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- Keep the newest row for exact duplicate user+url pairs before adding unique key.
DELETE ub1
FROM user_bookmarks ub1
JOIN user_bookmarks ub2
ON ub1.user_id = ub2.user_id
AND ub1.url = ub2.url
AND ub1.id < ub2.id;
SET @idx_exists = (
SELECT COUNT(*)
FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'user_bookmarks'
AND INDEX_NAME = 'uniq_ub_user_url'
);
SET @sql = IF(@idx_exists = 0,
'ALTER TABLE `user_bookmarks` ADD UNIQUE KEY `uniq_ub_user_url` (`user_id`, `url`)',
'SELECT 1'
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @idx_group_sort_exists = (
SELECT COUNT(*)
FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'user_bookmarks'
AND INDEX_NAME = 'idx_ub_user_group_sort'
);
SET @sql = IF(@idx_group_sort_exists = 0,
'ALTER TABLE `user_bookmarks` ADD KEY `idx_ub_user_group_sort` (`user_id`, `group_id`, `sort_order`)',
'SELECT 1'
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;