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"), "channel_id" UUID NOT NULL REFERENCES "channel" ("id"), "content" TEXT NOT NULL ); 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; $$;