github.com/authzed/spicedb@v1.32.1-0.20240520085336-ebda56537386/internal/datastore/mysql/migrations/manager.go (about) 1 package migrations 2 3 import ( 4 "database/sql" 5 "fmt" 6 "regexp" 7 8 "github.com/authzed/spicedb/pkg/migrate" 9 ) 10 11 const migrationNamePattern = `^[_a-zA-Z]*$` 12 13 var ( 14 noNonatomicMigration migrate.MigrationFunc[Wrapper] 15 noTxMigration migrate.TxMigrationFunc[TxWrapper] // nolint: deadcode, unused, varcheck 16 17 migrationNameRe = regexp.MustCompile(migrationNamePattern) 18 19 // Manager is the singleton migration manager instance for MySQL 20 Manager = migrate.NewManager[*MySQLDriver, Wrapper, TxWrapper]() 21 ) 22 23 // Wrapper makes it possible to forward the table schema needed for MySQL MigrationFunc to run 24 type Wrapper struct { 25 db *sql.DB 26 tables *tables 27 } 28 29 // TxWrapper makes it possible to forward the table schema to a transactional migration func. 30 type TxWrapper struct { 31 tx *sql.Tx 32 tables *tables 33 } 34 35 func mustRegisterMigration(version, replaces string, up migrate.MigrationFunc[Wrapper], upTx migrate.TxMigrationFunc[TxWrapper]) { 36 if err := registerMigration(version, replaces, up, upTx); err != nil { 37 panic("failed to register migration " + err.Error()) 38 } 39 } 40 41 func registerMigration(version, replaces string, up migrate.MigrationFunc[Wrapper], upTx migrate.TxMigrationFunc[TxWrapper]) error { 42 // validate migration names to ensure they are compatible with mysql column names 43 for _, v := range []string{version, replaces} { 44 if match := migrationNameRe.MatchString(version); !match { 45 return fmt.Errorf("migration from '%s' to '%s': '%s' is an invalid mysql migration version, expected to match pattern '%s'", 46 replaces, version, v, migrationNamePattern, 47 ) 48 } 49 } 50 51 // register the migration 52 return Manager.Register(version, replaces, up, upTx) 53 }