diff --git a/doctests/cmds_hash_test.go b/doctests/cmds_hash_test.go index f9630a9de..52ade74e9 100644 --- a/doctests/cmds_hash_test.go +++ b/doctests/cmds_hash_test.go @@ -5,6 +5,7 @@ package example_commands_test import ( "context" "fmt" + "sort" "github.com/redis/go-redis/v9" ) @@ -74,8 +75,20 @@ func ExampleClient_hset() { panic(err) } - fmt.Println(res6) - // >>> map[field1:Hello field2:Hi field3:World] + keys := make([]string, 0, len(res6)) + + for key, _ := range res6 { + keys = append(keys, key) + } + + sort.Strings(keys) + + for _, key := range keys { + fmt.Printf("Key: %v, value: %v\n", key, res6[key]) + } + // >>> Key: field1, value: Hello + // >>> Key: field2, value: Hi + // >>> Key: field3, value: World // STEP_END // Output: @@ -84,7 +97,9 @@ func ExampleClient_hset() { // 2 // Hi // World - // map[field1:Hello field2:Hi field3:World] + // Key: field1, value: Hello + // Key: field2, value: Hi + // Key: field3, value: World } func ExampleClient_hget() { @@ -131,3 +146,96 @@ func ExampleClient_hget() { // foo // redis: nil } + +func ExampleClient_hgetall() { + ctx := context.Background() + + rdb := redis.NewClient(&redis.Options{ + Addr: "localhost:6379", + Password: "", // no password + DB: 0, // use default DB + }) + + // REMOVE_START + rdb.Del(ctx, "myhash") + // REMOVE_END + + // STEP_START hgetall + hGetAllResult1, err := rdb.HSet(ctx, "myhash", + "field1", "Hello", + "field2", "World", + ).Result() + + if err != nil { + panic(err) + } + + fmt.Println(hGetAllResult1) // >>> 2 + + hGetAllResult2, err := rdb.HGetAll(ctx, "myhash").Result() + + if err != nil { + panic(err) + } + + keys := make([]string, 0, len(hGetAllResult2)) + + for key, _ := range hGetAllResult2 { + keys = append(keys, key) + } + + sort.Strings(keys) + + for _, key := range keys { + fmt.Printf("Key: %v, value: %v\n", key, hGetAllResult2[key]) + } + // >>> Key: field1, value: Hello + // >>> Key: field2, value: World + // STEP_END + + // Output: + // 2 + // Key: field1, value: Hello + // Key: field2, value: World +} + +func ExampleClient_hvals() { + ctx := context.Background() + + rdb := redis.NewClient(&redis.Options{ + Addr: "localhost:6379", + Password: "", // no password docs + DB: 0, // use default DB + }) + + // REMOVE_START + rdb.Del(ctx, "myhash") + // REMOVE_END + + // STEP_START hvals + hValsResult1, err := rdb.HSet(ctx, "myhash", + "field1", "Hello", + "field2", "World", + ).Result() + + if err != nil { + panic(err) + } + + fmt.Println(hValsResult1) // >>> 2 + + hValsResult2, err := rdb.HVals(ctx, "myhash").Result() + + if err != nil { + panic(err) + } + + sort.Strings(hValsResult2) + + fmt.Println(hValsResult2) // >>> [Hello World] + // STEP_END + + // Output: + // 2 + // [Hello World] +} diff --git a/doctests/pipe_trans_example_test.go b/doctests/pipe_trans_example_test.go new file mode 100644 index 000000000..ea1dd5b48 --- /dev/null +++ b/doctests/pipe_trans_example_test.go @@ -0,0 +1,180 @@ +// EXAMPLE: pipe_trans_tutorial +// HIDE_START +package example_commands_test + +import ( + "context" + "fmt" + + "github.com/redis/go-redis/v9" +) + +// HIDE_END + +func ExampleClient_transactions() { + ctx := context.Background() + + rdb := redis.NewClient(&redis.Options{ + Addr: "localhost:6379", + Password: "", // no password docs + DB: 0, // use default DB + }) + // REMOVE_START + for i := 0; i < 5; i++ { + rdb.Del(ctx, fmt.Sprintf("seat:%d", i)) + } + + rdb.Del(ctx, "counter:1", "counter:2", "counter:3", "shellpath") + // REMOVE_END + + // STEP_START basic_pipe + pipe := rdb.Pipeline() + + for i := 0; i < 5; i++ { + pipe.Set(ctx, fmt.Sprintf("seat:%v", i), fmt.Sprintf("#%v", i), 0) + } + + cmds, err := pipe.Exec(ctx) + + if err != nil { + panic(err) + } + + for _, c := range cmds { + fmt.Printf("%v;", c.(*redis.StatusCmd).Val()) + } + + fmt.Println("") + // >>> OK;OK;OK;OK;OK; + + pipe = rdb.Pipeline() + + get0Result := pipe.Get(ctx, "seat:0") + get3Result := pipe.Get(ctx, "seat:3") + get4Result := pipe.Get(ctx, "seat:4") + + cmds, err = pipe.Exec(ctx) + + // The results are available only after the pipeline + // has finished executing. + fmt.Println(get0Result.Val()) // >>> #0 + fmt.Println(get3Result.Val()) // >>> #3 + fmt.Println(get4Result.Val()) // >>> #4 + // STEP_END + + // STEP_START basic_pipe_pipelined + var pd0Result *redis.StatusCmd + var pd3Result *redis.StatusCmd + var pd4Result *redis.StatusCmd + + cmds, err = rdb.Pipelined(ctx, func(pipe redis.Pipeliner) error { + pd0Result = (*redis.StatusCmd)(pipe.Get(ctx, "seat:0")) + pd3Result = (*redis.StatusCmd)(pipe.Get(ctx, "seat:3")) + pd4Result = (*redis.StatusCmd)(pipe.Get(ctx, "seat:4")) + return nil + }) + + if err != nil { + panic(err) + } + + // The results are available only after the pipeline + // has finished executing. + fmt.Println(pd0Result.Val()) // >>> #0 + fmt.Println(pd3Result.Val()) // >>> #3 + fmt.Println(pd4Result.Val()) // >>> #4 + // STEP_END + + // STEP_START basic_trans + trans := rdb.TxPipeline() + + trans.IncrBy(ctx, "counter:1", 1) + trans.IncrBy(ctx, "counter:2", 2) + trans.IncrBy(ctx, "counter:3", 3) + + cmds, err = trans.Exec(ctx) + + for _, c := range cmds { + fmt.Println(c.(*redis.IntCmd).Val()) + } + // >>> 1 + // >>> 2 + // >>> 3 + // STEP_END + + // STEP_START basic_trans_txpipelined + var tx1Result *redis.IntCmd + var tx2Result *redis.IntCmd + var tx3Result *redis.IntCmd + + cmds, err = rdb.TxPipelined(ctx, func(trans redis.Pipeliner) error { + tx1Result = trans.IncrBy(ctx, "counter:1", 1) + tx2Result = trans.IncrBy(ctx, "counter:2", 2) + tx3Result = trans.IncrBy(ctx, "counter:3", 3) + return nil + }) + + if err != nil { + panic(err) + } + + fmt.Println(tx1Result.Val()) // >>> 2 + fmt.Println(tx2Result.Val()) // >>> 4 + fmt.Println(tx3Result.Val()) // >>> 6 + // STEP_END + + // STEP_START trans_watch + // Set initial value of `shellpath`. + rdb.Set(ctx, "shellpath", "/usr/syscmds/", 0) + + const maxRetries = 1000 + + // Retry if the key has been changed. + for i := 0; i < maxRetries; i++ { + err := rdb.Watch(ctx, + func(tx *redis.Tx) error { + currentPath, err := rdb.Get(ctx, "shellpath").Result() + newPath := currentPath + ":/usr/mycmds/" + + _, err = tx.TxPipelined(ctx, func(pipe redis.Pipeliner) error { + pipe.Set(ctx, "shellpath", newPath, 0) + return nil + }) + + return err + }, + "shellpath", + ) + + if err == nil { + // Success. + break + } else if err == redis.TxFailedErr { + // Optimistic lock lost. Retry the transaction. + continue + } else { + // Panic for any other error. + panic(err) + } + } + + fmt.Println(rdb.Get(ctx, "shellpath").Val()) + // >>> /usr/syscmds/:/usr/mycmds/ + // STEP_END + + // Output: + // OK;OK;OK;OK;OK; + // #0 + // #3 + // #4 + // #0 + // #3 + // #4 + // 1 + // 2 + // 3 + // 2 + // 4 + // 6 + // /usr/syscmds/:/usr/mycmds/ +} diff --git a/doctests/sets_example_test.go b/doctests/sets_example_test.go index 7446a2789..2d6504e2b 100644 --- a/doctests/sets_example_test.go +++ b/doctests/sets_example_test.go @@ -5,6 +5,7 @@ package example_commands_test import ( "context" "fmt" + "sort" "github.com/redis/go-redis/v9" ) @@ -215,6 +216,9 @@ func ExampleClient_saddsmembers() { panic(err) } + // Sort the strings in the slice to make sure the output is lexicographical + sort.Strings(res10) + fmt.Println(res10) // >>> [bike:1 bike:2 bike:3] // STEP_END @@ -294,6 +298,10 @@ func ExampleClient_sdiff() { panic(err) } + + // Sort the strings in the slice to make sure the output is lexicographical + sort.Strings(res13) + fmt.Println(res13) // >>> [bike:2 bike:3] // STEP_END @@ -349,6 +357,9 @@ func ExampleClient_multisets() { panic(err) } + // Sort the strings in the slice to make sure the output is lexicographical + sort.Strings(res15) + fmt.Println(res15) // >>> [bike:1 bike:2 bike:3 bike:4] res16, err := rdb.SDiff(ctx, "bikes:racing:france", "bikes:racing:usa", "bikes:racing:italy").Result() @@ -373,6 +384,9 @@ func ExampleClient_multisets() { panic(err) } + // Sort the strings in the slice to make sure the output is lexicographical + sort.Strings(res18) + fmt.Println(res18) // >>> [bike:2 bike:3] // STEP_END