From c5f38e2c6904dca435e026e0d8c5e4cfab470a51 Mon Sep 17 00:00:00 2001 From: Seth Hoenig Date: Wed, 19 Aug 2026 14:16:08 -0500 Subject: [PATCH] client: switch to using generic methods --- Justfile | 3 +- README.md | 14 ++--- e2e_test.go | 172 +++++++++++++++++++++++++-------------------------- go.mod | 2 +- multi.go | 12 ++-- unix_test.go | 20 +++--- verbs.go | 30 ++++----- 7 files changed, 126 insertions(+), 127 deletions(-) diff --git a/Justfile b/Justfile index 005eb82..8e310bc 100644 --- a/Justfile +++ b/Justfile @@ -2,7 +2,6 @@ set shell := ["bash", "-u", "-c"] export scripts := ".github/workflows/scripts" export GOBIN := `echo $PWD/.bin` -export GOTOOLCHAIN := 'go1.26.1' # show available commands [private] @@ -43,4 +42,4 @@ lint: vet # locally install build dependencies [group('build')] init: - go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.11.3 + go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.13.0 diff --git a/README.md b/README.md index fbfb23e..bf2ac62 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ client := memc.New( ##### Setting a value in memcached. ```go -err := memc.Set(client, "my/key/name", "some_value") +err := client.Set("my/key/name", "some_value") ``` Note that the `memc` library can handle arbitrary value types, as long as they @@ -50,7 +50,7 @@ can be encoded using Go's built-in `gob` package. The library automatically handles serialization on writes and de-serialization on reads. ```go -err := memc.Set(client, "my/key/name", &Person{Name: "Bob"}) +err := client.Set("my/key/name", &Person{Name: "Bob"}) ``` ##### Reading a value from memcached. @@ -59,7 +59,7 @@ The `memc` package will automatically convert the value `[]byte` into the type of your Go variable. ```go -value, err := memc.Get[T](client, "my/key/name") +value, err := client.Get[T]("my/key/name") ``` ##### Incrementing/Decrementing a counter in memcached. @@ -70,20 +70,20 @@ and must be in the form of an ASCII string representation of a number. The delta value must be positive. ```go -err := memc.Set(client, "/my/counter", "100") +err := client.Set("/my/counter", "100") ``` Using `Increment` to increase the counter value by 1. ```go -v, err := memc.Increment("/my/counter", 1) +v, err := client.Increment("/my/counter", 1) // v is now 101 ``` Using `Decrement` to decrease the value by 5. ```go -v, err := memc.Decrement("/my/counter", 5) +v, err := client.Decrement("/my/counter", 5) // v is now 96 ``` @@ -136,7 +136,7 @@ consuming resources. In-flight requests will be closed once complete. Once closed the client cannot be reused. ```go -_ = memc.Close() +_ = client.Close() ``` ### License diff --git a/e2e_test.go b/e2e_test.go index ebbdc4d..d93c47a 100644 --- a/e2e_test.go +++ b/e2e_test.go @@ -28,53 +28,53 @@ func TestE2E_SetGet_simple(t *testing.T) { defer ignore.Close(c) t.Run("string", func(t *testing.T) { - err := Set(c, "mystring", "myvalue") + err := c.Set("mystring", "myvalue") must.NoError(t, err) var v string - v, err = Get[string](c, "mystring") + v, err = c.Get[string]("mystring") must.NoError(t, err) must.Eq(t, "myvalue", v) }) t.Run("[]byte", func(t *testing.T) { - err := Set(c, "mybytes", []byte{2, 4, 6, 8}) + err := c.Set("mybytes", []byte{2, 4, 6, 8}) must.NoError(t, err) var v []byte - v, err = Get[[]byte](c, "mybytes") + v, err = c.Get[[]byte]("mybytes") must.NoError(t, err) must.Eq(t, []byte{2, 4, 6, 8}, v) }) t.Run("int", func(t *testing.T) { - err := Set(c, "myint", 998877) + err := c.Set("myint", 998877) must.NoError(t, err) var v int - v, err = Get[int](c, "myint") + v, err = c.Get[int]("myint") must.NoError(t, err) must.Eq(t, 998877, v) }) t.Run("struct pointer", func(t *testing.T) { p := &person{Name: "Seth", Age: 34} - err := Set(c, "myperson_p", p) + err := c.Set("myperson_p", p) must.NoError(t, err) var v *person - v, err = Get[*person](c, "myperson_p") + v, err = c.Get[*person]("myperson_p") must.NoError(t, err) must.Eq(t, &person{Name: "Seth", Age: 34}, v) }) t.Run("struct value", func(t *testing.T) { p := person{Name: "Seth", Age: 34} - err := Set(c, "myperson_v", p) + err := c.Set("myperson_v", p) must.NoError(t, err) var v person - v, err = Get[person](c, "myperson_v") + v, err = c.Get[person]("myperson_v") must.NoError(t, err) must.Eq(t, person{Name: "Seth", Age: 34}, v) }) @@ -90,13 +90,13 @@ func TestE2E_SetGet_expiration(t *testing.T) { defer ignore.Close(c) t.Run("hour", func(t *testing.T) { - err := Set(c, "mykey", "myvalue", TTL(1*time.Hour)) + err := c.Set("mykey", "myvalue", TTL(1*time.Hour)) must.NoError(t, err) }) t.Run("months", func(t *testing.T) { ttl := 90 * 24 * time.Hour // 3 months - err := Set(c, "mykey", "myvalue", TTL(ttl)) + err := c.Set("mykey", "myvalue", TTL(ttl)) must.NoError(t, err) }) } @@ -110,7 +110,7 @@ func TestE2E_Get_miss(t *testing.T) { c := New([]string{address}) defer ignore.Close(c) - _, err := Get[string](c, "missing") + _, err := c.Get[string]("missing") must.ErrorIs(t, err, ErrCacheMiss) } @@ -124,18 +124,18 @@ func TestE2E_Delete(t *testing.T) { defer ignore.Close(c) t.Run("not found", func(t *testing.T) { - err := Delete(c, "does-not-exist") + err := c.Delete("does-not-exist") must.ErrorIs(t, err, ErrNotFound) }) t.Run("success", func(t *testing.T) { - err := Set(c, "key1", "value1") + err := c.Set("key1", "value1") must.NoError(t, err) - err = Delete(c, "key1") + err = c.Delete("key1") must.NoError(t, err) - err = Delete(c, "key1") + err = c.Delete("key1") must.ErrorIs(t, err, ErrNotFound) }) } @@ -150,22 +150,22 @@ func TestE2E_Add(t *testing.T) { defer ignore.Close(c) t.Run("success", func(t *testing.T) { - err := Add(c, "key1", "value1") + err := c.Add("key1", "value1") must.NoError(t, err) - v, verr := Get[string](c, "key1") + v, verr := c.Get[string]("key1") must.NoError(t, verr) must.Eq(t, v, "value1") }) t.Run("overwrite", func(t *testing.T) { - err := Set(c, "key2", "value2") + err := c.Set("key2", "value2") must.NoError(t, err) - err = Add(c, "key2", "value2.b") + err = c.Add("key2", "value2.b") must.ErrorIs(t, err, ErrNotStored) - v, verr := Get[string](c, "key2") + v, verr := c.Get[string]("key2") must.NoError(t, verr) must.Eq(t, v, "value2") }) @@ -181,22 +181,22 @@ func TestE2E_Replace(t *testing.T) { defer ignore.Close(c) t.Run("success", func(t *testing.T) { - err := Set(c, "key1", "value1") + err := c.Set("key1", "value1") must.NoError(t, err) - err = Replace(c, "key1", "value1.replaced") + err = c.Replace("key1", "value1.replaced") must.NoError(t, err) - v, verr := Get[string](c, "key1") + v, verr := c.Get[string]("key1") must.NoError(t, verr) must.Eq(t, "value1.replaced", v) }) t.Run("not found", func(t *testing.T) { - err := Replace(c, "key-does-not-exist", "value") + err := c.Replace("key-does-not-exist", "value") must.ErrorIs(t, err, ErrNotStored) - _, verr := Get[string](c, "key-does-not-exist") + _, verr := c.Get[string]("key-does-not-exist") must.ErrorIs(t, verr, ErrCacheMiss) }) } @@ -211,19 +211,19 @@ func TestE2E_Append(t *testing.T) { defer ignore.Close(c) t.Run("success", func(t *testing.T) { - err := Set(c, "key1", "value1") + err := c.Set("key1", "value1") must.NoError(t, err) - err = Append(c, "key1", ".appended") + err = c.Append("key1", ".appended") must.NoError(t, err) - v, verr := Get[string](c, "key1") + v, verr := c.Get[string]("key1") must.NoError(t, verr) must.Eq(t, "value1.appended", v) }) t.Run("not found", func(t *testing.T) { - err := Append(c, "key-does-not-exist", "value") + err := c.Append("key-does-not-exist", "value") must.ErrorIs(t, err, ErrNotStored) }) } @@ -238,19 +238,19 @@ func TestE2E_Prepend(t *testing.T) { defer ignore.Close(c) t.Run("success", func(t *testing.T) { - err := Set(c, "key1", "value1") + err := c.Set("key1", "value1") must.NoError(t, err) - err = Prepend(c, "key1", "prepended.") + err = c.Prepend("key1", "prepended.") must.NoError(t, err) - v, verr := Get[string](c, "key1") + v, verr := c.Get[string]("key1") must.NoError(t, verr) must.Eq(t, "prepended.value1", v) }) t.Run("not found", func(t *testing.T) { - err := Prepend(c, "key-does-not-exist", "value") + err := c.Prepend("key-does-not-exist", "value") must.ErrorIs(t, err, ErrNotStored) }) } @@ -265,31 +265,31 @@ func TestE2E_Increment(t *testing.T) { defer ignore.Close(c) t.Run("unset", func(t *testing.T) { - _, err := Increment(c, "counter-a", 0) + _, err := c.Increment("counter-a", 0) must.ErrorIs(t, err, ErrNotFound) }) t.Run("negative", func(t *testing.T) { - err := Set(c, "counter-b", "100") + err := c.Set("counter-b", "100") must.NoError(t, err) - _, err = Increment(c, "counter-b", -2) + _, err = c.Increment("counter-b", -2) must.ErrorIs(t, err, ErrNegativeInc) }) t.Run("uncountable", func(t *testing.T) { - err := Set(c, "counter-c", "blah") + err := c.Set("counter-c", "blah") must.NoError(t, err) - _, err = Increment(c, "counter-c", 1) + _, err = c.Increment("counter-c", 1) must.ErrorIs(t, err, ErrNonNumeric) }) t.Run("works", func(t *testing.T) { - err := Set(c, "counter-d", "1000") + err := c.Set("counter-d", "1000") must.NoError(t, err) - v, verr := Increment(c, "counter-d", 2) + v, verr := c.Increment("counter-d", 2) must.NoError(t, verr) must.Eq(t, 1002, v) }) @@ -305,31 +305,31 @@ func TestE2E_Decrement(t *testing.T) { defer ignore.Close(c) t.Run("unset", func(t *testing.T) { - _, err := Decrement(c, "counter-a", 0) + _, err := c.Decrement("counter-a", 0) must.ErrorIs(t, err, ErrNotFound) }) t.Run("negative", func(t *testing.T) { - err := Set(c, "counter-b", "100") + err := c.Set("counter-b", "100") must.NoError(t, err) - _, err = Decrement(c, "counter-b", -2) + _, err = c.Decrement("counter-b", -2) must.ErrorIs(t, err, ErrNegativeInc) }) t.Run("uncountable", func(t *testing.T) { - err := Set(c, "counter-c", "blah") + err := c.Set("counter-c", "blah") must.NoError(t, err) - _, err = Decrement(c, "counter-c", 1) + _, err = c.Decrement("counter-c", 1) must.ErrorIs(t, err, ErrNonNumeric) }) t.Run("works", func(t *testing.T) { - err := Set(c, "counter-d", "1000") + err := c.Set("counter-d", "1000") must.NoError(t, err) - v, verr := Decrement(c, "counter-d", 2) + v, verr := c.Decrement("counter-d", 2) must.NoError(t, verr) must.Eq(t, 998, v) }) @@ -344,22 +344,22 @@ func TestE2E_SetMulti(t *testing.T) { c := New([]string{address}) defer ignore.Close(c) - err := SetMulti(c, []*Pair[string, int]{ + err := c.SetMulti([]*Pair[string, int]{ {"one", 1}, {"two", 2}, {"three", 3}, }) must.NoError(t, err) - one, err1 := Get[int](c, "one") + one, err1 := c.Get[int]("one") must.NoError(t, err1) must.Eq(t, 1, one) - two, err2 := Get[int](c, "two") + two, err2 := c.Get[int]("two") must.NoError(t, err2) must.Eq(t, 2, two) - three, err3 := Get[int](c, "three") + three, err3 := c.Get[int]("three") must.NoError(t, err3) must.Eq(t, 3, three) } @@ -373,22 +373,22 @@ func TestE2E_AddMulti(t *testing.T) { c := New([]string{address}) defer ignore.Close(c) - err := AddMulti(c, []*Pair[string, int]{ + err := c.AddMulti([]*Pair[string, int]{ {"one", 1}, {"two", 2}, {"three", 3}, }) must.NoError(t, err) - one, err1 := Get[int](c, "one") + one, err1 := c.Get[int]("one") must.NoError(t, err1) must.Eq(t, 1, one) - two, err2 := Get[int](c, "two") + two, err2 := c.Get[int]("two") must.NoError(t, err2) must.Eq(t, 2, two) - three, err3 := Get[int](c, "three") + three, err3 := c.Get[int]("three") must.NoError(t, err3) must.Eq(t, 3, three) } @@ -402,14 +402,14 @@ func TestE2E_GetMulti(t *testing.T) { c := New([]string{address}) defer ignore.Close(c) - err := SetMulti(c, []*Pair[string, int]{ + err := c.SetMulti([]*Pair[string, int]{ {"one", 1}, {"two", 2}, {"three", 3}, }) must.NoError(t, err) - results := GetMulti[int](c, []string{"one", "two", "three"}) + results := c.GetMulti[int]([]string{"one", "two", "three"}) must.Eq(t, []*Pair[int, error]{ {A: 1, B: nil}, {A: 2, B: nil}, @@ -426,13 +426,13 @@ func TestE2E_GetMulti_missing(t *testing.T) { c := New([]string{address}) defer ignore.Close(c) - err := SetMulti(c, []*Pair[string, int]{ + err := c.SetMulti([]*Pair[string, int]{ {"one", 1}, {"three", 3}, }) must.NoError(t, err) - results := GetMulti[int](c, []string{"one", "two", "three"}) + results := c.GetMulti[int]([]string{"one", "two", "three"}) must.Eq(t, &Pair[int, error]{A: 1, B: nil}, results[0]) must.Eq(t, &Pair[int, error]{A: 3, B: nil}, results[2]) must.ErrorIs(t, ErrCacheMiss, results[1].B) @@ -448,10 +448,10 @@ func TestE2E_Stats(t *testing.T) { defer ignore.Close(c) // insert an item - err := Set(c, "mykey", "myvalue", TTL(1*time.Hour)) + err := c.Set("mykey", "myvalue", TTL(1*time.Hour)) must.NoError(t, err) - s, serr := Stats(c) + s, serr := c.Stats() must.NoError(t, serr) // spot check a few fields @@ -473,10 +473,10 @@ func TestE2E_StatsSlabs(t *testing.T) { defer ignore.Close(c) // insert an item - err := Set(c, "mykey", "myvalue", TTL(1*time.Hour)) + err := c.Set("mykey", "myvalue", TTL(1*time.Hour)) must.NoError(t, err) - s, serr := StatsSlabs(c) + s, serr := c.StatsSlabs() must.NoError(t, serr) // spot check a few fields @@ -496,10 +496,10 @@ func TestE2E_StatsItems(t *testing.T) { defer ignore.Close(c) // insert an item - err := Set(c, "mykey", "myvalue", TTL(1*time.Hour)) + err := c.Set("mykey", "myvalue", TTL(1*time.Hour)) must.NoError(t, err) - data, derr := StatsItems(c) + data, derr := c.StatsItems() must.NoError(t, derr) // spot check a few fields @@ -518,22 +518,22 @@ func TestE2E_Flush(t *testing.T) { defer ignore.Close(c) t.Run("success", func(t *testing.T) { - err := Set(c, "key1", "value1") + err := c.Set("key1", "value1") must.NoError(t, err) - v, verr := Get[string](c, "key1") + v, verr := c.Get[string]("key1") must.NoError(t, verr) must.Eq(t, "value1", v) - err = Flush(c, 0) + err = c.Flush(0) must.NoError(t, err) - _, err = Get[string](c, "key1") + _, err = c.Get[string]("key1") must.ErrorIs(t, err, ErrCacheMiss) }) t.Run("empty cache", func(t *testing.T) { - err := Flush(c, 0) + err := c.Flush(0) must.NoError(t, err) }) } @@ -548,54 +548,54 @@ func TestE2E_CAS(t *testing.T) { defer ignore.Close(c) t.Run("success", func(t *testing.T) { - err := Set(c, "key1", "value1") + err := c.Set("key1", "value1") must.NoError(t, err) - v, cas, verr := Gets[string](c, "key1") + v, cas, verr := c.Gets[string]("key1") must.NoError(t, verr) must.Eq(t, "value1", v) must.Positive(t, uint64(cas)) - err = CompareAndSwap(c, "key1", cas, "value1.updated") + err = c.CompareAndSwap("key1", cas, "value1.updated") must.NoError(t, err) - v, err = Get[string](c, "key1") + v, err = c.Get[string]("key1") must.NoError(t, err) must.Eq(t, "value1.updated", v) }) t.Run("conflict", func(t *testing.T) { - err := Set(c, "key2", "original") + err := c.Set("key2", "original") must.NoError(t, err) - _, cas1, verr := Gets[string](c, "key2") + _, cas1, verr := c.Gets[string]("key2") must.NoError(t, verr) - _, _, verr = Gets[string](c, "key2") + _, _, verr = c.Gets[string]("key2") must.NoError(t, verr) - err = CompareAndSwap(c, "key2", cas1, "first-update") + err = c.CompareAndSwap("key2", cas1, "first-update") must.NoError(t, err) - err = CompareAndSwap(c, "key2", cas1, "stale-update") + err = c.CompareAndSwap("key2", cas1, "stale-update") must.ErrorIs(t, err, ErrConflict) - v, err := Get[string](c, "key2") + v, err := c.Get[string]("key2") must.NoError(t, err) must.Eq(t, "first-update", v) }) t.Run("not found", func(t *testing.T) { - err := Set(c, "key3", "value3") + err := c.Set("key3", "value3") must.NoError(t, err) - _, cas, verr := Gets[string](c, "key3") + _, cas, verr := c.Gets[string]("key3") must.NoError(t, verr) - err = Delete(c, "key3") + err = c.Delete("key3") must.NoError(t, err) - err = CompareAndSwap(c, "key3", cas, "newvalue") + err = c.CompareAndSwap("key3", cas, "newvalue") must.ErrorIs(t, err, ErrNotFound) }) } diff --git a/go.mod b/go.mod index d82e1e5..21c52ef 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module cattlecloud.net/go/memc -go 1.26 +go 1.27 require ( cattlecloud.net/go/scope v1.3.0 diff --git a/multi.go b/multi.go index 0dca80d..09a2135 100644 --- a/multi.go +++ b/multi.go @@ -22,10 +22,10 @@ type Pair[T, U any] struct { // // One or more Option(s) may be applied to configure things such as the // value expiration TTL or its associated flags. -func SetMulti[T any](c *Client, items []*Pair[string, T], opts ...Option) error { +func (c *Client) SetMulti[T any](items []*Pair[string, T], opts ...Option) error { var errs []error for _, item := range items { - if err := Set(c, item.A, item.B, opts...); err != nil { + if err := c.Set(item.A, item.B, opts...); err != nil { errs = append(errs, err) } } @@ -43,10 +43,10 @@ func SetMulti[T any](c *Client, items []*Pair[string, T], opts ...Option) error // // One or more Option(s) may be applied to configure things such as the // value expiration TTL or its associated flags. -func AddMulti[T any](c *Client, items []*Pair[string, T], opts ...Option) error { +func (c *Client) AddMulti[T any](items []*Pair[string, T], opts ...Option) error { var errs []error for _, item := range items { - if err := Add(c, item.A, item.B, opts...); err != nil { + if err := c.Add(item.A, item.B, opts...); err != nil { errs = append(errs, err) } } @@ -58,10 +58,10 @@ func AddMulti[T any](c *Client, items []*Pair[string, T], opts ...Option) error // // Uses Client c to connect to a memcached instance, and automatically handles // connection pooling and reuse. -func GetMulti[T any](c *Client, keys []string) []*Pair[T, error] { +func (c *Client) GetMulti[T any](keys []string) []*Pair[T, error] { results := make([]*Pair[T, error], 0, len(keys)) for _, key := range keys { - v, err := Get[T](c, key) + v, err := c.Get[T](key) if err != nil { results = append(results, &Pair[T, error]{B: err}) } else { diff --git a/unix_test.go b/unix_test.go index f993139..8b39703 100644 --- a/unix_test.go +++ b/unix_test.go @@ -21,53 +21,53 @@ func TestUnix_simple(t *testing.T) { defer ignore.Close(c) t.Run("string", func(t *testing.T) { - err := Set(c, "mystring", "myvalue") + err := c.Set("mystring", "myvalue") must.NoError(t, err) var v string - v, err = Get[string](c, "mystring") + v, err = c.Get[string]("mystring") must.NoError(t, err) must.Eq(t, "myvalue", v) }) t.Run("[]byte", func(t *testing.T) { - err := Set(c, "mybytes", []byte{2, 4, 6, 8}) + err := c.Set("mybytes", []byte{2, 4, 6, 8}) must.NoError(t, err) var v []byte - v, err = Get[[]byte](c, "mybytes") + v, err = c.Get[[]byte]("mybytes") must.NoError(t, err) must.Eq(t, []byte{2, 4, 6, 8}, v) }) t.Run("int", func(t *testing.T) { - err := Set(c, "myint", 998877) + err := c.Set("myint", 998877) must.NoError(t, err) var v int - v, err = Get[int](c, "myint") + v, err = c.Get[int]("myint") must.NoError(t, err) must.Eq(t, 998877, v) }) t.Run("struct pointer", func(t *testing.T) { p := &person{Name: "Seth", Age: 34} - err := Set(c, "myperson_p", p) + err := c.Set("myperson_p", p) must.NoError(t, err) var v *person - v, err = Get[*person](c, "myperson_p") + v, err = c.Get[*person]("myperson_p") must.NoError(t, err) must.Eq(t, &person{Name: "Seth", Age: 34}, v) }) t.Run("struct value", func(t *testing.T) { p := person{Name: "Seth", Age: 34} - err := Set(c, "myperson_v", p) + err := c.Set("myperson_v", p) must.NoError(t, err) var v person - v, err = Get[person](c, "myperson_v") + v, err = c.Get[person]("myperson_v") must.NoError(t, err) must.Eq(t, person{Name: "Seth", Age: 34}, v) }) diff --git a/verbs.go b/verbs.go index 00b823f..b21050e 100644 --- a/verbs.go +++ b/verbs.go @@ -67,7 +67,7 @@ func Flags(flags int) Option { // // One or more Option(s) may be applied to configure things such as the // value expiration TTL or its associated flags. -func Set[T any](c *Client, key string, item T, opts ...Option) error { +func (c *Client) Set[T any](key string, item T, opts ...Option) error { if err := check(key); err != nil { return err } @@ -141,7 +141,7 @@ func Set[T any](c *Client, key string, item T, opts ...Option) error { // // One or more Option(s) may be applied to configure things such as the // value expiration TTL or its associated flags. -func Replace[T any](c *Client, key string, item T, opts ...Option) error { +func (c *Client) Replace[T any](key string, item T, opts ...Option) error { if err := check(key); err != nil { return err } @@ -218,7 +218,7 @@ func Replace[T any](c *Client, key string, item T, opts ...Option) error { // // One or more Option(s) may be applied to configure things such as the // value expiration TTL or its associated flags. -func Prepend[T any](c *Client, key string, item T, opts ...Option) error { +func (c *Client) Prepend[T any](key string, item T, opts ...Option) error { if err := check(key); err != nil { return err } @@ -297,7 +297,7 @@ func Prepend[T any](c *Client, key string, item T, opts ...Option) error { // // One or more Option(s) may be applied to configure things such as the // value expiration TTL or its associated flags. -func Append[T any](c *Client, key string, item T, opts ...Option) error { +func (c *Client) Append[T any](key string, item T, opts ...Option) error { if err := check(key); err != nil { return err } @@ -373,7 +373,7 @@ func Append[T any](c *Client, key string, item T, opts ...Option) error { // // One or more Option(s) may be applied to configure things such as the // value expiration TTL or its associated flags. -func Add[T any](c *Client, key string, item T, opts ...Option) error { +func (c *Client) Add[T any](key string, item T, opts ...Option) error { if err := check(key); err != nil { return err } @@ -455,7 +455,7 @@ func Add[T any](c *Client, key string, item T, opts ...Option) error { // // One or more Option(s) may be applied to configure things such as the value // expiration TTL or its associated flags. -func CompareAndSwap[T any](c *Client, key string, cas CAS, item T, opts ...Option) error { +func (c *Client) CompareAndSwap[T any](key string, cas CAS, item T, opts ...Option) error { if err := check(key); err != nil { return err } @@ -527,7 +527,7 @@ func CompareAndSwap[T any](c *Client, key string, cas CAS, item T, opts ...Optio // // Uses Client c to connect to a memcached instance, and automatically handles // connection pooling and reuse. -func Get[T any](c *Client, key string) (T, error) { +func (c *Client) Get[T any](key string) (T, error) { var result T if err := check(key); err != nil { @@ -566,7 +566,7 @@ func Get[T any](c *Client, key string) (T, error) { // // Uses Client c to connect to a memcached instance, and automatically handles // connection pooling and reuse. -func Gets[T any](c *Client, key string) (T, CAS, error) { +func (c *Client) Gets[T any](key string) (T, CAS, error) { var result T var casToken CAS @@ -698,7 +698,7 @@ func getPayloadWithCAS(r *bufio.Reader) ([]byte, uint64, error) { // the Client is configured with multiple server addresses. This is intentional, // as flush is typically used by local administration tools that connect to a // single memcached instance. -func Flush(c *Client, timeout time.Duration) error { +func (c *Client) Flush(timeout time.Duration) error { return c.do("", func(conn *iopool.Buffer) error { expiration, err := c.seconds(timeout) if err != nil { @@ -735,7 +735,7 @@ func Flush(c *Client, timeout time.Duration) error { // // Uses Client c to connect to a memcached instance, and automatically handles // connection pooling and reuse. -func Delete(c *Client, key string) error { +func (c *Client) Delete(key string) error { if err := check(key); err != nil { return err } @@ -778,7 +778,7 @@ func Delete(c *Client, key string) error { // // Set(client, "counter", "100") // Increment(client, "counter", 1) // counter = 101 -func Increment[T Countable](c *Client, key string, delta T) (T, error) { +func (c *Client) Increment[T Countable](key string, delta T) (T, error) { if err := check(key); err != nil { return T(0), err } @@ -842,7 +842,7 @@ func Increment[T Countable](c *Client, key string, delta T) (T, error) { // // Set(client, "counter", "100") // Decrement(client, "counter", 1) // counter = 99 -func Decrement[T Countable](c *Client, key string, delta T) (T, error) { +func (c *Client) Decrement[T Countable](key string, delta T) (T, error) { if err := check(key); err != nil { return T(0), err } @@ -905,7 +905,7 @@ func Decrement[T Countable](c *Client, key string, delta T) (T, error) { // the Client is configured with multiple server addresses. This is intentional, // as stats is typically used by local monitoring tools that connect to a // single memcached instance. -func Stats(c *Client) (*Statistics, error) { +func (c *Client) Stats() (*Statistics, error) { var statistics *Statistics err := c.do("", func(conn *iopool.Buffer) error { @@ -938,7 +938,7 @@ func Stats(c *Client) (*Statistics, error) { // the Client is configured with multiple server addresses. This is intentional, // as stats is typically used by local monitoring tools that connect to a // single memcached instance. -func StatsSlabs(c *Client) (*SlabStatistics, error) { +func (c *Client) StatsSlabs() (*SlabStatistics, error) { var statistics *SlabStatistics err := c.do("", func(conn *iopool.Buffer) error { @@ -971,7 +971,7 @@ func StatsSlabs(c *Client) (*SlabStatistics, error) { // the Client is configured with multiple server addresses. This is intentional, // as stats is typically used by local monitoring tools that connect to a // single memcached instance. -func StatsItems(c *Client) ([]*ItemStatistics, error) { +func (c *Client) StatsItems() ([]*ItemStatistics, error) { var statistics []*ItemStatistics err := c.do("", func(conn *iopool.Buffer) error {