package mysql import ( "errors" "fmt" "gorm.io/gorm" "zestack.dev/env" ) func PublicDatabase() string { return env.String("DB_NAME") } func TenantBasename() string { return env.String("TENANT_BASENAME", "tenant_") } func TenantDatabase(tenant uint) string { if tenant == 0 { return PublicDatabase() } return fmt.Sprintf("%s%d", TenantBasename(), tenant) } func UseDatabase(tx *gorm.DB, database string) (reset func() error, err error) { if database == "" { err = errors.New("database name is empty") tx.AddError(err) return } if database == CurrentDatabase(tx) { reset = func() error { return nil } return } sql := "USE " + tx.Statement.Quote(database) if execErr := tx.Exec(sql).Error; execErr != nil { err = fmt.Errorf("failed to set database %q: %w", database, execErr) tx.AddError(err) return } reset = func() error { publicDatabase := PublicDatabase() if database == publicDatabase { return nil } return tx.Exec("USE " + tx.Statement.Quote(publicDatabase)).Error } return } func CurrentDatabase(tx *gorm.DB) string { var database string tx.Raw("SELECT DATABASE()").Row().Scan(&database) return database }