Documentation
¶
Overview ¶
Package escalate finds database call sites that must become domain commands when a handle moves off-thread (plan item P3.15b).
Moving a database to a worker changes what a call site can be. An in-process Query returns a cursor over a live connection; an off-thread one cannot, because there is no connection on this side. Every call site has to become a command — a named operation the worker performs — and that is a design decision per site, not a mechanical rewrite.
So this is an ASSISTANT and explicitly NOT A CODEMOD, which the plan states outright. It finds the sites, says what each one appears to do, and proposes a signature. A human writes the body. The reason is not caution for its own sake: a rewrite that mechanically wrapped each Query in a command would produce one command per call site, which is a chatty protocol with the same round-trip problem the move was meant to solve. Deciding which sites collapse into one command is the actual work, and a tool cannot do it.
What the tool CAN do reliably is find every site and refuse to guess about the ones it cannot read.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Access ¶
type Access string
Access classifies what a call site does to the database.
const ( // AccessRead only reads. AccessRead Access = "read" // AccessWrite modifies data or schema. AccessWrite Access = "write" // AccessUnknown means the SQL could not be read at this call site — it is // built at runtime, or comes from a variable or a constant elsewhere. // // Reported as its own class rather than guessed at. A write misclassified as // a read becomes a command the caller believes is safe to retry, and the // whole point of classifying is to inform exactly that decision. AccessUnknown Access = "unknown" )
func ClassifySQL ¶
ClassifySQL reports whether a statement reads or writes.
Exported because it is useful on its own, and because it is the piece most worth testing directly: a write misclassified as a read becomes a command a caller believes is safe to retry.
type Finding ¶
type Finding struct {
// File and Line locate the call.
File string
Line int
// Method is the method called: Query, QueryRow, or Exec.
Method string
// Receiver is the expression the method was called on, as written.
Receiver string
// SQL is the literal statement, empty when it could not be read.
SQL string
// Access classifies the statement.
Access Access
// ArgCount is the number of bind parameters passed.
ArgCount int
// ProposedCommand is a suggested command name derived from the statement.
ProposedCommand string
// ProposedSignature is a suggested Go declaration for the command.
ProposedSignature string
// NeedsHuman marks a site the tool could not classify, so a reviewer knows
// which findings are information and which are questions.
NeedsHuman bool
// Note explains a NeedsHuman finding.
Note string
}
Finding is one call site that must become a command.
func AnalyzeSource ¶
func AnalyzeSource(parseFileName string, parseSource string, parseOptions Options) ([]Finding, error)
AnalyzeSource finds escalation sites in one Go source file.
Source text rather than a path so the analysis is testable without fixtures on disk and usable on unsaved buffers in an editor.
type Options ¶
type Options struct {
// Receivers restricts findings to calls on these receiver expressions, as
// written in the source — "db", "s.db", "app.store".
//
// Empty means every receiver, which is the honest default for a first pass:
// over-reporting is a reviewer's afternoon, and under-reporting is a call
// site that silently keeps blocking the render thread.
Receivers []string
}
Options configure an analysis.