(ctx context.Context, model Model, withValidations bool, isForAuxDB bool)
| 366 | } |
| 367 | |
| 368 | func (app *BaseApp) update(ctx context.Context, model Model, withValidations bool, isForAuxDB bool) error { |
| 369 | event := new(ModelEvent) |
| 370 | event.App = app |
| 371 | event.Context = ctx |
| 372 | event.Type = ModelEventTypeUpdate |
| 373 | event.Model = model |
| 374 | |
| 375 | saveErr := app.OnModelUpdate().Trigger(event, func(e *ModelEvent) error { |
| 376 | // run validations (if any) |
| 377 | if withValidations { |
| 378 | validateErr := e.App.ValidateWithContext(e.Context, e.Model) |
| 379 | if validateErr != nil { |
| 380 | return validateErr |
| 381 | } |
| 382 | } |
| 383 | |
| 384 | // db write |
| 385 | return e.App.OnModelUpdateExecute().Trigger(event, func(e *ModelEvent) error { |
| 386 | var db dbx.Builder |
| 387 | if isForAuxDB { |
| 388 | db = e.App.AuxNonconcurrentDB() |
| 389 | } else { |
| 390 | db = e.App.NonconcurrentDB() |
| 391 | } |
| 392 | |
| 393 | return baseLockRetry(func(attempt int) error { |
| 394 | if m, ok := e.Model.(DBExporter); ok { |
| 395 | data, err := m.DBExport(e.App) |
| 396 | if err != nil { |
| 397 | return err |
| 398 | } |
| 399 | |
| 400 | // note: for now disallow primary key change for consistency with dbx.ModelQuery.Update() |
| 401 | if data[idColumn] != e.Model.LastSavedPK() { |
| 402 | return errors.New("primary key change is not allowed") |
| 403 | } |
| 404 | |
| 405 | _, err = db.Update(e.Model.TableName(), data, dbx.HashExp{ |
| 406 | idColumn: e.Model.LastSavedPK(), |
| 407 | }).WithContext(e.Context).Execute() |
| 408 | |
| 409 | return err |
| 410 | } |
| 411 | |
| 412 | return db.Model(e.Model).WithContext(e.Context).Update() |
| 413 | }, defaultMaxLockRetries) |
| 414 | }) |
| 415 | }) |
| 416 | if saveErr != nil { |
| 417 | errEvent := &ModelErrorEvent{ModelEvent: *event, Error: saveErr} |
| 418 | errEvent.App = app // replace with the initial app in case it was changed by the hook |
| 419 | hookErr := app.OnModelAfterUpdateError().Trigger(errEvent) |
| 420 | if hookErr != nil { |
| 421 | return errors.Join(saveErr, hookErr) |
| 422 | } |
| 423 | |
| 424 | return saveErr |
| 425 | } |
no test coverage detected