github.com/woocoos/entcache@v0.0.0-20231206055445-856f0148efa5/ent.go (about)

     1  package entcache
     2  
     3  import (
     4  	"context"
     5  	"entgo.io/ent"
     6  	"strconv"
     7  )
     8  
     9  type HookOption func(*hookOptions)
    10  
    11  type hookOptions struct {
    12  	// DriverName is the key of the cache.
    13  	DriverName string
    14  }
    15  
    16  // WithDriverName sets which named ent cache driver name to use.
    17  func WithDriverName(name string) HookOption {
    18  	return func(options *hookOptions) {
    19  		options.DriverName = name
    20  	}
    21  }
    22  
    23  // DataChangeNotify returns a hook that notifies the cache when a mutation is performed.
    24  //
    25  // Driver in method is a placeholder for the cache driver name, which is lazy loaded by NewDriver.
    26  // Use IDs method to get the ids of the mutation, that also works for XXXOne.
    27  func DataChangeNotify(opts ...HookOption) ent.Hook {
    28  	var options = hookOptions{
    29  		DriverName: defaultDriverName,
    30  	}
    31  	for _, opt := range opts {
    32  		opt(&options)
    33  	}
    34  	driver, ok := driverManager[options.DriverName]
    35  	if !ok {
    36  		driver = new(Driver)
    37  		driverManager[options.DriverName] = driver
    38  	}
    39  	return func(next ent.Mutator) ent.Mutator {
    40  		return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (v ent.Value, err error) {
    41  			op := m.Op()
    42  			if op.Is(ent.OpCreate) || driver.Config == nil {
    43  				return next.Mutate(ctx, m)
    44  			}
    45  			var ids []int
    46  			switch op {
    47  			case ent.OpUpdateOne, ent.OpUpdate:
    48  				v, err = next.Mutate(ctx, m)
    49  				if err == nil {
    50  					ider, ok := m.(interface {
    51  						IDs(ctx context.Context) ([]int, error)
    52  					})
    53  					if ok {
    54  						ids, err = ider.IDs(ctx)
    55  						if err != nil {
    56  							return nil, err
    57  						}
    58  					}
    59  				}
    60  			case ent.OpDeleteOne, ent.OpDelete:
    61  				ider, ok := m.(interface {
    62  					IDs(ctx context.Context) ([]int, error)
    63  				})
    64  				if ok {
    65  					ids, err = ider.IDs(ctx)
    66  					if err != nil {
    67  						return nil, err
    68  					}
    69  				}
    70  				v, err = next.Mutate(ctx, m)
    71  			}
    72  			if len(ids) > 0 {
    73  				var keys = make([]Key, len(ids))
    74  				for i, id := range ids {
    75  					keys[i] = NewEntryKey(m.Type(), strconv.Itoa(id))
    76  				}
    77  				driver.ChangeSet.Store(keys...)
    78  			}
    79  			return v, err
    80  		})
    81  	}
    82  }