github.com/octohelm/storage@v0.0.0-20240516030302-1ac2cc1ea347/pkg/sqlbuilder/def_key.go (about)

     1  package sqlbuilder
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"strings"
     7  )
     8  
     9  func PrimaryKey(columns ColumnCollection, optFns ...IndexOptionFunc) Key {
    10  	return UniqueIndex("PRIMARY", columns, optFns...)
    11  }
    12  
    13  func UniqueIndex(name string, columns ColumnCollection, optFns ...IndexOptionFunc) Key {
    14  	return Index(name, columns, append(optFns, IndexUnique(true))...)
    15  }
    16  
    17  type IndexOptionFunc func(k *key)
    18  
    19  func IndexUnique(unique bool) IndexOptionFunc {
    20  	return func(k *key) {
    21  		k.isUnique = unique
    22  	}
    23  }
    24  
    25  func IndexUsing(method string) IndexOptionFunc {
    26  	return func(k *key) {
    27  		k.method = method
    28  	}
    29  }
    30  
    31  func IndexColNameAndOptions(colNameAndOptions ...string) IndexOptionFunc {
    32  	return func(k *key) {
    33  		k.colNameAndOptions = colNameAndOptions
    34  	}
    35  }
    36  
    37  func Index(name string, columns ColumnCollection, optFns ...IndexOptionFunc) Key {
    38  	k := &key{
    39  		name: strings.ToLower(name),
    40  	}
    41  
    42  	if columns != nil {
    43  		columns.RangeCol(func(col Column, idx int) bool {
    44  			k.colNameAndOptions = append(k.colNameAndOptions, col.Name())
    45  			return true
    46  		})
    47  	}
    48  
    49  	for i := range optFns {
    50  		optFns[i](k)
    51  	}
    52  
    53  	return k
    54  }
    55  
    56  type Key interface {
    57  	SqlExpr
    58  	TableDefinition
    59  
    60  	Of(table Table) Key
    61  
    62  	IsPrimary() bool
    63  	IsUnique() bool
    64  	Name() string
    65  	Columns() ColumnCollection
    66  }
    67  
    68  type KeyDef interface {
    69  	Method() string
    70  	ColNameAndOptions() []string
    71  }
    72  
    73  type key struct {
    74  	table             Table
    75  	name              string
    76  	isUnique          bool
    77  	method            string
    78  	colNameAndOptions []string
    79  }
    80  
    81  func (k *key) IsNil() bool {
    82  	return k == nil
    83  }
    84  
    85  func (k *key) Ex(ctx context.Context) *Ex {
    86  	return ExactlyExpr(k.name).Ex(ctx)
    87  }
    88  
    89  func (k *key) T() Table {
    90  	return k.table
    91  }
    92  
    93  func (k *key) Method() string {
    94  	return k.method
    95  }
    96  
    97  func (k *key) ColNameAndOptions() []string {
    98  	return k.colNameAndOptions
    99  }
   100  
   101  func (k key) Of(table Table) Key {
   102  	return &key{
   103  		table:             table,
   104  		name:              k.name,
   105  		isUnique:          k.isUnique,
   106  		method:            k.method,
   107  		colNameAndOptions: k.colNameAndOptions,
   108  	}
   109  }
   110  
   111  func (k *key) Name() string {
   112  	return k.name
   113  }
   114  
   115  func (k *key) IsUnique() bool {
   116  	return k.isUnique
   117  }
   118  
   119  func (k *key) IsPrimary() bool {
   120  	return k.isUnique && k.name == "primary" || strings.HasSuffix(k.name, "pkey")
   121  }
   122  
   123  func (k *key) Columns() ColumnCollection {
   124  	if len(k.colNameAndOptions) == 0 {
   125  		panic(fmt.Errorf("invalid key %s of %s, missing cols", k.name, k.table.TableName()))
   126  	}
   127  
   128  	names := make([]string, len(k.colNameAndOptions))
   129  
   130  	for i := range names {
   131  		names[i] = strings.Split(k.colNameAndOptions[i], "/")[0]
   132  	}
   133  
   134  	return k.table.Cols(names...)
   135  }