github.com/mpontillo/pop@v4.13.1+incompatible/genny/fizz/ctable/create_table.go (about)

     1  package ctable
     2  
     3  import (
     4  	"fmt"
     5  	"path/filepath"
     6  	"strings"
     7  
     8  	"github.com/gobuffalo/fizz"
     9  	"github.com/gobuffalo/genny"
    10  	"github.com/pkg/errors"
    11  )
    12  
    13  // New creates a generator to make files for a table based
    14  // on the given options.
    15  func New(opts *Options) (*genny.Generator, error) {
    16  	g := genny.New()
    17  
    18  	if err := opts.Validate(); err != nil {
    19  		return g, err
    20  	}
    21  
    22  	t := fizz.NewTable(opts.TableName, map[string]interface{}{
    23  		"timestamps": opts.ForceDefaultTimestamps,
    24  	})
    25  	for _, attr := range opts.Attrs {
    26  		o := fizz.Options{}
    27  		name := attr.Name.Underscore().String()
    28  		colType := fizzColType(attr.CommonType())
    29  		if name == "id" {
    30  			o["primary"] = true
    31  		}
    32  		if strings.HasPrefix(attr.GoType(), "nulls.") {
    33  			o["null"] = true
    34  		}
    35  		if err := t.Column(name, colType, o); err != nil {
    36  			return g, err
    37  		}
    38  	}
    39  	var f genny.File
    40  	up := t.Fizz()
    41  	down := t.UnFizz()
    42  	if opts.Type == "sql" {
    43  		type nameable interface {
    44  			Name() string
    45  		}
    46  		translatorNameable, ok := opts.Translator.(nameable)
    47  		if !ok {
    48  			return g, errors.New("fizz translator needs a Name method")
    49  		}
    50  		m, err := fizz.AString(up, opts.Translator)
    51  		if err != nil {
    52  			return g, err
    53  		}
    54  		f = genny.NewFileS(filepath.Join(opts.Path, fmt.Sprintf("%s.%s.up.sql", opts.Name, translatorNameable.Name())), m)
    55  		g.File(f)
    56  		m, err = fizz.AString(down, opts.Translator)
    57  		if err != nil {
    58  			return g, err
    59  		}
    60  		f = genny.NewFileS(filepath.Join(opts.Path, fmt.Sprintf("%s.%s.down.sql", opts.Name, translatorNameable.Name())), m)
    61  		g.File(f)
    62  		return g, nil
    63  	}
    64  	f = genny.NewFileS(filepath.Join(opts.Path, opts.Name+".up.fizz"), up)
    65  	g.File(f)
    66  	f = genny.NewFileS(filepath.Join(opts.Path, opts.Name+".down.fizz"), down)
    67  	g.File(f)
    68  	return g, nil
    69  }
    70  
    71  func fizzColType(s string) string {
    72  	switch strings.ToLower(s) {
    73  	case "int":
    74  		return "integer"
    75  	case "time", "datetime":
    76  		return "timestamp"
    77  	case "uuid.uuid", "uuid":
    78  		return "uuid"
    79  	case "nulls.float32", "nulls.float64":
    80  		return "float"
    81  	case "slices.string", "slices.uuid", "[]string":
    82  		return "varchar[]"
    83  	case "slices.float", "[]float", "[]float32", "[]float64":
    84  		return "numeric[]"
    85  	case "slices.int":
    86  		return "int[]"
    87  	case "slices.map":
    88  		return "jsonb"
    89  	case "float32", "float64", "float":
    90  		return "decimal"
    91  	case "blob", "[]byte":
    92  		return "blob"
    93  	default:
    94  		if strings.HasPrefix(s, "nulls.") {
    95  			return fizzColType(strings.Replace(s, "nulls.", "", -1))
    96  		}
    97  		return strings.ToLower(s)
    98  	}
    99  }