From 04d32e7a91e89724ff36e28fbb163a8d9e499b6a Mon Sep 17 00:00:00 2001 From: John Guo Date: Wed, 25 May 2022 16:22:46 +0800 Subject: [PATCH] improve FieldsPrefix for gdb.Model --- .../mysql/mysql_feature_model_join_test.go | 24 +++ database/gdb/gdb_model_fields.go | 154 +++++++++--------- 2 files changed, 97 insertions(+), 81 deletions(-) diff --git a/contrib/drivers/mysql/mysql_feature_model_join_test.go b/contrib/drivers/mysql/mysql_feature_model_join_test.go index 3b3c002b8..548d8b750 100644 --- a/contrib/drivers/mysql/mysql_feature_model_join_test.go +++ b/contrib/drivers/mysql/mysql_feature_model_join_test.go @@ -82,3 +82,27 @@ func Test_Model_InnerJoinOnField(t *testing.T) { t.Assert(r[1]["id"], "2") }) } + +func Test_Model_FieldsPrefix(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, "id"). + FieldsPrefix(table2, "nickname"). + LeftJoinOnField(table2, "id"). + WhereIn("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[0]["nickname"], "name_1") + }) +} diff --git a/database/gdb/gdb_model_fields.go b/database/gdb/gdb_model_fields.go index 935d09efb..a9a54711c 100644 --- a/database/gdb/gdb_model_fields.go +++ b/database/gdb/gdb_model_fields.go @@ -27,44 +27,21 @@ func (m *Model) Fields(fieldNamesOrMapStruct ...interface{}) *Model { if length == 0 { return m } - switch { - // String slice. - case length >= 2: - return m.appendFieldsByStr(gstr.Join( - m.mappingAndFilterToTableFields(gconv.Strings(fieldNamesOrMapStruct), true), - ",", - )) - - // It needs type asserting. - case length == 1: - structOrMap := fieldNamesOrMapStruct[0] - switch r := structOrMap.(type) { - case string: - return m.appendFieldsByStr(gstr.Join( - m.mappingAndFilterToTableFields([]string{r}, false), ",", - )) - case []string: - return m.appendFieldsByStr(gstr.Join( - m.mappingAndFilterToTableFields(r, true), ",", - )) - case Raw, *Raw: - return m.appendFieldsByStr(gconv.String(structOrMap)) - default: - return m.appendFieldsByStr(gstr.Join( - m.mappingAndFilterToTableFields(getFieldsFromStructOrMap(structOrMap), true), ",", - )) - } + fields := m.getFieldsFrom(fieldNamesOrMapStruct...) + if len(fields) == 0 { + return m } - return m + return m.appendFieldsByStr(gstr.Join(fields, ",")) } // FieldsPrefix performs as function Fields but add extra prefix for each field. func (m *Model) FieldsPrefix(prefix string, fieldNamesOrMapStruct ...interface{}) *Model { - model := m.Fields(fieldNamesOrMapStruct...) - array := gstr.SplitAndTrim(model.fields, ",") - gstr.PrefixArray(array, prefix+".") - model.fields = gstr.Join(array, ",") - return model + fields := m.getFieldsFrom(fieldNamesOrMapStruct...) + if len(fields) == 0 { + return m + } + gstr.PrefixArray(fields, prefix+".") + return m.appendFieldsByStr(gstr.Join(fields, ",")) } // FieldsEx appends `fieldNamesOrMapStruct` to the excluded operation fields of the model, @@ -78,28 +55,11 @@ func (m *Model) FieldsEx(fieldNamesOrMapStruct ...interface{}) *Model { if length == 0 { return m } - model := m.getModel() - switch { - case length >= 2: - model.fieldsEx = gstr.Join( - m.mappingAndFilterToTableFields(gconv.Strings(fieldNamesOrMapStruct), true), - ",", - ) - return model - case length == 1: - switch r := fieldNamesOrMapStruct[0].(type) { - case string: - model.fieldsEx = gstr.Join(m.mappingAndFilterToTableFields([]string{r}, false), ",") - case []string: - model.fieldsEx = gstr.Join(m.mappingAndFilterToTableFields(r, true), ",") - case Raw, *Raw: - model.fieldsEx = gconv.String(fieldNamesOrMapStruct[0]) - default: - model.fieldsEx = gstr.Join(m.mappingAndFilterToTableFields(getFieldsFromStructOrMap(r), true), ",") - } - return model + fields := m.getFieldsFrom(fieldNamesOrMapStruct...) + if len(fields) == 0 { + return m } - return m + return m.appendFieldsExByStr(gstr.Join(fields, ",")) } // FieldsExPrefix performs as function FieldsEx but add extra prefix for each field. @@ -156,33 +116,6 @@ func (m *Model) FieldAvg(column string, as ...string) *Model { return m.appendFieldsByStr(fmt.Sprintf(`AVG(%s)%s`, m.QuoteWord(column), asStr)) } -func (m *Model) appendFieldsByStr(fields string) *Model { - if fields != "" { - model := m.getModel() - if model.fields == defaultFields { - model.fields = "" - } - if model.fields != "" { - model.fields += "," - } - model.fields += fields - return model - } - return m -} - -func (m *Model) appendFieldsExByStr(fieldsEx string) *Model { - if fieldsEx != "" { - model := m.getModel() - if model.fieldsEx != "" { - model.fieldsEx += "," - } - model.fieldsEx += fieldsEx - return model - } - return m -} - // GetFieldsStr retrieves and returns all fields from the table, joined with char ','. // The optional parameter `prefix` specifies the prefix for each field, eg: GetFieldsStr("u."). func (m *Model) GetFieldsStr(prefix ...string) string { @@ -251,3 +184,62 @@ func (m *Model) GetFieldsExStr(fields string, prefix ...string) string { func (m *Model) HasField(field string) (bool, error) { return m.db.GetCore().HasField(m.GetCtx(), m.tablesInit, field) } + +func (m *Model) getFieldsFrom(fieldNamesOrMapStruct ...interface{}) []string { + length := len(fieldNamesOrMapStruct) + if length == 0 { + return nil + } + switch { + // String slice. + case length >= 2: + return m.mappingAndFilterToTableFields(gconv.Strings(fieldNamesOrMapStruct), true) + + // It needs type asserting. + case length == 1: + structOrMap := fieldNamesOrMapStruct[0] + switch r := structOrMap.(type) { + case string: + return m.mappingAndFilterToTableFields([]string{r}, false) + + case []string: + return m.mappingAndFilterToTableFields(r, true) + + case Raw, *Raw: + return []string{gconv.String(structOrMap)} + + default: + return m.mappingAndFilterToTableFields(getFieldsFromStructOrMap(structOrMap), true) + } + + default: + return nil + } +} + +func (m *Model) appendFieldsByStr(fields string) *Model { + if fields != "" { + model := m.getModel() + if model.fields == defaultFields { + model.fields = "" + } + if model.fields != "" { + model.fields += "," + } + model.fields += fields + return model + } + return m +} + +func (m *Model) appendFieldsExByStr(fieldsEx string) *Model { + if fieldsEx != "" { + model := m.getModel() + if model.fieldsEx != "" { + model.fieldsEx += "," + } + model.fieldsEx += fieldsEx + return model + } + return m +}