Create Schema Manager and propagate contexts into the DB calls downstream. Add checks at controller startup and database init for correct schema version and schema migration dirty bit being set.
60 lines
1.5 KiB
Go
60 lines
1.5 KiB
Go
package schema
|
|
|
|
import (
|
|
"fmt"
|
|
"sort"
|
|
|
|
"github.com/hashicorp/boundary/internal/errors"
|
|
)
|
|
|
|
// statementProvider provides the migration statements in order.
|
|
// Next should be called prior to calling Version() or ReadUp() or sentinel
|
|
// values (-1 and nil) will be returned.
|
|
type statementProvider struct {
|
|
pos int
|
|
versions []int
|
|
up, down map[int][]byte
|
|
}
|
|
|
|
func newStatementProvider(dialect string, curVer int) (*statementProvider, error) {
|
|
op := errors.Op("schema.newStatementProvider")
|
|
qp := statementProvider{pos: -1}
|
|
qp.up, qp.down = getUpMigration(dialect), getDownMigration(dialect)
|
|
if len(qp.up) != len(qp.down) {
|
|
return nil, errors.New(errors.MigrationIntegrity, op, fmt.Sprintf("Mismatch up/down size: up %d vs. down %d", len(qp.up), len(qp.down)))
|
|
}
|
|
for k := range qp.up {
|
|
if _, ok := qp.down[k]; !ok {
|
|
return nil, errors.New(errors.MigrationIntegrity, op, fmt.Sprintf("Up key %d doesn't exist in down %v", k, qp.down))
|
|
}
|
|
qp.versions = append(qp.versions, k)
|
|
}
|
|
sort.Ints(qp.versions)
|
|
|
|
for len(qp.versions) > 0 && qp.versions[0] <= curVer {
|
|
qp.versions = qp.versions[1:]
|
|
}
|
|
|
|
return &qp, nil
|
|
}
|
|
|
|
func (q *statementProvider) Next() bool {
|
|
q.pos++
|
|
return len(q.versions) > q.pos
|
|
}
|
|
|
|
func (q *statementProvider) Version() int {
|
|
if q.pos < 0 || q.pos >= len(q.versions) {
|
|
return -1
|
|
}
|
|
return q.versions[q.pos]
|
|
}
|
|
|
|
// ReadUp reads the current up migration
|
|
func (q *statementProvider) ReadUp() []byte {
|
|
if q.pos < 0 || q.pos >= len(q.versions) {
|
|
return nil
|
|
}
|
|
return q.up[q.versions[q.pos]]
|
|
}
|