store/schema_version.go
Rama main · réplica de lectura del repositorio original.
package store
import (
"cmp"
"regexp"
"strconv"
"strings"
"github.com/pkg/errors"
)
// Schema versions are legacy 0.MINOR.SEQUENCE or calendar YY.M.SEQUENCE.
// The sequence tracks database migrations, independently of release revisions.
// Calendar markers omit month padding so old binaries can reject downgrades
// using their SemVer comparator. Release tags and migration directories retain it.
var calendarMigrationSeriesPattern = regexp.MustCompile(`^[1-9][0-9]\.(0[1-9]|1[0-2])$`)
var migrationFilePattern = regexp.MustCompile(`^[0-9]+__[^/]+\.sql$`)
var schemaVersionPattern = regexp.MustCompile(`^(0\.(0|[1-9][0-9]*)|[1-9][0-9]\.([1-9]|1[0-2]))\.(0|[1-9][0-9]*)$`)
func parseSchemaVersion(value string) ([3]int, error) {
var result [3]int
if !schemaVersionPattern.MatchString(value) {
return result, errors.Errorf("invalid database schema version %q", value)
}
for i, part := range strings.Split(value, ".") {
number, err := strconv.Atoi(part)
if err != nil {
return result, errors.Wrapf(err, "invalid database schema version %q", value)
}
result[i] = number
}
return result, nil
}
// mustParseSchemaVersion is for versions the migrator itself produced or
// declared as constants; those are valid by construction.
func mustParseSchemaVersion(value string) [3]int {
parsed, err := parseSchemaVersion(value)
if err != nil {
panic(err)
}
return parsed
}
func compareParsedSchemaVersions(a, b [3]int) int {
for i := range a {
if order := cmp.Compare(a[i], b[i]); order != 0 {
return order
}
}
return 0
}
func compareSchemaVersions(a, b string) (int, error) {
left, err := parseSchemaVersion(a)
if err != nil {
return 0, err
}
right, err := parseSchemaVersion(b)
if err != nil {
return 0, err
}
return compareParsedSchemaVersions(left, right), nil
}