Save updates value in database. If value doesn't contain a matching primary key, value is inserted.
(value interface{})
| 83 | |
| 84 | // Save updates value in database. If value doesn't contain a matching primary key, value is inserted. |
| 85 | func (db *DB) Save(value interface{}) (tx *DB) { |
| 86 | tx = db.getInstance() |
| 87 | tx.Statement.Dest = value |
| 88 | |
| 89 | reflectValue := reflect.Indirect(reflect.ValueOf(value)) |
| 90 | for reflectValue.Kind() == reflect.Ptr || reflectValue.Kind() == reflect.Interface { |
| 91 | reflectValue = reflect.Indirect(reflectValue) |
| 92 | } |
| 93 | |
| 94 | switch reflectValue.Kind() { |
| 95 | case reflect.Slice, reflect.Array: |
| 96 | if _, ok := tx.Statement.Clauses["ON CONFLICT"]; !ok { |
| 97 | tx = tx.Clauses(clause.OnConflict{UpdateAll: true}) |
| 98 | } |
| 99 | tx = tx.callbacks.Create().Execute(tx.Set("gorm:update_track_time", true)) |
| 100 | case reflect.Struct: |
| 101 | if err := tx.Statement.Parse(value); err == nil && tx.Statement.Schema != nil { |
| 102 | for _, pf := range tx.Statement.Schema.PrimaryFields { |
| 103 | if _, isZero := pf.ValueOf(tx.Statement.Context, reflectValue); isZero { |
| 104 | return tx.callbacks.Create().Execute(tx) |
| 105 | } |
| 106 | } |
| 107 | } |
| 108 | |
| 109 | fallthrough |
| 110 | default: |
| 111 | selectedUpdate := len(tx.Statement.Selects) != 0 |
| 112 | // when updating, use all fields including those zero-value fields |
| 113 | if !selectedUpdate { |
| 114 | tx.Statement.Selects = append(tx.Statement.Selects, "*") |
| 115 | } |
| 116 | |
| 117 | updateTx := tx.callbacks.Update().Execute(tx.Session(&Session{Initialized: true})) |
| 118 | |
| 119 | if updateTx.Error == nil && updateTx.RowsAffected == 0 && !updateTx.DryRun && !selectedUpdate { |
| 120 | return tx.Session(&Session{SkipHooks: true}).Clauses(clause.OnConflict{UpdateAll: true}).Create(value) |
| 121 | } |
| 122 | |
| 123 | return updateTx |
| 124 | } |
| 125 | |
| 126 | return |
| 127 | } |
| 128 | |
| 129 | // First finds the first record ordered by primary key, matching given conditions conds |
| 130 | func (db *DB) First(dest interface{}, conds ...interface{}) (tx *DB) { |