improve WhereBuilder feature for package gdb

This commit is contained in:
John Guo
2022-05-07 14:26:56 +08:00
parent 8c40a53b80
commit eaae7f46d2
6 changed files with 32 additions and 22 deletions

View File

@ -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 {

View File

@ -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
}

View File

@ -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...)
}

View File

@ -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)

View File

@ -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)

View File

@ -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,