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  }