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  }