github.com/pjdufour-truss/pop@v4.11.2-0.20190705085848-4c90b0ff4d5a+incompatible/soda/cmd/generate/attribute.go (about)

     1  package generate
     2  
     3  import (
     4  	"fmt"
     5  	"regexp"
     6  	"strings"
     7  
     8  	"github.com/gobuffalo/flect"
     9  )
    10  
    11  var attrNamePattern = regexp.MustCompile(`^\p{L}[\p{L}\d_]*$`)
    12  
    13  type attribute struct {
    14  	Name              flect.Ident
    15  	OriginalType      string
    16  	GoType            string
    17  	Nullable          bool
    18  	Primary           bool
    19  	PreventValidation bool
    20  	StructTag         string
    21  }
    22  
    23  func (a attribute) String() string {
    24  	if len(a.StructTag) == 0 {
    25  		a.StructTag = "json"
    26  	}
    27  	return fmt.Sprintf("\t%s %s `%s:\"%s\" db:\"%s\"`", a.Name.Pascalize(), a.GoType, a.StructTag, a.Name.Underscore(), a.Name.Underscore())
    28  }
    29  
    30  func (a attribute) IsValidable() bool {
    31  	return !a.PreventValidation && (a.GoType == "string" || a.GoType == "time.Time" || a.GoType == "int")
    32  }
    33  
    34  func newAttribute(base string, model *model) (attribute, error) {
    35  	col := strings.Split(base, ":")
    36  	if len(col) == 1 {
    37  		col = append(col, "string")
    38  	}
    39  
    40  	if !attrNamePattern.MatchString(col[0]) {
    41  		return attribute{}, fmt.Errorf("%s is not a valid attribute name", col[0])
    42  	}
    43  
    44  	nullable := strings.HasPrefix(col[1], "nulls.")
    45  	if !model.HasNulls && nullable {
    46  		model.HasNulls = true
    47  		model.Imports = append(model.Imports, "github.com/gobuffalo/nulls")
    48  	} else if !model.HasSlices && strings.HasPrefix(col[1], "slices.") {
    49  		model.HasSlices = true
    50  		model.Imports = append(model.Imports, "github.com/gobuffalo/pop/slices")
    51  	} else if !model.HasUUID && col[1] == "uuid" {
    52  		model.HasUUID = true
    53  		model.Imports = append(model.Imports, "github.com/gofrs/uuid")
    54  	}
    55  
    56  	got := colType(col[1])
    57  	if len(col) > 2 {
    58  		got = col[2]
    59  	}
    60  	name := flect.New(col[0])
    61  	primary := false
    62  	if name.String() == "id" {
    63  		primary = true
    64  	}
    65  	a := attribute{
    66  		Name:         name,
    67  		OriginalType: col[1],
    68  		GoType:       got,
    69  		Nullable:     nullable,
    70  		StructTag:    model.StructTag,
    71  		Primary:      primary,
    72  	}
    73  
    74  	return a, nil
    75  }
    76  
    77  func colType(s string) string {
    78  	switch strings.ToLower(s) {
    79  	case "text":
    80  		return "string"
    81  	case "time", "timestamp", "datetime":
    82  		return "time.Time"
    83  	case "nulls.text":
    84  		return "nulls.String"
    85  	case "uuid":
    86  		return "uuid.UUID"
    87  	case "json", "jsonb":
    88  		return "slices.Map"
    89  	case "[]string":
    90  		return "slices.String"
    91  	case "[]int":
    92  		return "slices.Int"
    93  	case "slices.float", "[]float", "[]float32", "[]float64":
    94  		return "slices.Float"
    95  	case "decimal", "float":
    96  		return "float64"
    97  	case "[]byte", "blob":
    98  		return "[]byte"
    99  	default:
   100  		return s
   101  	}
   102  }