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  }