.
This commit is contained in:
105
migrations/20250510184011_channel_message.sql
Normal file
105
migrations/20250510184011_channel_message.sql
Normal file
@@ -0,0 +1,105 @@
|
||||
CREATE TABLE IF NOT EXISTS "channel"
|
||||
(
|
||||
"id" UUID NOT NULL PRIMARY KEY DEFAULT uuid_generate_v7(),
|
||||
"name" VARCHAR NOT NULL,
|
||||
"type" INT2 NOT NULL,
|
||||
"position" INT2 NOT NULL,
|
||||
"server_id" UUID REFERENCES "server" ("id") ON DELETE CASCADE, -- only for server channels
|
||||
"parent" UUID REFERENCES "channel" ("id") ON DELETE SET NULL, -- only for server channels
|
||||
"owner_id" UUID REFERENCES "user" ("id") ON DELETE SET NULL -- only for group channels
|
||||
);
|
||||
|
||||
-- only for dm or group channels
|
||||
CREATE TABLE IF NOT EXISTS "channel_recipient"
|
||||
(
|
||||
"channel_id" UUID NOT NULL REFERENCES "channel" ("id") ON DELETE CASCADE,
|
||||
"user_id" UUID NOT NULL REFERENCES "user" ("id") ON DELETE CASCADE,
|
||||
PRIMARY KEY ("channel_id", "user_id")
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "message"
|
||||
(
|
||||
"id" UUID NOT NULL PRIMARY KEY DEFAULT uuid_generate_v7(),
|
||||
"author_id" UUID NOT NULL REFERENCES "user" ("id") ON DELETE CASCADE,
|
||||
"channel_id" UUID NOT NULL REFERENCES "channel" ("id") ON DELETE CASCADE,
|
||||
"content" TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "message_attachment"
|
||||
(
|
||||
"message_id" UUID NOT NULL REFERENCES "message" ON DELETE CASCADE,
|
||||
"file_id" UUID NOT NULL REFERENCES "file" ON DELETE CASCADE,
|
||||
"order" INT2 NOT NULL,
|
||||
PRIMARY KEY ("message_id", "file_id")
|
||||
);
|
||||
|
||||
ALTER TABLE "channel"
|
||||
ADD COLUMN "last_message_id" UUID REFERENCES "message" ("id") ON DELETE SET NULL;
|
||||
|
||||
|
||||
CREATE OR REPLACE FUNCTION create_dm_channel(
|
||||
user1_id UUID,
|
||||
user2_id UUID,
|
||||
channel_type INT2
|
||||
)
|
||||
RETURNS UUID
|
||||
LANGUAGE plpgsql
|
||||
AS
|
||||
$$
|
||||
DECLARE
|
||||
new_channel_id UUID;
|
||||
channel_name VARCHAR;
|
||||
BEGIN
|
||||
-- Validate parameters
|
||||
IF user1_id IS NULL OR user2_id IS NULL THEN
|
||||
RAISE EXCEPTION 'Both user IDs must be provided';
|
||||
END IF;
|
||||
|
||||
IF user1_id = user2_id THEN
|
||||
RAISE EXCEPTION 'Cannot create a DM channel with the same user';
|
||||
END IF;
|
||||
|
||||
-- Check if users exist
|
||||
IF NOT exists (SELECT 1 FROM "user" WHERE id = user1_id) OR
|
||||
NOT exists (SELECT 1 FROM "user" WHERE id = user2_id) THEN
|
||||
RAISE EXCEPTION 'One or both users do not exist';
|
||||
END IF;
|
||||
|
||||
-- Check if DM already exists between these users
|
||||
IF exists (SELECT 1
|
||||
FROM channel c
|
||||
JOIN channel_recipient cr1 ON c.id = cr1.channel_id AND cr1.user_id = user1_id
|
||||
JOIN channel_recipient cr2 ON c.id = cr2.channel_id AND cr2.user_id = user2_id
|
||||
WHERE c.type = channel_type
|
||||
AND (SELECT count(*) FROM channel_recipient WHERE channel_id = c.id) = 2) THEN
|
||||
-- Find and return the existing channel ID
|
||||
SELECT c.id
|
||||
INTO new_channel_id
|
||||
FROM channel c
|
||||
JOIN channel_recipient cr1 ON c.id = cr1.channel_id AND cr1.user_id = user1_id
|
||||
JOIN channel_recipient cr2 ON c.id = cr2.channel_id AND cr2.user_id = user2_id
|
||||
WHERE c.type = channel_type
|
||||
AND (SELECT count(*) FROM channel_recipient WHERE channel_id = c.id) = 2
|
||||
LIMIT 1;
|
||||
|
||||
RAISE NOTICE 'DM channel already exists between these users with ID: %', new_channel_id;
|
||||
RETURN new_channel_id;
|
||||
END IF;
|
||||
|
||||
-- Generate channel name (conventionally uses user IDs in DMs)
|
||||
channel_name := concat(user1_id, '-', user2_id);
|
||||
|
||||
-- Create new channel
|
||||
INSERT INTO "channel" ("name", "type", "position")
|
||||
VALUES (channel_name, channel_type, 0)
|
||||
RETURNING id INTO new_channel_id;
|
||||
|
||||
-- Add both users as recipients
|
||||
INSERT INTO "channel_recipient" ("channel_id", "user_id")
|
||||
VALUES (new_channel_id, user1_id),
|
||||
(new_channel_id, user2_id);
|
||||
|
||||
RAISE NOTICE 'DM channel created with ID: %', new_channel_id;
|
||||
RETURN new_channel_id;
|
||||
END;
|
||||
$$;
|
||||
Reference in New Issue
Block a user