From 9a1c0d956d3b9504dacbd1c09dc1d93e2b16ff38 Mon Sep 17 00:00:00 2001 From: Jinzhu Date: Sun, 17 Nov 2013 08:28:30 +0800 Subject: [PATCH] cache snake, upper values --- README.md | 2 ++ field.go | 2 +- gorm_test.go | 4 ++-- model.go | 11 +---------- utils.go | 30 ++++++++++++++++++++++++++---- 5 files changed, 32 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 27a5f3e0..3b50dab1 100644 --- a/README.md +++ b/README.md @@ -735,6 +735,8 @@ db.Where("email = ?", "x@example.org").Attrs(User{RegisteredIp: "111.111.111.111 ``` ## TODO +* Rows, Row +* Cache Stmt for performance * Join, Having, Group, Includes * Scopes, Valiations * AlertColumn, DropColumn, AddIndex, RemoveIndex diff --git a/field.go b/field.go index 8455c184..16016c34 100644 --- a/field.go +++ b/field.go @@ -107,7 +107,7 @@ func parseSqlTag(str string) (typ string, addational_typ string, size int) { m := make(map[string]string) for _, value := range tags { v := strings.Split(value, ":") - k := strings.Trim(strings.ToUpper(v[0]), " ") + k := strings.TrimSpace(strings.ToUpper(v[0])) if len(v) == 2 { m[k] = v[1] } else { diff --git a/gorm_test.go b/gorm_test.go index 38ec2b54..54c4c49e 100644 --- a/gorm_test.go +++ b/gorm_test.go @@ -1365,7 +1365,7 @@ func TestQueryChain(t *testing.T) { } func BenchmarkGorm(b *testing.B) { - b.N = 2000 + b.N = 5000 for x := 0; x < b.N; x++ { e := strconv.Itoa(x) + "benchmark@example.org" email := BigEmail{Email: e, UserAgent: "pc", RegisteredAt: time.Now()} @@ -1388,7 +1388,7 @@ func BenchmarkRawSql(b *testing.B) { update_sql := "UPDATE emails SET email = $1, updated_at = $2 WHERE id = $3" delete_sql := "DELETE FROM orders WHERE id = $1" - b.N = 2000 + b.N = 5000 for x := 0; x < b.N; x++ { var id int64 e := strconv.Itoa(x) + "benchmark@example.org" diff --git a/model.go b/model.go index 0bb29e84..a9f7440e 100644 --- a/model.go +++ b/model.go @@ -40,10 +40,6 @@ func (m *Model) primaryKeyDb() string { } func (m *Model) fields(operation string) (fields []*Field) { - if len(m._cache_fields[operation]) > 0 { - return m._cache_fields[operation] - } - indirect_value := m.reflectData() if !indirect_value.IsValid() { return @@ -79,14 +75,10 @@ func (m *Model) fields(operation string) (fields []*Field) { field.structField = p field.reflectValue = value field.Value = value.Interface() + field.parseAssociation() fields = append(fields, &field) } } - - if len(m._cache_fields) == 0 { - m._cache_fields = map[string][]*Field{} - } - m._cache_fields[operation] = fields return } @@ -225,7 +217,6 @@ func (m *Model) setValueByColumn(name string, value interface{}, out interface{} func (m *Model) beforeAssociations() (fields []*Field) { for _, field := range m.fields("null") { - field.parseAssociation() if field.beforeAssociation && !field.isBlank() { fields = append(fields, field) } diff --git a/utils.go b/utils.go index d4897c13..0d0b48fd 100644 --- a/utils.go +++ b/utils.go @@ -10,18 +10,37 @@ import ( "time" ) -func toSnake(s string) string { +var toSnakeMap map[string]string +var toUpperMap map[string]string + +func init() { + toSnakeMap = map[string]string{} + toUpperMap = map[string]string{} +} + +func toSnake(u string) string { + if v := toSnakeMap[u]; v != "" { + return v + } + buf := bytes.NewBufferString("") - for i, v := range s { + for i, v := range u { if i > 0 && v >= 'A' && v <= 'Z' { buf.WriteRune('_') } buf.WriteRune(v) } - return strings.ToLower(buf.String()) + + s := strings.ToLower(buf.String()) + toSnakeMap[u] = s + return s } func snakeToUpperCamel(s string) string { + if v := toUpperMap[s]; v != "" { + return v + } + buf := bytes.NewBufferString("") for _, v := range strings.Split(s, "_") { if len(v) > 0 { @@ -29,7 +48,10 @@ func snakeToUpperCamel(s string) string { buf.WriteString(v[1:]) } } - return buf.String() + + u := buf.String() + toUpperMap[s] = u + return u } func toSearchableMap(attrs ...interface{}) (result interface{}) {