Documentation
¶
Overview ¶
Package diffplan is the declarative front door as a library: a parsed desired-state schema in, the routed convergence plan out. The CLI's diff command and orchestrators embedding pg-sprite share this one pipeline, so a stored report means the same thing no matter which caller produced it.
Callers own the boundary concerns: parse the desired file through statement.ParseDesired (refusals surface at the caller) and build the connection through dbconn.NewPool. Plan never writes the live table, but it is not read-only either — desired state is realized by execute-and-introspect on a rolled-back scratch schema, so the connection requirements on Plan apply.
Before a v1 module tag the Go API carries no compatibility promise: the JSON plan.Report is the stability boundary, the Go API follows at v1 (see docs/architecture.md).
Example (Plan) ¶
Example_plan is the full library flow an orchestrator embeds: parse the desired-state schema, connect, and derive the routed convergence plan. It is compile-checked but not executed — Plan needs a live PostgreSQL database.
package main
import (
"context"
"fmt"
"log"
"github.com/block/pg-sprite/pkg/dbconn"
"github.com/block/pg-sprite/pkg/diffplan"
"github.com/block/pg-sprite/pkg/statement"
)
func main() {
ctx := context.Background()
// Parse refusals (inadmissible desired files) surface here, at the
// boundary where the embedder can render them.
ds, err := statement.ParseDesired(
"CREATE TABLE events (id bigint PRIMARY KEY, name varchar(50) NOT NULL);\n" +
"CREATE INDEX events_name_idx ON events (name);")
if err != nil {
log.Print(err)
return
}
// Plan is not read-only: the desired DDL runs in an always-rolled-back
// scratch schema, so connect read-write (not a hot standby) as a role
// with CREATE on the target database. The live table is never written.
pool, err := dbconn.NewPool(ctx, dbconn.Config{URL: "postgres://engine@localhost:5432/app"})
if err != nil {
log.Print(err)
return
}
defer pool.Close()
report, err := diffplan.Plan(ctx, pool, diffplan.Request{Schema: "public", Desired: ds})
if err != nil {
log.Print(err)
return
}
// Disposition says whether the whole plan can execute; each statement
// carries its route and the engine's canonical SQL rendering.
fmt.Println(report.Disposition)
for _, st := range report.Statements {
fmt.Println(st.Route, st.SQL)
}
}
Output:
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Plan ¶
Plan derives the ordered, classified, and routed convergence plan for the desired schema against the live database: introspect the live table, derive the changes (the full qualified desired schema when the table does not exist yet), classify each change with live-column facts, route the set, and stamp the report with the server version and fingerprint.
Plan needs more than a read-only connection: desired state is realized by executing the desired DDL in a scratch schema inside a transaction that is always rolled back, so the pool must connect read-write (not a hot standby) as a role with CREATE privilege on the target database. The live table is introspected only — never written. Plan does not close the pool; one pool serves any number of calls.
Types ¶
type Request ¶
type Request struct {
// Schema is the target schema the desired table lives in.
Schema string
// Desired is the parsed desired-state schema for the table.
Desired statement.DesiredSchema
}
Request names the inputs to Plan. Zero-value fields are invalid: the schema must be set, and the desired state must come from statement.ParseDesired — the zero DesiredSchema is refused.