Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 
 

85 строки
2.4 KiB

  1. package redis
  2. import (
  3. "context"
  4. "crypto/sha1"
  5. "encoding/hex"
  6. "io"
  7. )
  8. type Scripter interface {
  9. Eval(ctx context.Context, script string, keys []string, args ...interface{}) *Cmd
  10. EvalSha(ctx context.Context, sha1 string, keys []string, args ...interface{}) *Cmd
  11. EvalRO(ctx context.Context, script string, keys []string, args ...interface{}) *Cmd
  12. EvalShaRO(ctx context.Context, sha1 string, keys []string, args ...interface{}) *Cmd
  13. ScriptExists(ctx context.Context, hashes ...string) *BoolSliceCmd
  14. ScriptLoad(ctx context.Context, script string) *StringCmd
  15. }
  16. var (
  17. _ Scripter = (*Client)(nil)
  18. _ Scripter = (*Ring)(nil)
  19. _ Scripter = (*ClusterClient)(nil)
  20. )
  21. type Script struct {
  22. src, hash string
  23. }
  24. func NewScript(src string) *Script {
  25. h := sha1.New()
  26. _, _ = io.WriteString(h, src)
  27. return &Script{
  28. src: src,
  29. hash: hex.EncodeToString(h.Sum(nil)),
  30. }
  31. }
  32. func (s *Script) Hash() string {
  33. return s.hash
  34. }
  35. func (s *Script) Load(ctx context.Context, c Scripter) *StringCmd {
  36. return c.ScriptLoad(ctx, s.src)
  37. }
  38. func (s *Script) Exists(ctx context.Context, c Scripter) *BoolSliceCmd {
  39. return c.ScriptExists(ctx, s.hash)
  40. }
  41. func (s *Script) Eval(ctx context.Context, c Scripter, keys []string, args ...interface{}) *Cmd {
  42. return c.Eval(ctx, s.src, keys, args...)
  43. }
  44. func (s *Script) EvalRO(ctx context.Context, c Scripter, keys []string, args ...interface{}) *Cmd {
  45. return c.EvalRO(ctx, s.src, keys, args...)
  46. }
  47. func (s *Script) EvalSha(ctx context.Context, c Scripter, keys []string, args ...interface{}) *Cmd {
  48. return c.EvalSha(ctx, s.hash, keys, args...)
  49. }
  50. func (s *Script) EvalShaRO(ctx context.Context, c Scripter, keys []string, args ...interface{}) *Cmd {
  51. return c.EvalShaRO(ctx, s.hash, keys, args...)
  52. }
  53. // Run optimistically uses EVALSHA to run the script. If script does not exist
  54. // it is retried using EVAL.
  55. func (s *Script) Run(ctx context.Context, c Scripter, keys []string, args ...interface{}) *Cmd {
  56. r := s.EvalSha(ctx, c, keys, args...)
  57. if HasErrorPrefix(r.Err(), "NOSCRIPT") {
  58. return s.Eval(ctx, c, keys, args...)
  59. }
  60. return r
  61. }
  62. // RunRO optimistically uses EVALSHA_RO to run the script. If script does not exist
  63. // it is retried using EVAL_RO.
  64. func (s *Script) RunRO(ctx context.Context, c Scripter, keys []string, args ...interface{}) *Cmd {
  65. r := s.EvalShaRO(ctx, c, keys, args...)
  66. if HasErrorPrefix(r.Err(), "NOSCRIPT") {
  67. return s.EvalRO(ctx, c, keys, args...)
  68. }
  69. return r
  70. }