gdb_model_update.go 3.3 KB

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