Skip to content

Commit

Permalink
add restoring and restored events
Browse files Browse the repository at this point in the history
  • Loading branch information
hwbrzzl committed Dec 20, 2024
1 parent a0319f9 commit 133e4b4
Show file tree
Hide file tree
Showing 16 changed files with 890 additions and 383 deletions.
2 changes: 2 additions & 0 deletions contracts/database/orm/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ const (
EventDeleted EventType = "deleted"
EventForceDeleting EventType = "force_deleting"
EventForceDeleted EventType = "force_deleted"
EventRestored EventType = "restored"
EventRestoring EventType = "restoring"
)

type Event interface {
Expand Down
59 changes: 45 additions & 14 deletions contracts/database/orm/observer.go
Original file line number Diff line number Diff line change
@@ -1,30 +1,61 @@
package orm

type Observer interface {
// Retrieved called when the model is retrieved from the database.
Retrieved(Event) error
// Creating called when the model is being created.
Creating(Event) error
// Created called when the model has been created.
Created(Event) error
// Updating called when the model is being updated.
Updating(Event) error
// Updated called when the model has been updated.
Updated(Event) error
// Saving called when the model is being saved.
Saving(Event) error
// Saved called when the model has been saved.
Saved(Event) error
// Deleting called when the model is being deleted.
Deleting(Event) error
// Deleted called when the model has been deleted.
Deleted(Event) error
// ForceDeleting called when the model is being force deleted.
ForceDeleting(Event) error
// ForceDeleted called when the model has been force deleted.
ForceDeleted(Event) error
}

type ObserverWithCreating interface {
// Creating called when the model is being created.
Creating(Event) error
}

type ObserverWithDeleting interface {
// Deleting called when the model is being deleted.
Deleting(Event) error
}

type ObserverWithForceDeleting interface {
// ForceDeleting called when the model is being force deleted.
ForceDeleting(Event) error
}

type ObserverWithRestored interface {
// Restored called when the model has been restored.
Restored(Event) error
}

type ObserverWithRestoring interface {
// Restoring called when the model is being restored.
Restoring(Event) error
}

type ObserverWithRetrieved interface {
// Retrieved called when the model is retrieved from the database.
Retrieved(Event) error
}

type ObserverWithSaved interface {
// Saved called when the model has been saved.
Saved(Event) error
}

type ObserverWithSaving interface {
// Saving called when the model is being saved.
Saving(Event) error
}

type ObserverWithUpdating interface {
// Updating called when the model is being updated.
Updating(Event) error
}

type ModelToObserver struct {
Model any
Observer Observer
Expand Down
28 changes: 0 additions & 28 deletions database/console/stubs.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,46 +26,18 @@ import (
type DummyObserver struct{}
func (u *DummyObserver) Retrieved(event orm.Event) error {
return nil
}
func (u *DummyObserver) Creating(event orm.Event) error {
return nil
}
func (u *DummyObserver) Created(event orm.Event) error {
return nil
}
func (u *DummyObserver) Updating(event orm.Event) error {
return nil
}
func (u *DummyObserver) Updated(event orm.Event) error {
return nil
}
func (u *DummyObserver) Saving(event orm.Event) error {
return nil
}
func (u *DummyObserver) Saved(event orm.Event) error {
return nil
}
func (u *DummyObserver) Deleting(event orm.Event) error {
return nil
}
func (u *DummyObserver) Deleted(event orm.Event) error {
return nil
}
func (u *DummyObserver) ForceDeleting(event orm.Event) error {
return nil
}
func (u *DummyObserver) ForceDeleted(event orm.Event) error {
return nil
}
Expand Down
73 changes: 54 additions & 19 deletions database/gorm/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -674,11 +674,19 @@ func (r *Query) Restore(model ...any) (*contractsorm.Result, error) {
return nil, errors.OrmDeletedAtColumnNotFound
}

Check warning on line 675 in database/gorm/query.go

View check run for this annotation

Codecov / codecov/patch

database/gorm/query.go#L674-L675

Added lines #L674 - L675 were not covered by tests

if err := r.restoring(realModel); err != nil {
return nil, err
}

Check warning on line 679 in database/gorm/query.go

View check run for this annotation

Codecov / codecov/patch

database/gorm/query.go#L678-L679

Added lines #L678 - L679 were not covered by tests

res := tx.Update(deletedAtColumnName, nil)
if res.Error != nil {
return nil, res.Error
}

Check warning on line 684 in database/gorm/query.go

View check run for this annotation

Codecov / codecov/patch

database/gorm/query.go#L683-L684

Added lines #L683 - L684 were not covered by tests

if err := r.restored(realModel); err != nil {
return nil, err
}

Check warning on line 688 in database/gorm/query.go

View check run for this annotation

Codecov / codecov/patch

database/gorm/query.go#L687-L688

Added lines #L687 - L688 were not covered by tests

return &contractsorm.Result{
RowsAffected: res.RowsAffected,
}, res.Error
Expand Down Expand Up @@ -1439,6 +1447,14 @@ func (r *Query) refreshConnection(model any) (*Query, error) {
return query, nil
}

func (r *Query) restored(dest any) error {
return r.event(contractsorm.EventRestored, r.instance.Statement.Model, dest)
}

func (r *Query) restoring(dest any) error {
return r.event(contractsorm.EventRestoring, r.instance.Statement.Model, dest)
}

func (r *Query) retrieved(dest any) error {
return r.event(contractsorm.EventRetrieved, nil, dest)
}
Expand Down Expand Up @@ -1590,11 +1606,8 @@ func getDeletedAtColumn(model any) string {
}

Check warning on line 1606 in database/gorm/query.go

View check run for this annotation

Codecov / codecov/patch

database/gorm/query.go#L1605-L1606

Added lines #L1605 - L1606 were not covered by tests

t := reflect.TypeOf(model)
v := reflect.ValueOf(model)

if t.Kind() == reflect.Pointer {
t = t.Elem()
v = v.Elem()
}

for i := 0; i < t.NumField(); i++ {
Expand Down Expand Up @@ -1660,28 +1673,50 @@ func getModelConnection(model any) (string, error) {

func getObserverEvent(event contractsorm.EventType, observer contractsorm.Observer) func(contractsorm.Event) error {
switch event {
case contractsorm.EventRetrieved:
return observer.Retrieved
case contractsorm.EventCreating:
return observer.Creating
case contractsorm.EventCreated:
return observer.Created
case contractsorm.EventUpdating:
return observer.Updating
case contractsorm.EventUpdated:
return observer.Updated
case contractsorm.EventSaving:
return observer.Saving
case contractsorm.EventSaved:
return observer.Saved
case contractsorm.EventDeleting:
return observer.Deleting
case contractsorm.EventCreating:
if o, ok := observer.(contractsorm.ObserverWithCreating); ok {
return o.Creating
}
case contractsorm.EventDeleted:
return observer.Deleted
case contractsorm.EventForceDeleting:
return observer.ForceDeleting
case contractsorm.EventDeleting:
if o, ok := observer.(contractsorm.ObserverWithDeleting); ok {
return o.Deleting
}
case contractsorm.EventForceDeleted:
return observer.ForceDeleted
case contractsorm.EventForceDeleting:
if o, ok := observer.(contractsorm.ObserverWithForceDeleting); ok {
return o.ForceDeleting
}
case contractsorm.EventRestored:
if o, ok := observer.(contractsorm.ObserverWithRestored); ok {
return o.Restored
}
case contractsorm.EventRestoring:
if o, ok := observer.(contractsorm.ObserverWithRestoring); ok {
return o.Restoring
}

Check warning on line 1701 in database/gorm/query.go

View check run for this annotation

Codecov / codecov/patch

database/gorm/query.go#L1694-L1701

Added lines #L1694 - L1701 were not covered by tests
case contractsorm.EventRetrieved:
if o, ok := observer.(contractsorm.ObserverWithRetrieved); ok {
return o.Retrieved
}
case contractsorm.EventSaved:
if o, ok := observer.(contractsorm.ObserverWithSaved); ok {
return o.Saved
}
case contractsorm.EventSaving:
if o, ok := observer.(contractsorm.ObserverWithSaving); ok {
return o.Saving
}
case contractsorm.EventUpdated:
return observer.Updated
case contractsorm.EventUpdating:
if o, ok := observer.(contractsorm.ObserverWithUpdating); ok {
return o.Updating
}
}

return nil
Expand Down
44 changes: 44 additions & 0 deletions database/gorm/query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1444,6 +1444,50 @@ func (s *QueryTestSuite) TestEvent_ForceDeleted() {
}
}

func (s *QueryTestSuite) TestEvent_Restored() {
for _, query := range s.queries {
user := User{Name: "event_restored_name", Avatar: "event_restored_avatar"}
s.Nil(query.Query().Create(&user))

res, err := query.Query().Delete(&user)
s.NoError(err)
s.Equal(int64(1), res.RowsAffected)

res, err = query.Query().WithTrashed().Restore(&user)
s.NoError(err)
s.Equal(int64(1), res.RowsAffected)
s.Equal("event_restored_name1", user.Name)

var user1 User
s.Nil(query.Query().Find(&user1, user.ID))
s.True(user1.ID > 0)
s.Equal("event_restored_name", user1.Name)
s.Equal("event_restored_avatar", user1.Avatar)
}
}

func (s *QueryTestSuite) TestEvent_Restoring() {
for _, query := range s.queries {
user := User{Name: "event_restoring_name", Avatar: "event_restoring_avatar"}
s.Nil(query.Query().Create(&user))

res, err := query.Query().Delete(&user)
s.NoError(err)
s.Equal(int64(1), res.RowsAffected)

res, err = query.Query().WithTrashed().Restore(&user)
s.NoError(err)
s.Equal(int64(1), res.RowsAffected)
s.Equal("event_restoring_name1", user.Name)

var user1 User
s.Nil(query.Query().Find(&user1, user.ID))
s.True(user1.ID > 0)
s.Equal("event_restoring_name", user1.Name)
s.Equal("event_restoring_avatar", user1.Avatar)
}
}

func (s *QueryTestSuite) TestEvent_Retrieved() {
for _, query := range s.queries {
tests := []struct {
Expand Down
16 changes: 16 additions & 0 deletions database/gorm/test_models.go
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,22 @@ func (u *User) DispatchesEvents() map[ormcontract.EventType]func(ormcontract.Eve
event.SetAttribute("name", "event_retrieved_name1")
}

return nil
},
ormcontract.EventRestored: func(event ormcontract.Event) error {
name := event.GetAttribute("name")
if name != nil && name.(string) == "event_restored_name" {
event.SetAttribute("name", "event_restored_name1")
}

return nil
},
ormcontract.EventRestoring: func(event ormcontract.Event) error {
name := event.GetAttribute("name")
if name != nil && name.(string) == "event_restoring_name" {
event.SetAttribute("name", "event_restoring_name1")
}

return nil
},
}
Expand Down
Loading

0 comments on commit 133e4b4

Please sign in to comment.