// Code generated by sqlc. DO NOT EDIT. // versions: // sqlc v1.31.1 // source: issue_read_cursor.sql package db import ( "context" "github.com/jackc/pgx/v5/pgtype" ) const deleteIssueReadCursorsByIssue = `-- name: DeleteIssueReadCursorsByIssue :exec DELETE FROM issue_read_cursor WHERE issue_id = $1::uuid AND workspace_id = $2::uuid ` type DeleteIssueReadCursorsByIssueParams struct { IssueID pgtype.UUID `json:"issue_id"` WorkspaceID pgtype.UUID `json:"workspace_id"` } // No foreign keys by project rule, so issue deletion cleans up here. func (q *Queries) DeleteIssueReadCursorsByIssue(ctx context.Context, arg DeleteIssueReadCursorsByIssueParams) error { _, err := q.db.Exec(ctx, deleteIssueReadCursorsByIssue, arg.IssueID, arg.WorkspaceID) return err } const deleteIssueReadCursorsByUserWorkspace = `-- name: DeleteIssueReadCursorsByUserWorkspace :exec DELETE FROM issue_read_cursor WHERE user_id = $1::uuid AND workspace_id = $2::uuid ` type DeleteIssueReadCursorsByUserWorkspaceParams struct { UserID pgtype.UUID `json:"user_id"` WorkspaceID pgtype.UUID `json:"workspace_id"` } // A departing member's cursors, in the same tx as the member-row delete. func (q *Queries) DeleteIssueReadCursorsByUserWorkspace(ctx context.Context, arg DeleteIssueReadCursorsByUserWorkspaceParams) error { _, err := q.db.Exec(ctx, deleteIssueReadCursorsByUserWorkspace, arg.UserID, arg.WorkspaceID) return err } const deleteIssueReadCursorsForWorkspace = `-- name: DeleteIssueReadCursorsForWorkspace :exec DELETE FROM issue_read_cursor WHERE workspace_id = $1::uuid ` // No foreign keys by project rule, so workspace teardown cleans up here. func (q *Queries) DeleteIssueReadCursorsForWorkspace(ctx context.Context, workspaceID pgtype.UUID) error { _, err := q.db.Exec(ctx, deleteIssueReadCursorsForWorkspace, workspaceID) return err } const listIssueReadCursors = `-- name: ListIssueReadCursors :many SELECT issue_id, last_read_at FROM issue_read_cursor WHERE user_id = $1::uuid AND workspace_id = $2::uuid AND issue_id = ANY($3::uuid[]) ` type ListIssueReadCursorsParams struct { UserID pgtype.UUID `json:"user_id"` WorkspaceID pgtype.UUID `json:"workspace_id"` IssueIds []pgtype.UUID `json:"issue_ids"` } type ListIssueReadCursorsRow struct { IssueID pgtype.UUID `json:"issue_id"` LastReadAt pgtype.Timestamptz `json:"last_read_at"` } // The caller's cursors for a batch of issues, scoped to the workspace. Issues // the user never opened have no row. func (q *Queries) ListIssueReadCursors(ctx context.Context, arg ListIssueReadCursorsParams) ([]ListIssueReadCursorsRow, error) { rows, err := q.db.Query(ctx, listIssueReadCursors, arg.UserID, arg.WorkspaceID, arg.IssueIds) if err != nil { return nil, err } defer rows.Close() items := []ListIssueReadCursorsRow{} for rows.Next() { var i ListIssueReadCursorsRow if err := rows.Scan(&i.IssueID, &i.LastReadAt); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const upsertIssueReadCursor = `-- name: UpsertIssueReadCursor :exec INSERT INTO issue_read_cursor (user_id, issue_id, workspace_id, last_read_at) VALUES ( $1::uuid, $2::uuid, $3::uuid, COALESCE($4::timestamptz, now()) ) ON CONFLICT (user_id, issue_id) DO UPDATE SET last_read_at = GREATEST(issue_read_cursor.last_read_at, EXCLUDED.last_read_at) ` type UpsertIssueReadCursorParams struct { UserID pgtype.UUID `json:"user_id"` IssueID pgtype.UUID `json:"issue_id"` WorkspaceID pgtype.UUID `json:"workspace_id"` LastReadAt pgtype.Timestamptz `json:"last_read_at"` } // Monotonic: GREATEST keeps the newest value, so a late or replayed request // never moves a cursor backwards and re-marking an issue as read is a no-op. // A NULL last_read_at means "now" on the database clock, the same clock that // stamps comment.created_at, so API/DB clock skew cannot leave a just-read // issue looking unread. func (q *Queries) UpsertIssueReadCursor(ctx context.Context, arg UpsertIssueReadCursorParams) error { _, err := q.db.Exec(ctx, upsertIssueReadCursor, arg.UserID, arg.IssueID, arg.WorkspaceID, arg.LastReadAt, ) return err }