[FIX] Migration 006: usa stored procedure per indici condizionali
Compatibilita' MySQL 8.0: CREATE INDEX IF NOT EXISTS non supportato, uso procedura helper con check su information_schema.statistics Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
18dec35380
commit
a5eb84108a
@ -1,24 +1,46 @@
|
|||||||
-- ============================================================
|
-- ============================================================
|
||||||
-- NIS2 Agile - Migration 006: Security & Performance Improvements
|
-- NIS2 Agile - Migration 006: Security & Performance Improvements
|
||||||
-- Data: 2026-02-20
|
-- Data: 2026-02-20
|
||||||
-- Eseguire come: mysql -u root -p nis2_agile_db < 006_security_improvements.sql
|
-- Compatibile: MySQL 8.0 (senza CREATE INDEX IF NOT EXISTS)
|
||||||
-- Compatibile: MySQL 8.0+
|
|
||||||
-- ============================================================
|
-- ============================================================
|
||||||
|
|
||||||
|
-- Procedura helper: crea indice solo se non esiste
|
||||||
|
DROP PROCEDURE IF EXISTS create_index_if_not_exists;
|
||||||
|
DELIMITER //
|
||||||
|
CREATE PROCEDURE create_index_if_not_exists(
|
||||||
|
IN p_table VARCHAR(100),
|
||||||
|
IN p_index VARCHAR(100),
|
||||||
|
IN p_cols VARCHAR(500)
|
||||||
|
)
|
||||||
|
BEGIN
|
||||||
|
IF NOT EXISTS (
|
||||||
|
SELECT 1 FROM information_schema.statistics
|
||||||
|
WHERE table_schema = DATABASE()
|
||||||
|
AND table_name = p_table
|
||||||
|
AND index_name = p_index
|
||||||
|
) THEN
|
||||||
|
SET @sql = CONCAT('CREATE INDEX `', p_index, '` ON `', p_table, '` (', p_cols, ')');
|
||||||
|
PREPARE stmt FROM @sql;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
END IF;
|
||||||
|
END //
|
||||||
|
DELIMITER ;
|
||||||
|
|
||||||
-- ── 1. Indici performance su incidents ────────────────────────────────────
|
-- ── 1. Indici performance su incidents ────────────────────────────────────
|
||||||
CREATE INDEX IF NOT EXISTS idx_inc_org_status ON incidents (organization_id, status);
|
CALL create_index_if_not_exists('incidents', 'idx_inc_org_status', 'organization_id, status');
|
||||||
CREATE INDEX IF NOT EXISTS idx_inc_org_significant ON incidents (organization_id, is_significant);
|
CALL create_index_if_not_exists('incidents', 'idx_inc_org_significant', 'organization_id, is_significant');
|
||||||
CREATE INDEX IF NOT EXISTS idx_inc_early_warning_due ON incidents (organization_id, early_warning_due);
|
CALL create_index_if_not_exists('incidents', 'idx_inc_early_warning_due','organization_id, early_warning_due');
|
||||||
CREATE INDEX IF NOT EXISTS idx_inc_notification_due ON incidents (organization_id, notification_due);
|
CALL create_index_if_not_exists('incidents', 'idx_inc_notification_due', 'organization_id, notification_due');
|
||||||
CREATE INDEX IF NOT EXISTS idx_inc_final_report_due ON incidents (organization_id, final_report_due);
|
CALL create_index_if_not_exists('incidents', 'idx_inc_final_report_due', 'organization_id, final_report_due');
|
||||||
|
|
||||||
-- ── 2. Indici performance su risks ────────────────────────────────────────
|
-- ── 2. Indici performance su risks ────────────────────────────────────────
|
||||||
CREATE INDEX IF NOT EXISTS idx_risks_org_status ON risks (organization_id, status);
|
CALL create_index_if_not_exists('risks', 'idx_risks_org_status', 'organization_id, status');
|
||||||
CREATE INDEX IF NOT EXISTS idx_risks_score ON risks (organization_id, inherent_risk_score);
|
CALL create_index_if_not_exists('risks', 'idx_risks_score', 'organization_id, inherent_risk_score');
|
||||||
|
|
||||||
-- ── 3. Indici performance su audit_logs ───────────────────────────────────
|
-- ── 3. Indici performance su audit_logs ───────────────────────────────────
|
||||||
CREATE INDEX IF NOT EXISTS idx_audit_org_created ON audit_logs (organization_id, created_at);
|
CALL create_index_if_not_exists('audit_logs', 'idx_audit_org_created', 'organization_id, created_at');
|
||||||
CREATE INDEX IF NOT EXISTS idx_audit_entity ON audit_logs (entity_type, entity_id);
|
CALL create_index_if_not_exists('audit_logs', 'idx_audit_entity', 'entity_type, entity_id');
|
||||||
|
|
||||||
-- ── 4. Trigger per rendere audit_log immutabile ───────────────────────────
|
-- ── 4. Trigger per rendere audit_log immutabile ───────────────────────────
|
||||||
DROP TRIGGER IF EXISTS prevent_audit_log_update;
|
DROP TRIGGER IF EXISTS prevent_audit_log_update;
|
||||||
@ -49,23 +71,15 @@ ALTER TABLE policies
|
|||||||
ALTER TABLE suppliers
|
ALTER TABLE suppliers
|
||||||
ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMP NULL DEFAULT NULL AFTER updated_at;
|
ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMP NULL DEFAULT NULL AFTER updated_at;
|
||||||
|
|
||||||
-- Indici per soft delete (escludono record eliminati nelle query standard)
|
-- Indici per le colonne deleted_at
|
||||||
CREATE INDEX IF NOT EXISTS idx_risks_deleted ON risks (organization_id, deleted_at);
|
CALL create_index_if_not_exists('risks', 'idx_risks_deleted', 'organization_id, deleted_at');
|
||||||
CREATE INDEX IF NOT EXISTS idx_policies_deleted ON policies (organization_id, deleted_at);
|
CALL create_index_if_not_exists('policies', 'idx_policies_deleted', 'organization_id, deleted_at');
|
||||||
|
|
||||||
-- ── 6. Indice su refresh_tokens ───────────────────────────────────────────
|
-- ── 6. Indice su refresh_tokens ───────────────────────────────────────────
|
||||||
CREATE INDEX IF NOT EXISTS idx_refresh_user_expires ON refresh_tokens (user_id, expires_at);
|
CALL create_index_if_not_exists('refresh_tokens', 'idx_refresh_user_expires', 'user_id, expires_at');
|
||||||
|
|
||||||
-- ── 7. Evento pulizia refresh token scaduti ───────────────────────────────
|
-- ── 7. Pulizia procedura temporanea ───────────────────────────────────────
|
||||||
DROP EVENT IF EXISTS cleanup_expired_refresh_tokens;
|
DROP PROCEDURE IF EXISTS create_index_if_not_exists;
|
||||||
CREATE EVENT IF NOT EXISTS cleanup_expired_refresh_tokens
|
|
||||||
ON SCHEDULE EVERY 6 HOUR
|
|
||||||
STARTS CURRENT_TIMESTAMP
|
|
||||||
DO
|
|
||||||
DELETE FROM refresh_tokens WHERE expires_at < NOW() - INTERVAL 1 DAY;
|
|
||||||
|
|
||||||
-- ── 8. Verifica ───────────────────────────────────────────────────────────
|
-- ── 8. Verifica ───────────────────────────────────────────────────────────
|
||||||
SELECT 'Migration 006 completed successfully' AS status;
|
SELECT 'Migration 006 completed successfully' AS status;
|
||||||
|
|
||||||
-- Nota: per abilitare event scheduler (richiede SUPER):
|
|
||||||
-- SET GLOBAL event_scheduler = ON;
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user