83 lines
2.9 KiB
MySQL
83 lines
2.9 KiB
MySQL
|
|
-- migrate:up
|
||
|
|
--
|
||
|
|
-- One-shot plate consolidation:
|
||
|
|
-- 1. extract plate from each device's device_name (post " - ", strip _cam)
|
||
|
|
-- 2. for each plate appearing on >1 device (tracker+camera pair), pick the
|
||
|
|
-- lowest existing vehicle_id as canonical
|
||
|
|
-- 3. remap state.position_history, state.live_positions, domain.devices
|
||
|
|
-- to the canonical vehicle_id
|
||
|
|
-- 4. delete orphaned vehicle rows
|
||
|
|
-- 5. update canonical vehicles' plate to the extracted plate
|
||
|
|
--
|
||
|
|
-- After this runs, domain.vehicles holds one row per physical plate. The
|
||
|
|
-- PRD F1.6 dedup rule in serve.fn_live_view picks tracker-first when both
|
||
|
|
-- a tracker and camera report for the same vehicle.
|
||
|
|
--
|
||
|
|
-- Idempotent: re-running the migration only updates plates that have moved on.
|
||
|
|
|
||
|
|
DO $migration$
|
||
|
|
BEGIN
|
||
|
|
CREATE TEMP TABLE _plate_map ON COMMIT DROP AS
|
||
|
|
SELECT
|
||
|
|
d.imei,
|
||
|
|
d.vehicle_id AS current_vehicle_id,
|
||
|
|
regexp_replace(
|
||
|
|
(regexp_match(lp.device_name, '^.* - (.+)$'))[1],
|
||
|
|
'_(cam|CAM)$', ''
|
||
|
|
) AS new_plate
|
||
|
|
FROM domain.devices d
|
||
|
|
JOIN state.live_positions lp ON lp.imei = d.imei
|
||
|
|
WHERE lp.device_name LIKE '% - %';
|
||
|
|
|
||
|
|
DELETE FROM _plate_map
|
||
|
|
WHERE new_plate IS NULL
|
||
|
|
OR new_plate = ''
|
||
|
|
OR new_plate !~ '[A-Z]'
|
||
|
|
OR new_plate !~ '[0-9]';
|
||
|
|
|
||
|
|
CREATE TEMP TABLE _canonical ON COMMIT DROP AS
|
||
|
|
SELECT new_plate, min(current_vehicle_id) AS canonical_vehicle_id
|
||
|
|
FROM _plate_map
|
||
|
|
GROUP BY new_plate;
|
||
|
|
|
||
|
|
-- Drop UNIQUE so the multi-row plate assignment doesn't transiently violate
|
||
|
|
ALTER TABLE domain.vehicles DROP CONSTRAINT IF EXISTS vehicles_plate_key;
|
||
|
|
|
||
|
|
UPDATE state.position_history ph
|
||
|
|
SET vehicle_id = c.canonical_vehicle_id
|
||
|
|
FROM _plate_map pm
|
||
|
|
JOIN _canonical c ON c.new_plate = pm.new_plate
|
||
|
|
WHERE ph.imei = pm.imei
|
||
|
|
AND ph.vehicle_id != c.canonical_vehicle_id;
|
||
|
|
|
||
|
|
UPDATE state.live_positions lp
|
||
|
|
SET vehicle_id = c.canonical_vehicle_id
|
||
|
|
FROM _plate_map pm
|
||
|
|
JOIN _canonical c ON c.new_plate = pm.new_plate
|
||
|
|
WHERE lp.imei = pm.imei
|
||
|
|
AND lp.vehicle_id != c.canonical_vehicle_id;
|
||
|
|
|
||
|
|
UPDATE domain.devices d
|
||
|
|
SET vehicle_id = c.canonical_vehicle_id
|
||
|
|
FROM _plate_map pm
|
||
|
|
JOIN _canonical c ON c.new_plate = pm.new_plate
|
||
|
|
WHERE d.imei = pm.imei
|
||
|
|
AND d.vehicle_id != c.canonical_vehicle_id;
|
||
|
|
|
||
|
|
DELETE FROM domain.vehicles v
|
||
|
|
WHERE NOT EXISTS (SELECT 1 FROM domain.devices d WHERE d.vehicle_id = v.vehicle_id)
|
||
|
|
AND NOT EXISTS (SELECT 1 FROM state.live_positions lp WHERE lp.vehicle_id = v.vehicle_id)
|
||
|
|
AND NOT EXISTS (SELECT 1 FROM state.position_history ph WHERE ph.vehicle_id = v.vehicle_id);
|
||
|
|
|
||
|
|
UPDATE domain.vehicles v
|
||
|
|
SET plate = c.new_plate, updated_at = now()
|
||
|
|
FROM _canonical c
|
||
|
|
WHERE v.vehicle_id = c.canonical_vehicle_id;
|
||
|
|
|
||
|
|
ALTER TABLE domain.vehicles ADD CONSTRAINT vehicles_plate_key UNIQUE (plate);
|
||
|
|
END
|
||
|
|
$migration$;
|
||
|
|
|
||
|
|
-- migrate:down
|
||
|
|
-- No-op: plate consolidation is a one-way operation.
|