github.com/friesencr/pop/v6@v6.1.6/callbacks.go (about) 1 package pop 2 3 import ( 4 "reflect" 5 6 "golang.org/x/sync/errgroup" 7 ) 8 9 // AfterFindable callback will be called after a record, or records, 10 // has been retrieved from the database. 11 type AfterFindable interface { 12 AfterFind(*Connection) error 13 } 14 15 // AfterEagerFindable callback will be called after a record, or records, 16 // has been retrieved from the database and their associations have been 17 // eagerly loaded. 18 type AfterEagerFindable interface { 19 AfterEagerFind(*Connection) error 20 } 21 22 func (m *Model) afterFind(c *Connection, eager bool) error { 23 if eager { 24 if x, ok := m.Value.(AfterEagerFindable); ok { 25 if err := x.AfterEagerFind(c); err != nil { 26 return err 27 } 28 } 29 } else { 30 if x, ok := m.Value.(AfterFindable); ok { 31 if err := x.AfterFind(c); err != nil { 32 return err 33 } 34 } 35 } 36 37 // if the "model" is a slice/array we want 38 // to loop through each of the elements in the collection 39 // and call AfterFind on them if they exist. 40 rv := reflect.Indirect(reflect.ValueOf(m.Value)) 41 kind := rv.Kind() 42 if kind != reflect.Slice && kind != reflect.Array { 43 return nil 44 } 45 46 wg := &errgroup.Group{} 47 for i := 0; i < rv.Len(); i++ { 48 elem := rv.Index(i).Addr() 49 50 if eager { 51 if x, ok := elem.Interface().(AfterEagerFindable); ok { 52 wg.Go(func() error { 53 return x.AfterEagerFind(c) 54 }) 55 } 56 } else { 57 if x, ok := elem.Interface().(AfterFindable); ok { 58 wg.Go(func() error { 59 return x.AfterFind(c) 60 }) 61 } 62 } 63 } 64 65 return wg.Wait() 66 } 67 68 // BeforeSaveable callback will be called before a record is 69 // either created or updated in the database. 70 type BeforeSaveable interface { 71 BeforeSave(*Connection) error 72 } 73 74 func (m *Model) beforeSave(c *Connection) error { 75 if x, ok := m.Value.(BeforeSaveable); ok { 76 return x.BeforeSave(c) 77 } 78 return nil 79 } 80 81 // BeforeCreateable callback will be called before a record is 82 // created in the database. 83 type BeforeCreateable interface { 84 BeforeCreate(*Connection) error 85 } 86 87 func (m *Model) beforeCreate(c *Connection) error { 88 if x, ok := m.Value.(BeforeCreateable); ok { 89 return x.BeforeCreate(c) 90 } 91 return nil 92 } 93 94 // BeforeUpdateable callback will be called before a record is 95 // updated in the database. 96 type BeforeUpdateable interface { 97 BeforeUpdate(*Connection) error 98 } 99 100 func (m *Model) beforeUpdate(c *Connection) error { 101 if x, ok := m.Value.(BeforeUpdateable); ok { 102 return x.BeforeUpdate(c) 103 } 104 return nil 105 } 106 107 // BeforeDestroyable callback will be called before a record is 108 // destroyed in the database. 109 type BeforeDestroyable interface { 110 BeforeDestroy(*Connection) error 111 } 112 113 func (m *Model) beforeDestroy(c *Connection) error { 114 if x, ok := m.Value.(BeforeDestroyable); ok { 115 return x.BeforeDestroy(c) 116 } 117 return nil 118 } 119 120 // BeforeValidateable callback will be called before a record is 121 // validated during 122 // ValidateAndCreate, ValidateAndUpdate, or ValidateAndSave 123 type BeforeValidateable interface { 124 BeforeValidate(*Connection) error 125 } 126 127 func (m *Model) beforeValidate(c *Connection) error { 128 if x, ok := m.Value.(BeforeValidateable); ok { 129 return x.BeforeValidate(c) 130 } 131 return nil 132 } 133 134 // AfterDestroyable callback will be called after a record is 135 // destroyed in the database. 136 type AfterDestroyable interface { 137 AfterDestroy(*Connection) error 138 } 139 140 func (m *Model) afterDestroy(c *Connection) error { 141 if x, ok := m.Value.(AfterDestroyable); ok { 142 return x.AfterDestroy(c) 143 } 144 return nil 145 } 146 147 // AfterUpdateable callback will be called after a record is 148 // updated in the database. 149 type AfterUpdateable interface { 150 AfterUpdate(*Connection) error 151 } 152 153 func (m *Model) afterUpdate(c *Connection) error { 154 if x, ok := m.Value.(AfterUpdateable); ok { 155 return x.AfterUpdate(c) 156 } 157 return nil 158 } 159 160 // AfterCreateable callback will be called after a record is 161 // created in the database. 162 type AfterCreateable interface { 163 AfterCreate(*Connection) error 164 } 165 166 func (m *Model) afterCreate(c *Connection) error { 167 if x, ok := m.Value.(AfterCreateable); ok { 168 return x.AfterCreate(c) 169 } 170 return nil 171 } 172 173 // AfterSaveable callback will be called after a record is 174 // either created or updated in the database. 175 type AfterSaveable interface { 176 AfterSave(*Connection) error 177 } 178 179 func (m *Model) afterSave(c *Connection) error { 180 if x, ok := m.Value.(AfterSaveable); ok { 181 return x.AfterSave(c) 182 } 183 return nil 184 }