Files
multica/server/pkg/db/generated/github_snapshot.sql.go
2026-07-24 17:30:43 +08:00

329 lines
10 KiB
Go

// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.31.1
// source: github_snapshot.sql
package db
import (
"context"
"github.com/jackc/pgx/v5/pgtype"
)
const deleteGitHubPRCheckRuns = `-- name: DeleteGitHubPRCheckRuns :exec
DELETE FROM github_pull_request_check_run WHERE pr_id = $1
`
// First half of the atomic per-check replace. Runs inside the same transaction
// as UpdateGitHubPRSnapshot and the inserts below.
func (q *Queries) DeleteGitHubPRCheckRuns(ctx context.Context, prID pgtype.UUID) error {
_, err := q.db.Exec(ctx, deleteGitHubPRCheckRuns, prID)
return err
}
const getGitHubPullRequestByID = `-- name: GetGitHubPullRequestByID :one
SELECT id, workspace_id, installation_id, repo_owner, repo_name, pr_number, title, state, html_url, branch, author_login, author_avatar_url, merged_at, closed_at, pr_created_at, pr_updated_at, created_at, updated_at, head_sha, mergeable_state, additions, deletions, changed_files, api_mergeable, api_merge_state_status, checks_rollup_state, snapshot_head_sha, snapshot_fetched_at FROM github_pull_request WHERE id = $1
`
func (q *Queries) GetGitHubPullRequestByID(ctx context.Context, id pgtype.UUID) (GithubPullRequest, error) {
row := q.db.QueryRow(ctx, getGitHubPullRequestByID, id)
var i GithubPullRequest
err := row.Scan(
&i.ID,
&i.WorkspaceID,
&i.InstallationID,
&i.RepoOwner,
&i.RepoName,
&i.PrNumber,
&i.Title,
&i.State,
&i.HtmlUrl,
&i.Branch,
&i.AuthorLogin,
&i.AuthorAvatarUrl,
&i.MergedAt,
&i.ClosedAt,
&i.PrCreatedAt,
&i.PrUpdatedAt,
&i.CreatedAt,
&i.UpdatedAt,
&i.HeadSha,
&i.MergeableState,
&i.Additions,
&i.Deletions,
&i.ChangedFiles,
&i.ApiMergeable,
&i.ApiMergeStateStatus,
&i.ChecksRollupState,
&i.SnapshotHeadSha,
&i.SnapshotFetchedAt,
)
return i, err
}
const insertGitHubPRCheckRun = `-- name: InsertGitHubPRCheckRun :exec
INSERT INTO github_pull_request_check_run (
pr_id, head_sha, ordinal, name, status, conclusion, details_url, is_status_context
) VALUES (
$1, $2, $3, $4, $5, $7, $8, $6
)
`
type InsertGitHubPRCheckRunParams struct {
PrID pgtype.UUID `json:"pr_id"`
HeadSha string `json:"head_sha"`
Ordinal int32 `json:"ordinal"`
Name string `json:"name"`
Status string `json:"status"`
IsStatusContext bool `json:"is_status_context"`
Conclusion pgtype.Text `json:"conclusion"`
DetailsUrl pgtype.Text `json:"details_url"`
}
func (q *Queries) InsertGitHubPRCheckRun(ctx context.Context, arg InsertGitHubPRCheckRunParams) error {
_, err := q.db.Exec(ctx, insertGitHubPRCheckRun,
arg.PrID,
arg.HeadSha,
arg.Ordinal,
arg.Name,
arg.Status,
arg.IsStatusContext,
arg.Conclusion,
arg.DetailsUrl,
)
return err
}
const listGitHubPRNumbersByHeadSHA = `-- name: ListGitHubPRNumbersByHeadSHA :many
SELECT DISTINCT pr_number
FROM github_pull_request
WHERE installation_id = $1 AND repo_owner = $2 AND repo_name = $3 AND head_sha = $4
`
type ListGitHubPRNumbersByHeadSHAParams struct {
InstallationID int64 `json:"installation_id"`
RepoOwner string `json:"repo_owner"`
RepoName string `json:"repo_name"`
HeadSha string `json:"head_sha"`
}
// Resolves a commit SHA to the PR numbers whose head it is. `status` webhook
// events (legacy commit statuses) carry a SHA + repo but no PR number, so we
// map back through the mirrored head_sha to find which PR(s) to refresh.
func (q *Queries) ListGitHubPRNumbersByHeadSHA(ctx context.Context, arg ListGitHubPRNumbersByHeadSHAParams) ([]int32, error) {
rows, err := q.db.Query(ctx, listGitHubPRNumbersByHeadSHA,
arg.InstallationID,
arg.RepoOwner,
arg.RepoName,
arg.HeadSha,
)
if err != nil {
return nil, err
}
defer rows.Close()
items := []int32{}
for rows.Next() {
var pr_number int32
if err := rows.Scan(&pr_number); err != nil {
return nil, err
}
items = append(items, pr_number)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listGitHubPRRowsByAddress = `-- name: ListGitHubPRRowsByAddress :many
SELECT id, workspace_id, head_sha, state
FROM github_pull_request
WHERE installation_id = $1 AND repo_owner = $2 AND repo_name = $3 AND pr_number = $4
`
type ListGitHubPRRowsByAddressParams struct {
InstallationID int64 `json:"installation_id"`
RepoOwner string `json:"repo_owner"`
RepoName string `json:"repo_name"`
PrNumber int32 `json:"pr_number"`
}
type ListGitHubPRRowsByAddressRow struct {
ID pgtype.UUID `json:"id"`
WorkspaceID pgtype.UUID `json:"workspace_id"`
HeadSha string `json:"head_sha"`
State string `json:"state"`
}
// =====================
// GitHub API snapshot (MUL-5265, Plan C)
//
// These queries back the API-snapshot refresh pipeline. The GitHub GraphQL
// response is the single source of truth; each successful fetch is written as
// one atomic batch replace (guarded update of the PR row + full replace of the
// per-check rows) inside a single transaction.
// =====================
// One (installation, owner, repo, number) address can map to several
// github_pull_request rows — the same installation can be bound to multiple
// workspaces (#4823/#4855), each mirroring its own row. A single API fetch is
// applied to every matching row (each guarded by its own head_sha).
func (q *Queries) ListGitHubPRRowsByAddress(ctx context.Context, arg ListGitHubPRRowsByAddressParams) ([]ListGitHubPRRowsByAddressRow, error) {
rows, err := q.db.Query(ctx, listGitHubPRRowsByAddress,
arg.InstallationID,
arg.RepoOwner,
arg.RepoName,
arg.PrNumber,
)
if err != nil {
return nil, err
}
defer rows.Close()
items := []ListGitHubPRRowsByAddressRow{}
for rows.Next() {
var i ListGitHubPRRowsByAddressRow
if err := rows.Scan(
&i.ID,
&i.WorkspaceID,
&i.HeadSha,
&i.State,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listStaleUndecidedGitHubPRs = `-- name: ListStaleUndecidedGitHubPRs :many
WITH candidates AS (
SELECT installation_id, repo_owner, repo_name, pr_number
FROM github_pull_request AS pr
WHERE state IN ('open', 'draft')
AND (snapshot_fetched_at IS NULL OR snapshot_fetched_at < $6)
AND (
snapshot_fetched_at IS NULL
OR api_mergeable IS NULL
OR api_mergeable = 'UNKNOWN'
OR checks_rollup_state IN ('PENDING', 'EXPECTED')
OR EXISTS (
SELECT 1
FROM github_pull_request_check_run AS cr
WHERE cr.pr_id = pr.id AND cr.status <> 'completed'
)
)
GROUP BY installation_id, repo_owner, repo_name, pr_number
)
SELECT installation_id, repo_owner, repo_name, pr_number
FROM candidates
ORDER BY (
ROW(installation_id, repo_owner, repo_name, pr_number) >
ROW(
$1::BIGINT,
$2::TEXT,
$3::TEXT,
$4::INTEGER
)
) DESC,
installation_id, repo_owner, repo_name, pr_number
LIMIT $5
`
type ListStaleUndecidedGitHubPRsParams struct {
AfterInstallationID int64 `json:"after_installation_id"`
AfterRepoOwner string `json:"after_repo_owner"`
AfterRepoName string `json:"after_repo_name"`
AfterPrNumber int32 `json:"after_pr_number"`
MaxRows int32 `json:"max_rows"`
OlderThan pgtype.Timestamptz `json:"older_than"`
}
type ListStaleUndecidedGitHubPRsRow struct {
InstallationID int64 `json:"installation_id"`
RepoOwner string `json:"repo_owner"`
RepoName string `json:"repo_name"`
PrNumber int32 `json:"pr_number"`
}
// TTL / safety-net sweep source. Returns distinct addresses of open/draft PRs
// whose snapshot is both stale and undecided. A decided snapshot leaves the
// periodic refresh set; later webhook or view activity can still refresh it.
// The caller advances an address cursor after each bounded batch. Rows after
// the cursor sort first, followed by a wrap to the start, so even perpetually
// failing addresses cannot pin the same first LIMIT rows forever.
func (q *Queries) ListStaleUndecidedGitHubPRs(ctx context.Context, arg ListStaleUndecidedGitHubPRsParams) ([]ListStaleUndecidedGitHubPRsRow, error) {
rows, err := q.db.Query(ctx, listStaleUndecidedGitHubPRs,
arg.AfterInstallationID,
arg.AfterRepoOwner,
arg.AfterRepoName,
arg.AfterPrNumber,
arg.MaxRows,
arg.OlderThan,
)
if err != nil {
return nil, err
}
defer rows.Close()
items := []ListStaleUndecidedGitHubPRsRow{}
for rows.Next() {
var i ListStaleUndecidedGitHubPRsRow
if err := rows.Scan(
&i.InstallationID,
&i.RepoOwner,
&i.RepoName,
&i.PrNumber,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const updateGitHubPRSnapshot = `-- name: UpdateGitHubPRSnapshot :execrows
UPDATE github_pull_request
SET api_mergeable = $1,
api_merge_state_status = $2,
checks_rollup_state = $3,
snapshot_head_sha = $4,
snapshot_fetched_at = $5,
updated_at = now()
WHERE id = $6 AND head_sha = $4
`
type UpdateGitHubPRSnapshotParams struct {
ApiMergeable pgtype.Text `json:"api_mergeable"`
ApiMergeStateStatus pgtype.Text `json:"api_merge_state_status"`
ChecksRollupState pgtype.Text `json:"checks_rollup_state"`
HeadSha string `json:"head_sha"`
FetchedAt pgtype.Timestamptz `json:"fetched_at"`
PrID pgtype.UUID `json:"pr_id"`
}
// Head-SHA anti-stale write (acceptance criterion 1): the snapshot is written
// only when the row's current head_sha still equals the head the snapshot was
// fetched for. If the head advanced (a newer push landed while this request was
// in flight, mirrored by the pull_request webhook), 0 rows are updated and the
// caller discards the whole response — the per-check replace is skipped too.
func (q *Queries) UpdateGitHubPRSnapshot(ctx context.Context, arg UpdateGitHubPRSnapshotParams) (int64, error) {
result, err := q.db.Exec(ctx, updateGitHubPRSnapshot,
arg.ApiMergeable,
arg.ApiMergeStateStatus,
arg.ChecksRollupState,
arg.HeadSha,
arg.FetchedAt,
arg.PrID,
)
if err != nil {
return 0, err
}
return result.RowsAffected(), nil
}