diff --git a/database/gdb/gdb_model.go b/database/gdb/gdb_model.go index 7ce229346..70429a339 100644 --- a/database/gdb/gdb_model.go +++ b/database/gdb/gdb_model.go @@ -136,9 +136,7 @@ func (c *Core) Model(tableNameQueryOrStruct ...interface{}) *Model { extraArgs: extraArgs, } m.whereBuilder = m.Builder() - // Assign the safe attribute of WhereBuilder to nil, - // to make it use the safe attribute of its bound model. - m.whereBuilder.safe = nil + m.whereBuilder.safe = &m.safe if defaultModelSafe { m.safe = true } @@ -253,8 +251,8 @@ func (m *Model) Schema(schema string) *Model { return model } -// Clone creates and returns a new model which is a clone of current model. -// Note that it uses deep-copy for the clone. +// Clone creates and returns a new model which is a Clone of current model. +// Note that it uses deep-copy for the Clone. func (m *Model) Clone() *Model { newModel := (*Model)(nil) if m.tx != nil { @@ -265,7 +263,7 @@ func (m *Model) Clone() *Model { // Basic attributes copy. *newModel = *m // WhereBuilder copy, note the attribute pointer. - newModel.whereBuilder = m.whereBuilder.clone() + newModel.whereBuilder = m.whereBuilder.Clone() newModel.whereBuilder.model = newModel // Shallow copy slice attributes. if n := len(m.extraArgs); n > 0 { diff --git a/database/gdb/gdb_model_builder.go b/database/gdb/gdb_model_builder.go index 7687da675..a271e33f5 100644 --- a/database/gdb/gdb_model_builder.go +++ b/database/gdb/gdb_model_builder.go @@ -48,11 +48,11 @@ func (b *WhereBuilder) getBuilder() *WhereBuilder { if !isSafe { return b } else { - return b.clone() + return b.Clone() } } -func (b *WhereBuilder) clone() *WhereBuilder { +func (b *WhereBuilder) Clone() *WhereBuilder { newBuilder := b.model.Builder() newBuilder.safe = b.safe newBuilder.whereHolder = make([]WhereHolder, len(b.whereHolder)) @@ -114,3 +114,21 @@ func (b *WhereBuilder) Build() (conditionWhere string, conditionArgs []interface } return } + +func (b *WhereBuilder) convertWrappedBuilder(where interface{}, args []interface{}) (newWhere interface{}, newArgs []interface{}) { + var builder *WhereBuilder + switch v := where.(type) { + case WhereBuilder: + builder = &v + case *WhereBuilder: + builder = v + } + if builder != nil { + conditionWhere, conditionArgs := builder.Build() + if len(b.whereHolder) == 0 { + conditionWhere = "(" + conditionWhere + ")" + } + return conditionWhere, conditionArgs + } + return where, args +} diff --git a/database/gdb/gdb_model_builder_where.go b/database/gdb/gdb_model_builder_where.go index 0a4e45de7..4980175c0 100644 --- a/database/gdb/gdb_model_builder_where.go +++ b/database/gdb/gdb_model_builder_where.go @@ -16,6 +16,8 @@ import ( // string/map/gmap/slice/struct/*struct, etc. Note that, if it's called more than one times, // multiple conditions will be joined into where statement using "AND". func (b *WhereBuilder) doWhereType(whereType string, where interface{}, args ...interface{}) *WhereBuilder { + where, args = b.convertWrappedBuilder(where, args) + builder := b.getBuilder() if builder.whereHolder == nil { builder.whereHolder = make([]WhereHolder, 0) @@ -59,20 +61,6 @@ func (b *WhereBuilder) doWherefType(t string, format string, args ...interface{} // Where("age IN(?,?)", 18, 50) // Where(User{ Id : 1, UserName : "john"}). func (b *WhereBuilder) Where(where interface{}, args ...interface{}) *WhereBuilder { - var builder *WhereBuilder - switch v := where.(type) { - case WhereBuilder: - builder = &v - case *WhereBuilder: - builder = v - } - if builder != nil { - conditionWhere, conditionArgs := builder.Build() - if len(b.whereHolder) == 0 { - conditionWhere = "(" + conditionWhere + ")" - } - return b.doWhereType(``, conditionWhere, conditionArgs...) - } return b.doWhereType(``, where, args...) } diff --git a/database/gdb/gdb_model_builder_where_prefix.go b/database/gdb/gdb_model_builder_where_prefix.go index 7cc189901..5fbebb6a0 100644 --- a/database/gdb/gdb_model_builder_where_prefix.go +++ b/database/gdb/gdb_model_builder_where_prefix.go @@ -11,6 +11,8 @@ package gdb // WherePrefix("order", "status", "paid") => WHERE `order`.`status`='paid' // WherePrefix("order", struct{Status:"paid", "channel":"bank"}) => WHERE `order`.`status`='paid' AND `order`.`channel`='bank' func (b *WhereBuilder) WherePrefix(prefix string, where interface{}, args ...interface{}) *WhereBuilder { + where, args = b.convertWrappedBuilder(where, args) + builder := b.getBuilder() if builder.whereHolder == nil { builder.whereHolder = make([]WhereHolder, 0) diff --git a/database/gdb/gdb_model_builder_whereor.go b/database/gdb/gdb_model_builder_whereor.go index 993c4def3..ebd5157b3 100644 --- a/database/gdb/gdb_model_builder_whereor.go +++ b/database/gdb/gdb_model_builder_whereor.go @@ -14,6 +14,8 @@ import ( // WhereOr adds "OR" condition to the where statement. func (b *WhereBuilder) doWhereOrType(t string, where interface{}, args ...interface{}) *WhereBuilder { + where, args = b.convertWrappedBuilder(where, args) + builder := b.getBuilder() if builder.whereHolder == nil { builder.whereHolder = make([]WhereHolder, 0) diff --git a/database/gdb/gdb_model_builder_whereor_prefix.go b/database/gdb/gdb_model_builder_whereor_prefix.go index c720b7c3f..102c4936a 100644 --- a/database/gdb/gdb_model_builder_whereor_prefix.go +++ b/database/gdb/gdb_model_builder_whereor_prefix.go @@ -11,6 +11,8 @@ package gdb // WhereOrPrefix("order", "status", "paid") => WHERE xxx OR (`order`.`status`='paid') // WhereOrPrefix("order", struct{Status:"paid", "channel":"bank"}) => WHERE xxx OR (`order`.`status`='paid' AND `order`.`channel`='bank') func (b *WhereBuilder) WhereOrPrefix(prefix string, where interface{}, args ...interface{}) *WhereBuilder { + where, args = b.convertWrappedBuilder(where, args) + builder := b.getBuilder() builder.whereHolder = append(builder.whereHolder, WhereHolder{ Type: whereHolderTypeDefault,