store

package
v0.1.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 8, 2026 License: Apache-2.0 Imports: 17 Imported by: 0

Documentation

Overview

Package store is the single entry point to Githome's metadata database. It supports PostgreSQL (jackc/pgx/v5 via database/sql) and SQLite (modernc.org/sqlite, pure Go, no cgo) behind one dialect-aware Store. The same embedded migrations run on both.

Write-throughput ceiling

SQLite serializes all writers at the database level: only one write transaction runs at a time. On modern NVMe storage each committed write transaction costs ~0.1–0.5 ms (one fsync), giving a ceiling of roughly 2–10K writes/sec for single-statement mutations. The multi-statement write path for an issue or pull request (number allocation, row insert, label/assignee associations, counter bump, event + job batch) sits comfortably inside that ceiling at development scale but tops out below the 500 RPS SLO target.

Postgres lifts this ceiling: each write transaction acquires row-level locks (not a database-wide write lock), so unrelated writes proceed concurrently and the throughput scales with connection-pool depth and hardware IOPS. Githome targets Postgres for production at scale; SQLite serves development, tests, and single-user instances where the ceiling is not a bottleneck.

Index

Constants

This section is empty.

Variables

View Source
var ErrNotFound = errors.New("store: not found")

ErrNotFound is returned when a row that was expected to exist does not.

View Source
var ErrOptimisticLock = errors.New("store: optimistic lock conflict")

ErrOptimisticLock signals that a row's version moved between read and write, so the caller should re-read and retry the edit.

View Source
var ReactionContents = []string{"+1", "-1", "laugh", "confused", "heart", "hooray", "rocket", "eyes"}

ReactionContents is the set of reaction names GitHub accepts, in the order its rollup reports them.

Functions

func EncodeCursor added in v0.1.1

func EncodeCursor(c IssueCursor) string

EncodeCursor serializes the cursor to a URL-safe base64 string.

func EncodePullCursor added in v0.1.2

func EncodePullCursor(c PullCursor) string

EncodePullCursor serializes a pull cursor to a URL-safe base64 string.

Types

type CheckRunRow

type CheckRunRow struct {
	PK            int64
	DBID          int64
	SuitePK       int64
	RepoPK        int64
	HeadSHA       string
	Name          string
	Status        string
	Conclusion    *string
	DetailsURL    *string
	ExternalID    *string
	OutputTitle   *string
	OutputSummary *string
	OutputText    *string
	StartedAt     *time.Time
	CompletedAt   *time.Time
	CreatedAt     time.Time
	UpdatedAt     time.Time
}

CheckRunRow is a row of check_runs, one named check against a head sha inside a suite. Status is queued, in_progress, or completed; Conclusion (success, failure, neutral, cancelled, timed_out, action_required, skipped) is set when the run completes.

type CheckSuiteRow

type CheckSuiteRow struct {
	PK         int64
	DBID       int64
	RepoPK     int64
	HeadSHA    string
	AppSlug    string
	Status     string
	Conclusion *string
	CreatedAt  time.Time
	UpdatedAt  time.Time
}

CheckSuiteRow is a row of check_suites, the per-app container for the check runs reported against a head sha. Status is queued, in_progress, or completed; Conclusion is set only once completed.

type CommentRow

type CommentRow struct {
	PK        int64
	DBID      int64
	IssuePK   int64
	UserPK    int64
	Body      string
	CreatedAt time.Time
	UpdatedAt time.Time
}

CommentRow is a row of the issue_comments table: a comment on an issue or pull request (both live in the issues table). Soft deletes keep the row so reaction and event history stays intact; reads skip deleted rows.

type CommitStatusRow

type CommitStatusRow struct {
	PK          int64
	DBID        int64
	RepoPK      int64
	SHA         string
	State       string
	Context     string
	TargetURL   *string
	Description *string
	CreatorPK   *int64
	CreatedAt   time.Time
	UpdatedAt   time.Time
}

CommitStatusRow is a row of commit_statuses, one external pass/fail report against a sha under a context. State is error, failure, pending, or success.

type DeviceCodeRow

type DeviceCodeRow struct {
	PK             int64
	DeviceCodeHash []byte
	UserCode       string
	OAuthAppPK     *int64
	Scopes         string
	State          string // pending | approved | denied
	UserPK         *int64
	IntervalSec    int
	LastPolledAt   *time.Time
	ExpiresAt      time.Time
	CreatedAt      time.Time
}

DeviceCodeRow is a row of the oauth_device_codes table backing the device flow state machine.

type Dialect

type Dialect int

Dialect is the database backend in use. It is resolved once at Open from the DSN scheme and never changes for the life of a Store.

const (
	// DialectPostgres is PostgreSQL via the pgx stdlib driver.
	DialectPostgres Dialect = iota
	// DialectSQLite is SQLite via the pure-Go modernc.org/sqlite driver.
	DialectSQLite
)

func (Dialect) String

func (d Dialect) String() string

type EventFilter

type EventFilter struct {
	RepoPK     *int64
	ActorPK    *int64
	PublicOnly bool
	Limit      int
}

EventFilter selects a slice of the activity feed. RepoPK and ActorPK are the per-repository and per-user scopes; PublicOnly applies the visibility filter the unauthenticated Events API enforces (the repo is public and the event is public). Limit caps the page.

type EventRow

type EventRow struct {
	PK        int64
	DBID      int64
	Event     string
	Action    string
	ActorPK   int64
	RepoPK    int64
	IssuePK   *int64
	Payload   string
	Public    bool
	CreatedAt time.Time
}

EventRow is a row of the events table: one append-only record of an action a user took on a repository. It feeds both the pull-based Events API and the push-based webhook fan-out. IssuePK is nullable because push and repository events have no issue. Public is the repo-visibility-derived flag the public Events API filters on; Payload is the rendered Events-API JSON document.

type IssueCursor added in v0.1.1

type IssueCursor struct {
	CreatedAt time.Time
	Number    int64
}

IssueCursor is the opaque seek key for keyset-paginated issue lists. It encodes the (created_at, number) pair of the last item on the current page so the next page can be fetched with a single index seek rather than an OFFSET scan.

The cursor is an implementation detail of the store package; callers treat the encoded string as opaque and round-trip it unchanged.

func DecodeCursor added in v0.1.1

func DecodeCursor(s string) (IssueCursor, error)

DecodeCursor parses a cursor returned by EncodeCursor. Any malformed input returns an error; callers fall back to OFFSET when decoding fails.

type IssueEventRow

type IssueEventRow struct {
	PK        int64
	DBID      int64
	RepoPK    int64
	IssuePK   int64
	ActorPK   *int64
	Event     string
	Payload   string
	CreatedAt time.Time
}

IssueEventRow is a row of the issue_events timeline log.

type IssueFilter

type IssueFilter struct {
	State        string   // "open" | "closed" | "all"; "" means "open"
	Labels       []string // issue must carry every named label
	CreatorPK    *int64
	AssigneePK   *int64 // 0-valued pointer not used; nil means unfiltered
	MilestonePK  *int64
	IncludePulls bool   // when false, is_pull rows are excluded
	Sort         string // "created" | "updated" | "comments"; "" means "created"
	Direction    string // "asc" | "desc"; "" means "desc"
	Limit        int    // 0 means the default page of 30
	Offset       int
	// Cursor, when non-nil, switches the data query from OFFSET to a keyset
	// seek: WHERE (created_at, number) < cursor. Only effective when Sort is
	// "created" (or ""); ignored for other sort columns since the cursor encodes
	// created_at. CountIssues always uses OFFSET so the total stays correct.
	Cursor *IssueCursor
}

IssueFilter narrows a repository's issue list the way GitHub's list endpoint does. The zero value lists open issues, newest first, excluding pull requests. Empty slice/zero fields mean "do not filter on this".

type IssueRow

type IssueRow struct {
	PK               int64
	DBID             int64
	RepoPK           int64
	Number           int64
	IsPull           bool
	Title            string
	Body             *string
	UserPK           int64
	State            string
	StateReason      *string
	MilestonePK      *int64
	Locked           bool
	ActiveLockReason *string
	CommentsCount    int
	ClosedAt         *time.Time
	ClosedByPK       *int64
	LockVersion      int64
	CreatedAt        time.Time
	UpdatedAt        time.Time
}

IssueRow is a row of the issues table. The table is shared by issues and pull requests (IsPull tells them apart) since GitHub numbers them from one sequence per repository, but M4 only writes IsPull=false rows; the pull request milestone fills in the rest. StateReason carries GitHub's completed/reopened/not_planned qualifier and is nil for open issues that have never been closed.

type IssueSearch

type IssueSearch struct {
	ViewerPK    int64
	Terms       []string
	MatchTitle  bool
	MatchBody   bool
	IsPull      *bool
	State       string // "", "open", "closed"
	AuthorPK    *int64
	AssigneePK  *int64
	Labels      []string
	RepoPKs     []int64
	OwnerPKs    []int64
	MilestonePK *int64
	Sort        string // "created" | "updated" | "comments"; "" is created
	Order       string // "asc" | "desc"; "" is desc
	Limit       int
	Offset      int
}

IssueSearch is a resolved cross-repository issue query. The domain fills it from the parsed qualifiers: logins and repo names are already resolved to the internal pks here, so the store only filters. ViewerPK gates visibility: a row is returned only when its repository is public or owned by the viewer, so search never leaks a private repository. A nil pointer or empty slice means the corresponding filter is not applied; the term slice is ANDed, each term matched case-insensitively against the selected fields.

type JobRow

type JobRow struct {
	PK          int64
	Kind        string
	Payload     string
	DedupeKey   string
	State       string
	Attempts    int
	MaxAttempts int
}

JobRow is a row of the jobs table: one unit of background work. Payload is a JSON document the worker for that Kind decodes. DedupeKey, when non-empty, makes the job idempotent across a burst: while an identical key is queued or running, EnqueueJob skips the insert.

type LabelRow

type LabelRow struct {
	PK          int64
	DBID        int64
	RepoPK      int64
	Name        string
	Color       string
	Description *string
	IsDefault   bool
	CreatedAt   time.Time
	UpdatedAt   time.Time
}

LabelRow is a row of the labels table: a named, colored tag scoped to one repository. Color is stored as a six-hex string without the leading hash, the form GitHub's API returns. Description is nullable.

type MilestoneRow

type MilestoneRow struct {
	PK          int64
	DBID        int64
	RepoPK      int64
	Number      int64
	Title       string
	Description *string
	State       string
	DueOn       *time.Time
	CreatorPK   *int64
	ClosedAt    *time.Time
	CreatedAt   time.Time
	UpdatedAt   time.Time
}

MilestoneRow is a row of the milestones table. Milestones carry their own per-repo number, allocated from repositories.next_milestone_number, separate from the issue/PR number sequence. The open and closed issue counts GitHub reports are computed on read rather than cached, so they are not columns.

type OAuthAppRow

type OAuthAppRow struct {
	PK                int64
	ClientID          string
	ClientSecretHash  []byte
	Name              string
	OwnerPK           *int64
	DeviceFlowEnabled bool
	CreatedAt         time.Time
}

OAuthAppRow is a row of the oauth_apps table.

type PullCheckStateRow

type PullCheckStateRow struct {
	PullPK         int64
	ReviewDecision *string
	RollupState    string
	UpdatedAt      time.Time
}

PullCheckStateRow is the denormalized snapshot the recompute worker writes: a pull request's derived review decision and status check rollup state, so list views and webhook payloads read one row instead of re-aggregating.

type PullCursor added in v0.1.2

type PullCursor struct {
	Number int64
}

PullCursor is the opaque seek key for keyset-paginated pull-request lists. The list orders by per-repo number descending, which is unique within a repo, so the cursor needs only that number: the next page seeks number < cursor. The (repo_pk, number) unique index makes the seek a single index step regardless of page depth.

func DecodePullCursor added in v0.1.2

func DecodePullCursor(s string) (PullCursor, error)

DecodePullCursor parses a cursor returned by EncodePullCursor. Malformed input returns an error; callers fall back to OFFSET when decoding fails.

type PullRow

type PullRow struct {
	PK                    int64
	DBID                  int64
	IssuePK               int64
	RepoPK                int64
	BaseRef               string
	BaseSHA               string
	HeadRef               string
	HeadSHA               string
	HeadRepoPK            *int64
	Draft                 bool
	MaintainerCanModify   bool
	Merged                bool
	MergedAt              *time.Time
	MergedByPK            *int64
	MergeCommitSHA        *string
	Mergeable             *bool
	MergeableState        string
	Rebaseable            *bool
	Additions             int
	Deletions             int
	ChangedFiles          int
	CommitsCount          int
	MergeabilityCheckedAt *time.Time
	CreatedAt             time.Time
	UpdatedAt             time.Time
}

PullRow is a row of the pull_requests table, the extension a pull request carries on top of its issue row. IssuePK ties it to the issues row that holds the title, body, state, and per-repo number; the fields here are the git coordinates and the merge state. Mergeable and Rebaseable are pointers because they are NULL until the recompute_mergeability worker computes them, the null-then-value contract the API surfaces. HeadRepoPK, MergedAt, MergedByPK, MergeCommitSHA, and MergeabilityCheckedAt are nullable for the same reason a pull request acquires them only over its lifetime.

type ReactionRollup

type ReactionRollup struct {
	TotalCount int
	Counts     map[string]int
}

ReactionRollup is the per-content count GitHub embeds on reactable objects, plus the total.

type ReactionRow

type ReactionRow struct {
	PK          int64
	DBID        int64
	SubjectType string
	SubjectPK   int64
	UserPK      int64
	Content     string
	CreatedAt   time.Time
}

ReactionRow is a row of the reactions table. Reactions are polymorphic: a (SubjectType, SubjectPK) pair points at an issue, a comment, or later a review. Content is one of GitHub's eight reaction names (+1, -1, laugh, confused, heart, hooray, rocket, eyes).

type RepoRow

type RepoRow struct {
	PK              int64
	DBID            int64
	OwnerPK         int64
	Name            string
	Description     *string
	Homepage        *string
	Private         bool
	Fork            bool
	DefaultBranch   string
	HasIssues       bool
	HasProjects     bool
	HasWiki         bool
	HasDownloads    bool
	Archived        bool
	Disabled        bool
	IsTemplate      bool
	OpenIssuesCount int
	PushedAt        *time.Time
	CreatedAt       time.Time
	UpdatedAt       time.Time
}

RepoRow is a row of the repositories table, including the settings columns 0003 adds. OwnerPK is the internal pk of the owning user; the public owner object is resolved separately. Description and Homepage are nullable; the boolean flags carry GitHub's per-repository feature and state settings.

type RepoSearch

type RepoSearch struct {
	ViewerPK int64
	Terms    []string
	OwnerPKs []int64
	Fork     *bool
	Sort     string // "updated" | "created"; "" is created
	Order    string // "asc" | "desc"; "" is desc
	Limit    int
	Offset   int
}

RepoSearch is a resolved cross-repository repository query. As with IssueSearch the domain resolves user:/org: to owner pks before building it, and ViewerPK gates visibility to public repositories and the viewer's own.

type ReviewCommentRow

type ReviewCommentRow struct {
	PK                int64
	DBID              int64
	ReviewPK          int64
	PullPK            int64
	RepoPK            int64
	UserPK            int64
	Path              string
	Side              string
	Line              *int64
	StartLine         *int64
	StartSide         *string
	OriginalLine      *int64
	OriginalStartLine *int64
	Position          *int64
	OriginalPosition  *int64
	CommitID          string
	OriginalCommitID  string
	InReplyToPK       *int64
	DiffHunk          string
	SubjectType       string
	Body              string
	Resolved          bool
	ResolvedByPK      *int64
	CreatedAt         time.Time
	UpdatedAt         time.Time
}

ReviewCommentRow is a row of pull_request_review_comments, a comment anchored to a diff line. Line/StartLine are file line numbers in the new model; Position is the legacy 1-based diff offset, kept for the older API shape. Side and StartSide are LEFT (base) or RIGHT (head). InReplyToPK threads a reply under the comment that started a conversation; Resolved marks that thread settled.

type ReviewRow

type ReviewRow struct {
	PK               int64
	DBID             int64
	PullPK           int64
	RepoPK           int64
	UserPK           int64
	State            string
	Body             string
	CommitID         string
	DismissedMessage *string
	SubmittedAt      *time.Time
	CreatedAt        time.Time
	UpdatedAt        time.Time
}

ReviewRow is a row of pull_request_reviews, one act of reviewing a pull request. State is PENDING (a draft with no submitted_at yet), APPROVED, CHANGES_REQUESTED, COMMENTED, or DISMISSED. SubmittedAt is nil while the review is still a pending draft. DismissedMessage carries the reason a review was later dismissed.

type Store

type Store struct {
	// contains filtered or unexported fields
}

Store wraps a *sql.DB together with its resolved dialect. It is safe for concurrent use; *sql.DB is a connection pool.

func Open

func Open(ctx context.Context, dsn string, pgPoolSize ...int) (*Store, error)

Open resolves the dialect from the DSN, opens a pooled *sql.DB with the right driver, applies dialect-specific pool tuning, and verifies connectivity. pgPoolSize sets the Postgres max-open-connections limit; pass 0 (or use the default config value of 25) for the built-in default.

func (*Store) AllocDBID

func (s *Store) AllocDBID(ctx context.Context) (int64, error)

AllocDBID returns the next value of the global ID sequence shared by every public resource (the REST `id` / GraphQL `databaseId`). On Postgres this draws from a SEQUENCE; on SQLite it bumps the single-row high-water allocator.

func (*Store) AssigneesByIssuePKs added in v0.1.1

func (s *Store) AssigneesByIssuePKs(ctx context.Context, issuePKs []int64) (map[int64][]int64, error)

AssigneesByIssuePKs loads all assignees for the given issue PKs in one query. Returns a map from issue_pk to the ordered slice of assignee user PKs.

func (*Store) BulkLoad added in v0.1.2

func (s *Store) BulkLoad(ctx context.Context, fn func() error) error

BulkLoad runs fn with the store tuned for a one-time bulk load and restores the serving pragmas afterward. On SQLite it trades durability for speed during the load (synchronous=OFF, journal_mode=MEMORY): a crash mid-load can corrupt the database, which is acceptable because a seed is re-runnable against a clean target, and the gain is large because the load stops paying a per-commit fsync. On Postgres it is a passthrough; its bulk speed comes from the multi-row path, not session pragmas. The serving pragmas (WAL, synchronous=NORMAL) are restored even if fn fails.

func (*Store) BumpTokenLastUsed

func (s *Store) BumpTokenLastUsed(ctx context.Context, at map[int64]time.Time) error

BumpTokenLastUsed records the last-used timestamp for a batch of tokens in one transaction. The async debouncer in auth coalesces touches and calls this at most once every couple of seconds, so the per-row UPDATE loop is cheap.

func (*Store) ClaimJob

func (s *Store) ClaimJob(ctx context.Context) (*JobRow, error)

ClaimJob atomically takes the oldest runnable queued job, moving it to the running state and bumping its attempt count under the database's own clock so concurrent claimers never hand out the same job. It returns ErrNotFound when the queue holds nothing runnable. Postgres skips rows another transaction has locked; SQLite's single-writer transaction serializes claimers on its own.

func (*Store) Close

func (s *Store) Close() error

Close releases the connection pool.

func (*Store) CompleteJob

func (s *Store) CompleteJob(ctx context.Context, pk int64) error

CompleteJob removes a finished job. A completed job leaves no trace; the dedupe key it held frees up immediately for the next enqueue.

func (*Store) CountIssues

func (s *Store) CountIssues(ctx context.Context, repoPK int64, f IssueFilter) (int, error)

CountIssues counts the issues matching the filter, ignoring its page window.

func (*Store) CountPulls

func (s *Store) CountPulls(ctx context.Context, repoPK int64, state string) (int, error)

CountPulls counts a repository's pull requests matching the state filter.

func (*Store) CountSearchIssues

func (s *Store) CountSearchIssues(ctx context.Context, q IssueSearch) (int, error)

CountSearchIssues counts every issue matching the query, ignoring its page window, for the search envelope's total_count.

func (*Store) CountSearchRepositories

func (s *Store) CountSearchRepositories(ctx context.Context, q RepoSearch) (int, error)

CountSearchRepositories counts every repository matching the query for the envelope's total_count.

func (*Store) DB

func (s *Store) DB() *sql.DB

DB exposes the underlying pool. Reserved for the migration runner and tests; application code goes through typed Store methods.

func (*Store) DeleteComment

func (s *Store) DeleteComment(ctx context.Context, pk int64) error

DeleteComment soft deletes a comment and decrements its issue's cached count in one transaction so the count and the visible rows stay consistent.

func (*Store) DeleteDeviceCode

func (s *Store) DeleteDeviceCode(ctx context.Context, pk int64) error

DeleteDeviceCode removes a device-flow row once it is spent (token issued, denied, or expired).

func (*Store) DeleteLabel

func (s *Store) DeleteLabel(ctx context.Context, pk int64) error

DeleteLabel removes a label; the issue_labels rows cascade.

func (*Store) DeleteMilestone

func (s *Store) DeleteMilestone(ctx context.Context, pk int64) error

DeleteMilestone removes a milestone; issues pointing at it have milestone_pk reset to NULL by the foreign key.

func (*Store) DeleteReaction

func (s *Store) DeleteReaction(ctx context.Context, subjectType string, subjectPK, dbID int64) error

DeleteReaction removes a reaction by its public database id, scoped to its subject so a caller cannot delete a reaction belonging to another object.

func (*Store) DeleteWebhook

func (s *Store) DeleteWebhook(ctx context.Context, repoPK, dbID int64) error

DeleteWebhook removes a webhook by its public id and, by cascade, its deliveries.

func (*Store) DeviceCodeByHash

func (s *Store) DeviceCodeByHash(ctx context.Context, hash []byte) (*DeviceCodeRow, error)

DeviceCodeByHash loads a device-flow row by sha256(device_code), the lookup the polling endpoint uses.

func (*Store) DeviceCodeByUserCode

func (s *Store) DeviceCodeByUserCode(ctx context.Context, userCode string) (*DeviceCodeRow, error)

DeviceCodeByUserCode loads a device-flow row by the human-typed user_code.

func (*Store) Dialect

func (s *Store) Dialect() Dialect

Dialect reports the resolved database dialect.

func (*Store) DismissReview

func (s *Store) DismissReview(ctx context.Context, pk int64, message string) error

DismissReview marks a submitted review dismissed with a reason, dropping its approval or change request from the decision without deleting its comments.

func (*Store) EnqueueJob

func (s *Store) EnqueueJob(ctx context.Context, j *JobRow) (deduped bool, err error)

EnqueueJob inserts a queued job and fills the server-assigned fields back onto j. When DedupeKey is non-empty and an active (queued or running) job already carries that key, the insert is skipped and deduped is true, so a flurry of pushes to one pull request collapses into a single recompute. The partial unique index backstops a race between two concurrent enqueues.

func (*Store) EnsureCheckSuite

func (s *Store) EnsureCheckSuite(ctx context.Context, repoPK int64, headSHA, appSlug string) (*CheckSuiteRow, error)

EnsureCheckSuite returns the suite for (repo, head_sha, app), creating it on first report. The unique key makes the create idempotent under the same head.

func (*Store) FailJob

func (s *Store) FailJob(ctx context.Context, pk int64, attempts, maxAttempts int, reason string, backoffSeconds int) error

FailJob records a handler failure. While attempts remain it requeues the job for a later retry after backoffSeconds, computed on the database clock so the run_after stays in the column's native format. Once the attempts are spent it parks the job in the dead state far in the future, kept for inspection rather than deleted.

func (*Store) GetCheckRun

func (s *Store) GetCheckRun(ctx context.Context, dbID int64) (*CheckRunRow, error)

GetCheckRun resolves a check run by its public database id.

func (*Store) GetComment

func (s *Store) GetComment(ctx context.Context, dbID int64) (*CommentRow, error)

GetComment resolves a single comment by its public database id.

func (*Store) GetCommentByPK

func (s *Store) GetCommentByPK(ctx context.Context, pk int64) (*CommentRow, error)

GetCommentByPK resolves a single comment by primary key.

func (*Store) GetDeliveryByPK

func (s *Store) GetDeliveryByPK(ctx context.Context, pk int64) (*WebhookDeliveryRow, error)

GetDeliveryByPK resolves one delivery by primary key, the value a redeliver job carries so the worker can replay the recorded request.

func (*Store) GetDeliveryForWebhook

func (s *Store) GetDeliveryForWebhook(ctx context.Context, webhookPK, dbID int64) (*WebhookDeliveryRow, error)

GetDeliveryForWebhook resolves one delivery by its public id scoped to its webhook, the lookup the inspect and redeliver endpoints use.

func (*Store) GetEventByPK

func (s *Store) GetEventByPK(ctx context.Context, pk int64) (*EventRow, error)

GetEventByPK resolves one event by primary key, the value a deliver_event job carries so the fan-out worker can render and store its payload.

func (*Store) GetIssueByDBID

func (s *Store) GetIssueByDBID(ctx context.Context, dbID int64) (*IssueRow, error)

GetIssueByDBID resolves an issue by its public database id.

func (*Store) GetIssueByNumber

func (s *Store) GetIssueByNumber(ctx context.Context, repoPK, number int64) (*IssueRow, error)

GetIssueByNumber resolves an issue by its per-repo number, skipping soft deleted rows.

func (*Store) GetIssueByPK

func (s *Store) GetIssueByPK(ctx context.Context, pk int64) (*IssueRow, error)

GetIssueByPK resolves an issue by primary key.

func (*Store) GetLabel

func (s *Store) GetLabel(ctx context.Context, repoPK int64, name string) (*LabelRow, error)

GetLabel resolves a single label by name within a repository, case-insensitively, matching GitHub's case-preserving but case-insensitive label names.

func (*Store) GetMilestoneByNumber

func (s *Store) GetMilestoneByNumber(ctx context.Context, repoPK, number int64) (*MilestoneRow, error)

GetMilestoneByNumber resolves a milestone by its per-repo number.

func (*Store) GetMilestoneByPK

func (s *Store) GetMilestoneByPK(ctx context.Context, pk int64) (*MilestoneRow, error)

GetMilestoneByPK resolves a milestone by primary key.

func (*Store) GetPullByDBID

func (s *Store) GetPullByDBID(ctx context.Context, dbID int64) (*PullRow, error)

GetPullByDBID resolves a pull request by its public database id, the value a PullRequest node id decodes to.

func (*Store) GetPullByIssuePK

func (s *Store) GetPullByIssuePK(ctx context.Context, issuePK int64) (*PullRow, error)

GetPullByIssuePK resolves the pull request extension of an issue row.

func (*Store) GetPullCheckState

func (s *Store) GetPullCheckState(ctx context.Context, pullPK int64) (*PullCheckStateRow, error)

GetPullCheckState returns a pull request's cached review decision and rollup snapshot, or ErrNotFound before the recompute worker has written one.

func (*Store) GetReviewByDBID

func (s *Store) GetReviewByDBID(ctx context.Context, dbID int64) (*ReviewRow, error)

GetReviewByDBID resolves a review by its public database id, the value a PullRequestReview node id decodes to.

func (*Store) GetReviewByPK

func (s *Store) GetReviewByPK(ctx context.Context, pk int64) (*ReviewRow, error)

GetReviewByPK resolves a review by primary key.

func (*Store) GetReviewComment

func (s *Store) GetReviewComment(ctx context.Context, dbID int64) (*ReviewCommentRow, error)

GetReviewComment resolves an inline comment by its public database id.

func (*Store) GetReviewCommentByPK

func (s *Store) GetReviewCommentByPK(ctx context.Context, pk int64) (*ReviewCommentRow, error)

GetReviewCommentByPK resolves an inline comment by primary key.

func (*Store) GetWebhookByPK

func (s *Store) GetWebhookByPK(ctx context.Context, pk int64) (*WebhookRow, error)

GetWebhookByPK resolves a webhook by primary key.

func (*Store) GetWebhookForRepo

func (s *Store) GetWebhookForRepo(ctx context.Context, repoPK, dbID int64) (*WebhookRow, error)

GetWebhookForRepo resolves a webhook by its public id scoped to its repository, the lookup the REST CRUD endpoints use so a hook id from one repository never addresses another's.

func (*Store) InsertCheckRun

func (s *Store) InsertCheckRun(ctx context.Context, r *CheckRunRow) error

InsertCheckRun writes a check run with a freshly allocated db_id.

func (*Store) InsertComment

func (s *Store) InsertComment(ctx context.Context, c *CommentRow) error

InsertComment writes a comment and bumps the issue's cached comment count in one transaction, filling the server-assigned fields back onto c.

func (*Store) InsertCommitStatus

func (s *Store) InsertCommitStatus(ctx context.Context, st *CommitStatusRow) error

InsertCommitStatus appends a status report for a sha under a context. Each report is its own row; the latest per context wins when combining, matching GitHub's append-and-supersede model.

func (*Store) InsertDelivery

func (s *Store) InsertDelivery(ctx context.Context, d *WebhookDeliveryRow) error

InsertDelivery records the result of one POST with a freshly allocated db_id, filling the server-assigned fields back onto d.

func (*Store) InsertDeviceCode

func (s *Store) InsertDeviceCode(ctx context.Context, d *DeviceCodeRow) error

InsertDeviceCode opens a new device-flow row in the pending state.

func (*Store) InsertEvent

func (s *Store) InsertEvent(ctx context.Context, e *EventRow) error

InsertEvent appends one event row with a freshly allocated db_id, filling the server-assigned fields back onto e. It opens its own transaction because the caller records the event after its own mutation has committed.

func (*Store) InsertEventAndJob added in v0.1.1

func (s *Store) InsertEventAndJob(ctx context.Context, e *EventRow, jobKind string, buildPayload func(eventPK int64) string) error

InsertEventAndJob appends an event row and enqueues a background job in one transaction, halving the write-transaction count for a triggered write (the three-transaction sequence of mutation / event / job becomes two). buildPayload is called after the event INSERT so it can embed the event's assigned PK; the job uses no dedupe key. On failure the event and job both roll back together.

func (*Store) InsertLabel

func (s *Store) InsertLabel(ctx context.Context, l *LabelRow) error

InsertLabel writes a label and fills the server-assigned fields back onto l.

func (*Store) InsertMilestone

func (s *Store) InsertMilestone(ctx context.Context, m *MilestoneRow) error

InsertMilestone allocates the per-repo milestone number and the global db_id in one transaction with the row insert.

func (*Store) InsertOAuthApp

func (s *Store) InsertOAuthApp(ctx context.Context, a *OAuthAppRow) error

InsertOAuthApp registers an OAuth/GitHub-App client. The installer seeds the first-party gh client this way; tests use it to set up a device-flow app.

func (*Store) InsertReaction

func (s *Store) InsertReaction(ctx context.Context, r *ReactionRow) (created bool, err error)

InsertReaction adds a reaction, returning created=false when the user already reacted with that content on that subject (GitHub responds 200 with the existing reaction rather than creating a duplicate). The unique index backstops a race.

func (*Store) InsertRepo

func (s *Store) InsertRepo(ctx context.Context, r *RepoRow) error

InsertRepo allocates the shared db_id, writes the row, and fills the server-assigned fields back onto r. The feature and state flags are left to their column defaults (GitHub turns issues, projects, wiki, and downloads on at creation; archived, disabled, and is_template start off) and read back via RETURNING, so a freshly inserted RepoRow reflects exactly what is stored. A repository-settings update path arrives with its milestone.

func (*Store) InsertToken

func (s *Store) InsertToken(ctx context.Context, t *TokenRow) error

InsertToken writes a new credential and fills PK and CreatedAt back onto t.

func (*Store) InsertUser

func (s *Store) InsertUser(ctx context.Context, u *UserRow) error

InsertUser allocates the shared db_id, writes the row, and fills the server-assigned fields (PK, DBID, CreatedAt, UpdatedAt) back onto u.

func (*Store) InsertWebhook

func (s *Store) InsertWebhook(ctx context.Context, w *WebhookRow) error

InsertWebhook writes a webhook row with a freshly allocated db_id, filling the server-assigned fields back onto w.

func (*Store) Install added in v0.1.2

func (s *Store) Install(ctx context.Context) error

Install provisions a fresh database from the consolidated schema file rather than replaying the incremental migrations one by one. It applies schema.<dialect>.sql in a single transaction, then stamps schema_migrations with every known version and its checksum so a subsequent Migrate sees the database as fully up to date and does nothing.

Install refuses to run on a database that already carries applied migrations: it is a fresh-install fast path, not a substitute for Migrate on an existing database. Callers that are unsure should call Migrate, which is always safe.

func (*Store) IsAssigned

func (s *Store) IsAssigned(ctx context.Context, issuePK, userPK int64) (bool, error)

IsAssigned reports whether a user is currently assigned to an issue.

func (*Store) IssuesByPKs added in v0.1.1

func (s *Store) IssuesByPKs(ctx context.Context, pks []int64) (map[int64]*IssueRow, error)

IssuesByPKs loads issues by primary key in one round trip. PKs with no live row are silently absent from the returned map.

func (*Store) LabelsByIssue

func (s *Store) LabelsByIssue(ctx context.Context, issuePK int64) ([]LabelRow, error)

LabelsByIssue returns the labels attached to one issue, in name order.

func (*Store) LabelsByIssuePKs added in v0.1.1

func (s *Store) LabelsByIssuePKs(ctx context.Context, issuePKs []int64) (map[int64][]LabelRow, error)

LabelsByIssuePKs loads all labels for the given issue PKs in one query. Returns a map from issue_pk to the ordered slice of labels for that issue.

func (*Store) LabelsByNames

func (s *Store) LabelsByNames(ctx context.Context, repoPK int64, names []string) ([]LabelRow, error)

LabelsByNames resolves the named labels within a repository, skipping any that do not exist. The result preserves the order the names were given so the caller can render labels in request order.

func (*Store) ListActiveWebhooks

func (s *Store) ListActiveWebhooks(ctx context.Context, repoPK int64) ([]WebhookRow, error)

ListActiveWebhooks returns a repository's active webhooks, the candidate set the fan-out worker filters by subscribed event.

func (*Store) ListAssigneePKs

func (s *Store) ListAssigneePKs(ctx context.Context, issuePK int64) ([]int64, error)

ListAssigneePKs returns the user primary keys assigned to an issue, in the order they were assigned (the position column). The presenter resolves these to user rows; keeping the join read here avoids loading whole user rows when a caller only needs the set.

func (*Store) ListCheckRunsForRef

func (s *Store) ListCheckRunsForRef(ctx context.Context, repoPK int64, headSHA string) ([]CheckRunRow, error)

ListCheckRunsForRef returns every check run reported against a head sha, the list the rollup folds and the check-runs endpoint pages.

func (*Store) ListCheckRunsForSuite

func (s *Store) ListCheckRunsForSuite(ctx context.Context, suitePK int64) ([]CheckRunRow, error)

ListCheckRunsForSuite returns the runs inside one suite.

func (*Store) ListCheckRunsForSuites added in v0.1.1

func (s *Store) ListCheckRunsForSuites(ctx context.Context, suitePKs []int64) (map[int64][]CheckRunRow, error)

ListCheckRunsForSuites loads all check runs for any of the given suite PKs in one query. Returns a map from suite_pk to its ordered slice of check runs.

func (*Store) ListCheckSuites

func (s *Store) ListCheckSuites(ctx context.Context, repoPK int64, headSHA string) ([]CheckSuiteRow, error)

ListCheckSuites returns every suite reported against a head sha.

func (*Store) ListCommitStatuses

func (s *Store) ListCommitStatuses(ctx context.Context, repoPK int64, sha string) ([]CommitStatusRow, error)

ListCommitStatuses returns every status reported for a sha, newest first, the raw list the statuses endpoint pages and the combined-state algorithm folds.

func (*Store) ListDeliveries

func (s *Store) ListDeliveries(ctx context.Context, webhookPK int64, limit int) ([]WebhookDeliveryRow, error)

ListDeliveries returns a webhook's recent deliveries, newest first.

func (*Store) ListEvents

func (s *Store) ListEvents(ctx context.Context, f EventFilter) ([]EventRow, error)

ListEvents returns the activity feed matching f, newest first. It joins the owning repository so the public filter reads the live visibility rather than only the flag frozen on the event at insert time.

func (*Store) ListIssueComments

func (s *Store) ListIssueComments(ctx context.Context, issuePK int64, limit, offset int) ([]CommentRow, error)

ListIssueComments returns an issue's comments in chronological order, one page at a time. A limit of zero returns the default page of 30.

func (*Store) ListIssueEvents

func (s *Store) ListIssueEvents(ctx context.Context, issuePK int64) ([]IssueEventRow, error)

ListIssueEvents returns an issue's timeline in chronological order.

func (*Store) ListIssues

func (s *Store) ListIssues(ctx context.Context, repoPK int64, f IssueFilter) ([]IssueRow, error)

ListIssues returns a repository's issues matching the filter, one page at a time. When the filter carries a Cursor and the sort is "created" (default), the query is a keyset seek instead of OFFSET, so deep pages are O(1) in page depth rather than O(page*per_page).

func (*Store) ListIssuesPage added in v0.1.2

func (s *Store) ListIssuesPage(ctx context.Context, repoPK int64, f IssueFilter) ([]IssueRow, bool, error)

ListIssuesPage serves a keyset-paginated issue page and reports whether a further page exists, without a COUNT. It fetches one row beyond the page and uses its presence as the has-next signal, so a list request on a several-hundred-thousand-issue repo costs the page, not a full count plus a deep OFFSET scan. The filter must be keysetEligible; callers check that the cursor decoded before routing here.

func (*Store) ListJobs

func (s *Store) ListJobs(ctx context.Context) ([]JobRow, error)

ListJobs returns every job ordered by primary key. It backs tests and the worker's startup recovery scan; the per-kind claim path lands with the worker milestone.

func (*Store) ListLabels

func (s *Store) ListLabels(ctx context.Context, repoPK int64) ([]LabelRow, error)

ListLabels returns a repository's labels in name order.

func (*Store) ListMilestones

func (s *Store) ListMilestones(ctx context.Context, repoPK int64, state string) ([]MilestoneRow, error)

ListMilestones returns a repository's milestones filtered by state ("open"|"closed"|"all"), ordered by number.

func (*Store) ListPulls

func (s *Store) ListPulls(ctx context.Context, repoPK int64, state string, limit, offset int) ([]PullRow, error)

ListPulls returns a repository's pull requests, newest number first, paged. state is "open", "closed", or "all"; the empty string lists open ones. It joins the issues table so the state filter and the number ordering read from the row that owns them.

func (*Store) ListPullsPage added in v0.1.2

func (s *Store) ListPullsPage(ctx context.Context, repoPK int64, state string, cursor *PullCursor, limit int) ([]PullRow, bool, error)

ListPullsPage serves a keyset-paginated pull-request page and reports whether a further page exists, without a COUNT. The list orders by number descending, so a cursor seeks number < cursor.Number, served by the (repo_pk, number) unique index in one step regardless of page depth. It fetches one row beyond the page and uses its presence as the has-next signal, so a list request on a repo with hundreds of thousands of pulls costs the page, not a full count plus a deep OFFSET scan. A nil cursor starts from the highest number.

func (*Store) ListReactions

func (s *Store) ListReactions(ctx context.Context, subjectType string, subjectPK int64) ([]ReactionRow, error)

ListReactions returns every reaction on a subject, oldest first.

func (*Store) ListReviewComments

func (s *Store) ListReviewComments(ctx context.Context, pullPK int64) ([]ReviewCommentRow, error)

ListReviewComments returns every inline comment on a pull request, oldest first, the set the thread grouping in the GraphQL layer folds into threads.

func (*Store) ListReviewCommentsForReview

func (s *Store) ListReviewCommentsForReview(ctx context.Context, reviewPK int64) ([]ReviewCommentRow, error)

ListReviewCommentsForReview returns the inline comments a single review owns.

func (*Store) ListReviews

func (s *Store) ListReviews(ctx context.Context, pullPK int64) ([]ReviewRow, error)

ListReviews returns a pull request's submitted reviews in chronological order. Pending drafts are excluded: they are private to their author until submitted.

func (*Store) ListWebhooks

func (s *Store) ListWebhooks(ctx context.Context, repoPK int64) ([]WebhookRow, error)

ListWebhooks returns a repository's webhooks, oldest first.

func (*Store) Migrate

func (s *Store) Migrate(ctx context.Context) error

Migrate applies every pending up migration in version order. It is safe to run on every boot: already-applied migrations are skipped, and a checksum mismatch on a previously-applied version is reported rather than silently re-run.

func (*Store) MilestoneIssueCounts

func (s *Store) MilestoneIssueCounts(ctx context.Context, milestonePK int64) (open, closed int, err error)

MilestoneIssueCounts returns the open and closed issue counts for a milestone, computed from the issues that point at it.

func (*Store) MilestonesByPKs added in v0.1.1

func (s *Store) MilestonesByPKs(ctx context.Context, pks []int64) (map[int64]*MilestoneRow, error)

MilestonesByPKs loads milestones by primary key in one round trip. PKs with no matching row are silently absent from the returned map.

func (*Store) OAuthAppByClientID

func (s *Store) OAuthAppByClientID(ctx context.Context, clientID string) (*OAuthAppRow, error)

OAuthAppByClientID loads an OAuth app by its public client_id.

func (*Store) OpenPullsByBaseRef

func (s *Store) OpenPullsByBaseRef(ctx context.Context, repoPK int64, baseRef string) ([]PullRow, error)

OpenPullsByBaseRef returns the open pull requests in a repository that target the given base branch, the set whose behind count and mergeability the post-receive sink re-checks when that branch moves.

func (*Store) OpenPullsByHeadRef

func (s *Store) OpenPullsByHeadRef(ctx context.Context, repoPK int64, headRef string) ([]PullRow, error)

OpenPullsByHeadRef returns the open pull requests in a repository whose head branch is the given short ref name, the set the post-receive sink refreshes and re-checks when that branch moves.

func (*Store) OpenPullsByHeadSHA

func (s *Store) OpenPullsByHeadSHA(ctx context.Context, repoPK int64, headSHA string) ([]PullRow, error)

OpenPullsByHeadSHA returns the open pull requests in a repository whose head currently points at the given sha, the set a status or check report against that sha refreshes the rollup of.

func (*Store) PendingReviewFor

func (s *Store) PendingReviewFor(ctx context.Context, pullPK, userPK int64) (*ReviewRow, error)

PendingReviewFor returns the user's open pending review on a pull request, or ErrNotFound when they hold none. It enforces the one-pending-draft rule the service checks before opening a new draft.

func (*Store) Ping

func (s *Store) Ping(ctx context.Context) error

Ping verifies the database is reachable.

func (*Store) PullNumberByPK

func (s *Store) PullNumberByPK(ctx context.Context, pullPK int64) (int64, error)

PullNumberByPK resolves the issue number that backs a pull request, addressed by the pull extension's pk. The standalone review-comment lookup needs it to build the comment's pull request urls without the number in the request path.

func (*Store) ReactionRollupFor

func (s *Store) ReactionRollupFor(ctx context.Context, subjectType string, subjectPK int64) (ReactionRollup, error)

ReactionRollupFor returns the reaction counts for a subject keyed by content.

func (*Store) ReactionRollupsBySubjectPKs added in v0.1.1

func (s *Store) ReactionRollupsBySubjectPKs(ctx context.Context, subjectType string, subjectPKs []int64) (map[int64]ReactionRollup, error)

ReactionRollupsBySubjectPKs loads reaction counts for multiple subjects of the same type in one query. Returns a map from subject_pk to its rollup.

func (*Store) RecomputeIssueCommentCounts added in v0.1.2

func (s *Store) RecomputeIssueCommentCounts(ctx context.Context, repoPK int64) error

RecomputeIssueCommentCounts rebuilds issues.comments_count from the live issue_comments rows, so the denormalized counter the dataset shipped is replaced by one the corpus is internally consistent with.

func (*Store) RepoByDBID

func (s *Store) RepoByDBID(ctx context.Context, dbID int64) (*RepoRow, error)

RepoByDBID loads a repository by its public database id.

func (*Store) RepoByOwnerName

func (s *Store) RepoByOwnerName(ctx context.Context, owner, name string) (*RepoRow, error)

RepoByOwnerName resolves a repository by its owner login (case-insensitively, matching GitHub's case-preserving account and repo names) and repo name. It returns ErrNotFound when no live row matches.

func (*Store) RepoByPK

func (s *Store) RepoByPK(ctx context.Context, pk int64) (*RepoRow, error)

RepoByPK loads a repository by primary key.

func (*Store) Rollback

func (s *Store) Rollback(ctx context.Context, n int) error

Rollback reverts the last n applied migrations, most recent first. A zero or negative n is treated as 1.

func (*Store) SearchIssues

func (s *Store) SearchIssues(ctx context.Context, q IssueSearch) ([]IssueRow, error)

SearchIssues returns the page of issues and pull requests matching the query, joined across every repository the viewer may see.

func (*Store) SearchRepositories

func (s *Store) SearchRepositories(ctx context.Context, q RepoSearch) ([]RepoRow, error)

SearchRepositories returns the page of repositories matching the query.

func (*Store) SetCheckSuiteState

func (s *Store) SetCheckSuiteState(ctx context.Context, pk int64, status string, conclusion *string) error

SetCheckSuiteState rolls a suite's status and conclusion forward, the summary the recompute derives from the suite's runs.

func (*Store) SetDeviceInterval

func (s *Store) SetDeviceInterval(ctx context.Context, pk int64, interval int) error

SetDeviceInterval bumps the stored poll interval used to enforce slow_down.

func (*Store) SetDevicePolled

func (s *Store) SetDevicePolled(ctx context.Context, pk int64, at time.Time) error

SetDevicePolled records the most recent poll time for slow_down enforcement.

func (*Store) SetDeviceState

func (s *Store) SetDeviceState(ctx context.Context, pk int64, state string, userPK int64) error

SetDeviceState moves a device-flow row to approved or denied. userPK is the approving user; pass 0 on denial to leave user_pk NULL.

func (*Store) SetEventPayload

func (s *Store) SetEventPayload(ctx context.Context, pk int64, payload string) error

SetEventPayload stores the rendered Events-API document on an event row, the body the feed serves once the fan-out worker has built it.

func (*Store) SetMergeability

func (s *Store) SetMergeability(ctx context.Context, issuePK int64, mergeable *bool, state string, rebaseable *bool, additions, deletions, changedFiles, commits int, checkedAt time.Time) error

SetMergeability writes the derived merge state the worker computed: the tri-state mergeable, the mergeable_state string, the rebaseable flag, the diff stats, and the staleness stamp. A nil mergeable writes SQL NULL, the not-yet-computed value the read path surfaces as UNKNOWN.

func (*Store) SetNextIssueNumber added in v0.1.2

func (s *Store) SetNextIssueNumber(ctx context.Context, repoPK, next int64) error

SetNextIssueNumber moves a repository's number allocator past the highest seeded number so the first live issue created after a seed does not collide with a preserved corpus number.

func (*Store) SetThreadResolved

func (s *Store) SetThreadResolved(ctx context.Context, rootPK int64, resolved bool, resolverPK *int64) error

SetThreadResolved resolves or unresolves the thread a comment roots: every comment sharing its root (itself or its in_reply_to chain head) flips together. resolverPK is recorded on resolve and cleared on unresolve.

func (*Store) SetWebhookLastResponse

func (s *Store) SetWebhookLastResponse(ctx context.Context, pk int64, summary string) error

SetWebhookLastResponse records the JSON summary of the most recent delivery on the hook, the last_response the API surfaces.

func (*Store) TokenByHash

func (s *Store) TokenByHash(ctx context.Context, hash []byte) (*TokenRow, error)

TokenByHash loads the token whose stored sha256 equals hash. The caller has already hashed the presented secret; the unique index on token_hash makes this a point lookup. Returns ErrNotFound when no row matches.

func (*Store) TouchRepoPushedAt

func (s *Store) TouchRepoPushedAt(ctx context.Context, pk int64, at time.Time) error

TouchRepoPushedAt advances pushed_at (and updated_at) to at, which the post-receive sink calls after a push so the pushed_at field and the pushed-sort order reflect the push. The time is stored in UTC to match how every other timestamp round-trips through the scanner.

func (*Store) UpdateCheckRun

func (s *Store) UpdateCheckRun(ctx context.Context, r *CheckRunRow) error

UpdateCheckRun rewrites a run's mutable fields, the transition a re-report or a run finishing performs.

func (*Store) UpdateComment

func (s *Store) UpdateComment(ctx context.Context, c *CommentRow) error

UpdateComment changes a comment's body and stamps updated_at.

func (*Store) UpdateLabel

func (s *Store) UpdateLabel(ctx context.Context, l *LabelRow) error

UpdateLabel changes a label's name, color, and description, returning the updated row.

func (*Store) UpdateMilestone

func (s *Store) UpdateMilestone(ctx context.Context, m *MilestoneRow) error

UpdateMilestone writes the editable fields and the close transition (state flipping to closed stamps closed_at; reopening clears it).

func (*Store) UpdateReviewCommentBody

func (s *Store) UpdateReviewCommentBody(ctx context.Context, pk int64, body string) error

UpdateReviewCommentBody changes an inline comment's body and stamps updated_at.

func (*Store) UpdateWebhook

func (s *Store) UpdateWebhook(ctx context.Context, w *WebhookRow) error

UpdateWebhook writes the editable fields of an existing webhook and stamps updated_at. The service loads the row, applies the patch, and calls this.

func (*Store) UpsertPullCheckState

func (s *Store) UpsertPullCheckState(ctx context.Context, pullPK int64, decision *string, rollup string, at time.Time) error

UpsertPullCheckState writes a pull request's derived review decision and rollup state, the snapshot the recompute worker refreshes on review and status change.

func (*Store) UserByLogin

func (s *Store) UserByLogin(ctx context.Context, login string) (*UserRow, error)

UserByLogin loads a user by login, case-insensitively, matching GitHub's case-preserving but case-insensitive account names.

func (*Store) UserByPK

func (s *Store) UserByPK(ctx context.Context, pk int64) (*UserRow, error)

UserByPK loads a user by primary key. It returns ErrNotFound when no live row matches.

func (*Store) UsersByPKs added in v0.1.1

func (s *Store) UsersByPKs(ctx context.Context, pks []int64) (map[int64]*UserRow, error)

UsersByPKs loads users by primary key in one round trip. PKs that have no live row are silently absent from the returned map.

func (*Store) Version

func (s *Store) Version(ctx context.Context) (int64, error)

Version reports the highest applied migration version, or 0 when none have been applied.

func (*Store) VisibleRepoPKs

func (s *Store) VisibleRepoPKs(ctx context.Context, viewerPK int64, ownerPKs []int64) ([]int64, error)

VisibleRepoPKs lists the internal pks of every repository the viewer may see among the given owners, deleted rows excluded. Code search uses it to scope a git tree walk to the repositories a user:/org: qualifier selects. An empty owners slice lists every visible repository.

func (*Store) WithTx

func (s *Store) WithTx(ctx context.Context, fn func(*Tx) error) error

WithTx runs fn inside a single transaction, committing when fn returns nil and rolling back on any error or panic. The issue service uses it so allocating a number, inserting the issue, attaching labels and assignees, and writing the timeline rows are one atomic unit.

type TokenRow

type TokenRow struct {
	PK          int64
	UserPK      *int64
	OAuthAppPK  *int64
	TokenHash   []byte
	TokenPrefix string
	LastEight   string
	Kind        string // pat | oauth
	Scopes      string // comma-space header form, the X-OAuth-Scopes value
	Note        string
	ExpiresAt   *time.Time
	RevokedAt   *time.Time
	LastUsedAt  *time.Time
	CreatedAt   time.Time
}

TokenRow is a row of the tokens table. UserPK and OAuthAppPK are nullable because installation and app credentials (later milestones) have no user, and PATs have no granting OAuth app.

type Tx

type Tx struct {
	// contains filtered or unexported fields
}

Tx is a transaction-scoped handle the multi-statement writes run through, so a mutation and the timeline and counter updates it implies all commit together or not at all. It exposes the same write methods the store does, bound to one *sql.Tx.

func (*Tx) AddAssignees

func (t *Tx) AddAssignees(ctx context.Context, issuePK int64, userPKs []int64) error

AddAssignees links the given users to the issue, preserving request order in the position column and ignoring users already assigned.

func (*Tx) AdjustOpenIssuesCount

func (t *Tx) AdjustOpenIssuesCount(ctx context.Context, repoPK int64, delta int) error

AdjustOpenIssuesCount bumps the repositories.open_issues_count cache when an issue opens or closes so the repository view need not aggregate on read.

func (*Tx) AllocIssueNumber

func (t *Tx) AllocIssueNumber(ctx context.Context, repoPK int64) (int64, error)

AllocIssueNumber atomically hands out the next per-repo issue/PR number from the shared counter, so an issue and a pull request never collide.

func (*Tx) AttachLabels

func (t *Tx) AttachLabels(ctx context.Context, issuePK int64, labelPKs []int64) error

AttachLabels links the given labels to the issue, ignoring any already linked.

func (*Tx) BumpCommentsCount

func (t *Tx) BumpCommentsCount(ctx context.Context, issuePK int64, delta int) error

BumpCommentsCount adjusts an issue's cached comment count and advances its updated_at, so the issue view need not aggregate comments on read.

func (*Tx) DetachLabel

func (t *Tx) DetachLabel(ctx context.Context, issuePK, labelPK int64) error

DetachLabel removes one label from an issue.

func (*Tx) InsertComment

func (t *Tx) InsertComment(ctx context.Context, c *CommentRow) error

InsertComment is the transaction-scoped form, so a comment created as part of a larger unit of work shares its atomicity.

func (*Tx) InsertEvent

func (t *Tx) InsertEvent(ctx context.Context, e *EventRow) error

InsertEvent appends one event row inside an existing transaction.

func (*Tx) InsertIssue

func (t *Tx) InsertIssue(ctx context.Context, iss *IssueRow) error

InsertIssue writes the issue row with a freshly allocated db_id and the number the caller already allocated, filling the server-assigned fields back onto iss.

func (*Tx) InsertIssueEvent

func (t *Tx) InsertIssueEvent(ctx context.Context, e *IssueEventRow) error

InsertIssueEvent appends a timeline event (closed, reopened, labeled, ...) to an issue's history. Payload is a JSON document the event renderer decodes.

func (*Tx) InsertLabel

func (t *Tx) InsertLabel(ctx context.Context, l *LabelRow) error

InsertLabel writes a label inside a transaction, used to seed a repository's default label set as part of the repository-create unit of work.

func (*Tx) InsertPull

func (t *Tx) InsertPull(ctx context.Context, p *PullRow) error

InsertPull writes the pull request extension row with a freshly allocated db_id, filling the server-assigned fields back onto p. It runs inside the same transaction as the issue insert it extends, so a pull request and its issue row commit together.

func (*Tx) InsertReview

func (t *Tx) InsertReview(ctx context.Context, r *ReviewRow) error

InsertReview writes a review row with a freshly allocated db_id, filling the server-assigned fields back onto r.

func (*Tx) InsertReviewComment

func (t *Tx) InsertReviewComment(ctx context.Context, c *ReviewCommentRow) error

InsertReviewComment writes one inline comment with a freshly allocated db_id, filling the server-assigned fields back onto c.

func (*Tx) MarkMerged

func (t *Tx) MarkMerged(ctx context.Context, pullPK int64, mergerPK int64, mergeCommitSHA string, mergedAt time.Time) error

MarkMerged records a successful merge: the merged flag, the instant, the merger, and the merge commit sha. It runs in the same transaction as the issue close so a merged pull request is also a closed issue.

func (*Tx) RemoveAssignees

func (t *Tx) RemoveAssignees(ctx context.Context, issuePK int64, userPKs []int64) error

RemoveAssignees unlinks the given users from the issue.

func (*Tx) ReplaceAssignees

func (t *Tx) ReplaceAssignees(ctx context.Context, issuePK int64, userPKs []int64) error

ReplaceAssignees sets an issue's assignees to exactly the given set.

func (*Tx) ReplaceLabels

func (t *Tx) ReplaceLabels(ctx context.Context, issuePK int64, labelPKs []int64) error

ReplaceLabels sets an issue's labels to exactly the given set.

func (*Tx) SeedComment added in v0.1.2

func (t *Tx) SeedComment(ctx context.Context, c *CommentRow) error

SeedComment inserts one issue_comments row preserving its timestamps.

func (*Tx) SeedCommitStatus added in v0.1.2

func (t *Tx) SeedCommitStatus(ctx context.Context, st *CommitStatusRow) error

SeedCommitStatus inserts one commit_statuses row preserving its timestamps.

func (*Tx) SeedIssue added in v0.1.2

func (t *Tx) SeedIssue(ctx context.Context, iss *IssueRow) error

SeedIssue inserts one issues row with the per-repo number preserved from the corpus so URLs match real GitHub paths, all state fields and timestamps written verbatim. It fills PK and DBID. The table is shared by issues and pull requests; IsPull tells them apart.

func (*Tx) SeedIssueEvent added in v0.1.2

func (t *Tx) SeedIssueEvent(ctx context.Context, e *IssueEventRow) error

SeedIssueEvent inserts one issue_events timeline row preserving its created_at and the rendered payload, filling PK and DBID. This is the largest table in a real-world corpus, so the timeline and events-feed reads run against realistic volume.

func (*Tx) SeedIssueEventsBulk added in v0.1.2

func (t *Tx) SeedIssueEventsBulk(ctx context.Context, rows []IssueEventRow) error

SeedIssueEventsBulk inserts many issue_events rows in chunked multi-row INSERTs over one batch-allocated id range, preserving each row's created_at and rendered payload. The timeline is the largest table in an automation-heavy corpus, so this is the bulk path that makes seeding it feasible.

func (*Tx) SeedLabel added in v0.1.2

func (t *Tx) SeedLabel(ctx context.Context, l *LabelRow) error

SeedLabel inserts one labels row preserving its timestamps, filling PK and DBID. The caller dedupes labels per repository before calling.

func (*Tx) SeedMilestone added in v0.1.2

func (t *Tx) SeedMilestone(ctx context.Context, m *MilestoneRow) error

SeedMilestone inserts one milestones row with the number preserved from the corpus (not allocated), filling PK and DBID.

func (*Tx) SeedPull added in v0.1.2

func (t *Tx) SeedPull(ctx context.Context, p *PullRow) error

SeedPull inserts one pull_requests row joined to its issue, with the merge state and diff stats written verbatim. mergeable is left NULL (the not-yet-computed contract) unless the corpus carried a value.

func (*Tx) SeedReaction added in v0.1.2

func (t *Tx) SeedReaction(ctx context.Context, r *ReactionRow) error

SeedReaction inserts one reactions row preserving its created_at. The caller supplies the reactor user pk; the corpus carries counts, not per-user rows, so the seeder materializes them against a bounded reactor pool.

func (*Tx) SeedReactionsBulk added in v0.1.2

func (t *Tx) SeedReactionsBulk(ctx context.Context, rows []ReactionRow) error

SeedReactionsBulk inserts many reactions rows in chunked multi-row INSERTs over one batch-allocated id range, preserving each row's created_at. It is the bulk analog of SeedReaction for the seeder's materialized reactor-pool rows, which are the most numerous synthesized rows in a corpus.

func (*Tx) SeedRepo added in v0.1.2

func (t *Tx) SeedRepo(ctx context.Context, r *RepoRow) error

SeedRepo inserts one repositories row preserving its timestamps and pushed_at, filling PK and DBID back onto r. next_issue_number keeps its default; the caller sets it past the seeded numbers with SetNextIssueNumber once the issues are in.

func (*Tx) SeedReview added in v0.1.2

func (t *Tx) SeedReview(ctx context.Context, r *ReviewRow) error

SeedReview inserts one pull_request_reviews row preserving submitted_at and the timestamps.

func (*Tx) SeedReviewComment added in v0.1.2

func (t *Tx) SeedReviewComment(ctx context.Context, c *ReviewCommentRow) error

SeedReviewComment inserts one pull_request_review_comments row preserving the diff anchor and the reply linkage so threaded conversations reassemble.

func (*Tx) SeedUser added in v0.1.2

func (t *Tx) SeedUser(ctx context.Context, u *UserRow) error

SeedUser inserts one users row preserving its timestamps, filling PK and DBID back onto u. The profile columns keep their defaults; a corpus carries identity, not full profiles.

func (*Tx) SubmitReview

func (t *Tx) SubmitReview(ctx context.Context, pk int64, state, body, commitID string, submittedAt time.Time) error

SubmitReview stamps a pending review with its final state, body, and submit instant, the transition from draft to a review the pull request shows.

func (*Tx) TouchIssue

func (t *Tx) TouchIssue(ctx context.Context, issuePK int64) error

TouchIssue bumps an issue's updated_at without touching the optimistic lock, used when a related row (a comment, a reaction) changes and GitHub advances the issue's updated timestamp.

func (*Tx) UpdateIssue

func (t *Tx) UpdateIssue(ctx context.Context, iss *IssueRow) error

UpdateIssue writes the editable fields under an optimistic lock: the row is updated only if its lock_version still matches the one read, and lock_version is bumped. A no-row result means a concurrent writer moved first; the caller re-reads and retries. The close transition (state, closed_at, closed_by_pk, state_reason) is written here too.

func (*Tx) UpdatePullHead

func (t *Tx) UpdatePullHead(ctx context.Context, pullPK int64, headSHA string) error

UpdatePullHead repoints a pull request's head sha after a push to its head branch and clears the mergeability stamp so the next read treats the cached merge state as stale.

type UserRow

type UserRow struct {
	PK              int64
	DBID            int64
	Login           string
	Type            string
	Name            *string
	Email           *string
	SiteAdmin       bool
	Company         *string
	Blog            string
	Location        *string
	Bio             *string
	Hireable        *bool
	TwitterUsername *string
	PublicRepos     int
	PublicGists     int
	Followers       int
	Following       int
	CreatedAt       time.Time
	UpdatedAt       time.Time
}

UserRow is a row of the users table, including the profile columns 0002 adds.

type WebhookDeliveryRow

type WebhookDeliveryRow struct {
	PK              int64
	DBID            int64
	WebhookPK       int64
	GUID            string
	Event           string
	Action          string
	StatusCode      *int64
	RequestURL      string
	RequestHeaders  string
	RequestBody     string
	ResponseHeaders string
	ResponseBody    string
	DurationMS      int64
	Redelivery      bool
	Success         bool
	CreatedAt       time.Time
}

WebhookDeliveryRow is a row of the webhook_deliveries table: the recorded result of one POST to a webhook. StatusCode is nullable because a transport failure (connection refused, timeout) produces no HTTP status. Redelivery marks a delivery that replayed an earlier one; Success is the 2xx outcome.

type WebhookRow

type WebhookRow struct {
	PK           int64
	DBID         int64
	RepoPK       int64
	Name         string
	URL          string
	ContentType  string
	Secret       *string
	InsecureSSL  bool
	Active       bool
	Events       string
	LastResponse *string
	CreatedAt    time.Time
	UpdatedAt    time.Time
}

WebhookRow is a row of the webhooks table: a repository's registration of a URL to POST events to. Secret is nullable and held in the clear because HMAC signing needs the original bytes; the API always redacts it. Events is the JSON array of subscribed event names ("*" means all). LastResponse is the JSON summary of the most recent delivery, nil until the first POST.

Directories

Path Synopsis
Package migrations holds Githome's embedded SQL schema migrations and exposes them as a read-only filesystem for the store's migration runner.
Package migrations holds Githome's embedded SQL schema migrations and exposes them as a read-only filesystem for the store's migration runner.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL