From afc967174ba02925519d3a32ed52004d3543340a Mon Sep 17 00:00:00 2001 From: Jonathan Duck <jonathan@ec2software.com> Date: Tue, 27 Aug 2019 13:23:39 -0700 Subject: [PATCH] Fixed column order (#430) * Add test to demonstrate INSERT fails with a suffix on quoted column name #429 * Ensure columns are sorted the same way each time. --- columns/columns.go | 30 +++++++++++++++++------------- columns/columns_test.go | 21 +++++++++++++++++++++ 2 files changed, 38 insertions(+), 13 deletions(-) diff --git a/columns/columns.go b/columns/columns.go index 823d6455..8ee8f15c 100644 --- a/columns/columns.go +++ b/columns/columns.go @@ -118,37 +118,41 @@ func (c Columns) Readable() *ReadableColumns { return w } +// colNames returns a slice of column names in a deterministic order +func (c Columns) colNames() []string { + var xs []string + for _, t := range c.Cols { + xs = append(xs, t.Name) + } + sort.Strings(xs) + return xs +} + type quoter interface { Quote(key string) string } // QuotedString gives the columns list quoted with the given quoter function. func (c Columns) QuotedString(quoter quoter) string { - var xs []string - for _, t := range c.Cols { - xs = append(xs, quoter.Quote(t.Name)) + xs := c.colNames() + for i, n := range xs { + xs[i] = quoter.Quote(n) } - sort.Strings(xs) return strings.Join(xs, ", ") } func (c Columns) String() string { - var xs []string - for _, t := range c.Cols { - xs = append(xs, t.Name) - } - sort.Strings(xs) + xs := c.colNames() return strings.Join(xs, ", ") } // SymbolizedString returns a list of tokens (:token) to bind // a value to an INSERT query. func (c Columns) SymbolizedString() string { - var xs []string - for _, t := range c.Cols { - xs = append(xs, ":"+t.Name) + xs := c.colNames() + for i, n := range xs { + xs[i] = ":" + n } - sort.Strings(xs) return strings.Join(xs, ", ") } diff --git a/columns/columns_test.go b/columns/columns_test.go index 71095b5f..c4194d2e 100644 --- a/columns/columns_test.go +++ b/columns/columns_test.go @@ -1,6 +1,7 @@ package columns_test import ( + "fmt" "testing" "github.com/gobuffalo/pop/columns" @@ -60,3 +61,23 @@ func Test_Columns_Remove(t *testing.T) { r.Equal(len(c.Cols), 3) } } + +type fooWithSuffix struct { + Amount float64 `db:"amount"` + AmountUnits string `db:"amount_units"` +} +type fooQuoter struct{} + +func (fooQuoter) Quote(key string) string { + return fmt.Sprintf("`%v`", key) +} + +func Test_Columns_Sorted(t *testing.T) { + r := require.New(t) + + c := columns.ForStruct(fooWithSuffix{}, "fooWithSuffix") + r.Equal(len(c.Cols), 2) + r.Equal(c.SymbolizedString(), ":amount, :amount_units") + r.Equal(c.String(), "amount, amount_units") + r.Equal(c.QuotedString(fooQuoter{}), "`amount`, `amount_units`") +}