// 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 }