constraint.go 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. package schema
  2. import (
  3. "regexp"
  4. "strings"
  5. "gorm.io/gorm/clause"
  6. )
  7. // reg match english letters and midline
  8. var regEnLetterAndMidline = regexp.MustCompile(`^[\w-]+$`)
  9. type CheckConstraint struct {
  10. Name string
  11. Constraint string // length(phone) >= 10
  12. *Field
  13. }
  14. func (chk *CheckConstraint) GetName() string { return chk.Name }
  15. func (chk *CheckConstraint) Build() (sql string, vars []interface{}) {
  16. return "CONSTRAINT ? CHECK (?)", []interface{}{clause.Column{Name: chk.Name}, clause.Expr{SQL: chk.Constraint}}
  17. }
  18. // ParseCheckConstraints parse schema check constraints
  19. func (schema *Schema) ParseCheckConstraints() map[string]CheckConstraint {
  20. checks := map[string]CheckConstraint{}
  21. for _, field := range schema.FieldsByDBName {
  22. if chk := field.TagSettings["CHECK"]; chk != "" {
  23. names := strings.Split(chk, ",")
  24. if len(names) > 1 && regEnLetterAndMidline.MatchString(names[0]) {
  25. checks[names[0]] = CheckConstraint{Name: names[0], Constraint: strings.Join(names[1:], ","), Field: field}
  26. } else {
  27. if names[0] == "" {
  28. chk = strings.Join(names[1:], ",")
  29. }
  30. name := schema.namer.CheckerName(schema.Table, field.DBName)
  31. checks[name] = CheckConstraint{Name: name, Constraint: chk, Field: field}
  32. }
  33. }
  34. }
  35. return checks
  36. }
  37. type UniqueConstraint struct {
  38. Name string
  39. Field *Field
  40. }
  41. func (uni *UniqueConstraint) GetName() string { return uni.Name }
  42. func (uni *UniqueConstraint) Build() (sql string, vars []interface{}) {
  43. return "CONSTRAINT ? UNIQUE (?)", []interface{}{clause.Column{Name: uni.Name}, clause.Column{Name: uni.Field.DBName}}
  44. }
  45. // ParseUniqueConstraints parse schema unique constraints
  46. func (schema *Schema) ParseUniqueConstraints() map[string]UniqueConstraint {
  47. uniques := make(map[string]UniqueConstraint)
  48. for _, field := range schema.Fields {
  49. if field.Unique {
  50. name := schema.namer.UniqueName(schema.Table, field.DBName)
  51. uniques[name] = UniqueConstraint{Name: name, Field: field}
  52. }
  53. }
  54. return uniques
  55. }