Add TitleCase cache
This commit is contained in:
parent
b101df0a24
commit
09fb8005f6
13 changed files with 69 additions and 103 deletions
|
@ -20,7 +20,7 @@ same SQL helpers and wrappers for every project we were creating, but did not wa
|
||||||
there that utilize the "code-first" approach. `SQLX` is a great project, but very minimalistic and still requires a
|
there that utilize the "code-first" approach. `SQLX` is a great project, but very minimalistic and still requires a
|
||||||
considerable amount of boilerplate for every project. Originally this project started as a SQL boilerplate generator (hence the name)
|
considerable amount of boilerplate for every project. Originally this project started as a SQL boilerplate generator (hence the name)
|
||||||
that generated simple helper functions, but we found that we could accomplish the same task by turning it into a
|
that generated simple helper functions, but we found that we could accomplish the same task by turning it into a
|
||||||
(mostly) fully fledged ORM, without any sacrifice in performance or congruency, but generous gains in flexibility.
|
(mostly) fully fledged ORM generator, without any sacrifice in performance or congruency, but generous gains in flexibility.
|
||||||
|
|
||||||
The approach we've taken has afforded us the following benefits:
|
The approach we've taken has afforded us the following benefits:
|
||||||
|
|
||||||
|
|
|
@ -74,18 +74,12 @@ func (q *Query) BindP(obj interface{}) {
|
||||||
// For custom objects that want to use eager loading, please see the
|
// For custom objects that want to use eager loading, please see the
|
||||||
// loadRelationships function.
|
// loadRelationships function.
|
||||||
func Bind(rows *sql.Rows, obj interface{}) error {
|
func Bind(rows *sql.Rows, obj interface{}) error {
|
||||||
return BindFast(rows, obj, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
// BindFast uses a lookup table for column_name to ColumnName to avoid TitleCase.
|
|
||||||
func BindFast(rows *sql.Rows, obj interface{}, titleCases map[string]string) error {
|
|
||||||
structType, sliceType, singular, err := bindChecks(obj)
|
structType, sliceType, singular, err := bindChecks(obj)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return bind(rows, obj, structType, sliceType, singular, titleCases)
|
return bind(rows, obj, structType, sliceType, singular)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bind executes the query and inserts the
|
// Bind executes the query and inserts the
|
||||||
|
@ -93,11 +87,6 @@ func BindFast(rows *sql.Rows, obj interface{}, titleCases map[string]string) err
|
||||||
//
|
//
|
||||||
// See documentation for boil.Bind()
|
// See documentation for boil.Bind()
|
||||||
func (q *Query) Bind(obj interface{}) error {
|
func (q *Query) Bind(obj interface{}) error {
|
||||||
return q.BindFast(obj, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
// BindFast uses a lookup table for column_name to ColumnName to avoid TitleCase.
|
|
||||||
func (q *Query) BindFast(obj interface{}, titleCases map[string]string) error {
|
|
||||||
structType, sliceType, singular, err := bindChecks(obj)
|
structType, sliceType, singular, err := bindChecks(obj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -108,8 +97,7 @@ func (q *Query) BindFast(obj interface{}, titleCases map[string]string) error {
|
||||||
return errors.Wrap(err, "bind failed to execute query")
|
return errors.Wrap(err, "bind failed to execute query")
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
|
if res := bind(rows, obj, structType, sliceType, singular); res != nil {
|
||||||
if res := bind(rows, obj, structType, sliceType, singular, titleCases); res != nil {
|
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -255,7 +243,7 @@ func bindChecks(obj interface{}) (structType reflect.Type, sliceType reflect.Typ
|
||||||
return structType, sliceType, singular, nil
|
return structType, sliceType, singular, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func bind(rows *sql.Rows, obj interface{}, structType, sliceType reflect.Type, singular bool, titleCases map[string]string) error {
|
func bind(rows *sql.Rows, obj interface{}, structType, sliceType reflect.Type, singular bool) error {
|
||||||
cols, err := rows.Columns()
|
cols, err := rows.Columns()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "bind failed to get column names")
|
return errors.Wrap(err, "bind failed to get column names")
|
||||||
|
@ -275,7 +263,7 @@ func bind(rows *sql.Rows, obj interface{}, structType, sliceType reflect.Type, s
|
||||||
mut.RUnlock()
|
mut.RUnlock()
|
||||||
|
|
||||||
if !ok {
|
if !ok {
|
||||||
mapping, err = bindMapping(structType, titleCases, cols)
|
mapping, err = bindMapping(structType, cols)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -317,13 +305,13 @@ func bind(rows *sql.Rows, obj interface{}, structType, sliceType reflect.Type, s
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func bindMapping(typ reflect.Type, titleCases map[string]string, cols []string) ([]uint64, error) {
|
func bindMapping(typ reflect.Type, cols []string) ([]uint64, error) {
|
||||||
ptrs := make([]uint64, len(cols))
|
ptrs := make([]uint64, len(cols))
|
||||||
mapping := makeStructMapping(typ, titleCases)
|
mapping := makeStructMapping(typ)
|
||||||
|
|
||||||
ColLoop:
|
ColLoop:
|
||||||
for i, c := range cols {
|
for i, c := range cols {
|
||||||
name := strmangle.TitleCaseIdentifier(c, titleCases)
|
name := strmangle.TitleCaseIdentifier(c)
|
||||||
ptrMap, ok := mapping[name]
|
ptrMap, ok := mapping[name]
|
||||||
if ok {
|
if ok {
|
||||||
ptrs[i] = ptrMap
|
ptrs[i] = ptrMap
|
||||||
|
@ -376,13 +364,13 @@ func ptrFromMapping(val reflect.Value, mapping uint64) reflect.Value {
|
||||||
panic("could not find pointer from mapping")
|
panic("could not find pointer from mapping")
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeStructMapping(typ reflect.Type, titleCases map[string]string) map[string]uint64 {
|
func makeStructMapping(typ reflect.Type) map[string]uint64 {
|
||||||
fieldMaps := make(map[string]uint64)
|
fieldMaps := make(map[string]uint64)
|
||||||
makeStructMappingHelper(typ, "", 0, 0, fieldMaps, titleCases)
|
makeStructMappingHelper(typ, "", 0, 0, fieldMaps)
|
||||||
return fieldMaps
|
return fieldMaps
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeStructMappingHelper(typ reflect.Type, prefix string, current uint64, depth uint, fieldMaps map[string]uint64, titleCases map[string]string) {
|
func makeStructMappingHelper(typ reflect.Type, prefix string, current uint64, depth uint, fieldMaps map[string]uint64) {
|
||||||
if typ.Kind() == reflect.Ptr {
|
if typ.Kind() == reflect.Ptr {
|
||||||
typ = typ.Elem()
|
typ = typ.Elem()
|
||||||
}
|
}
|
||||||
|
@ -391,7 +379,7 @@ func makeStructMappingHelper(typ reflect.Type, prefix string, current uint64, de
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
f := typ.Field(i)
|
f := typ.Field(i)
|
||||||
|
|
||||||
tag, recurse := getBoilTag(f, titleCases)
|
tag, recurse := getBoilTag(f)
|
||||||
if len(tag) == 0 {
|
if len(tag) == 0 {
|
||||||
tag = f.Name
|
tag = f.Name
|
||||||
} else if tag[0] == '-' {
|
} else if tag[0] == '-' {
|
||||||
|
@ -403,7 +391,7 @@ func makeStructMappingHelper(typ reflect.Type, prefix string, current uint64, de
|
||||||
}
|
}
|
||||||
|
|
||||||
if recurse {
|
if recurse {
|
||||||
makeStructMappingHelper(f.Type, tag, current|uint64(i)<<depth, depth+8, fieldMaps, titleCases)
|
makeStructMappingHelper(f.Type, tag, current|uint64(i)<<depth, depth+8, fieldMaps)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -411,7 +399,7 @@ func makeStructMappingHelper(typ reflect.Type, prefix string, current uint64, de
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getBoilTag(field reflect.StructField, titleCases map[string]string) (name string, recurse bool) {
|
func getBoilTag(field reflect.StructField) (name string, recurse bool) {
|
||||||
tag := field.Tag.Get("boil")
|
tag := field.Tag.Get("boil")
|
||||||
name = field.Name
|
name = field.Name
|
||||||
|
|
||||||
|
@ -419,24 +407,15 @@ func getBoilTag(field reflect.StructField, titleCases map[string]string) (name s
|
||||||
return name, false
|
return name, false
|
||||||
}
|
}
|
||||||
|
|
||||||
var ok bool
|
|
||||||
ind := strings.IndexByte(tag, ',')
|
ind := strings.IndexByte(tag, ',')
|
||||||
if ind == -1 {
|
if ind == -1 {
|
||||||
name, ok = titleCases[tag]
|
return strmangle.TitleCase(tag), false
|
||||||
if !ok {
|
|
||||||
name = strmangle.TitleCase(tag)
|
|
||||||
}
|
|
||||||
return name, false
|
|
||||||
} else if ind == 0 {
|
} else if ind == 0 {
|
||||||
return name, true
|
return name, true
|
||||||
}
|
}
|
||||||
|
|
||||||
nameFragment := tag[:ind]
|
nameFragment := tag[:ind]
|
||||||
name, ok = titleCases[nameFragment]
|
return strmangle.TitleCase(nameFragment), true
|
||||||
if !ok {
|
|
||||||
name = strmangle.TitleCase(nameFragment)
|
|
||||||
}
|
|
||||||
return name, true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeCacheKey(typ string, cols []string) string {
|
func makeCacheKey(typ string, cols []string) string {
|
||||||
|
@ -452,17 +431,12 @@ func makeCacheKey(typ string, cols []string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetStructValues returns the values (as interface) of the matching columns in obj
|
// GetStructValues returns the values (as interface) of the matching columns in obj
|
||||||
func GetStructValues(obj interface{}, titleCases map[string]string, columns ...string) []interface{} {
|
func GetStructValues(obj interface{}, columns ...string) []interface{} {
|
||||||
ret := make([]interface{}, len(columns))
|
ret := make([]interface{}, len(columns))
|
||||||
val := reflect.Indirect(reflect.ValueOf(obj))
|
val := reflect.Indirect(reflect.ValueOf(obj))
|
||||||
|
|
||||||
for i, c := range columns {
|
for i, c := range columns {
|
||||||
var fieldName string
|
fieldName := strmangle.TitleCase(c)
|
||||||
if titleCases == nil {
|
|
||||||
fieldName = strmangle.TitleCase(c)
|
|
||||||
} else {
|
|
||||||
fieldName = titleCases[c]
|
|
||||||
}
|
|
||||||
field := val.FieldByName(fieldName)
|
field := val.FieldByName(fieldName)
|
||||||
if !field.IsValid() {
|
if !field.IsValid() {
|
||||||
panic(fmt.Sprintf("unable to find field with name: %s\n%#v", fieldName, obj))
|
panic(fmt.Sprintf("unable to find field with name: %s\n%#v", fieldName, obj))
|
||||||
|
@ -474,19 +448,13 @@ func GetStructValues(obj interface{}, titleCases map[string]string, columns ...s
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSliceValues returns the values (as interface) of the matching columns in obj.
|
// GetSliceValues returns the values (as interface) of the matching columns in obj.
|
||||||
func GetSliceValues(slice []interface{}, titleCases map[string]string, columns ...string) []interface{} {
|
func GetSliceValues(slice []interface{}, columns ...string) []interface{} {
|
||||||
ret := make([]interface{}, len(slice)*len(columns))
|
ret := make([]interface{}, len(slice)*len(columns))
|
||||||
|
|
||||||
for i, obj := range slice {
|
for i, obj := range slice {
|
||||||
val := reflect.Indirect(reflect.ValueOf(obj))
|
val := reflect.Indirect(reflect.ValueOf(obj))
|
||||||
for j, c := range columns {
|
for j, c := range columns {
|
||||||
var fieldName string
|
fieldName := strmangle.TitleCase(c)
|
||||||
if titleCases == nil {
|
|
||||||
fieldName = strmangle.TitleCase(c)
|
|
||||||
} else {
|
|
||||||
fieldName = titleCases[c]
|
|
||||||
}
|
|
||||||
|
|
||||||
field := val.FieldByName(fieldName)
|
field := val.FieldByName(fieldName)
|
||||||
if !field.IsValid() {
|
if !field.IsValid() {
|
||||||
panic(fmt.Sprintf("unable to find field with name: %s\n%#v", fieldName, obj))
|
panic(fmt.Sprintf("unable to find field with name: %s\n%#v", fieldName, obj))
|
||||||
|
@ -499,7 +467,7 @@ func GetSliceValues(slice []interface{}, titleCases map[string]string, columns .
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetStructPointers returns a slice of pointers to the matching columns in obj
|
// GetStructPointers returns a slice of pointers to the matching columns in obj
|
||||||
func GetStructPointers(obj interface{}, titleCases map[string]string, columns ...string) []interface{} {
|
func GetStructPointers(obj interface{}, columns ...string) []interface{} {
|
||||||
val := reflect.ValueOf(obj).Elem()
|
val := reflect.ValueOf(obj).Elem()
|
||||||
|
|
||||||
var ln int
|
var ln int
|
||||||
|
@ -513,14 +481,7 @@ func GetStructPointers(obj interface{}, titleCases map[string]string, columns ..
|
||||||
} else {
|
} else {
|
||||||
ln = len(columns)
|
ln = len(columns)
|
||||||
getField = func(v reflect.Value, i int) reflect.Value {
|
getField = func(v reflect.Value, i int) reflect.Value {
|
||||||
var fieldName string
|
return v.FieldByName(strmangle.TitleCase(columns[i]))
|
||||||
if titleCases == nil {
|
|
||||||
fieldName = strmangle.TitleCase(columns[i])
|
|
||||||
} else {
|
|
||||||
fieldName = titleCases[columns[i]]
|
|
||||||
}
|
|
||||||
|
|
||||||
return v.FieldByName(fieldName)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -115,7 +115,7 @@ func TestMakeStructMapping(t *testing.T) {
|
||||||
} `boil:",bind"`
|
} `boil:",bind"`
|
||||||
}{}
|
}{}
|
||||||
|
|
||||||
got := makeStructMapping(reflect.TypeOf(testStruct), nil)
|
got := makeStructMapping(reflect.TypeOf(testStruct))
|
||||||
|
|
||||||
expectMap := map[string]uint64{
|
expectMap := map[string]uint64{
|
||||||
"Different": testMakeMapping(0),
|
"Different": testMakeMapping(0),
|
||||||
|
@ -189,16 +189,6 @@ func TestGetBoilTag(t *testing.T) {
|
||||||
Nose string
|
Nose string
|
||||||
}
|
}
|
||||||
|
|
||||||
var testTitleCases = map[string]string{
|
|
||||||
"test_one": "TestOne",
|
|
||||||
"test_two": "TestTwo",
|
|
||||||
"middle_name": "MiddleName",
|
|
||||||
"awesome_name": "AwesomeName",
|
|
||||||
"age": "Age",
|
|
||||||
"face": "Face",
|
|
||||||
"nose": "Nose",
|
|
||||||
}
|
|
||||||
|
|
||||||
var structFields []reflect.StructField
|
var structFields []reflect.StructField
|
||||||
typ := reflect.TypeOf(TestStruct{})
|
typ := reflect.TypeOf(TestStruct{})
|
||||||
removeOk := func(thing reflect.StructField, ok bool) reflect.StructField {
|
removeOk := func(thing reflect.StructField, ok bool) reflect.StructField {
|
||||||
|
@ -228,7 +218,7 @@ func TestGetBoilTag(t *testing.T) {
|
||||||
{"Nose", false},
|
{"Nose", false},
|
||||||
}
|
}
|
||||||
for i, s := range structFields {
|
for i, s := range structFields {
|
||||||
name, recurse := getBoilTag(s, testTitleCases)
|
name, recurse := getBoilTag(s)
|
||||||
if expect[i].Name != name {
|
if expect[i].Name != name {
|
||||||
t.Errorf("Invalid name, expect %q, got %q", expect[i].Name, name)
|
t.Errorf("Invalid name, expect %q, got %q", expect[i].Name, name)
|
||||||
}
|
}
|
||||||
|
@ -665,7 +655,7 @@ func TestGetStructValues(t *testing.T) {
|
||||||
NullBool: null.NewBool(true, false),
|
NullBool: null.NewBool(true, false),
|
||||||
}
|
}
|
||||||
|
|
||||||
vals := GetStructValues(&o, nil, "title_thing", "name", "id", "stuff", "things", "time", "null_bool")
|
vals := GetStructValues(&o, "title_thing", "name", "id", "stuff", "things", "time", "null_bool")
|
||||||
if vals[0].(string) != "patrick" {
|
if vals[0].(string) != "patrick" {
|
||||||
t.Errorf("Want test, got %s", vals[0])
|
t.Errorf("Want test, got %s", vals[0])
|
||||||
}
|
}
|
||||||
|
@ -704,7 +694,7 @@ func TestGetSliceValues(t *testing.T) {
|
||||||
in[0] = o[0]
|
in[0] = o[0]
|
||||||
in[1] = o[1]
|
in[1] = o[1]
|
||||||
|
|
||||||
vals := GetSliceValues(in, nil, "id", "name")
|
vals := GetSliceValues(in, "id", "name")
|
||||||
if got := vals[0].(int); got != 5 {
|
if got := vals[0].(int); got != 5 {
|
||||||
t.Error(got)
|
t.Error(got)
|
||||||
}
|
}
|
||||||
|
@ -729,7 +719,7 @@ func TestGetStructPointers(t *testing.T) {
|
||||||
Title: "patrick",
|
Title: "patrick",
|
||||||
}
|
}
|
||||||
|
|
||||||
ptrs := GetStructPointers(&o, nil, "title", "id")
|
ptrs := GetStructPointers(&o, "title", "id")
|
||||||
*ptrs[0].(*string) = "test"
|
*ptrs[0].(*string) = "test"
|
||||||
if o.Title != "test" {
|
if o.Title != "test" {
|
||||||
t.Errorf("Expected test, got %s", o.Title)
|
t.Errorf("Expected test, got %s", o.Title)
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"math"
|
"math"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -150,6 +151,13 @@ func Singular(name string) string {
|
||||||
return buf.String()
|
return buf.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// titleCaseCache holds the mapping of title cases.
|
||||||
|
// Example: map["MyWord"] == "my_word"
|
||||||
|
var (
|
||||||
|
mut sync.RWMutex
|
||||||
|
titleCaseCache = map[string]string{}
|
||||||
|
)
|
||||||
|
|
||||||
// TitleCase changes a snake-case variable name
|
// TitleCase changes a snake-case variable name
|
||||||
// into a go styled object variable name of "ColumnName".
|
// into a go styled object variable name of "ColumnName".
|
||||||
// titleCase also fully uppercases "ID" components of names, for example
|
// titleCase also fully uppercases "ID" components of names, for example
|
||||||
|
@ -158,6 +166,14 @@ func Singular(name string) string {
|
||||||
// Note: This method is ugly because it has been highly optimized,
|
// Note: This method is ugly because it has been highly optimized,
|
||||||
// we found that it was a fairly large bottleneck when we were using regexp.
|
// we found that it was a fairly large bottleneck when we were using regexp.
|
||||||
func TitleCase(n string) string {
|
func TitleCase(n string) string {
|
||||||
|
// Attempt to fetch from cache
|
||||||
|
mut.RLock()
|
||||||
|
val, ok := titleCaseCache[n]
|
||||||
|
mut.RUnlock()
|
||||||
|
if ok {
|
||||||
|
return val
|
||||||
|
}
|
||||||
|
|
||||||
ln := len(n)
|
ln := len(n)
|
||||||
name := []byte(n)
|
name := []byte(n)
|
||||||
buf := GetBuffer()
|
buf := GetBuffer()
|
||||||
|
@ -219,6 +235,12 @@ func TitleCase(n string) string {
|
||||||
|
|
||||||
ret := buf.String()
|
ret := buf.String()
|
||||||
PutBuffer(buf)
|
PutBuffer(buf)
|
||||||
|
|
||||||
|
// Cache the title case result
|
||||||
|
mut.Lock()
|
||||||
|
titleCaseCache[n] = ret
|
||||||
|
mut.Unlock()
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,14 +286,10 @@ func CamelCase(name string) string {
|
||||||
|
|
||||||
// TitleCaseIdentifier splits on dots and then titlecases each fragment.
|
// TitleCaseIdentifier splits on dots and then titlecases each fragment.
|
||||||
// map titleCase (split c ".")
|
// map titleCase (split c ".")
|
||||||
func TitleCaseIdentifier(id string, titleCases map[string]string) string {
|
func TitleCaseIdentifier(id string) string {
|
||||||
nextDot := strings.IndexByte(id, '.')
|
nextDot := strings.IndexByte(id, '.')
|
||||||
if nextDot < 0 {
|
if nextDot < 0 {
|
||||||
titled, ok := titleCases[id]
|
return TitleCase(id)
|
||||||
if !ok {
|
|
||||||
titled = TitleCase(id)
|
|
||||||
}
|
|
||||||
return titled
|
|
||||||
}
|
}
|
||||||
|
|
||||||
buf := GetBuffer()
|
buf := GetBuffer()
|
||||||
|
@ -283,10 +301,7 @@ func TitleCaseIdentifier(id string, titleCases map[string]string) string {
|
||||||
fmt.Println(lastDot, nextDot)
|
fmt.Println(lastDot, nextDot)
|
||||||
fragment := id[lastDot:nextDot]
|
fragment := id[lastDot:nextDot]
|
||||||
|
|
||||||
titled, ok := titleCases[fragment]
|
titled := TitleCase(fragment)
|
||||||
if !ok {
|
|
||||||
titled = TitleCase(fragment)
|
|
||||||
}
|
|
||||||
|
|
||||||
if addDots {
|
if addDots {
|
||||||
buf.WriteByte('.')
|
buf.WriteByte('.')
|
||||||
|
|
|
@ -242,7 +242,7 @@ func TestTitleCaseIdentifier(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, test := range tests {
|
for i, test := range tests {
|
||||||
if out := TitleCaseIdentifier(test.In, nil); out != test.Out {
|
if out := TitleCaseIdentifier(test.In); out != test.Out {
|
||||||
t.Errorf("[%d] (%s) Out was wrong: %q, want: %q", i, test.In, out, test.Out)
|
t.Errorf("[%d] (%s) Out was wrong: %q, want: %q", i, test.In, out, test.Out)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ func (q {{$varNameSingular}}Query) One() (*{{$tableNameSingular}}, error) {
|
||||||
|
|
||||||
boil.SetLimit(q.Query, 1)
|
boil.SetLimit(q.Query, 1)
|
||||||
|
|
||||||
err := q.BindFast(o, {{$varNameSingular}}TitleCases)
|
err := q.Bind(o)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Cause(err) == sql.ErrNoRows {
|
if errors.Cause(err) == sql.ErrNoRows {
|
||||||
return nil, sql.ErrNoRows
|
return nil, sql.ErrNoRows
|
||||||
|
@ -47,7 +47,7 @@ func (q {{$varNameSingular}}Query) AllP() {{$tableNameSingular}}Slice {
|
||||||
func (q {{$varNameSingular}}Query) All() ({{$tableNameSingular}}Slice, error) {
|
func (q {{$varNameSingular}}Query) All() ({{$tableNameSingular}}Slice, error) {
|
||||||
var o {{$tableNameSingular}}Slice
|
var o {{$tableNameSingular}}Slice
|
||||||
|
|
||||||
err := q.BindFast(&o, {{$varNameSingular}}TitleCases)
|
err := q.Bind(&o)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "{{.PkgName}}: failed to assign all query results to {{$tableNameSingular}} slice")
|
return nil, errors.Wrap(err, "{{.PkgName}}: failed to assign all query results to {{$tableNameSingular}} slice")
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ func ({{$varNameSingular}}L) Load{{.Function.Name}}(e boil.Executor, singular bo
|
||||||
defer results.Close()
|
defer results.Close()
|
||||||
|
|
||||||
var resultSlice []*{{.ForeignTable.NameGo}}
|
var resultSlice []*{{.ForeignTable.NameGo}}
|
||||||
if err = boil.BindFast(results, &resultSlice, {{.ForeignTable.Name | singular | camelCase}}TitleCases); err != nil {
|
if err = boil.Bind(results, &resultSlice); err != nil {
|
||||||
return errors.Wrap(err, "failed to bind eager loaded slice {{.ForeignTable.NameGo}}")
|
return errors.Wrap(err, "failed to bind eager loaded slice {{.ForeignTable.NameGo}}")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,7 @@ func ({{$varNameSingular}}L) Load{{$txt.Function.Name}}(e boil.Executor, singula
|
||||||
return errors.Wrap(err, "failed to plebian-bind eager loaded slice {{.ForeignTable}}")
|
return errors.Wrap(err, "failed to plebian-bind eager loaded slice {{.ForeignTable}}")
|
||||||
}
|
}
|
||||||
{{else -}}
|
{{else -}}
|
||||||
if err = boil.BindFast(results, &resultSlice, {{.ForeignTable | singular | camelCase}}TitleCases); err != nil {
|
if err = boil.Bind(results, &resultSlice); err != nil {
|
||||||
return errors.Wrap(err, "failed to bind eager loaded slice {{.ForeignTable}}")
|
return errors.Wrap(err, "failed to bind eager loaded slice {{.ForeignTable}}")
|
||||||
}
|
}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
|
@ -34,7 +34,7 @@ func Find{{$tableNameSingular}}(exec boil.Executor, {{$pkArgs}}, selectCols ...s
|
||||||
|
|
||||||
q := boil.SQL(exec, query, {{$pkNames | join ", "}})
|
q := boil.SQL(exec, query, {{$pkNames | join ", "}})
|
||||||
|
|
||||||
err := q.BindFast({{$varNameSingular}}Obj, {{$varNameSingular}}TitleCases)
|
err := q.Bind({{$varNameSingular}}Obj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Cause(err) == sql.ErrNoRows {
|
if errors.Cause(err) == sql.ErrNoRows {
|
||||||
return nil, sql.ErrNoRows
|
return nil, sql.ErrNoRows
|
||||||
|
|
|
@ -53,10 +53,10 @@ func (o *{{$tableNameSingular}}) Insert(exec boil.Executor, whitelist ... string
|
||||||
{{if .UseLastInsertID}}
|
{{if .UseLastInsertID}}
|
||||||
if boil.DebugMode {
|
if boil.DebugMode {
|
||||||
fmt.Fprintln(boil.DebugWriter, ins)
|
fmt.Fprintln(boil.DebugWriter, ins)
|
||||||
fmt.Fprintln(boil.DebugWriter, boil.GetStructValues(o, {{$varNameSingular}}TitleCases, wl...))
|
fmt.Fprintln(boil.DebugWriter, boil.GetStructValues(o, wl...))
|
||||||
}
|
}
|
||||||
|
|
||||||
result, err := exec.Exec(ins, boil.GetStructValues(o, {{$varNameSingular}}TitleCases, wl...)...)
|
result, err := exec.Exec(ins, boil.GetStructValues(o, wl...)...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "{{.PkgName}}: unable to insert into {{.Table.Name}}")
|
return errors.Wrap(err, "{{.PkgName}}: unable to insert into {{.Table.Name}}")
|
||||||
}
|
}
|
||||||
|
@ -77,21 +77,21 @@ func (o *{{$tableNameSingular}}) Insert(exec boil.Executor, whitelist ... string
|
||||||
}
|
}
|
||||||
|
|
||||||
sel := fmt.Sprintf(`SELECT %s FROM {{.Table.Name}} WHERE %s`, strings.Join(returnColumns, `","`), strmangle.WhereClause(1, {{$varNameSingular}}AutoIncPrimaryKeys))
|
sel := fmt.Sprintf(`SELECT %s FROM {{.Table.Name}} WHERE %s`, strings.Join(returnColumns, `","`), strmangle.WhereClause(1, {{$varNameSingular}}AutoIncPrimaryKeys))
|
||||||
err = exec.QueryRow(sel, lastID).Scan(boil.GetStructPointers(o, {{$varNameSingular}}TitleCases, returnColumns...))
|
err = exec.QueryRow(sel, lastID).Scan(boil.GetStructPointers(o, returnColumns...))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "{{.PkgName}}: unable to populate default values for {{.Table.Name}}")
|
return errors.Wrap(err, "{{.PkgName}}: unable to populate default values for {{.Table.Name}}")
|
||||||
}
|
}
|
||||||
{{else}}
|
{{else}}
|
||||||
if len(returnColumns) != 0 {
|
if len(returnColumns) != 0 {
|
||||||
ins = ins + fmt.Sprintf(` RETURNING %s`, strings.Join(returnColumns, ","))
|
ins = ins + fmt.Sprintf(` RETURNING %s`, strings.Join(returnColumns, ","))
|
||||||
err = exec.QueryRow(ins, boil.GetStructValues(o, {{$varNameSingular}}TitleCases, wl...)...).Scan(boil.GetStructPointers(o, {{$varNameSingular}}TitleCases, returnColumns...)...)
|
err = exec.QueryRow(ins, boil.GetStructValues(o, wl...)...).Scan(boil.GetStructPointers(o, returnColumns...)...)
|
||||||
} else {
|
} else {
|
||||||
_, err = exec.Exec(ins, boil.GetStructValues(o, {{$varNameSingular}}TitleCases, wl...)...)
|
_, err = exec.Exec(ins, boil.GetStructValues(o, wl...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
if boil.DebugMode {
|
if boil.DebugMode {
|
||||||
fmt.Fprintln(boil.DebugWriter, ins)
|
fmt.Fprintln(boil.DebugWriter, ins)
|
||||||
fmt.Fprintln(boil.DebugWriter, boil.GetStructValues(o, {{$varNameSingular}}TitleCases, wl...))
|
fmt.Fprintln(boil.DebugWriter, boil.GetStructValues(o, wl...))
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -53,7 +53,7 @@ func (o *{{$tableNameSingular}}) Update(exec boil.Executor, whitelist ... string
|
||||||
}
|
}
|
||||||
|
|
||||||
query = fmt.Sprintf(`UPDATE {{.Table.Name}} SET %s WHERE %s`, strmangle.SetParamNames(wl), strmangle.WhereClause(len(wl)+1, {{$varNameSingular}}PrimaryKeyColumns))
|
query = fmt.Sprintf(`UPDATE {{.Table.Name}} SET %s WHERE %s`, strmangle.SetParamNames(wl), strmangle.WhereClause(len(wl)+1, {{$varNameSingular}}PrimaryKeyColumns))
|
||||||
values = boil.GetStructValues(o, {{$varNameSingular}}TitleCases, wl...)
|
values = boil.GetStructValues(o, wl...)
|
||||||
values = append(values, {{.Table.PKey.Columns | stringMap .StringFuncs.titleCase | prefixStringSlice "o." | join ", "}})
|
values = append(values, {{.Table.PKey.Columns | stringMap .StringFuncs.titleCase | prefixStringSlice "o." | join ", "}})
|
||||||
|
|
||||||
if boil.DebugMode {
|
if boil.DebugMode {
|
||||||
|
|
|
@ -58,16 +58,16 @@ func (o *{{$tableNameSingular}}) Upsert(exec boil.Executor, updateOnConflict boo
|
||||||
|
|
||||||
if boil.DebugMode {
|
if boil.DebugMode {
|
||||||
fmt.Fprintln(boil.DebugWriter, query)
|
fmt.Fprintln(boil.DebugWriter, query)
|
||||||
fmt.Fprintln(boil.DebugWriter, boil.GetStructValues(o, {{$varNameSingular}}TitleCases, whitelist...))
|
fmt.Fprintln(boil.DebugWriter, boil.GetStructValues(o, whitelist...))
|
||||||
}
|
}
|
||||||
|
|
||||||
{{- if .UseLastInsertID}}
|
{{- if .UseLastInsertID}}
|
||||||
return errors.New("don't know how to do this yet")
|
return errors.New("don't know how to do this yet")
|
||||||
{{- else}}
|
{{- else}}
|
||||||
if len(ret) != 0 {
|
if len(ret) != 0 {
|
||||||
err = exec.QueryRow(query, boil.GetStructValues(o, {{$varNameSingular}}TitleCases, whitelist...)...).Scan(boil.GetStructPointers(o, {{$varNameSingular}}TitleCases, ret...)...)
|
err = exec.QueryRow(query, boil.GetStructValues(o, whitelist...)...).Scan(boil.GetStructPointers(o, ret...)...)
|
||||||
} else {
|
} else {
|
||||||
_, err = exec.Exec(query, boil.GetStructValues(o, {{$varNameSingular}}TitleCases, whitelist...)...)
|
_, err = exec.Exec(query, boil.GetStructValues(o, whitelist...)...)
|
||||||
}
|
}
|
||||||
{{- end}}
|
{{- end}}
|
||||||
|
|
||||||
|
|
|
@ -74,7 +74,7 @@ func (o *{{$tableNameSingular}}Slice) ReloadAll(exec boil.Executor) error {
|
||||||
|
|
||||||
q := boil.SQL(exec, sql, args...)
|
q := boil.SQL(exec, sql, args...)
|
||||||
|
|
||||||
err := q.BindFast(&{{$varNamePlural}}, {{$varNameSingular}}TitleCases)
|
err := q.Bind(&{{$varNamePlural}})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "{{.PkgName}}: unable to reload all in {{$tableNameSingular}}Slice")
|
return errors.Wrap(err, "{{.PkgName}}: unable to reload all in {{$tableNameSingular}}Slice")
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue