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

     1  package entcache
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"github.com/tsingsun/woocoo/pkg/cache"
     7  	"time"
     8  )
     9  
    10  // ctxOptions allows injecting runtime options.
    11  type ctxOptions struct {
    12  	evict    bool           // i.e. skip and invalidate entry.
    13  	key      Key            // entry key.
    14  	ref      bool           // indicates if the key is a reference key.
    15  	ttl      time.Duration  // entry duration.
    16  	skipMode cache.SkipMode // skip mode
    17  }
    18  
    19  var ctxOptionsKey ctxOptions
    20  
    21  // Skip returns a new Context that tells the Driver
    22  // to skip the cache entry on Query.
    23  //
    24  //	client.T.Query().All(entcache.Skip(ctx))
    25  func Skip(ctx context.Context) context.Context {
    26  	c, ok := ctx.Value(ctxOptionsKey).(*ctxOptions)
    27  	if !ok {
    28  		return context.WithValue(ctx, ctxOptionsKey, &ctxOptions{skipMode: cache.SkipCache})
    29  	}
    30  	c.skipMode = cache.SkipCache
    31  	return ctx
    32  }
    33  
    34  // Evict returns a new Context that tells the Driver to refresh the cache entry on Query.
    35  //
    36  //	client.T.Query().All(entcache.Evict(ctx))
    37  func Evict(ctx context.Context) context.Context {
    38  	c, ok := ctx.Value(ctxOptionsKey).(*ctxOptions)
    39  	if !ok {
    40  		return context.WithValue(ctx, ctxOptionsKey, &ctxOptions{evict: true})
    41  	}
    42  	c.evict = true
    43  	return ctx
    44  }
    45  
    46  // WithEntryKey returns a new Context that carries the Key for the cache entry.
    47  // Note that the key is one shot, otherwise cause error if the ent.Client query involves
    48  // more than 1 SQL query (e.g. eager loading).
    49  func WithEntryKey(ctx context.Context, typ string, id any) context.Context {
    50  	key := NewEntryKey(typ, fmt.Sprint(id))
    51  	c, ok := ctx.Value(ctxOptionsKey).(*ctxOptions)
    52  	if !ok {
    53  		return context.WithValue(ctx, ctxOptionsKey, &ctxOptions{key: key})
    54  	}
    55  	c.key = key
    56  	return ctx
    57  }
    58  
    59  // WithRefEntryKey returns a new Context that carries a reference Entry Key for the cache entry.
    60  // RefEntryKey indicates if the key is a reference an entry key. For example, when Get is called, ref is false, because Get use
    61  // id query and get all fields. When others are called, such as Only, ref is false.
    62  func WithRefEntryKey(ctx context.Context, typ string, id any) context.Context {
    63  	key := NewEntryKey(typ, fmt.Sprint(id))
    64  	c, ok := ctx.Value(ctxOptionsKey).(*ctxOptions)
    65  	if !ok {
    66  		return context.WithValue(ctx, ctxOptionsKey, &ctxOptions{key: key, ref: true})
    67  	}
    68  	c.key = key
    69  	c.ref = true
    70  	return ctx
    71  }
    72  
    73  // WithTTL returns a new Context that carries the TTL for the cache entry.
    74  //
    75  //	client.T.Query().All(entcache.WithTTL(ctx, time.Second))
    76  func WithTTL(ctx context.Context, ttl time.Duration) context.Context {
    77  	c, ok := ctx.Value(ctxOptionsKey).(*ctxOptions)
    78  	if !ok {
    79  		return context.WithValue(ctx, ctxOptionsKey, &ctxOptions{ttl: ttl})
    80  	}
    81  	c.ttl = ttl
    82  	return ctx
    83  }