github.com/RevenueMonster/sqlike@v1.0.6/sqlike/indexes/index.go (about) 1 package indexes 2 3 import ( 4 "crypto/md5" 5 "fmt" 6 "io" 7 "strings" 8 9 "github.com/valyala/bytebufferpool" 10 ) 11 12 type writer interface { 13 io.Writer 14 io.StringWriter 15 io.ByteWriter 16 } 17 18 // Type : 19 type Type int 20 21 // types : 22 const ( 23 BTree Type = iota + 1 24 FullText 25 Unique 26 Spatial 27 Primary 28 MultiValued 29 ) 30 31 func (t Type) String() string { 32 switch t { 33 case FullText: 34 return "FULLTEXT" 35 case Unique: 36 return "UNIQUE" 37 case Spatial: 38 return "SPATIAL" 39 case Primary: 40 return "PRIMARY" 41 case MultiValued: 42 return "MULTI-VALUED" 43 default: 44 return "BTREE" 45 } 46 } 47 48 // Index : 49 type Index struct { 50 Name string 51 Cast string 52 As string 53 Type Type 54 Columns []Col 55 Comment string 56 } 57 58 // Direction : 59 type Direction int 60 61 // direction : 62 const ( 63 Ascending Direction = iota 64 Descending 65 ) 66 67 // Columns : 68 func Columns(names ...string) []Col { 69 columns := make([]Col, 0, len(names)) 70 for _, n := range names { 71 columns = append(columns, Column(n)) 72 } 73 return columns 74 } 75 76 // Column : 77 func Column(name string) Col { 78 dir := Ascending 79 name = strings.TrimSpace(name) 80 if name[0] == '-' { 81 name = name[1:] 82 dir = Descending 83 } 84 return Col{ 85 Name: name, 86 Direction: dir, 87 } 88 } 89 90 // Col : 91 type Col struct { 92 Name string 93 Direction Direction 94 } 95 96 // GetName : 97 func (idx Index) GetName() string { 98 if idx.Name != "" { 99 return idx.Name 100 } 101 return idx.HashName() 102 } 103 104 func (idx Index) buildName(w writer) { 105 switch idx.Type { 106 case Primary: 107 w.WriteString("PRIMARY") 108 return 109 110 case Unique: 111 w.WriteString("UX") 112 113 case FullText: 114 w.WriteString("FTX") 115 116 case MultiValued: 117 w.WriteString("MVX") 118 119 default: 120 w.WriteString("IX") 121 } 122 w.WriteByte('-') 123 for i, col := range idx.Columns { 124 if i > 0 { 125 w.WriteByte(';') 126 } 127 w.WriteString(col.Name) 128 w.WriteByte('@') 129 if col.Direction == 0 { 130 w.WriteString("ASC") 131 } else { 132 w.WriteString("DESC") 133 } 134 } 135 } 136 137 // HashName : 138 func (idx Index) HashName() string { 139 hash := md5.New() 140 buf := bytebufferpool.Get() 141 defer bytebufferpool.Put(buf) 142 idx.buildName(buf) 143 hash.Write(buf.Bytes()) 144 return fmt.Sprintf("%x", hash.Sum(nil)) 145 }