59 lines
1.5 KiB
Go
59 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]]
|
||
|
|
}
|