diff --git a/database/gdb/gdb_model.go b/database/gdb/gdb_model.go index 142a8f3cf..c8a51945d 100644 --- a/database/gdb/gdb_model.go +++ b/database/gdb/gdb_model.go @@ -65,6 +65,7 @@ type ModelWhereHolder struct { Operator int // Operator for this holder. Where interface{} // Where parameter, which can commonly be type of string/map/struct. Args []interface{} // Arguments for where parameter. + Prefix string // Field prefix, eg: "user.", "order.". } const ( diff --git a/database/gdb/gdb_model_condition.go b/database/gdb/gdb_model_condition.go index 65efb008f..06172dd05 100644 --- a/database/gdb/gdb_model_condition.go +++ b/database/gdb/gdb_model_condition.go @@ -37,6 +37,21 @@ func (m *Model) Where(where interface{}, args ...interface{}) *Model { return model } +// WherePrefix performs as Where, but it adds prefix to each field in where statement. +func (m *Model) WherePrefix(prefix string, where interface{}, args ...interface{}) *Model { + model := m.getModel() + if model.whereHolder == nil { + model.whereHolder = make([]ModelWhereHolder, 0) + } + model.whereHolder = append(model.whereHolder, ModelWhereHolder{ + Operator: whereHolderOperatorWhere, + Where: where, + Args: args, + Prefix: prefix, + }) + return model +} + // Having sets the having statement for the model. // The parameters of this function usage are as the same as function Where. // See Where. @@ -159,6 +174,21 @@ func (m *Model) WhereOr(where interface{}, args ...interface{}) *Model { return model } +// WhereOrPrefix performs as WhereOr, but it adds prefix to each field in where statement. +func (m *Model) WhereOrPrefix(prefix string, where interface{}, args ...interface{}) *Model { + model := m.getModel() + if model.whereHolder == nil { + model.whereHolder = make([]ModelWhereHolder, 0) + } + model.whereHolder = append(model.whereHolder, ModelWhereHolder{ + Operator: whereHolderOperatorOr, + Where: where, + Args: args, + Prefix: prefix, + }) + return model +} + // WhereOrf builds `OR` condition string using fmt.Sprintf and arguments. func (m *Model) WhereOrf(format string, args ...interface{}) *Model { var ( @@ -335,13 +365,16 @@ func (m *Model) Page(page, limit int) *Model { // The parameter `limit1` specifies whether limits querying only one record if m.limit is not set. func (m *Model) formatCondition(limit1 bool, isCountStatement bool) (conditionWhere string, conditionExtra string, conditionArgs []interface{}) { var ( - prefix = "" + autoPrefix = "" ) if gstr.Contains(m.tables, " JOIN ") { - prefix = m.db.GetCore().QuoteWord(m.tablesInit) + autoPrefix = m.db.GetCore().QuoteWord(m.tablesInit) } if len(m.whereHolder) > 0 { for _, v := range m.whereHolder { + if v.Prefix == "" { + v.Prefix = autoPrefix + } switch v.Operator { case whereHolderOperatorWhere: if conditionWhere == "" { @@ -352,7 +385,7 @@ func (m *Model) formatCondition(limit1 bool, isCountStatement bool) (conditionWh OmitEmpty: m.option&optionOmitEmptyWhere > 0, Schema: m.schema, Table: m.tables, - Prefix: prefix, + Prefix: v.Prefix, }) if len(newWhere) > 0 { conditionWhere = newWhere @@ -370,7 +403,7 @@ func (m *Model) formatCondition(limit1 bool, isCountStatement bool) (conditionWh OmitEmpty: m.option&optionOmitEmptyWhere > 0, Schema: m.schema, Table: m.tables, - Prefix: prefix, + Prefix: v.Prefix, }) if len(newWhere) > 0 { if len(conditionWhere) == 0 { @@ -391,7 +424,7 @@ func (m *Model) formatCondition(limit1 bool, isCountStatement bool) (conditionWh OmitEmpty: m.option&optionOmitEmptyWhere > 0, Schema: m.schema, Table: m.tables, - Prefix: prefix, + Prefix: v.Prefix, }) if len(newWhere) > 0 { if len(conditionWhere) == 0 { @@ -439,7 +472,7 @@ func (m *Model) formatCondition(limit1 bool, isCountStatement bool) (conditionWh OmitEmpty: m.option&optionOmitEmptyWhere > 0, Schema: m.schema, Table: m.tables, - Prefix: prefix, + Prefix: autoPrefix, }) if len(havingStr) > 0 { conditionExtra += " HAVING " + havingStr diff --git a/database/gdb/gdb_z_mysql_model_join_test.go b/database/gdb/gdb_z_mysql_model_join_test.go index 4942ac8e7..4230042a8 100644 --- a/database/gdb/gdb_z_mysql_model_join_test.go +++ b/database/gdb/gdb_z_mysql_model_join_test.go @@ -23,7 +23,6 @@ func Test_Model_LeftJoinOnField(t *testing.T) { createInitTable(table2) defer dropTable(table2) - db.SetDebug(true) gtest.C(t, func(t *gtest.T) { r, err := db.Model(table1). FieldsPrefix(table1, "*"). @@ -47,7 +46,6 @@ func Test_Model_RightJoinOnField(t *testing.T) { createInitTable(table2) defer dropTable(table2) - db.SetDebug(true) gtest.C(t, func(t *gtest.T) { r, err := db.Model(table1). FieldsPrefix(table1, "*"). @@ -71,7 +69,6 @@ func Test_Model_InnerJoinOnField(t *testing.T) { createInitTable(table2) defer dropTable(table2) - db.SetDebug(true) gtest.C(t, func(t *gtest.T) { r, err := db.Model(table1). FieldsPrefix(table1, "*"). diff --git a/database/gdb/gdb_z_mysql_model_where_test.go b/database/gdb/gdb_z_mysql_model_where_test.go new file mode 100644 index 000000000..796d23ffc --- /dev/null +++ b/database/gdb/gdb_z_mysql_model_where_test.go @@ -0,0 +1,70 @@ +// Copyright GoFrame Author(https://goframe.org). All Rights Reserved. +// +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, +// You can obtain one at https://github.com/gogf/gf. + +package gdb_test + +import ( + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gtime" + "github.com/gogf/gf/v2/test/gtest" + "testing" +) + +func Test_Model_WherePrefix(t *testing.T) { + var ( + table1 = gtime.TimestampNanoStr() + "_table1" + table2 = gtime.TimestampNanoStr() + "_table2" + ) + createInitTable(table1) + defer dropTable(table1) + createInitTable(table2) + defer dropTable(table2) + + gtest.C(t, func(t *gtest.T) { + r, err := db.Model(table1). + FieldsPrefix(table1, "*"). + LeftJoinOnField(table2, "id"). + WherePrefix(table2, g.Map{ + "id": g.Slice{1, 2}, + }). + Order("id asc").All() + t.AssertNil(err) + t.Assert(len(r), 2) + t.Assert(r[0]["id"], "1") + t.Assert(r[1]["id"], "2") + }) +} + +func Test_Model_WhereOrPrefix(t *testing.T) { + var ( + table1 = gtime.TimestampNanoStr() + "_table1" + table2 = gtime.TimestampNanoStr() + "_table2" + ) + createInitTable(table1) + defer dropTable(table1) + createInitTable(table2) + defer dropTable(table2) + + gtest.C(t, func(t *gtest.T) { + r, err := db.Model(table1). + FieldsPrefix(table1, "*"). + LeftJoinOnField(table2, "id"). + WhereOrPrefix(table1, g.Map{ + "id": g.Slice{1, 2}, + }). + WhereOrPrefix(table2, g.Map{ + "id": g.Slice{8, 9}, + }). + Order("id asc").All() + t.AssertNil(err) + t.Assert(len(r), 4) + t.Assert(r[0]["id"], "1") + t.Assert(r[1]["id"], "2") + t.Assert(r[2]["id"], "8") + t.Assert(r[3]["id"], "9") + + }) +}