github.com/gogf/gf@v1.16.9/database/gdb/gdb_model_update.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 "database/sql" 11 "fmt" 12 "github.com/gogf/gf/errors/gcode" 13 "reflect" 14 15 "github.com/gogf/gf/errors/gerror" 16 "github.com/gogf/gf/os/gtime" 17 "github.com/gogf/gf/text/gstr" 18 "github.com/gogf/gf/util/gconv" 19 ) 20 21 // Update does "UPDATE ... " statement for the model. 22 // 23 // If the optional parameter `dataAndWhere` is given, the dataAndWhere[0] is the updated data field, 24 // and dataAndWhere[1:] is treated as where condition fields. 25 // Also see Model.Data and Model.Where functions. 26 func (m *Model) Update(dataAndWhere ...interface{}) (result sql.Result, err error) { 27 if len(dataAndWhere) > 0 { 28 if len(dataAndWhere) > 2 { 29 return m.Data(dataAndWhere[0]).Where(dataAndWhere[1], dataAndWhere[2:]...).Update() 30 } else if len(dataAndWhere) == 2 { 31 return m.Data(dataAndWhere[0]).Where(dataAndWhere[1]).Update() 32 } else { 33 return m.Data(dataAndWhere[0]).Update() 34 } 35 } 36 defer func() { 37 if err == nil { 38 m.checkAndRemoveCache() 39 } 40 }() 41 if m.data == nil { 42 return nil, gerror.NewCode(gcode.CodeMissingParameter, "updating table with empty data") 43 } 44 var ( 45 updateData = m.data 46 fieldNameUpdate = m.getSoftFieldNameUpdated() 47 conditionWhere, conditionExtra, conditionArgs = m.formatCondition(false, false) 48 ) 49 // Automatically update the record updating time. 50 if !m.unscoped && fieldNameUpdate != "" { 51 var ( 52 refValue = reflect.ValueOf(m.data) 53 refKind = refValue.Kind() 54 ) 55 if refKind == reflect.Ptr { 56 refValue = refValue.Elem() 57 refKind = refValue.Kind() 58 } 59 switch refKind { 60 case reflect.Map, reflect.Struct: 61 dataMap := ConvertDataForTableRecord(m.data) 62 if fieldNameUpdate != "" { 63 dataMap[fieldNameUpdate] = gtime.Now().String() 64 } 65 updateData = dataMap 66 default: 67 updates := gconv.String(m.data) 68 if fieldNameUpdate != "" && !gstr.Contains(updates, fieldNameUpdate) { 69 updates += fmt.Sprintf(`,%s='%s'`, fieldNameUpdate, gtime.Now().String()) 70 } 71 updateData = updates 72 } 73 } 74 newData, err := m.filterDataForInsertOrUpdate(updateData) 75 if err != nil { 76 return nil, err 77 } 78 conditionStr := conditionWhere + conditionExtra 79 if !gstr.ContainsI(conditionStr, " WHERE ") { 80 return nil, gerror.NewCode(gcode.CodeMissingParameter, "there should be WHERE condition statement for UPDATE operation") 81 } 82 return m.db.DoUpdate( 83 m.GetCtx(), 84 m.getLink(true), 85 m.tables, 86 newData, 87 conditionStr, 88 m.mergeArguments(conditionArgs)..., 89 ) 90 } 91 92 // Increment increments a column's value by a given amount. 93 // The parameter `amount` can be type of float or integer. 94 func (m *Model) Increment(column string, amount interface{}) (sql.Result, error) { 95 return m.getModel().Data(column, &Counter{ 96 Field: column, 97 Value: gconv.Float64(amount), 98 }).Update() 99 } 100 101 // Decrement decrements a column's value by a given amount. 102 // The parameter `amount` can be type of float or integer. 103 func (m *Model) Decrement(column string, amount interface{}) (sql.Result, error) { 104 return m.getModel().Data(column, &Counter{ 105 Field: column, 106 Value: -gconv.Float64(amount), 107 }).Update() 108 }