github.com/systematiccaos/gorm@v1.22.6/schema/index.go (about) 1 package schema 2 3 import ( 4 "sort" 5 "strconv" 6 "strings" 7 ) 8 9 type Index struct { 10 Name string 11 Class string // UNIQUE | FULLTEXT | SPATIAL 12 Type string // btree, hash, gist, spgist, gin, and brin 13 Where string 14 Comment string 15 Option string // WITH PARSER parser_name 16 Fields []IndexOption 17 } 18 19 type IndexOption struct { 20 *Field 21 Expression string 22 Sort string // DESC, ASC 23 Collate string 24 Length int 25 priority int 26 } 27 28 // ParseIndexes parse schema indexes 29 func (schema *Schema) ParseIndexes() map[string]Index { 30 var indexes = map[string]Index{} 31 32 for _, field := range schema.Fields { 33 if field.TagSettings["INDEX"] != "" || field.TagSettings["UNIQUEINDEX"] != "" { 34 for _, index := range parseFieldIndexes(field) { 35 idx := indexes[index.Name] 36 idx.Name = index.Name 37 if idx.Class == "" { 38 idx.Class = index.Class 39 } 40 if idx.Type == "" { 41 idx.Type = index.Type 42 } 43 if idx.Where == "" { 44 idx.Where = index.Where 45 } 46 if idx.Comment == "" { 47 idx.Comment = index.Comment 48 } 49 if idx.Option == "" { 50 idx.Option = index.Option 51 } 52 53 idx.Fields = append(idx.Fields, index.Fields...) 54 sort.Slice(idx.Fields, func(i, j int) bool { 55 return idx.Fields[i].priority < idx.Fields[j].priority 56 }) 57 58 indexes[index.Name] = idx 59 } 60 } 61 } 62 63 return indexes 64 } 65 66 func (schema *Schema) LookIndex(name string) *Index { 67 if schema != nil { 68 indexes := schema.ParseIndexes() 69 for _, index := range indexes { 70 if index.Name == name { 71 return &index 72 } 73 74 for _, field := range index.Fields { 75 if field.Name == name { 76 return &index 77 } 78 } 79 } 80 } 81 82 return nil 83 } 84 85 func parseFieldIndexes(field *Field) (indexes []Index) { 86 for _, value := range strings.Split(field.Tag.Get("gorm"), ";") { 87 if value != "" { 88 v := strings.Split(value, ":") 89 k := strings.TrimSpace(strings.ToUpper(v[0])) 90 if k == "INDEX" || k == "UNIQUEINDEX" { 91 var ( 92 name string 93 tag = strings.Join(v[1:], ":") 94 idx = strings.Index(tag, ",") 95 settings = ParseTagSetting(tag, ",") 96 length, _ = strconv.Atoi(settings["LENGTH"]) 97 ) 98 99 if idx == -1 { 100 idx = len(tag) 101 } 102 103 if idx != -1 { 104 name = tag[0:idx] 105 } 106 107 if name == "" { 108 name = field.Schema.namer.IndexName(field.Schema.Table, field.Name) 109 } 110 111 if (k == "UNIQUEINDEX") || settings["UNIQUE"] != "" { 112 settings["CLASS"] = "UNIQUE" 113 } 114 115 priority, err := strconv.Atoi(settings["PRIORITY"]) 116 if err != nil { 117 priority = 10 118 } 119 120 indexes = append(indexes, Index{ 121 Name: name, 122 Class: settings["CLASS"], 123 Type: settings["TYPE"], 124 Where: settings["WHERE"], 125 Comment: settings["COMMENT"], 126 Option: settings["OPTION"], 127 Fields: []IndexOption{{ 128 Field: field, 129 Expression: settings["EXPRESSION"], 130 Sort: settings["SORT"], 131 Collate: settings["COLLATE"], 132 Length: length, 133 priority: priority, 134 }}, 135 }) 136 } 137 } 138 } 139 140 return 141 }