github.com/unionj-cloud/go-doudou@v1.3.8-0.20221011095552-0088008e5b31/cmd/internal/ddl/ddlast/ast.go (about)

     1  package ddlast
     2  
     3  import (
     4  	"github.com/unionj-cloud/go-doudou/cmd/internal/astutils"
     5  	"github.com/unionj-cloud/go-doudou/toolkit/sliceutils"
     6  	"sort"
     7  	"strings"
     8  )
     9  
    10  type sortableFieldMeta []astutils.FieldMeta
    11  
    12  // Len return length of sortableFieldMeta
    13  func (it sortableFieldMeta) Len() int {
    14  	return len(it)
    15  }
    16  
    17  // Less define asc or desc order
    18  func (it sortableFieldMeta) Less(i, j int) bool {
    19  	return it[i].Name < it[j].Name
    20  }
    21  
    22  // Swap change position of elements at i and j
    23  func (it sortableFieldMeta) Swap(i, j int) {
    24  	it[i], it[j] = it[j], it[i]
    25  }
    26  
    27  // FlatEmbed flat embed struct
    28  func FlatEmbed(structs []astutils.StructMeta) []astutils.StructMeta {
    29  	structMap := make(map[string]astutils.StructMeta)
    30  	for _, structMeta := range structs {
    31  		if _, exists := structMap[structMeta.Name]; !exists {
    32  			structMap[structMeta.Name] = structMeta
    33  		}
    34  	}
    35  	var result []astutils.StructMeta
    36  	for _, structMeta := range structs {
    37  		if sliceutils.IsEmpty(structMeta.Comments) {
    38  			continue
    39  		}
    40  		if !strings.Contains(structMeta.Comments[0], "dd:table") {
    41  			continue
    42  		}
    43  		_structMeta := astutils.StructMeta{
    44  			Name:     structMeta.Name,
    45  			Fields:   make([]astutils.FieldMeta, 0),
    46  			Comments: make([]string, len(structMeta.Comments)),
    47  		}
    48  		copy(_structMeta.Comments, structMeta.Comments)
    49  
    50  		fieldMap := make(map[string]astutils.FieldMeta)
    51  		embedFieldMap := make(map[string]astutils.FieldMeta)
    52  		for _, fieldMeta := range structMeta.Fields {
    53  			if strings.HasPrefix(fieldMeta.Type, "embed") {
    54  				if embedded, exists := structMap[fieldMeta.Name]; exists {
    55  					for _, field := range embedded.Fields {
    56  						embedFieldMap[field.Name] = field
    57  					}
    58  				}
    59  			} else {
    60  				_structMeta.Fields = append(_structMeta.Fields, fieldMeta)
    61  				fieldMap[fieldMeta.Name] = fieldMeta
    62  			}
    63  		}
    64  
    65  		var embedFields []astutils.FieldMeta
    66  		for key, field := range embedFieldMap {
    67  			if _, exists := fieldMap[key]; !exists {
    68  				embedFields = append(embedFields, field)
    69  			}
    70  		}
    71  
    72  		sort.Stable(sortableFieldMeta(embedFields))
    73  		_structMeta.Fields = append(_structMeta.Fields, embedFields...)
    74  		result = append(result, _structMeta)
    75  	}
    76  
    77  	return result
    78  }