diff --git a/columns.go b/columns.go index 151c7e86..e3c04f44 100644 --- a/columns.go +++ b/columns.go @@ -1,5 +1,12 @@ package fizz +import ( + "encoding/json" + "fmt" + "sort" + "strings" +) + var INT_ID_COL = Column{ Name: "id", Primary: true, @@ -24,6 +31,29 @@ type Column struct { Options map[string]interface{} } +func (c Column) String() string { + if c.Primary || c.Options != nil { + var opts map[string]interface{} + if c.Options == nil { + opts = make(map[string]interface{}, 0) + } else { + opts = c.Options + } + if c.Primary { + opts["primary"] = true + } + + o := make([]string, 0, len(opts)) + for k, v := range opts { + vv, _ := json.Marshal(v) + o = append(o, fmt.Sprintf("%s: %s", k, string(vv))) + } + sort.SliceStable(o, func(i, j int) bool { return o[i] < o[j] }) + return fmt.Sprintf(`t.Column("%s", "%s", {%s})`, c.Name, c.ColType, strings.Join(o, ", ")) + } + return fmt.Sprintf(`t.Column("%s", "%s")`, c.Name, c.ColType) +} + func (f fizzer) ChangeColumn(table, name, ctype string, options Options) { t := Table{ Name: table, diff --git a/columns_test.go b/columns_test.go new file mode 100644 index 00000000..c71f64eb --- /dev/null +++ b/columns_test.go @@ -0,0 +1,57 @@ +package fizz_test + +import ( + "testing" + + "github.com/gobuffalo/fizz" + "github.com/stretchr/testify/require" +) + +func Test_Column_Stringer(t *testing.T) { + t.Run("primary column", func(tt *testing.T) { + r := require.New(tt) + c := fizz.Column{ + Name: "pk", + ColType: "int", + Primary: true, + } + + r.Equal(`t.Column("pk", "int", {primary: true})`, c.String()) + }) + + t.Run("simple column", func(tt *testing.T) { + r := require.New(tt) + c := fizz.Column{ + Name: "name", + ColType: "string", + } + + r.Equal(`t.Column("name", "string")`, c.String()) + }) + + t.Run("with option", func(tt *testing.T) { + r := require.New(tt) + c := fizz.Column{ + Name: "alive", + ColType: "boolean", + Options: map[string]interface{}{ + "null": true, + }, + } + + r.Equal(`t.Column("alive", "boolean", {null: true})`, c.String()) + }) + + t.Run("with string option", func(tt *testing.T) { + r := require.New(tt) + c := fizz.Column{ + Name: "price", + ColType: "numeric", + Options: map[string]interface{}{ + "default": "1.00", + }, + } + + r.Equal(`t.Column("price", "numeric", {default: "1.00"})`, c.String()) + }) +} diff --git a/tables.go b/tables.go index 6e882e2b..1341f41c 100644 --- a/tables.go +++ b/tables.go @@ -1,6 +1,7 @@ package fizz import ( + "bytes" "fmt" "strings" @@ -16,6 +17,17 @@ type Table struct { Options map[string]interface{} } +func (t Table) String() string { + var buff bytes.Buffer + + buff.WriteString(fmt.Sprintf("create_table(\"%s\") {\n", t.Name)) + for _, c := range t.Columns { + buff.WriteString(fmt.Sprintf("\t%s\n", c.String())) + } + buff.WriteString("}") + return buff.String() +} + func (t *Table) DisableTimestamps() { t.Options["timestamps"] = false } diff --git a/tables_test.go b/tables_test.go new file mode 100644 index 00000000..0cadd6ea --- /dev/null +++ b/tables_test.go @@ -0,0 +1,71 @@ +package fizz_test + +import ( + "testing" + + "github.com/gobuffalo/fizz" + "github.com/stretchr/testify/require" +) + +func Test_Table_Stringer(t *testing.T) { + r := require.New(t) + + expected := + `create_table("users") { + t.Column("name", "string") + t.Column("alive", "boolean", {null: true}) + t.Column("birth_date", "timestamp", {null: true}) + t.Column("bio", "text", {null: true}) + t.Column("price", "numeric", {default: "1.00", null: true}) + t.Column("email", "string", {default: "foo@example.com", size: 50}) +}` + + table := fizz.Table{ + Name: "users", + Columns: []fizz.Column{ + fizz.Column{ + Name: "name", + ColType: "string", + }, + fizz.Column{ + Name: "alive", + ColType: "boolean", + Options: map[string]interface{}{ + "null": true, + }, + }, + fizz.Column{ + Name: "birth_date", + ColType: "timestamp", + Options: map[string]interface{}{ + "null": true, + }, + }, + fizz.Column{ + Name: "bio", + ColType: "text", + Options: map[string]interface{}{ + "null": true, + }, + }, + fizz.Column{ + Name: "price", + ColType: "numeric", + Options: map[string]interface{}{ + "null": true, + "default": "1.00", + }, + }, + fizz.Column{ + Name: "email", + ColType: "string", + Options: map[string]interface{}{ + "size": 50, + "default": "foo@example.com", + }, + }, + }, + } + + r.Equal(expected, table.String()) +}