From 09fb8005f6a92090fda2320d1818eb2aee2d233c Mon Sep 17 00:00:00 2001 From: Patrick O'brien Date: Fri, 2 Sep 2016 17:09:42 +1000 Subject: [PATCH] Add TitleCase cache --- README.md | 2 +- boil/reflect.go | 81 ++++++--------------- boil/reflect_test.go | 20 ++--- strmangle/strmangle.go | 35 ++++++--- strmangle/strmangle_test.go | 2 +- templates/03_finishers.tpl | 4 +- templates/06_relationship_to_one_eager.tpl | 2 +- templates/07_relationship_to_many_eager.tpl | 2 +- templates/11_find.tpl | 2 +- templates/12_insert.tpl | 12 +-- templates/13_update.tpl | 2 +- templates/14_upsert.tpl | 6 +- templates/16_reload.tpl | 2 +- 13 files changed, 69 insertions(+), 103 deletions(-) diff --git a/README.md b/README.md index 836b323..ff535ea 100644 --- a/README.md +++ b/README.md @@ -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 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 -(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: diff --git a/boil/reflect.go b/boil/reflect.go index 4f8a8d6..f7e279f 100644 --- a/boil/reflect.go +++ b/boil/reflect.go @@ -74,18 +74,12 @@ func (q *Query) BindP(obj interface{}) { // For custom objects that want to use eager loading, please see the // loadRelationships function. 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) - if err != nil { return err } - return bind(rows, obj, structType, sliceType, singular, titleCases) + return bind(rows, obj, structType, sliceType, singular) } // 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() 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) if err != nil { 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") } defer rows.Close() - - if res := bind(rows, obj, structType, sliceType, singular, titleCases); res != nil { + if res := bind(rows, obj, structType, sliceType, singular); res != nil { return res } @@ -255,7 +243,7 @@ func bindChecks(obj interface{}) (structType reflect.Type, sliceType reflect.Typ 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() if err != nil { 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() if !ok { - mapping, err = bindMapping(structType, titleCases, cols) + mapping, err = bindMapping(structType, cols) if err != nil { return err } @@ -317,13 +305,13 @@ func bind(rows *sql.Rows, obj interface{}, structType, sliceType reflect.Type, s 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)) - mapping := makeStructMapping(typ, titleCases) + mapping := makeStructMapping(typ) ColLoop: for i, c := range cols { - name := strmangle.TitleCaseIdentifier(c, titleCases) + name := strmangle.TitleCaseIdentifier(c) ptrMap, ok := mapping[name] if ok { ptrs[i] = ptrMap @@ -376,13 +364,13 @@ func ptrFromMapping(val reflect.Value, mapping uint64) reflect.Value { 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) - makeStructMappingHelper(typ, "", 0, 0, fieldMaps, titleCases) + makeStructMappingHelper(typ, "", 0, 0, 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 { typ = typ.Elem() } @@ -391,7 +379,7 @@ func makeStructMappingHelper(typ reflect.Type, prefix string, current uint64, de for i := 0; i < n; i++ { f := typ.Field(i) - tag, recurse := getBoilTag(f, titleCases) + tag, recurse := getBoilTag(f) if len(tag) == 0 { tag = f.Name } else if tag[0] == '-' { @@ -403,7 +391,7 @@ func makeStructMappingHelper(typ reflect.Type, prefix string, current uint64, de } if recurse { - makeStructMappingHelper(f.Type, tag, current|uint64(i)<