743 lines
21 KiB
Go
743 lines
21 KiB
Go
// Code generated by sqlc. DO NOT EDIT.
|
|
// versions:
|
|
// sqlc v1.30.0
|
|
// source: messages.sql
|
|
|
|
package sqlc
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/jackc/pgx/v5/pgtype"
|
|
)
|
|
|
|
const addMessageThreadParticipant = `-- name: AddMessageThreadParticipant :exec
|
|
INSERT INTO message_thread_participants (
|
|
thread_id,
|
|
user_id,
|
|
last_read_at
|
|
) VALUES (
|
|
$1,
|
|
$2,
|
|
$3
|
|
)
|
|
ON CONFLICT (thread_id, user_id) DO NOTHING
|
|
`
|
|
|
|
type AddMessageThreadParticipantParams struct {
|
|
ThreadID int64 `json:"thread_id"`
|
|
UserID int64 `json:"user_id"`
|
|
LastReadAt pgtype.Timestamptz `json:"last_read_at"`
|
|
}
|
|
|
|
func (q *Queries) AddMessageThreadParticipant(ctx context.Context, arg AddMessageThreadParticipantParams) error {
|
|
_, err := q.db.Exec(ctx, addMessageThreadParticipant, arg.ThreadID, arg.UserID, arg.LastReadAt)
|
|
return err
|
|
}
|
|
|
|
const createMessageThread = `-- name: CreateMessageThread :one
|
|
INSERT INTO message_threads (
|
|
created_by_user_id,
|
|
subject
|
|
) VALUES (
|
|
$1,
|
|
$2
|
|
)
|
|
RETURNING id, created_by_user_id, subject, created_at, updated_at
|
|
`
|
|
|
|
type CreateMessageThreadParams struct {
|
|
CreatedByUserID int64 `json:"created_by_user_id"`
|
|
Subject string `json:"subject"`
|
|
}
|
|
|
|
func (q *Queries) CreateMessageThread(ctx context.Context, arg CreateMessageThreadParams) (MessageThread, error) {
|
|
row := q.db.QueryRow(ctx, createMessageThread, arg.CreatedByUserID, arg.Subject)
|
|
var i MessageThread
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.CreatedByUserID,
|
|
&i.Subject,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const createThreadMessage = `-- name: CreateThreadMessage :one
|
|
INSERT INTO messages (
|
|
thread_id,
|
|
sender_user_id,
|
|
body
|
|
) VALUES (
|
|
$1,
|
|
$2,
|
|
$3
|
|
)
|
|
RETURNING id, thread_id, sender_user_id, body, created_at, updated_at
|
|
`
|
|
|
|
type CreateThreadMessageParams struct {
|
|
ThreadID int64 `json:"thread_id"`
|
|
SenderUserID int64 `json:"sender_user_id"`
|
|
Body string `json:"body"`
|
|
}
|
|
|
|
func (q *Queries) CreateThreadMessage(ctx context.Context, arg CreateThreadMessageParams) (Message, error) {
|
|
row := q.db.QueryRow(ctx, createThreadMessage, arg.ThreadID, arg.SenderUserID, arg.Body)
|
|
var i Message
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.ThreadID,
|
|
&i.SenderUserID,
|
|
&i.Body,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const deleteMessageThread = `-- name: DeleteMessageThread :one
|
|
DELETE FROM message_threads
|
|
WHERE id = $1
|
|
RETURNING id, created_by_user_id, subject, created_at, updated_at
|
|
`
|
|
|
|
func (q *Queries) DeleteMessageThread(ctx context.Context, threadID int64) (MessageThread, error) {
|
|
row := q.db.QueryRow(ctx, deleteMessageThread, threadID)
|
|
var i MessageThread
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.CreatedByUserID,
|
|
&i.Subject,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const deleteThreadMessage = `-- name: DeleteThreadMessage :one
|
|
DELETE FROM messages
|
|
WHERE id = $1
|
|
AND thread_id = $2
|
|
AND sender_user_id = $3
|
|
RETURNING id, thread_id, sender_user_id, body, created_at, updated_at
|
|
`
|
|
|
|
type DeleteThreadMessageParams struct {
|
|
MessageID int64 `json:"message_id"`
|
|
ThreadID int64 `json:"thread_id"`
|
|
UserID int64 `json:"user_id"`
|
|
}
|
|
|
|
func (q *Queries) DeleteThreadMessage(ctx context.Context, arg DeleteThreadMessageParams) (Message, error) {
|
|
row := q.db.QueryRow(ctx, deleteThreadMessage, arg.MessageID, arg.ThreadID, arg.UserID)
|
|
var i Message
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.ThreadID,
|
|
&i.SenderUserID,
|
|
&i.Body,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getMessageRecipientByIDForUser = `-- name: GetMessageRecipientByIDForUser :one
|
|
SELECT
|
|
u.id AS user_id,
|
|
u.email AS user_email,
|
|
u.role AS user_role,
|
|
u.full_name AS user_full_name,
|
|
p.preferred_name,
|
|
p.profile_icon_url,
|
|
p.headline
|
|
FROM users u
|
|
LEFT JOIN profiles p ON p.user_id = u.id
|
|
WHERE u.id = $2
|
|
AND u.id <> $1
|
|
AND u.is_active = TRUE
|
|
AND (
|
|
EXISTS (
|
|
SELECT 1
|
|
FROM classrooms c
|
|
JOIN classroom_students cs ON cs.classroom_id = c.id
|
|
WHERE c.teacher_id = u.id
|
|
AND cs.student_id = $1
|
|
)
|
|
OR EXISTS (
|
|
SELECT 1
|
|
FROM classrooms c
|
|
JOIN classroom_students cs ON cs.classroom_id = c.id
|
|
WHERE c.teacher_id = $1
|
|
AND cs.student_id = u.id
|
|
)
|
|
)
|
|
LIMIT 1
|
|
`
|
|
|
|
type GetMessageRecipientByIDForUserParams struct {
|
|
ID int64 `json:"id"`
|
|
ID_2 int64 `json:"id_2"`
|
|
}
|
|
|
|
type GetMessageRecipientByIDForUserRow struct {
|
|
UserID int64 `json:"user_id"`
|
|
UserEmail string `json:"user_email"`
|
|
UserRole UserRole `json:"user_role"`
|
|
UserFullName string `json:"user_full_name"`
|
|
PreferredName pgtype.Text `json:"preferred_name"`
|
|
ProfileIconUrl pgtype.Text `json:"profile_icon_url"`
|
|
Headline pgtype.Text `json:"headline"`
|
|
}
|
|
|
|
func (q *Queries) GetMessageRecipientByIDForUser(ctx context.Context, arg GetMessageRecipientByIDForUserParams) (GetMessageRecipientByIDForUserRow, error) {
|
|
row := q.db.QueryRow(ctx, getMessageRecipientByIDForUser, arg.ID, arg.ID_2)
|
|
var i GetMessageRecipientByIDForUserRow
|
|
err := row.Scan(
|
|
&i.UserID,
|
|
&i.UserEmail,
|
|
&i.UserRole,
|
|
&i.UserFullName,
|
|
&i.PreferredName,
|
|
&i.ProfileIconUrl,
|
|
&i.Headline,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getMessageThreadForUser = `-- name: GetMessageThreadForUser :one
|
|
SELECT
|
|
t.id,
|
|
t.subject,
|
|
t.created_by_user_id,
|
|
t.created_at,
|
|
t.updated_at,
|
|
participant.last_read_at,
|
|
COALESCE((
|
|
SELECT COUNT(*)::bigint
|
|
FROM messages unread
|
|
WHERE unread.thread_id = t.id
|
|
AND unread.sender_user_id <> $2
|
|
AND (participant.last_read_at IS NULL OR unread.created_at > participant.last_read_at)
|
|
), 0)::bigint AS unread_count
|
|
FROM message_threads t
|
|
JOIN message_thread_participants participant ON participant.thread_id = t.id
|
|
WHERE t.id = $1
|
|
AND participant.user_id = $2
|
|
AND participant.archived_at IS NULL
|
|
`
|
|
|
|
type GetMessageThreadForUserParams struct {
|
|
ID int64 `json:"id"`
|
|
SenderUserID int64 `json:"sender_user_id"`
|
|
}
|
|
|
|
type GetMessageThreadForUserRow struct {
|
|
ID int64 `json:"id"`
|
|
Subject string `json:"subject"`
|
|
CreatedByUserID int64 `json:"created_by_user_id"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
|
|
LastReadAt pgtype.Timestamptz `json:"last_read_at"`
|
|
UnreadCount int64 `json:"unread_count"`
|
|
}
|
|
|
|
func (q *Queries) GetMessageThreadForUser(ctx context.Context, arg GetMessageThreadForUserParams) (GetMessageThreadForUserRow, error) {
|
|
row := q.db.QueryRow(ctx, getMessageThreadForUser, arg.ID, arg.SenderUserID)
|
|
var i GetMessageThreadForUserRow
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.Subject,
|
|
&i.CreatedByUserID,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.LastReadAt,
|
|
&i.UnreadCount,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const listMessageRecipientsForUser = `-- name: ListMessageRecipientsForUser :many
|
|
SELECT
|
|
u.id AS user_id,
|
|
u.email AS user_email,
|
|
u.role AS user_role,
|
|
u.full_name AS user_full_name,
|
|
p.preferred_name,
|
|
p.profile_icon_url,
|
|
p.headline
|
|
FROM users u
|
|
LEFT JOIN profiles p ON p.user_id = u.id
|
|
WHERE u.id <> $1
|
|
AND u.is_active = TRUE
|
|
AND (
|
|
EXISTS (
|
|
SELECT 1
|
|
FROM classrooms c
|
|
JOIN classroom_students cs ON cs.classroom_id = c.id
|
|
WHERE c.teacher_id = u.id
|
|
AND cs.student_id = $1
|
|
)
|
|
OR EXISTS (
|
|
SELECT 1
|
|
FROM classrooms c
|
|
JOIN classroom_students cs ON cs.classroom_id = c.id
|
|
WHERE c.teacher_id = $1
|
|
AND cs.student_id = u.id
|
|
)
|
|
)
|
|
ORDER BY COALESCE(NULLIF(p.preferred_name, ''), u.full_name) ASC, u.id ASC
|
|
`
|
|
|
|
type ListMessageRecipientsForUserRow struct {
|
|
UserID int64 `json:"user_id"`
|
|
UserEmail string `json:"user_email"`
|
|
UserRole UserRole `json:"user_role"`
|
|
UserFullName string `json:"user_full_name"`
|
|
PreferredName pgtype.Text `json:"preferred_name"`
|
|
ProfileIconUrl pgtype.Text `json:"profile_icon_url"`
|
|
Headline pgtype.Text `json:"headline"`
|
|
}
|
|
|
|
func (q *Queries) ListMessageRecipientsForUser(ctx context.Context, id int64) ([]ListMessageRecipientsForUserRow, error) {
|
|
rows, err := q.db.Query(ctx, listMessageRecipientsForUser, id)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
items := []ListMessageRecipientsForUserRow{}
|
|
for rows.Next() {
|
|
var i ListMessageRecipientsForUserRow
|
|
if err := rows.Scan(
|
|
&i.UserID,
|
|
&i.UserEmail,
|
|
&i.UserRole,
|
|
&i.UserFullName,
|
|
&i.PreferredName,
|
|
&i.ProfileIconUrl,
|
|
&i.Headline,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
const listMessageThreadParticipantsForUser = `-- name: ListMessageThreadParticipantsForUser :many
|
|
SELECT
|
|
mtp.thread_id,
|
|
u.id AS user_id,
|
|
u.email AS user_email,
|
|
u.role AS user_role,
|
|
u.full_name AS user_full_name,
|
|
p.preferred_name,
|
|
p.profile_icon_url,
|
|
p.headline,
|
|
mtp.joined_at,
|
|
mtp.last_read_at,
|
|
mtp.archived_at
|
|
FROM message_thread_participants mtp
|
|
JOIN users u ON u.id = mtp.user_id
|
|
LEFT JOIN profiles p ON p.user_id = u.id
|
|
WHERE mtp.thread_id IN (
|
|
SELECT participant.thread_id
|
|
FROM message_thread_participants participant
|
|
WHERE participant.user_id = $1
|
|
AND participant.archived_at IS NULL
|
|
)
|
|
ORDER BY mtp.thread_id ASC, COALESCE(NULLIF(p.preferred_name, ''), u.full_name) ASC, u.id ASC
|
|
`
|
|
|
|
type ListMessageThreadParticipantsForUserRow struct {
|
|
ThreadID int64 `json:"thread_id"`
|
|
UserID int64 `json:"user_id"`
|
|
UserEmail string `json:"user_email"`
|
|
UserRole UserRole `json:"user_role"`
|
|
UserFullName string `json:"user_full_name"`
|
|
PreferredName pgtype.Text `json:"preferred_name"`
|
|
ProfileIconUrl pgtype.Text `json:"profile_icon_url"`
|
|
Headline pgtype.Text `json:"headline"`
|
|
JoinedAt pgtype.Timestamptz `json:"joined_at"`
|
|
LastReadAt pgtype.Timestamptz `json:"last_read_at"`
|
|
ArchivedAt pgtype.Timestamptz `json:"archived_at"`
|
|
}
|
|
|
|
func (q *Queries) ListMessageThreadParticipantsForUser(ctx context.Context, userID int64) ([]ListMessageThreadParticipantsForUserRow, error) {
|
|
rows, err := q.db.Query(ctx, listMessageThreadParticipantsForUser, userID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
items := []ListMessageThreadParticipantsForUserRow{}
|
|
for rows.Next() {
|
|
var i ListMessageThreadParticipantsForUserRow
|
|
if err := rows.Scan(
|
|
&i.ThreadID,
|
|
&i.UserID,
|
|
&i.UserEmail,
|
|
&i.UserRole,
|
|
&i.UserFullName,
|
|
&i.PreferredName,
|
|
&i.ProfileIconUrl,
|
|
&i.Headline,
|
|
&i.JoinedAt,
|
|
&i.LastReadAt,
|
|
&i.ArchivedAt,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
const listMessageThreadsForUser = `-- name: ListMessageThreadsForUser :many
|
|
SELECT
|
|
t.id AS thread_id,
|
|
t.subject,
|
|
t.created_by_user_id,
|
|
t.created_at AS thread_created_at,
|
|
t.updated_at AS thread_updated_at,
|
|
COALESCE(last_message.id, 0)::bigint AS last_message_id,
|
|
COALESCE(last_message.body, '') AS last_message_body,
|
|
last_message.created_at AS last_message_created_at,
|
|
COALESCE(last_message.sender_user_id, 0)::bigint AS last_message_sender_user_id,
|
|
sender.full_name AS last_message_sender_full_name,
|
|
sender_profile.preferred_name AS last_message_sender_preferred_name,
|
|
sender_profile.profile_icon_url AS last_message_sender_profile_icon_url,
|
|
COALESCE((
|
|
SELECT COUNT(*)::bigint
|
|
FROM messages unread
|
|
WHERE unread.thread_id = t.id
|
|
AND unread.sender_user_id <> $1
|
|
AND (participant.last_read_at IS NULL OR unread.created_at > participant.last_read_at)
|
|
), 0)::bigint AS unread_count
|
|
FROM message_thread_participants participant
|
|
JOIN message_threads t ON t.id = participant.thread_id
|
|
LEFT JOIN LATERAL (
|
|
SELECT m.id, m.body, m.created_at, m.sender_user_id
|
|
FROM messages m
|
|
WHERE m.thread_id = t.id
|
|
ORDER BY m.created_at DESC, m.id DESC
|
|
LIMIT 1
|
|
) AS last_message ON TRUE
|
|
LEFT JOIN users sender ON sender.id = last_message.sender_user_id
|
|
LEFT JOIN profiles sender_profile ON sender_profile.user_id = sender.id
|
|
WHERE participant.user_id = $1
|
|
AND participant.archived_at IS NULL
|
|
ORDER BY COALESCE(last_message.created_at, t.updated_at) DESC, t.id DESC
|
|
`
|
|
|
|
type ListMessageThreadsForUserRow struct {
|
|
ThreadID int64 `json:"thread_id"`
|
|
Subject string `json:"subject"`
|
|
CreatedByUserID int64 `json:"created_by_user_id"`
|
|
ThreadCreatedAt pgtype.Timestamptz `json:"thread_created_at"`
|
|
ThreadUpdatedAt pgtype.Timestamptz `json:"thread_updated_at"`
|
|
LastMessageID int64 `json:"last_message_id"`
|
|
LastMessageBody string `json:"last_message_body"`
|
|
LastMessageCreatedAt pgtype.Timestamptz `json:"last_message_created_at"`
|
|
LastMessageSenderUserID int64 `json:"last_message_sender_user_id"`
|
|
LastMessageSenderFullName pgtype.Text `json:"last_message_sender_full_name"`
|
|
LastMessageSenderPreferredName pgtype.Text `json:"last_message_sender_preferred_name"`
|
|
LastMessageSenderProfileIconUrl pgtype.Text `json:"last_message_sender_profile_icon_url"`
|
|
UnreadCount int64 `json:"unread_count"`
|
|
}
|
|
|
|
func (q *Queries) ListMessageThreadsForUser(ctx context.Context, senderUserID int64) ([]ListMessageThreadsForUserRow, error) {
|
|
rows, err := q.db.Query(ctx, listMessageThreadsForUser, senderUserID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
items := []ListMessageThreadsForUserRow{}
|
|
for rows.Next() {
|
|
var i ListMessageThreadsForUserRow
|
|
if err := rows.Scan(
|
|
&i.ThreadID,
|
|
&i.Subject,
|
|
&i.CreatedByUserID,
|
|
&i.ThreadCreatedAt,
|
|
&i.ThreadUpdatedAt,
|
|
&i.LastMessageID,
|
|
&i.LastMessageBody,
|
|
&i.LastMessageCreatedAt,
|
|
&i.LastMessageSenderUserID,
|
|
&i.LastMessageSenderFullName,
|
|
&i.LastMessageSenderPreferredName,
|
|
&i.LastMessageSenderProfileIconUrl,
|
|
&i.UnreadCount,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
const listMessagesForThreadForUser = `-- name: ListMessagesForThreadForUser :many
|
|
SELECT
|
|
m.id,
|
|
m.thread_id,
|
|
m.sender_user_id,
|
|
m.body,
|
|
m.created_at,
|
|
m.updated_at,
|
|
sender.email AS sender_email,
|
|
sender.role AS sender_role,
|
|
sender.full_name AS sender_full_name,
|
|
sender_profile.preferred_name AS sender_preferred_name,
|
|
sender_profile.profile_icon_url AS sender_profile_icon_url,
|
|
sender_profile.headline AS sender_headline
|
|
FROM messages m
|
|
JOIN message_thread_participants participant ON participant.thread_id = m.thread_id
|
|
JOIN users sender ON sender.id = m.sender_user_id
|
|
LEFT JOIN profiles sender_profile ON sender_profile.user_id = sender.id
|
|
WHERE m.thread_id = $1
|
|
AND participant.user_id = $2
|
|
AND participant.archived_at IS NULL
|
|
ORDER BY m.created_at ASC, m.id ASC
|
|
`
|
|
|
|
type ListMessagesForThreadForUserParams struct {
|
|
ThreadID int64 `json:"thread_id"`
|
|
UserID int64 `json:"user_id"`
|
|
}
|
|
|
|
type ListMessagesForThreadForUserRow struct {
|
|
ID int64 `json:"id"`
|
|
ThreadID int64 `json:"thread_id"`
|
|
SenderUserID int64 `json:"sender_user_id"`
|
|
Body string `json:"body"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
|
|
SenderEmail string `json:"sender_email"`
|
|
SenderRole UserRole `json:"sender_role"`
|
|
SenderFullName string `json:"sender_full_name"`
|
|
SenderPreferredName pgtype.Text `json:"sender_preferred_name"`
|
|
SenderProfileIconUrl pgtype.Text `json:"sender_profile_icon_url"`
|
|
SenderHeadline pgtype.Text `json:"sender_headline"`
|
|
}
|
|
|
|
func (q *Queries) ListMessagesForThreadForUser(ctx context.Context, arg ListMessagesForThreadForUserParams) ([]ListMessagesForThreadForUserRow, error) {
|
|
rows, err := q.db.Query(ctx, listMessagesForThreadForUser, arg.ThreadID, arg.UserID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
items := []ListMessagesForThreadForUserRow{}
|
|
for rows.Next() {
|
|
var i ListMessagesForThreadForUserRow
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.ThreadID,
|
|
&i.SenderUserID,
|
|
&i.Body,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.SenderEmail,
|
|
&i.SenderRole,
|
|
&i.SenderFullName,
|
|
&i.SenderPreferredName,
|
|
&i.SenderProfileIconUrl,
|
|
&i.SenderHeadline,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
const listParticipantsForThreadForUser = `-- name: ListParticipantsForThreadForUser :many
|
|
SELECT
|
|
mtp.thread_id,
|
|
u.id AS user_id,
|
|
u.email AS user_email,
|
|
u.role AS user_role,
|
|
u.full_name AS user_full_name,
|
|
p.preferred_name,
|
|
p.profile_icon_url,
|
|
p.headline,
|
|
mtp.joined_at,
|
|
mtp.last_read_at,
|
|
mtp.archived_at
|
|
FROM message_thread_participants mtp
|
|
JOIN users u ON u.id = mtp.user_id
|
|
LEFT JOIN profiles p ON p.user_id = u.id
|
|
WHERE mtp.thread_id = $1
|
|
AND EXISTS (
|
|
SELECT 1
|
|
FROM message_thread_participants participant
|
|
WHERE participant.thread_id = mtp.thread_id
|
|
AND participant.user_id = $2
|
|
AND participant.archived_at IS NULL
|
|
)
|
|
ORDER BY COALESCE(NULLIF(p.preferred_name, ''), u.full_name) ASC, u.id ASC
|
|
`
|
|
|
|
type ListParticipantsForThreadForUserParams struct {
|
|
ThreadID int64 `json:"thread_id"`
|
|
UserID int64 `json:"user_id"`
|
|
}
|
|
|
|
type ListParticipantsForThreadForUserRow struct {
|
|
ThreadID int64 `json:"thread_id"`
|
|
UserID int64 `json:"user_id"`
|
|
UserEmail string `json:"user_email"`
|
|
UserRole UserRole `json:"user_role"`
|
|
UserFullName string `json:"user_full_name"`
|
|
PreferredName pgtype.Text `json:"preferred_name"`
|
|
ProfileIconUrl pgtype.Text `json:"profile_icon_url"`
|
|
Headline pgtype.Text `json:"headline"`
|
|
JoinedAt pgtype.Timestamptz `json:"joined_at"`
|
|
LastReadAt pgtype.Timestamptz `json:"last_read_at"`
|
|
ArchivedAt pgtype.Timestamptz `json:"archived_at"`
|
|
}
|
|
|
|
func (q *Queries) ListParticipantsForThreadForUser(ctx context.Context, arg ListParticipantsForThreadForUserParams) ([]ListParticipantsForThreadForUserRow, error) {
|
|
rows, err := q.db.Query(ctx, listParticipantsForThreadForUser, arg.ThreadID, arg.UserID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
items := []ListParticipantsForThreadForUserRow{}
|
|
for rows.Next() {
|
|
var i ListParticipantsForThreadForUserRow
|
|
if err := rows.Scan(
|
|
&i.ThreadID,
|
|
&i.UserID,
|
|
&i.UserEmail,
|
|
&i.UserRole,
|
|
&i.UserFullName,
|
|
&i.PreferredName,
|
|
&i.ProfileIconUrl,
|
|
&i.Headline,
|
|
&i.JoinedAt,
|
|
&i.LastReadAt,
|
|
&i.ArchivedAt,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
const markMessageThreadRead = `-- name: MarkMessageThreadRead :one
|
|
UPDATE message_thread_participants
|
|
SET last_read_at = COALESCE((SELECT MAX(m.created_at) FROM messages m WHERE m.thread_id = $1), NOW())
|
|
WHERE message_thread_participants.thread_id = $1
|
|
AND message_thread_participants.user_id = $2
|
|
RETURNING thread_id, user_id, joined_at, last_read_at, archived_at
|
|
`
|
|
|
|
type MarkMessageThreadReadParams struct {
|
|
ThreadID int64 `json:"thread_id"`
|
|
UserID int64 `json:"user_id"`
|
|
}
|
|
|
|
func (q *Queries) MarkMessageThreadRead(ctx context.Context, arg MarkMessageThreadReadParams) (MessageThreadParticipant, error) {
|
|
row := q.db.QueryRow(ctx, markMessageThreadRead, arg.ThreadID, arg.UserID)
|
|
var i MessageThreadParticipant
|
|
err := row.Scan(
|
|
&i.ThreadID,
|
|
&i.UserID,
|
|
&i.JoinedAt,
|
|
&i.LastReadAt,
|
|
&i.ArchivedAt,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const touchMessageThread = `-- name: TouchMessageThread :exec
|
|
UPDATE message_threads
|
|
SET updated_at = NOW()
|
|
WHERE id = $1
|
|
`
|
|
|
|
func (q *Queries) TouchMessageThread(ctx context.Context, id int64) error {
|
|
_, err := q.db.Exec(ctx, touchMessageThread, id)
|
|
return err
|
|
}
|
|
|
|
const updateMessageThreadSubject = `-- name: UpdateMessageThreadSubject :one
|
|
UPDATE message_threads
|
|
SET subject = $1,
|
|
updated_at = NOW()
|
|
WHERE id = $2
|
|
RETURNING id, created_by_user_id, subject, created_at, updated_at
|
|
`
|
|
|
|
type UpdateMessageThreadSubjectParams struct {
|
|
Subject string `json:"subject"`
|
|
ThreadID int64 `json:"thread_id"`
|
|
}
|
|
|
|
func (q *Queries) UpdateMessageThreadSubject(ctx context.Context, arg UpdateMessageThreadSubjectParams) (MessageThread, error) {
|
|
row := q.db.QueryRow(ctx, updateMessageThreadSubject, arg.Subject, arg.ThreadID)
|
|
var i MessageThread
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.CreatedByUserID,
|
|
&i.Subject,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const updateThreadMessageBody = `-- name: UpdateThreadMessageBody :one
|
|
UPDATE messages
|
|
SET body = $1,
|
|
updated_at = NOW()
|
|
WHERE id = $2
|
|
AND thread_id = $3
|
|
AND sender_user_id = $4
|
|
RETURNING id, thread_id, sender_user_id, body, created_at, updated_at
|
|
`
|
|
|
|
type UpdateThreadMessageBodyParams struct {
|
|
Body string `json:"body"`
|
|
MessageID int64 `json:"message_id"`
|
|
ThreadID int64 `json:"thread_id"`
|
|
UserID int64 `json:"user_id"`
|
|
}
|
|
|
|
func (q *Queries) UpdateThreadMessageBody(ctx context.Context, arg UpdateThreadMessageBodyParams) (Message, error) {
|
|
row := q.db.QueryRow(ctx, updateThreadMessageBody,
|
|
arg.Body,
|
|
arg.MessageID,
|
|
arg.ThreadID,
|
|
arg.UserID,
|
|
)
|
|
var i Message
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.ThreadID,
|
|
&i.SenderUserID,
|
|
&i.Body,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
)
|
|
return i, err
|
|
}
|