github.com/go-generalize/volcago@v1.7.0/generator/index.go (about)

     1  package generator
     2  
     3  import (
     4  	"fmt"
     5  	"sort"
     6  	"strings"
     7  
     8  	"github.com/fatih/structtag"
     9  	"github.com/iancoleman/strcase"
    10  )
    11  
    12  const (
    13  	equal      = "equal"
    14  	like       = "like"
    15  	prefix     = "prefix"
    16  	suffix     = "suffix"
    17  	biunigrams = "Biunigrams"
    18  )
    19  
    20  func isUseIndexer(filters []string, p1, p2 string) bool {
    21  	for _, filter := range filters {
    22  		switch filter {
    23  		case p1, p2:
    24  			return true
    25  		}
    26  	}
    27  	return false
    28  }
    29  
    30  func (g *structGenerator) appendIndexer(tags *structtag.Tags, fsTagBase string, fieldInfo *FieldInfo) (*FieldInfo, error) {
    31  	filters := make([]string, 0)
    32  	if tags != nil {
    33  		if tag, err := validateFirestoreTag(tags); err != nil {
    34  			return nil, err
    35  		} else if tag != "" {
    36  			fieldInfo.FsTag = tag
    37  			if fsTagBase != "" {
    38  				fieldInfo.FsTag = fsTagBase + "." + tag
    39  			}
    40  		}
    41  
    42  		idr, err := tags.Get("indexer")
    43  		if err == nil {
    44  			fieldInfo.IndexerTag = idr.Value()
    45  			filters = strings.Split(idr.Value(), ",")
    46  		}
    47  	}
    48  
    49  	patterns := [4]string{
    50  		prefix, suffix, like, equal,
    51  	}
    52  	fieldLabel := g.structName + "IndexLabel"
    53  
    54  	for i := range patterns {
    55  		idx := &IndexesInfo{
    56  			ConstName: strings.ReplaceAll(fieldLabel+fieldInfo.Field+strcase.ToCamel(patterns[i]), ".", "_"),
    57  			Label:     uppercaseExtraction(fieldInfo.Field, g.dupMap),
    58  			Method:    "Add",
    59  		}
    60  
    61  		switch patterns[i] {
    62  		case prefix:
    63  			idx.Use = isUseIndexer(filters, "p", prefix)
    64  			idx.Method += strcase.ToCamel(prefix)
    65  			idx.Comment = fmt.Sprintf("prefix-match of %s", fieldInfo.Field)
    66  		case suffix:
    67  			idx.Use = isUseIndexer(filters, "s", suffix)
    68  			idx.Method += strcase.ToCamel(suffix)
    69  			idx.Comment = fmt.Sprintf("suffix-match of %s", fieldInfo.Field)
    70  		case like:
    71  			idx.Use = isUseIndexer(filters, "l", like)
    72  			idx.Method += biunigrams
    73  			idx.Comment = fmt.Sprintf("like-match of %s", fieldInfo.Field)
    74  		case equal:
    75  			idx.Use = isUseIndexer(filters, "e", equal)
    76  			idx.Comment = fmt.Sprintf("perfect-match of %s", fieldInfo.Field)
    77  		}
    78  
    79  		if fieldInfo.FieldType != typeString {
    80  			idx.Method = "AddSomething"
    81  		}
    82  
    83  		fieldInfo.Indexes = append(fieldInfo.Indexes, idx)
    84  	}
    85  
    86  	sort.Slice(fieldInfo.Indexes, func(i, j int) bool {
    87  		return fieldInfo.Indexes[i].Method < fieldInfo.Indexes[j].Method
    88  	})
    89  
    90  	return fieldInfo, nil
    91  }
    92  
    93  func uppercaseExtraction(name string, dupMap map[string]int) (lower string) {
    94  	defer func() {
    95  		if _, ok := dupMap[lower]; ok {
    96  			lower = fmt.Sprintf("%s%d", lower, dupMap[lower])
    97  		}
    98  	}()
    99  	for i, x := range name {
   100  		switch {
   101  		case 65 <= x && x <= 90:
   102  			x += 32
   103  			fallthrough
   104  		case 97 <= x && x <= 122:
   105  			if i == 0 {
   106  				lower += string(x)
   107  			}
   108  			if _, ok := dupMap[lower]; !ok {
   109  				dupMap[lower] = 1
   110  				return
   111  			}
   112  
   113  			if dupMap[lower] >= 9 && len(name) > i+1 {
   114  				lower += string(name[i+1])
   115  				continue
   116  			}
   117  			dupMap[lower]++
   118  			return
   119  		}
   120  	}
   121  	return
   122  }