Move string set operations to strmangle

- Delete MakeDBName (unused)
- Rename HasElement to SetInclude
This commit is contained in:
Aaron L 2016-08-13 16:03:34 -07:00
parent 160c6ff0f0
commit ab88d8511d
16 changed files with 290 additions and 297 deletions

View file

@ -7,66 +7,6 @@ import (
"github.com/vattle/sqlboiler/strmangle"
)
// SetComplement subtracts the elements in b from a
func SetComplement(a []string, b []string) []string {
c := make([]string, 0, len(a))
for _, aVal := range a {
found := false
for _, bVal := range b {
if aVal == bVal {
found = true
break
}
}
if !found {
c = append(c, aVal)
}
}
return c
}
// SetIntersect returns the elements that are common in a and b
func SetIntersect(a []string, b []string) []string {
c := make([]string, 0, len(a))
for _, aVal := range a {
found := false
for _, bVal := range b {
if aVal == bVal {
found = true
break
}
}
if found {
c = append(c, aVal)
}
}
return c
}
// SetMerge will return a merged slice without duplicates
func SetMerge(a []string, b []string) []string {
var x, merged []string
x = append(x, a...)
x = append(x, b...)
check := map[string]bool{}
for _, v := range x {
if check[v] == true {
continue
}
merged = append(merged, v)
check[v] = true
}
return merged
}
// NonZeroDefaultSet returns the fields included in the
// defaults slice that are non zero values
func NonZeroDefaultSet(defaults []string, obj interface{}) []string {
@ -89,26 +29,3 @@ func NonZeroDefaultSet(defaults []string, obj interface{}) []string {
return c
}
// SortByKeys returns a new ordered slice based on the keys ordering
func SortByKeys(keys []string, strs []string) []string {
c := make([]string, len(strs))
index := 0
Outer:
for _, v := range keys {
for _, k := range strs {
if v == k {
c[index] = v
index++
if index > len(strs)-1 {
break Outer
}
break
}
}
}
return c
}

View file

@ -14,125 +14,6 @@ type testObj struct {
HeadSize int
}
func TestSetComplement(t *testing.T) {
t.Parallel()
tests := []struct {
A []string
B []string
C []string
}{
{
[]string{"thing1", "thing2", "thing3"},
[]string{"thing2", "otherthing", "stuff"},
[]string{"thing1", "thing3"},
},
{
[]string{},
[]string{"thing1", "thing2"},
[]string{},
},
{
[]string{"thing1", "thing2"},
[]string{},
[]string{"thing1", "thing2"},
},
{
[]string{"thing1", "thing2"},
[]string{"thing1", "thing2"},
[]string{},
},
}
for i, test := range tests {
c := SetComplement(test.A, test.B)
if !reflect.DeepEqual(test.C, c) {
t.Errorf("[%d] mismatch:\nWant: %#v\nGot: %#v", i, test.C, c)
}
}
}
func TestSetIntersect(t *testing.T) {
t.Parallel()
tests := []struct {
A []string
B []string
C []string
}{
{
[]string{"thing1", "thing2", "thing3"},
[]string{"thing2", "otherthing", "stuff"},
[]string{"thing2"},
},
{
[]string{},
[]string{"thing1", "thing2"},
[]string{},
},
{
[]string{"thing1", "thing2"},
[]string{},
[]string{},
},
{
[]string{"thing1", "thing2"},
[]string{"thing1", "thing2"},
[]string{"thing1", "thing2"},
},
}
for i, test := range tests {
c := SetIntersect(test.A, test.B)
if !reflect.DeepEqual(test.C, c) {
t.Errorf("[%d] mismatch:\nWant: %#v\nGot: %#v", i, test.C, c)
}
}
}
func TestSetMerge(t *testing.T) {
t.Parallel()
tests := []struct {
A []string
B []string
C []string
}{
{
[]string{"thing1", "thing2", "thing3"},
[]string{"thing1", "thing3", "thing4"},
[]string{"thing1", "thing2", "thing3", "thing4"},
},
{
[]string{},
[]string{"thing1", "thing2"},
[]string{"thing1", "thing2"},
},
{
[]string{"thing1", "thing2"},
[]string{},
[]string{"thing1", "thing2"},
},
{
[]string{"thing1", "thing2", "thing3"},
[]string{"thing1", "thing2", "thing3"},
[]string{"thing1", "thing2", "thing3"},
},
{
[]string{"thing1", "thing2"},
[]string{"thing3", "thing4"},
[]string{"thing1", "thing2", "thing3", "thing4"},
},
}
for i, test := range tests {
m := SetMerge(test.A, test.B)
if !reflect.DeepEqual(test.C, m) {
t.Errorf("[%d] mismatch:\nWant: %#v\nGot: %#v", i, test.C, m)
}
}
}
func TestNonZeroDefaultSet(t *testing.T) {
t.Parallel()
@ -184,36 +65,3 @@ func TestNonZeroDefaultSet(t *testing.T) {
}
}
}
func TestSortByKeys(t *testing.T) {
t.Parallel()
tests := []struct {
Keys []string
Strs []string
Ret []string
}{
{
[]string{"id", "name", "thing", "stuff"},
[]string{"thing", "stuff", "name", "id"},
[]string{"id", "name", "thing", "stuff"},
},
{
[]string{"id", "name", "thing", "stuff"},
[]string{"id", "name", "thing", "stuff"},
[]string{"id", "name", "thing", "stuff"},
},
{
[]string{"id", "name", "thing", "stuff"},
[]string{"stuff", "thing"},
[]string{"thing", "stuff"},
},
}
for i, test := range tests {
z := SortByKeys(test.Keys, test.Strs)
if !reflect.DeepEqual(test.Ret, z) {
t.Errorf("[%d] mismatch:\nWant: %#v\nGot: %#v", i, test.Ret, z)
}
}
}

95
strmangle/sets.go Normal file
View file

@ -0,0 +1,95 @@
package strmangle
// SetInclude checks to see if the string is found in the string slice
func SetInclude(str string, slice []string) bool {
for _, s := range slice {
if str == s {
return true
}
}
return false
}
// SetComplement subtracts the elements in b from a
func SetComplement(a []string, b []string) []string {
c := make([]string, 0, len(a))
for _, aVal := range a {
found := false
for _, bVal := range b {
if aVal == bVal {
found = true
break
}
}
if !found {
c = append(c, aVal)
}
}
return c
}
// SetIntersect returns the elements that are common in a and b
func SetIntersect(a []string, b []string) []string {
c := make([]string, 0, len(a))
for _, aVal := range a {
found := false
for _, bVal := range b {
if aVal == bVal {
found = true
break
}
}
if found {
c = append(c, aVal)
}
}
return c
}
// SetMerge will return a merged slice without duplicates
func SetMerge(a []string, b []string) []string {
var x, merged []string
x = append(x, a...)
x = append(x, b...)
check := map[string]bool{}
for _, v := range x {
if check[v] == true {
continue
}
merged = append(merged, v)
check[v] = true
}
return merged
}
// SortByKeys returns a new ordered slice based on the keys ordering
func SortByKeys(keys []string, strs []string) []string {
c := make([]string, len(strs))
index := 0
Outer:
for _, v := range keys {
for _, k := range strs {
if v == k {
c[index] = v
index++
if index > len(strs)-1 {
break Outer
}
break
}
}
}
return c
}

170
strmangle/sets_test.go Normal file
View file

@ -0,0 +1,170 @@
package strmangle
import (
"reflect"
"testing"
)
func TestSetInclude(t *testing.T) {
t.Parallel()
elements := []string{"one", "two"}
if got := SetInclude("one", elements); !got {
t.Error("should have found element key")
}
if got := SetInclude("three", elements); got {
t.Error("should not have found element key")
}
}
func TestSetComplement(t *testing.T) {
t.Parallel()
tests := []struct {
A []string
B []string
C []string
}{
{
[]string{"thing1", "thing2", "thing3"},
[]string{"thing2", "otherthing", "stuff"},
[]string{"thing1", "thing3"},
},
{
[]string{},
[]string{"thing1", "thing2"},
[]string{},
},
{
[]string{"thing1", "thing2"},
[]string{},
[]string{"thing1", "thing2"},
},
{
[]string{"thing1", "thing2"},
[]string{"thing1", "thing2"},
[]string{},
},
}
for i, test := range tests {
c := SetComplement(test.A, test.B)
if !reflect.DeepEqual(test.C, c) {
t.Errorf("[%d] mismatch:\nWant: %#v\nGot: %#v", i, test.C, c)
}
}
}
func TestSetIntersect(t *testing.T) {
t.Parallel()
tests := []struct {
A []string
B []string
C []string
}{
{
[]string{"thing1", "thing2", "thing3"},
[]string{"thing2", "otherthing", "stuff"},
[]string{"thing2"},
},
{
[]string{},
[]string{"thing1", "thing2"},
[]string{},
},
{
[]string{"thing1", "thing2"},
[]string{},
[]string{},
},
{
[]string{"thing1", "thing2"},
[]string{"thing1", "thing2"},
[]string{"thing1", "thing2"},
},
}
for i, test := range tests {
c := SetIntersect(test.A, test.B)
if !reflect.DeepEqual(test.C, c) {
t.Errorf("[%d] mismatch:\nWant: %#v\nGot: %#v", i, test.C, c)
}
}
}
func TestSetMerge(t *testing.T) {
t.Parallel()
tests := []struct {
A []string
B []string
C []string
}{
{
[]string{"thing1", "thing2", "thing3"},
[]string{"thing1", "thing3", "thing4"},
[]string{"thing1", "thing2", "thing3", "thing4"},
},
{
[]string{},
[]string{"thing1", "thing2"},
[]string{"thing1", "thing2"},
},
{
[]string{"thing1", "thing2"},
[]string{},
[]string{"thing1", "thing2"},
},
{
[]string{"thing1", "thing2", "thing3"},
[]string{"thing1", "thing2", "thing3"},
[]string{"thing1", "thing2", "thing3"},
},
{
[]string{"thing1", "thing2"},
[]string{"thing3", "thing4"},
[]string{"thing1", "thing2", "thing3", "thing4"},
},
}
for i, test := range tests {
m := SetMerge(test.A, test.B)
if !reflect.DeepEqual(test.C, m) {
t.Errorf("[%d] mismatch:\nWant: %#v\nGot: %#v", i, test.C, m)
}
}
}
func TestSortByKeys(t *testing.T) {
t.Parallel()
tests := []struct {
Keys []string
Strs []string
Ret []string
}{
{
[]string{"id", "name", "thing", "stuff"},
[]string{"thing", "stuff", "name", "id"},
[]string{"id", "name", "thing", "stuff"},
},
{
[]string{"id", "name", "thing", "stuff"},
[]string{"id", "name", "thing", "stuff"},
[]string{"id", "name", "thing", "stuff"},
},
{
[]string{"id", "name", "thing", "stuff"},
[]string{"stuff", "thing"},
[]string{"thing", "stuff"},
},
}
for i, test := range tests {
z := SortByKeys(test.Keys, test.Strs)
if !reflect.DeepEqual(test.Ret, z) {
t.Errorf("[%d] mismatch:\nWant: %#v\nGot: %#v", i, test.Ret, z)
}
}
}

View file

@ -1,6 +1,6 @@
// Package strmangle is used exclusively by the templates in sqlboiler.
// There are many helper functions to deal with bdb.* values as well
// as string manipulation. Because it is focused on pipelining inside templates
// Package strmangle is a collection of string manipulation functions.
// Primarily used by boil and templates for code generation.
// Because it is focused on pipelining inside templates
// you will see some odd parameter ordering.
package strmangle
@ -216,24 +216,6 @@ func StringMap(modifier func(string) string, strs []string) []string {
return ret
}
// MakeDBName takes a table name in the format of "table_name" and a
// column name in the format of "column_name" and returns a name used in the
// `db:""` component of an object in the format of "table_name_column_name"
func MakeDBName(tableName, colName string) string {
return fmt.Sprintf("%s_%s", tableName, colName)
}
// HasElement checks to see if the string is found in the string slice
func HasElement(str string, slice []string) bool {
for _, s := range slice {
if str == s {
return true
}
}
return false
}
// PrefixStringSlice with the given str.
func PrefixStringSlice(str string, strs []string) []string {
ret := make([]string, len(strs))

View file

@ -234,26 +234,6 @@ func TestStringMap(t *testing.T) {
}
}
func TestMakeDBName(t *testing.T) {
t.Parallel()
if out := MakeDBName("a", "b"); out != "a_b" {
t.Error("Out was wrong:", out)
}
}
func TestHasElement(t *testing.T) {
t.Parallel()
elements := []string{"one", "two"}
if got := HasElement("one", elements); !got {
t.Error("should have found element key")
}
if got := HasElement("three", elements); got {
t.Error("should not have found element key")
}
}
func TestPrefixStringSlice(t *testing.T) {
t.Parallel()
@ -262,6 +242,7 @@ func TestPrefixStringSlice(t *testing.T) {
t.Error("wrong output:", got)
}
}
func TestWhereClause(t *testing.T) {
t.Parallel()

View file

@ -148,12 +148,14 @@ var templateFunctions = template.FuncMap{
"join": func(sep string, slice []string) string { return strings.Join(slice, sep) },
"joinSlices": strmangle.JoinSlices,
"stringMap": strmangle.StringMap,
"hasElement": strmangle.HasElement,
"prefixStringSlice": strmangle.PrefixStringSlice,
// String Map ops
"makeStringMap": strmangle.MakeStringMap,
// Set operations
"setInclude": strmangle.SetInclude,
// Database related mangling
"whereClause": strmangle.WhereClause,
"identQuote": strmangle.IdentQuote,
@ -165,7 +167,6 @@ var templateFunctions = template.FuncMap{
"textsFromRelationship": textsFromRelationship,
// dbdrivers ops
"makeDBName": strmangle.MakeDBName,
"driverUsesLastInsertID": bdb.DriverUsesLastInsertID,
"filterColumnsByDefault": bdb.FilterColumnsByDefault,
"filterColumnsBySimpleDefault": bdb.FilterColumnsBySimpleDefault,

View file

@ -9,7 +9,6 @@ var (
{{$varNameSingular}}UniqueColumns = []string{{"{"}}{{.Table.Columns | filterColumnsByUnique | columnNames | stringMap .StringFuncs.quoteWrap | join ", "}}{{"}"}}
{{$varNameSingular}}PrimaryKeyColumns = []string{{"{"}}{{.Table.PKey.Columns | stringMap .StringFuncs.quoteWrap | join ", "}}{{"}"}}
{{$varNameSingular}}AutoIncrementColumns = []string{{"{"}}{{.Table.Columns | filterColumnsByAutoIncrement true | columnNames | stringMap .StringFuncs.quoteWrap | join "," }}{{"}"}}
{{$varNameSingular}}AutoIncPrimaryKeys = []string{{"{"}}{{.Table.Columns | filterColumnsByPrimaryKey .Table.PKey | filterColumnsByDefault true | columnNames | join ", "}}{{"}"}}
)
type (

View file

@ -103,18 +103,18 @@ func (o *{{$tableNameSingular}}) Insert(exec boil.Executor, whitelist ... string
// - the return columns are the result of (columns with default values - the previous set)
func (o *{{$tableNameSingular}}) generateInsertColumns(whitelist ...string) ([]string, []string) {
if len(whitelist) > 0 {
return whitelist, boil.SetComplement({{$varNameSingular}}ColumnsWithDefault, whitelist)
return whitelist, strmangle.SetComplement({{$varNameSingular}}ColumnsWithDefault, whitelist)
}
var wl []string
wl = append(wl, {{$varNameSingular}}ColumnsWithoutDefault...)
wl = boil.SetMerge(boil.NonZeroDefaultSet({{$varNameSingular}}ColumnsWithDefault, o), wl)
wl = boil.SortByKeys({{$varNameSingular}}Columns, wl)
wl = strmangle.SetMerge(boil.NonZeroDefaultSet({{$varNameSingular}}ColumnsWithDefault, o), wl)
wl = strmangle.SortByKeys({{$varNameSingular}}Columns, wl)
// Only return the columns with default values that are not in the insert whitelist
rc := boil.SetComplement({{$varNameSingular}}ColumnsWithDefault, wl)
rc := strmangle.SetComplement({{$varNameSingular}}ColumnsWithDefault, wl)
return wl, rc
}

View file

@ -155,5 +155,5 @@ func (o *{{$tableNameSingular}}) generateUpdateColumns(whitelist ...string) []st
return whitelist
}
return boil.SetComplement({{$varNameSingular}}Columns, {{$varNameSingular}}PrimaryKeyColumns)
return strmangle.SetComplement({{$varNameSingular}}Columns, {{$varNameSingular}}PrimaryKeyColumns)
}

View file

@ -32,7 +32,7 @@ func Test{{$tableNamePlural}}Find(t *testing.T) {
}
{{end}}
colsWithoutPrimKeys := boil.SetComplement({{$varNameSingular}}Columns, {{$varNameSingular}}PrimaryKeyColumns)
colsWithoutPrimKeys := strmangle.SetComplement({{$varNameSingular}}Columns, {{$varNameSingular}}PrimaryKeyColumns)
fRef := reflect.ValueOf(f).Elem()
for _, v := range colsWithoutPrimKeys {
val := fRef.FieldByName(v)

View file

@ -9,25 +9,25 @@ func {{$varNameSingular}}CompareVals(o *{{$tableNameSingular}}, j *{{$tableNameS
{{if eq $value.Type "null.Time"}}
if ((equal && o.{{titleCase $value.Name}}.Time.Format("02/01/2006") != j.{{titleCase $value.Name}}.Time.Format("02/01/2006")) ||
(!equal && o.{{titleCase $value.Name}}.Time.Format("02/01/2006") == j.{{titleCase $value.Name}}.Time.Format("02/01/2006"))) &&
!strmangle.HasElement("{{$value.Name}}", blacklist) {
!strmangle.SetInclude("{{$value.Name}}", blacklist) {
return errors.New(fmt.Sprintf("NullTime {{$value.Name}} unexpected value, got:\nStruct: %#v\nResponse: %#v\n\n", o.{{titleCase $value.Name}}.Time.Format("02/01/2006"), j.{{titleCase $value.Name}}.Time.Format("02/01/2006")))
}
{{else if eq $value.Type "time.Time"}}
if ((equal && o.{{titleCase $value.Name}}.Format("02/01/2006") != j.{{titleCase $value.Name}}.Format("02/01/2006")) ||
(!equal && o.{{titleCase $value.Name}}.Format("02/01/2006") == j.{{titleCase $value.Name}}.Format("02/01/2006"))) &&
!strmangle.HasElement("{{$value.Name}}", blacklist) {
!strmangle.SetInclude("{{$value.Name}}", blacklist) {
return errors.New(fmt.Sprintf("Time {{$value.Name}} unexpected value, got:\nStruct: %#v\nResponse: %#v\n\n", o.{{titleCase $value.Name}}.Format("02/01/2006"), j.{{titleCase $value.Name}}.Format("02/01/2006")))
}
{{else if eq $value.Type "[]byte"}}
if ((equal && !byteSliceEqual(o.{{titleCase $value.Name}}, j.{{titleCase $value.Name}})) ||
(!equal && byteSliceEqual(o.{{titleCase $value.Name}}, j.{{titleCase $value.Name}}))) &&
!strmangle.HasElement("{{$value.Name}}", blacklist) {
!strmangle.SetInclude("{{$value.Name}}", blacklist) {
return errors.New(fmt.Sprintf("Expected {{$value.Name}} columns to match, got:\nStruct: %#v\nResponse: %#v\n\n", o.{{titleCase $value.Name}}, j.{{titleCase $value.Name}}))
}
{{else}}
if ((equal && j.{{titleCase $value.Name}} != o.{{titleCase $value.Name}}) ||
(!equal && j.{{titleCase $value.Name}} == o.{{titleCase $value.Name}})) &&
!strmangle.HasElement("{{$value.Name}}", blacklist) {
!strmangle.SetInclude("{{$value.Name}}", blacklist) {
return errors.New(fmt.Sprintf("Expected {{$value.Name}} columns to match, got:\nStruct: %#v\nResponse: %#v\n\n", o.{{titleCase $value.Name}}, j.{{titleCase $value.Name}}))
}
{{end}}

View file

@ -73,7 +73,7 @@ func Test{{$tableNamePlural}}Insert(t *testing.T) {
regularCols := []string{{"{"}}{{.Table.Columns | filterColumnsByAutoIncrement false | filterColumnsByDefault false | columnNames | stringMap $parent.StringFuncs.quoteWrap | join ", "}}{{"}"}}
// Remove the validated columns, they can never be zero values
regularCols = boil.SetComplement(regularCols, {{$varNameSingular}}ValidatedColumns)
regularCols = strmangle.SetComplement(regularCols, {{$varNameSingular}}ValidatedColumns)
// Ensure the non-defaultvalue columns and non-autoincrement columns are stored correctly as zero or null values.
for _, c := range regularCols {

View file

@ -26,7 +26,7 @@ func Test{{$tableNamePlural}}Reload(t *testing.T) {
t.Errorf("Unable to randomize {{$tableNameSingular}} struct members excluding primary keys: %s", err)
}
colsWithoutPrimKeys := boil.SetComplement({{$varNameSingular}}Columns, {{$varNameSingular}}PrimaryKeyColumns)
colsWithoutPrimKeys := strmangle.SetComplement({{$varNameSingular}}Columns, {{$varNameSingular}}PrimaryKeyColumns)
if err = o.UpdateG(colsWithoutPrimKeys...); err != nil {
t.Errorf("Unable to update the {{$tableNameSingular}} row: %s", err)
@ -73,7 +73,7 @@ func Test{{$tableNamePlural}}ReloadAll(t *testing.T) {
t.Errorf("Unable to randomize {{$tableNameSingular}} slice excluding primary keys: %s", err)
}
colsWithoutPrimKeys := boil.SetComplement({{$varNameSingular}}Columns, {{$varNameSingular}}PrimaryKeyColumns)
colsWithoutPrimKeys := strmangle.SetComplement({{$varNameSingular}}Columns, {{$varNameSingular}}PrimaryKeyColumns)
for i := 0; i < len(o1); i++ {
if err = o1[i].UpdateG(colsWithoutPrimKeys...); err != nil {

View file

@ -20,7 +20,7 @@ func Test{{$tableNamePlural}}Select(t *testing.T) {
item := {{$tableNameSingular}}{}
blacklistCols := boil.SetMerge({{$varNameSingular}}AutoIncrementColumns, {{$varNameSingular}}PrimaryKeyColumns)
blacklistCols := strmangle.SetMerge({{$varNameSingular}}AutoIncrementColumns, {{$varNameSingular}}PrimaryKeyColumns)
if err = boil.RandomizeStruct(&item, {{$varNameSingular}}DBTypes, false, blacklistCols...); err != nil {
t.Errorf("Unable to randomize {{$tableNameSingular}} struct: %s", err)
}

View file

@ -11,12 +11,12 @@ func Test{{$tableNamePlural}}Update(t *testing.T) {
t.Errorf("Unable to insert zero-value item {{$tableNameSingular}}:\n%#v\nErr: %s", item, err)
}
blacklistCols := boil.SetMerge({{$varNameSingular}}AutoIncrementColumns, {{$varNameSingular}}PrimaryKeyColumns)
blacklistCols := strmangle.SetMerge({{$varNameSingular}}AutoIncrementColumns, {{$varNameSingular}}PrimaryKeyColumns)
if err = boil.RandomizeStruct(&item, {{$varNameSingular}}DBTypes, false, blacklistCols...); err != nil {
t.Errorf("Unable to randomize {{$tableNameSingular}} struct: %s", err)
}
whitelist := boil.SetComplement({{$varNameSingular}}Columns, {{$varNameSingular}}AutoIncrementColumns)
whitelist := strmangle.SetComplement({{$varNameSingular}}Columns, {{$varNameSingular}}AutoIncrementColumns)
if err = item.UpdateG(whitelist...); err != nil {
t.Errorf("Unable to update {{$tableNameSingular}}: %s", err)
}
@ -64,14 +64,14 @@ func Test{{$tableNamePlural}}SliceUpdateAll(t *testing.T) {
vals := M{}
tmp := {{$tableNameSingular}}{}
blacklist := boil.SetMerge({{$varNameSingular}}PrimaryKeyColumns, {{$varNameSingular}}UniqueColumns)
blacklist := strmangle.SetMerge({{$varNameSingular}}PrimaryKeyColumns, {{$varNameSingular}}UniqueColumns)
if err = boil.RandomizeStruct(&tmp, {{$varNameSingular}}DBTypes, false, blacklist...); err != nil {
t.Errorf("Unable to randomize struct {{$tableNameSingular}}: %s", err)
}
// Build the columns and column values from the randomized struct
tmpVal := reflect.Indirect(reflect.ValueOf(tmp))
nonBlacklist := boil.SetComplement({{$varNameSingular}}Columns, blacklist)
nonBlacklist := strmangle.SetComplement({{$varNameSingular}}Columns, blacklist)
for _, col := range nonBlacklist {
vals[col] = tmpVal.FieldByName(strmangle.TitleCase(col)).Interface()
}