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