github.com/wangyougui/gf/v2@v2.6.5/database/gdb/gdb_model_fields.go (about) 1 // Copyright GoFrame Author(https://goframe.org). All Rights Reserved. 2 // 3 // This Source Code Form is subject to the terms of the MIT License. 4 // If a copy of the MIT was not distributed with this file, 5 // You can obtain one at https://github.com/wangyougui/gf. 6 7 package gdb 8 9 import ( 10 "fmt" 11 12 "github.com/wangyougui/gf/v2/container/gset" 13 "github.com/wangyougui/gf/v2/text/gstr" 14 "github.com/wangyougui/gf/v2/util/gconv" 15 ) 16 17 // Fields appends `fieldNamesOrMapStruct` to the operation fields of the model, multiple fields joined using char ','. 18 // The parameter `fieldNamesOrMapStruct` can be type of string/map/*map/struct/*struct. 19 // 20 // Eg: 21 // Fields("id", "name", "age") 22 // Fields([]string{"id", "name", "age"}) 23 // Fields(map[string]interface{}{"id":1, "name":"john", "age":18}) 24 // Fields(User{ Id: 1, Name: "john", Age: 18}). 25 func (m *Model) Fields(fieldNamesOrMapStruct ...interface{}) *Model { 26 length := len(fieldNamesOrMapStruct) 27 if length == 0 { 28 return m 29 } 30 fields := m.getFieldsFrom(m.tablesInit, fieldNamesOrMapStruct...) 31 if len(fields) == 0 { 32 return m 33 } 34 return m.appendFieldsByStr(gstr.Join(fields, ",")) 35 } 36 37 // FieldsPrefix performs as function Fields but add extra prefix for each field. 38 func (m *Model) FieldsPrefix(prefixOrAlias string, fieldNamesOrMapStruct ...interface{}) *Model { 39 fields := m.getFieldsFrom(m.getTableNameByPrefixOrAlias(prefixOrAlias), fieldNamesOrMapStruct...) 40 if len(fields) == 0 { 41 return m 42 } 43 gstr.PrefixArray(fields, prefixOrAlias+".") 44 return m.appendFieldsByStr(gstr.Join(fields, ",")) 45 } 46 47 // FieldsEx appends `fieldNamesOrMapStruct` to the excluded operation fields of the model, 48 // multiple fields joined using char ','. 49 // Note that this function supports only single table operations. 50 // The parameter `fieldNamesOrMapStruct` can be type of string/map/*map/struct/*struct. 51 // 52 // Also see Fields. 53 func (m *Model) FieldsEx(fieldNamesOrMapStruct ...interface{}) *Model { 54 return m.doFieldsEx(m.tablesInit, fieldNamesOrMapStruct...) 55 } 56 func (m *Model) doFieldsEx(table string, fieldNamesOrMapStruct ...interface{}) *Model { 57 length := len(fieldNamesOrMapStruct) 58 if length == 0 { 59 return m 60 } 61 fields := m.getFieldsFrom(table, fieldNamesOrMapStruct...) 62 if len(fields) == 0 { 63 return m 64 } 65 return m.appendFieldsExByStr(gstr.Join(fields, ",")) 66 } 67 68 // FieldsExPrefix performs as function FieldsEx but add extra prefix for each field. 69 func (m *Model) FieldsExPrefix(prefixOrAlias string, fieldNamesOrMapStruct ...interface{}) *Model { 70 model := m.doFieldsEx(m.getTableNameByPrefixOrAlias(prefixOrAlias), fieldNamesOrMapStruct...) 71 array := gstr.SplitAndTrim(model.fieldsEx, ",") 72 gstr.PrefixArray(array, prefixOrAlias+".") 73 model.fieldsEx = gstr.Join(array, ",") 74 return model 75 } 76 77 // FieldCount formats and appends commonly used field `COUNT(column)` to the select fields of model. 78 func (m *Model) FieldCount(column string, as ...string) *Model { 79 asStr := "" 80 if len(as) > 0 && as[0] != "" { 81 asStr = fmt.Sprintf(` AS %s`, m.db.GetCore().QuoteWord(as[0])) 82 } 83 return m.appendFieldsByStr(fmt.Sprintf(`COUNT(%s)%s`, m.QuoteWord(column), asStr)) 84 } 85 86 // FieldSum formats and appends commonly used field `SUM(column)` to the select fields of model. 87 func (m *Model) FieldSum(column string, as ...string) *Model { 88 asStr := "" 89 if len(as) > 0 && as[0] != "" { 90 asStr = fmt.Sprintf(` AS %s`, m.db.GetCore().QuoteWord(as[0])) 91 } 92 return m.appendFieldsByStr(fmt.Sprintf(`SUM(%s)%s`, m.QuoteWord(column), asStr)) 93 } 94 95 // FieldMin formats and appends commonly used field `MIN(column)` to the select fields of model. 96 func (m *Model) FieldMin(column string, as ...string) *Model { 97 asStr := "" 98 if len(as) > 0 && as[0] != "" { 99 asStr = fmt.Sprintf(` AS %s`, m.db.GetCore().QuoteWord(as[0])) 100 } 101 return m.appendFieldsByStr(fmt.Sprintf(`MIN(%s)%s`, m.QuoteWord(column), asStr)) 102 } 103 104 // FieldMax formats and appends commonly used field `MAX(column)` to the select fields of model. 105 func (m *Model) FieldMax(column string, as ...string) *Model { 106 asStr := "" 107 if len(as) > 0 && as[0] != "" { 108 asStr = fmt.Sprintf(` AS %s`, m.db.GetCore().QuoteWord(as[0])) 109 } 110 return m.appendFieldsByStr(fmt.Sprintf(`MAX(%s)%s`, m.QuoteWord(column), asStr)) 111 } 112 113 // FieldAvg formats and appends commonly used field `AVG(column)` to the select fields of model. 114 func (m *Model) FieldAvg(column string, as ...string) *Model { 115 asStr := "" 116 if len(as) > 0 && as[0] != "" { 117 asStr = fmt.Sprintf(` AS %s`, m.db.GetCore().QuoteWord(as[0])) 118 } 119 return m.appendFieldsByStr(fmt.Sprintf(`AVG(%s)%s`, m.QuoteWord(column), asStr)) 120 } 121 122 // GetFieldsStr retrieves and returns all fields from the table, joined with char ','. 123 // The optional parameter `prefix` specifies the prefix for each field, eg: GetFieldsStr("u."). 124 func (m *Model) GetFieldsStr(prefix ...string) string { 125 prefixStr := "" 126 if len(prefix) > 0 { 127 prefixStr = prefix[0] 128 } 129 tableFields, err := m.TableFields(m.tablesInit) 130 if err != nil { 131 panic(err) 132 } 133 if len(tableFields) == 0 { 134 panic(fmt.Sprintf(`empty table fields for table "%s"`, m.tables)) 135 } 136 fieldsArray := make([]string, len(tableFields)) 137 for k, v := range tableFields { 138 fieldsArray[v.Index] = k 139 } 140 newFields := "" 141 for _, k := range fieldsArray { 142 if len(newFields) > 0 { 143 newFields += "," 144 } 145 newFields += prefixStr + k 146 } 147 newFields = m.db.GetCore().QuoteString(newFields) 148 return newFields 149 } 150 151 // GetFieldsExStr retrieves and returns fields which are not in parameter `fields` from the table, 152 // joined with char ','. 153 // The parameter `fields` specifies the fields that are excluded. 154 // The optional parameter `prefix` specifies the prefix for each field, eg: FieldsExStr("id", "u."). 155 func (m *Model) GetFieldsExStr(fields string, prefix ...string) string { 156 prefixStr := "" 157 if len(prefix) > 0 { 158 prefixStr = prefix[0] 159 } 160 tableFields, err := m.TableFields(m.tablesInit) 161 if err != nil { 162 panic(err) 163 } 164 if len(tableFields) == 0 { 165 panic(fmt.Sprintf(`empty table fields for table "%s"`, m.tables)) 166 } 167 fieldsExSet := gset.NewStrSetFrom(gstr.SplitAndTrim(fields, ",")) 168 fieldsArray := make([]string, len(tableFields)) 169 for k, v := range tableFields { 170 fieldsArray[v.Index] = k 171 } 172 newFields := "" 173 for _, k := range fieldsArray { 174 if fieldsExSet.Contains(k) { 175 continue 176 } 177 if len(newFields) > 0 { 178 newFields += "," 179 } 180 newFields += prefixStr + k 181 } 182 newFields = m.db.GetCore().QuoteString(newFields) 183 return newFields 184 } 185 186 // HasField determine whether the field exists in the table. 187 func (m *Model) HasField(field string) (bool, error) { 188 return m.db.GetCore().HasField(m.GetCtx(), m.tablesInit, field) 189 } 190 191 // getFieldsFrom retrieves, filters and returns fields name from table `table`. 192 func (m *Model) getFieldsFrom(table string, fieldNamesOrMapStruct ...interface{}) []string { 193 length := len(fieldNamesOrMapStruct) 194 if length == 0 { 195 return nil 196 } 197 switch { 198 // String slice. 199 case length >= 2: 200 return m.mappingAndFilterToTableFields( 201 table, gconv.Strings(fieldNamesOrMapStruct), true, 202 ) 203 204 // It needs type asserting. 205 case length == 1: 206 structOrMap := fieldNamesOrMapStruct[0] 207 switch r := structOrMap.(type) { 208 case string: 209 return m.mappingAndFilterToTableFields(table, []string{r}, false) 210 211 case []string: 212 return m.mappingAndFilterToTableFields(table, r, true) 213 214 case Raw, *Raw: 215 return []string{gconv.String(structOrMap)} 216 217 default: 218 return m.mappingAndFilterToTableFields(table, getFieldsFromStructOrMap(structOrMap), true) 219 } 220 221 default: 222 return nil 223 } 224 } 225 226 func (m *Model) appendFieldsByStr(fields string) *Model { 227 if fields != "" { 228 model := m.getModel() 229 if model.fields == defaultFields { 230 model.fields = "" 231 } 232 if model.fields != "" { 233 model.fields += "," 234 } 235 model.fields += fields 236 return model 237 } 238 return m 239 } 240 241 func (m *Model) appendFieldsExByStr(fieldsEx string) *Model { 242 if fieldsEx != "" { 243 model := m.getModel() 244 if model.fieldsEx != "" { 245 model.fieldsEx += "," 246 } 247 model.fieldsEx += fieldsEx 248 return model 249 } 250 return m 251 }