gdb_model_update.go 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. // Copyright GoFrame Author(https://github.com/gogf/gf). 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/gerror"
  11. "github.com/gogf/gf/os/gtime"
  12. "github.com/gogf/gf/text/gstr"
  13. "github.com/gogf/gf/util/gconv"
  14. "github.com/gogf/gf/util/gutil"
  15. "reflect"
  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.New("updating table with empty data")
  39. }
  40. var (
  41. updateData = m.data
  42. fieldNameCreate = m.getSoftFieldNameCreated()
  43. fieldNameUpdate = m.getSoftFieldNameUpdated()
  44. fieldNameDelete = m.getSoftFieldNameDeleted()
  45. conditionWhere, conditionExtra, conditionArgs = m.formatCondition(false, false)
  46. )
  47. // Automatically update the record updating time.
  48. if !m.unscoped && fieldNameUpdate != "" {
  49. var (
  50. refValue = reflect.ValueOf(m.data)
  51. refKind = refValue.Kind()
  52. )
  53. if refKind == reflect.Ptr {
  54. refValue = refValue.Elem()
  55. refKind = refValue.Kind()
  56. }
  57. switch refKind {
  58. case reflect.Map, reflect.Struct:
  59. dataMap := ConvertDataForTableRecord(m.data)
  60. gutil.MapDelete(dataMap, fieldNameCreate, fieldNameUpdate, fieldNameDelete)
  61. if fieldNameUpdate != "" {
  62. dataMap[fieldNameUpdate] = gtime.Now().String()
  63. }
  64. updateData = dataMap
  65. default:
  66. updates := gconv.String(m.data)
  67. if fieldNameUpdate != "" && !gstr.Contains(updates, fieldNameUpdate) {
  68. updates += fmt.Sprintf(`,%s='%s'`, fieldNameUpdate, gtime.Now().String())
  69. }
  70. updateData = updates
  71. }
  72. }
  73. newData, err := m.filterDataForInsertOrUpdate(updateData)
  74. if err != nil {
  75. return nil, err
  76. }
  77. conditionStr := conditionWhere + conditionExtra
  78. if !gstr.ContainsI(conditionStr, " WHERE ") {
  79. return nil, gerror.New("there should be WHERE condition statement for UPDATE operation")
  80. }
  81. return m.db.DoUpdate(
  82. m.getLink(true),
  83. m.tables,
  84. newData,
  85. conditionStr,
  86. m.mergeArguments(conditionArgs)...,
  87. )
  88. }