github.com/artisanhe/tools@v1.0.1-0.20210607022958-19a8fef2eb04/sqlx/builder/obj_key.go (about)

     1  package builder
     2  
     3  import (
     4  	"container/list"
     5  	"fmt"
     6  )
     7  
     8  type keyType string
     9  
    10  const (
    11  	PRIMARY      keyType = "PRIMARY"
    12  	INDEX        keyType = "INDEX"
    13  	UNIQUE_INDEX keyType = "UNIQUE INDEX"
    14  )
    15  
    16  func PrimaryKey() *Key {
    17  	return &Key{
    18  		Name: string(PRIMARY),
    19  		Type: PRIMARY,
    20  	}
    21  }
    22  
    23  func Index(name string) *Key {
    24  	return &Key{
    25  		Name: name,
    26  		Type: INDEX,
    27  	}
    28  }
    29  
    30  func UniqueIndex(name string) *Key {
    31  	return &Key{
    32  		Name: name,
    33  		Type: UNIQUE_INDEX,
    34  	}
    35  }
    36  
    37  type Keys struct {
    38  	m map[string]*list.Element
    39  	l *list.List
    40  }
    41  
    42  func (keys *Keys) Clone() *Keys {
    43  	k := &Keys{}
    44  	keys.Range(func(key *Key, idx int) {
    45  		k.Add(key)
    46  	})
    47  	return k
    48  }
    49  
    50  func (keys *Keys) Len() int {
    51  	if keys.l == nil {
    52  		return 0
    53  	}
    54  	return keys.l.Len()
    55  }
    56  
    57  func (keys *Keys) IsEmpty() bool {
    58  	return keys.l == nil || keys.l.Len() == 0
    59  }
    60  
    61  func (keys *Keys) Key(keyName string) (key *Key, exists bool) {
    62  	if keys.m != nil {
    63  		if c, ok := keys.m[keyName]; ok {
    64  			return c.Value.(*Key), true
    65  		}
    66  	}
    67  	return nil, false
    68  }
    69  
    70  func (keys *Keys) Add(nextKeys ...*Key) {
    71  	if keys.m == nil {
    72  		keys.m = map[string]*list.Element{}
    73  		keys.l = list.New()
    74  	}
    75  	for _, key := range nextKeys {
    76  		keys.m[key.Name] = keys.l.PushBack(key)
    77  	}
    78  }
    79  
    80  func (keys *Keys) Remove(name string) {
    81  	if keys.m != nil {
    82  		if e, exists := keys.m[name]; exists {
    83  			keys.l.Remove(e)
    84  			delete(keys.m, name)
    85  		}
    86  	}
    87  }
    88  
    89  func (keys *Keys) Range(cb func(key *Key, idx int)) {
    90  	if keys.l != nil {
    91  		i := 0
    92  		for e := keys.l.Front(); e != nil; e = e.Next() {
    93  			cb(e.Value.(*Key), i)
    94  			i++
    95  		}
    96  	}
    97  }
    98  
    99  func (keys Keys) Diff(targetKeys Keys) keysDiffResult {
   100  	r := keysDiffResult{}
   101  
   102  	ks := keys.Clone()
   103  
   104  	targetKeys.Range(func(key *Key, idx int) {
   105  		if currentKey, exists := ks.Key(key.Name); exists {
   106  			if currentKey.Def().Query != key.Def().Query {
   107  				r.keysForUpdate.Add(key)
   108  			}
   109  		} else {
   110  			r.keysForAdd.Add(key)
   111  		}
   112  		ks.Remove(key.Name)
   113  	})
   114  
   115  	ks.Range(func(key *Key, idx int) {
   116  		r.keysForDelete.Add(key)
   117  	})
   118  
   119  	return r
   120  }
   121  
   122  type keysDiffResult struct {
   123  	keysForAdd    Keys
   124  	keysForUpdate Keys
   125  	keysForDelete Keys
   126  }
   127  
   128  func (r keysDiffResult) IsChanged() bool {
   129  	return !r.keysForAdd.IsEmpty() || !r.keysForUpdate.IsEmpty() || !r.keysForDelete.IsEmpty()
   130  }
   131  
   132  type Key struct {
   133  	Name string
   134  	Columns
   135  	Type keyType
   136  }
   137  
   138  func (key *Key) WithCols(columns ...*Column) *Key {
   139  	key.Columns.Add(columns...)
   140  	return key
   141  }
   142  
   143  func (key *Key) String() string {
   144  	return quote(key.Name)
   145  }
   146  
   147  func (key *Key) Add() *Expression {
   148  	return Expr("ADD").ConcatBy(" ", key.Def())
   149  }
   150  
   151  func (key *Key) Drop() *Expression {
   152  	if key.Type == PRIMARY {
   153  		return Expr(fmt.Sprintf("DROP %s KEY", key.Type))
   154  	}
   155  	return Expr(fmt.Sprintf("DROP INDEX %s", key.String()))
   156  }
   157  
   158  func (key *Key) IsValidDef() bool {
   159  	return !key.Columns.IsEmpty()
   160  }
   161  
   162  func (key *Key) Def() *Expression {
   163  	if key.Type == PRIMARY {
   164  		return Expr(string(key.Type)+" KEY").ConcatBy(" ", key.Columns.Wrap())
   165  	}
   166  	return Expr(string(key.Type)+" "+key.String()).ConcatBy(" ", key.Columns.Wrap())
   167  }