github.com/scraniel/migrate@v0.0.0-20230320185700-339088f36cee/database/util.go (about) 1 package database 2 3 import ( 4 "fmt" 5 "go.uber.org/atomic" 6 "hash/crc32" 7 "strings" 8 ) 9 10 const advisoryLockIDSalt uint = 1486364155 11 12 // GenerateAdvisoryLockId inspired by rails migrations, see https://goo.gl/8o9bCT 13 func GenerateAdvisoryLockId(databaseName string, additionalNames ...string) (string, error) { // nolint: golint 14 if len(additionalNames) > 0 { 15 databaseName = strings.Join(append(additionalNames, databaseName), "\x00") 16 } 17 sum := crc32.ChecksumIEEE([]byte(databaseName)) 18 sum = sum * uint32(advisoryLockIDSalt) 19 return fmt.Sprint(sum), nil 20 } 21 22 // CasRestoreOnErr CAS wrapper to automatically restore the lock state on error 23 func CasRestoreOnErr(lock *atomic.Bool, o, n bool, casErr error, f func() error) error { 24 if !lock.CAS(o, n) { 25 return casErr 26 } 27 if err := f(); err != nil { 28 // Automatically unlock/lock on error 29 lock.Store(o) 30 return err 31 } 32 return nil 33 }