package inventory import ( "context" "errors" "github.com/jackc/pgx/v5" ) // What a controller build knows of the store's schema (novox/hq issue 352): the highest migration it // carries, recorded by its version when it serves, and the highest migration the store has applied. A // put-back of the controller to a build that reaches less than the store is refused (gate.go), because // such a controller starts behind its own records and judges with what it can read. // RecordSchemaReach keeps the highest migration the build serving now carries. func (i *Inventory) RecordSchemaReach(ctx context.Context, build string, reach int) error { if build == "" { return errors.New("a schema reach is recorded by a build's version, and this controller has none") } _, err := i.store.Pool().Exec(ctx, `insert into controller_schema (build, reach) values ($1, $2) on conflict (build) do update set reach = excluded.reach, recorded = now()`, build, reach) return err } // SchemaReachOf is the highest migration a build carries, as it recorded when it served; false for a // build that never did. func (i *Inventory) SchemaReachOf(ctx context.Context, build string) (int, bool, error) { var reach int err := i.store.Pool().QueryRow(ctx, `select reach from controller_schema where build = $1`, build).Scan(&reach) if errors.Is(err, pgx.ErrNoRows) { return 0, false, nil } return reach, err == nil, err } // SchemaApplied is the highest migration the store has applied. func (i *Inventory) SchemaApplied(ctx context.Context) (int, error) { var n *int if err := i.store.Pool().QueryRow(ctx, `select max(number) from migration`).Scan(&n); err != nil { return 0, err } if n == nil { return 0, nil } return *n, nil }