owpengram-server/internal/store/postgres/queries/contact.sql
2026-06-04 01:37:39 +08:00

168 lines
4.5 KiB
SQL

-- name: ListContactsByUser :many
SELECT
c.contact_user_id,
c.mutual,
c.contact_phone,
c.contact_first_name,
c.contact_last_name,
c.note,
COALESCE(c.note_entities::text, '[]')::text AS note_entities_json,
u.id,
u.access_hash,
COALESCE(NULLIF(c.contact_phone, ''), u.phone)::text AS phone,
COALESCE(NULLIF(c.contact_first_name, ''), u.first_name)::text AS first_name,
COALESCE(c.contact_last_name, u.last_name)::text AS last_name,
u.username,
u.country_code,
u.verified,
u.support,
u.last_seen_at
FROM contacts c
JOIN users u ON u.id = c.contact_user_id
WHERE c.user_id = $1
ORDER BY c.contact_first_name, c.contact_last_name, u.first_name, u.last_name, u.id;
-- name: GetContact :one
SELECT
c.contact_user_id,
c.mutual,
c.contact_phone,
c.contact_first_name,
c.contact_last_name,
c.note,
COALESCE(c.note_entities::text, '[]')::text AS note_entities_json,
u.id,
u.access_hash,
COALESCE(NULLIF(c.contact_phone, ''), u.phone)::text AS phone,
COALESCE(NULLIF(c.contact_first_name, ''), u.first_name)::text AS first_name,
COALESCE(c.contact_last_name, u.last_name)::text AS last_name,
u.username,
u.country_code,
u.verified,
u.support,
u.last_seen_at
FROM contacts c
JOIN users u ON u.id = c.contact_user_id
WHERE c.user_id = $1
AND c.contact_user_id = $2;
-- name: UpsertContact :one
WITH reverse AS (
SELECT EXISTS (
SELECT 1
FROM contacts
WHERE user_id = sqlc.arg(contact_user_id)::bigint
AND contact_user_id = sqlc.arg(user_id)::bigint
)::boolean AS mutual
),
upserted AS (
INSERT INTO contacts (
user_id,
contact_user_id,
contact_phone,
contact_first_name,
contact_last_name,
note,
note_entities,
mutual
)
SELECT
sqlc.arg(user_id)::bigint,
sqlc.arg(contact_user_id)::bigint,
sqlc.arg(contact_phone)::text,
sqlc.arg(contact_first_name)::text,
sqlc.arg(contact_last_name)::text,
sqlc.arg(note)::text,
sqlc.arg(note_entities)::jsonb,
reverse.mutual
FROM reverse
ON CONFLICT (user_id, contact_user_id) DO UPDATE SET
contact_phone = EXCLUDED.contact_phone,
contact_first_name = EXCLUDED.contact_first_name,
contact_last_name = EXCLUDED.contact_last_name,
note = EXCLUDED.note,
note_entities = EXCLUDED.note_entities,
mutual = contacts.mutual OR EXCLUDED.mutual,
updated_at = now()
RETURNING *
),
reverse_updated AS (
UPDATE contacts c
SET mutual = true,
updated_at = now()
WHERE c.user_id = sqlc.arg(contact_user_id)::bigint
AND c.contact_user_id = sqlc.arg(user_id)::bigint
AND NOT c.mutual
RETURNING c.user_id
)
SELECT
c.contact_user_id,
c.mutual,
c.contact_phone,
c.contact_first_name,
c.contact_last_name,
c.note,
COALESCE(c.note_entities::text, '[]')::text AS note_entities_json,
u.id,
u.access_hash,
COALESCE(NULLIF(c.contact_phone, ''), u.phone)::text AS phone,
COALESCE(NULLIF(c.contact_first_name, ''), u.first_name)::text AS first_name,
COALESCE(c.contact_last_name, u.last_name)::text AS last_name,
u.username,
u.country_code,
u.verified,
u.support,
u.last_seen_at,
EXISTS (SELECT 1 FROM reverse_updated)::boolean AS reverse_mutual_changed
FROM upserted c
JOIN users u ON u.id = c.contact_user_id;
-- name: UpdateContactNote :one
WITH updated AS (
UPDATE contacts c
SET note = sqlc.arg(note)::text,
note_entities = sqlc.arg(note_entities)::jsonb,
updated_at = now()
WHERE c.user_id = sqlc.arg(user_id)::bigint
AND c.contact_user_id = sqlc.arg(contact_user_id)::bigint
RETURNING *
)
SELECT
c.contact_user_id,
c.mutual,
c.contact_phone,
c.contact_first_name,
c.contact_last_name,
c.note,
COALESCE(c.note_entities::text, '[]')::text AS note_entities_json,
u.id,
u.access_hash,
COALESCE(NULLIF(c.contact_phone, ''), u.phone)::text AS phone,
COALESCE(NULLIF(c.contact_first_name, ''), u.first_name)::text AS first_name,
COALESCE(c.contact_last_name, u.last_name)::text AS last_name,
u.username,
u.country_code,
u.verified,
u.support,
u.last_seen_at
FROM updated c
JOIN users u ON u.id = c.contact_user_id;
-- name: DeleteContacts :one
WITH deleted AS (
DELETE FROM contacts
WHERE user_id = sqlc.arg(user_id)::bigint
AND contact_user_id = ANY(sqlc.arg(contact_user_ids)::bigint[])
RETURNING contact_user_id
),
reverse_updated AS (
UPDATE contacts c
SET mutual = false,
updated_at = now()
FROM deleted d
WHERE c.user_id = d.contact_user_id
AND c.contact_user_id = sqlc.arg(user_id)::bigint
RETURNING c.user_id
)
SELECT COUNT(*)::int AS deleted_count
FROM deleted;