Some checks failed
Build and Push / Build and Push Docker Image (push) Failing after 2s
147 lines
3.6 KiB
Elixir
147 lines
3.6 KiB
Elixir
defmodule Aprsme.Repo.Migrations.ReplacePacketCountSequence do
|
|
use Ecto.Migration
|
|
|
|
def up do
|
|
execute("DROP TRIGGER IF EXISTS packet_insert_sequence ON packets")
|
|
execute("DROP TRIGGER IF EXISTS packet_delete_sequence ON packets")
|
|
|
|
execute("""
|
|
INSERT INTO packet_counters (counter_type, count, inserted_at, updated_at)
|
|
VALUES ('total_packets', 0, NOW(), NOW())
|
|
ON CONFLICT (counter_type) DO NOTHING
|
|
""")
|
|
|
|
execute("""
|
|
UPDATE packet_counters
|
|
SET count = (SELECT COUNT(*) FROM packets),
|
|
updated_at = NOW()
|
|
WHERE counter_type = 'total_packets'
|
|
""")
|
|
|
|
execute("""
|
|
CREATE OR REPLACE FUNCTION increment_packet_counter()
|
|
RETURNS TRIGGER AS $$
|
|
BEGIN
|
|
UPDATE packet_counters
|
|
SET count = count + 1,
|
|
updated_at = NOW()
|
|
WHERE counter_type = 'total_packets';
|
|
RETURN NEW;
|
|
END;
|
|
$$ LANGUAGE plpgsql
|
|
""")
|
|
|
|
execute("""
|
|
CREATE OR REPLACE FUNCTION decrement_packet_counter()
|
|
RETURNS TRIGGER AS $$
|
|
BEGIN
|
|
UPDATE packet_counters
|
|
SET count = GREATEST(0, count - 1),
|
|
updated_at = NOW()
|
|
WHERE counter_type = 'total_packets';
|
|
RETURN OLD;
|
|
END;
|
|
$$ LANGUAGE plpgsql
|
|
""")
|
|
|
|
execute("""
|
|
CREATE TRIGGER packet_insert_counter
|
|
AFTER INSERT ON packets
|
|
FOR EACH ROW
|
|
EXECUTE FUNCTION increment_packet_counter()
|
|
""")
|
|
|
|
execute("""
|
|
CREATE TRIGGER packet_delete_counter
|
|
AFTER DELETE ON packets
|
|
FOR EACH ROW
|
|
EXECUTE FUNCTION decrement_packet_counter()
|
|
""")
|
|
|
|
execute("""
|
|
CREATE OR REPLACE FUNCTION get_packet_count()
|
|
RETURNS BIGINT AS $$
|
|
BEGIN
|
|
RETURN COALESCE(
|
|
(SELECT count FROM packet_counters WHERE counter_type = 'total_packets'),
|
|
0
|
|
);
|
|
END;
|
|
$$ LANGUAGE plpgsql STABLE
|
|
""")
|
|
|
|
execute("DROP FUNCTION IF EXISTS increment_packet_sequence()")
|
|
execute("DROP FUNCTION IF EXISTS decrement_packet_sequence()")
|
|
execute("DROP SEQUENCE IF EXISTS packet_count_seq")
|
|
|
|
execute("""
|
|
COMMENT ON TABLE packet_counters IS
|
|
'Exact retained packet count. Updated atomically by packet DML and partition maintenance.'
|
|
""")
|
|
end
|
|
|
|
def down do
|
|
execute("DROP TRIGGER IF EXISTS packet_insert_counter ON packets")
|
|
execute("DROP TRIGGER IF EXISTS packet_delete_counter ON packets")
|
|
|
|
execute("""
|
|
CREATE SEQUENCE packet_count_seq
|
|
MINVALUE 0
|
|
START WITH 0
|
|
""")
|
|
|
|
execute("""
|
|
SELECT setval(
|
|
'packet_count_seq',
|
|
COALESCE((SELECT count FROM packet_counters WHERE counter_type = 'total_packets'), 0),
|
|
true
|
|
)
|
|
""")
|
|
|
|
execute("""
|
|
CREATE OR REPLACE FUNCTION increment_packet_sequence()
|
|
RETURNS TRIGGER AS $$
|
|
BEGIN
|
|
PERFORM nextval('packet_count_seq');
|
|
RETURN NEW;
|
|
END;
|
|
$$ LANGUAGE plpgsql
|
|
""")
|
|
|
|
execute("""
|
|
CREATE OR REPLACE FUNCTION decrement_packet_sequence()
|
|
RETURNS TRIGGER AS $$
|
|
DECLARE
|
|
current_val BIGINT;
|
|
BEGIN
|
|
SELECT last_value INTO current_val FROM packet_count_seq;
|
|
PERFORM setval('packet_count_seq', GREATEST(0, current_val - 1), true);
|
|
RETURN OLD;
|
|
END;
|
|
$$ LANGUAGE plpgsql
|
|
""")
|
|
|
|
execute("""
|
|
CREATE TRIGGER packet_insert_sequence
|
|
AFTER INSERT ON packets
|
|
FOR EACH ROW
|
|
EXECUTE FUNCTION increment_packet_sequence()
|
|
""")
|
|
|
|
execute("""
|
|
CREATE TRIGGER packet_delete_sequence
|
|
AFTER DELETE ON packets
|
|
FOR EACH ROW
|
|
EXECUTE FUNCTION decrement_packet_sequence()
|
|
""")
|
|
|
|
execute("""
|
|
CREATE OR REPLACE FUNCTION get_packet_count()
|
|
RETURNS BIGINT AS $$
|
|
BEGIN
|
|
RETURN last_value FROM packet_count_seq;
|
|
END;
|
|
$$ LANGUAGE plpgsql STABLE
|
|
""")
|
|
end
|
|
end
|