github.com/duskeagle/pop@v4.10.1-0.20190417200916-92f2b794aab5+incompatible/callbacks.go (about) 1 package pop 2 3 import ( 4 "context" 5 "reflect" 6 7 "github.com/pkg/errors" 8 "golang.org/x/sync/errgroup" 9 "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer" 10 ) 11 12 // AfterFindable callback will be called after a record, or records, 13 // has been retrieved from the database. 14 type AfterFindable interface { 15 AfterFind(*Connection) error 16 } 17 18 func (m *Model) afterFind(ctx context.Context, c *Connection) error { 19 span, ctx := tracer.StartSpanFromContext(ctx, "pop/callbacks/afterFind") 20 defer span.Finish() 21 22 if x, ok := m.Value.(AfterFindable); ok { 23 if err := x.AfterFind(c); err != nil { 24 return errors.WithStack(err) 25 } 26 } 27 28 // if the "model" is a slice/array we want 29 // to loop through each of the elements in the collection 30 // and call AfterFind on them if they exist. 31 rv := reflect.Indirect(reflect.ValueOf(m.Value)) 32 kind := rv.Kind() 33 if kind != reflect.Slice && kind != reflect.Array { 34 return nil 35 } 36 37 wg := &errgroup.Group{} 38 for i := 0; i < rv.Len(); i++ { 39 func(i int) { 40 wg.Go(func() error { 41 y := rv.Index(i) 42 y = y.Addr() 43 if x, ok := y.Interface().(AfterFindable); ok { 44 return x.AfterFind(c) 45 } 46 return nil 47 }) 48 }(i) 49 } 50 51 return wg.Wait() 52 } 53 54 // BeforeSaveable callback will be called before a record is 55 // either created or updated in the database. 56 type BeforeSaveable interface { 57 BeforeSave(*Connection) error 58 } 59 60 func (m *Model) beforeSave(c *Connection) error { 61 if x, ok := m.Value.(BeforeSaveable); ok { 62 return x.BeforeSave(c) 63 } 64 return nil 65 } 66 67 // BeforeCreateable callback will be called before a record is 68 // created in the database. 69 type BeforeCreateable interface { 70 BeforeCreate(*Connection) error 71 } 72 73 func (m *Model) beforeCreate(c *Connection) error { 74 if x, ok := m.Value.(BeforeCreateable); ok { 75 return x.BeforeCreate(c) 76 } 77 return nil 78 } 79 80 // BeforeUpdateable callback will be called before a record is 81 // updated in the database. 82 type BeforeUpdateable interface { 83 BeforeUpdate(*Connection) error 84 } 85 86 func (m *Model) beforeUpdate(c *Connection) error { 87 if x, ok := m.Value.(BeforeUpdateable); ok { 88 return x.BeforeUpdate(c) 89 } 90 return nil 91 } 92 93 // BeforeDestroyable callback will be called before a record is 94 // destroyed in the database. 95 type BeforeDestroyable interface { 96 BeforeDestroy(*Connection) error 97 } 98 99 func (m *Model) beforeDestroy(c *Connection) error { 100 if x, ok := m.Value.(BeforeDestroyable); ok { 101 return x.BeforeDestroy(c) 102 } 103 return nil 104 } 105 106 // AfterDestroyable callback will be called after a record is 107 // destroyed in the database. 108 type AfterDestroyable interface { 109 AfterDestroy(*Connection) error 110 } 111 112 func (m *Model) afterDestroy(c *Connection) error { 113 if x, ok := m.Value.(AfterDestroyable); ok { 114 return x.AfterDestroy(c) 115 } 116 return nil 117 } 118 119 // AfterUpdateable callback will be called after a record is 120 // updated in the database. 121 type AfterUpdateable interface { 122 AfterUpdate(*Connection) error 123 } 124 125 func (m *Model) afterUpdate(c *Connection) error { 126 if x, ok := m.Value.(AfterUpdateable); ok { 127 return x.AfterUpdate(c) 128 } 129 return nil 130 } 131 132 // AfterCreateable callback will be called after a record is 133 // created in the database. 134 type AfterCreateable interface { 135 AfterCreate(*Connection) error 136 } 137 138 func (m *Model) afterCreate(c *Connection) error { 139 if x, ok := m.Value.(AfterCreateable); ok { 140 return x.AfterCreate(c) 141 } 142 return nil 143 } 144 145 // AfterSaveable callback will be called after a record is 146 // either created or updated in the database. 147 type AfterSaveable interface { 148 AfterSave(*Connection) error 149 } 150 151 func (m *Model) afterSave(c *Connection) error { 152 if x, ok := m.Value.(AfterSaveable); ok { 153 return x.AfterSave(c) 154 } 155 return nil 156 }