mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2024-11-29 10:24:20 +01:00
115 lines
3.9 KiB
Ruby
115 lines
3.9 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
# Previously, the Slot table was holding data about reservations.
|
|
# This was a wrong assumption that leads to a bug.
|
|
# An Availability should have many slots but a slot can be related to multiple Reservations,
|
|
# so a slot must not hold data about a single reservation (like `offered`),these data
|
|
# should be stored in SlotsReservation instead.
|
|
class AddReservationFieldsToSlotsReservations < ActiveRecord::Migration[5.2]
|
|
def up
|
|
add_column :slots_reservations, :ex_start_at, :datetime
|
|
add_column :slots_reservations, :ex_end_at, :datetime
|
|
add_column :slots_reservations, :canceled_at, :datetime
|
|
add_column :slots_reservations, :offered, :boolean, default: false
|
|
|
|
execute <<-SQL
|
|
UPDATE slots_reservations
|
|
SET
|
|
ex_start_at=slots.ex_start_at,
|
|
ex_end_at=slots.ex_end_at,
|
|
canceled_at=slots.canceled_at,
|
|
offered=slots.offered
|
|
FROM slots
|
|
WHERE slots_reservations.slot_id = slots.id
|
|
SQL
|
|
|
|
remove_column :slots, :ex_start_at
|
|
remove_column :slots, :ex_end_at
|
|
remove_column :slots, :canceled_at
|
|
remove_column :slots, :offered
|
|
remove_column :slots, :destroying
|
|
|
|
# we gonna keep only only one slot (remove duplicates) because data is now hold in slots_reservations
|
|
|
|
# update slots_reservation.slot_id
|
|
execute <<-SQL
|
|
UPDATE slots_reservations
|
|
SET slot_id=r.kept
|
|
FROM (
|
|
SELECT count(*), start_at, end_at, availability_id, min(id) AS kept, array_agg(id) AS all_ids
|
|
FROM slots
|
|
GROUP BY start_at, end_at, availability_id
|
|
HAVING count(*) > 1) as r
|
|
WHERE slot_id = ANY(r.all_ids);
|
|
SQL
|
|
|
|
# remove useless slots
|
|
execute <<-SQL
|
|
WITH same_slots AS (
|
|
SELECT count(*), start_at, end_at, availability_id, min(id) AS kept, array_agg(id) AS all_ids
|
|
FROM slots
|
|
GROUP BY start_at, end_at, availability_id
|
|
HAVING count(*) > 1
|
|
)
|
|
DELETE FROM slots
|
|
WHERE id IN (SELECT unnest(all_ids) FROM same_slots)
|
|
AND id NOT IN (SELECT kept FROM same_slots);
|
|
SQL
|
|
end
|
|
|
|
def down
|
|
execute <<-SQL
|
|
DO
|
|
$$
|
|
DECLARE
|
|
sr_group RECORD;
|
|
slot slots%ROWTYPE;
|
|
new_slot_id slots.id%TYPE;
|
|
curr_slot_reservation_id slots_reservations.id%TYPE;
|
|
BEGIN
|
|
FOR sr_group IN
|
|
SELECT count(*), array_agg(id) AS all_ids, slot_id
|
|
FROM slots_reservations
|
|
GROUP BY slot_id
|
|
HAVING count(*) > 1
|
|
LOOP
|
|
SELECT * INTO slot FROM slots WHERE id = sr_group.slot_id;
|
|
FOR curr_slot_reservation_id IN
|
|
SELECT unnest(sr_group.all_ids[2:])
|
|
LOOP
|
|
INSERT INTO slots (start_at, end_at, created_at, updated_at, availability_id)
|
|
VALUES (slot.start_at, slot.end_at, now(), now(), slot.availability_id)
|
|
RETURNING id INTO new_slot_id;
|
|
UPDATE slots_reservations
|
|
SET slot_id=new_slot_id
|
|
WHERE id=curr_slot_reservation_id;
|
|
END LOOP;
|
|
END LOOP;
|
|
END;
|
|
$$
|
|
SQL
|
|
|
|
add_column :slots, :ex_start_at, :datetime
|
|
add_column :slots, :ex_end_at, :datetime
|
|
add_column :slots, :canceled_at, :datetime
|
|
add_column :slots, :offered, :boolean, default: false
|
|
add_column :slots, :destroying, :boolean, default: false
|
|
|
|
execute <<-SQL
|
|
UPDATE slots
|
|
SET
|
|
ex_start_at=slots_reservations.ex_start_at,
|
|
ex_end_at=slots_reservations.ex_end_at,
|
|
canceled_at=slots_reservations.canceled_at,
|
|
offered=slots_reservations.offered
|
|
FROM slots_reservations
|
|
WHERE slots_reservations.slot_id = slots.id
|
|
SQL
|
|
|
|
remove_column :slots_reservations, :ex_start_at
|
|
remove_column :slots_reservations, :ex_end_at
|
|
remove_column :slots_reservations, :canceled_at
|
|
remove_column :slots_reservations, :offered
|
|
end
|
|
end
|