Skip to content

Commit a94e7d8

Browse files
committed
add cas/cad commands
1 parent ce53464 commit a94e7d8

File tree

2 files changed

+491
-1
lines changed

2 files changed

+491
-1
lines changed

commands_test.go

Lines changed: 351 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1773,6 +1773,191 @@ var _ = Describe("Commands", func() {
17731773
Expect(get.Err()).To(Equal(redis.Nil))
17741774
})
17751775

1776+
It("should DelEx when value matches", func() {
1777+
SkipBeforeRedisVersion(8.4, "CAS/CAD commands require Redis >= 8.4")
1778+
1779+
// Set initial value
1780+
err := client.Set(ctx, "lock", "token-123", 0).Err()
1781+
Expect(err).NotTo(HaveOccurred())
1782+
1783+
// Delete only if value matches
1784+
deleted := client.DelEx(ctx, "lock", "token-123")
1785+
Expect(deleted.Err()).NotTo(HaveOccurred())
1786+
Expect(deleted.Val()).To(Equal(int64(1)))
1787+
1788+
// Verify key was deleted
1789+
get := client.Get(ctx, "lock")
1790+
Expect(get.Err()).To(Equal(redis.Nil))
1791+
})
1792+
1793+
It("should DelEx fail when value does not match", func() {
1794+
SkipBeforeRedisVersion(8.4, "CAS/CAD commands require Redis >= 8.4")
1795+
1796+
// Set initial value
1797+
err := client.Set(ctx, "lock", "token-123", 0).Err()
1798+
Expect(err).NotTo(HaveOccurred())
1799+
1800+
// Try to delete with wrong value
1801+
deleted := client.DelEx(ctx, "lock", "wrong-token")
1802+
Expect(deleted.Err()).NotTo(HaveOccurred())
1803+
Expect(deleted.Val()).To(Equal(int64(0)))
1804+
1805+
// Verify key was NOT deleted
1806+
val, err := client.Get(ctx, "lock").Result()
1807+
Expect(err).NotTo(HaveOccurred())
1808+
Expect(val).To(Equal("token-123"))
1809+
})
1810+
1811+
It("should DelEx on non-existent key", func() {
1812+
SkipBeforeRedisVersion(8.4, "CAS/CAD commands require Redis >= 8.4")
1813+
1814+
// Try to delete non-existent key
1815+
deleted := client.DelEx(ctx, "nonexistent", "any-value")
1816+
Expect(deleted.Err()).NotTo(HaveOccurred())
1817+
Expect(deleted.Val()).To(Equal(int64(0)))
1818+
})
1819+
1820+
It("should DelExArgs with IFEQ", func() {
1821+
SkipBeforeRedisVersion(8.4, "CAS/CAD commands require Redis >= 8.4")
1822+
1823+
// Set initial value
1824+
err := client.Set(ctx, "temp-key", "temp-value", 0).Err()
1825+
Expect(err).NotTo(HaveOccurred())
1826+
1827+
// Delete with IFEQ
1828+
args := redis.DelExArgs{
1829+
Mode: "IFEQ",
1830+
MatchValue: "temp-value",
1831+
}
1832+
deleted := client.DelExArgs(ctx, "temp-key", args)
1833+
Expect(deleted.Err()).NotTo(HaveOccurred())
1834+
Expect(deleted.Val()).To(Equal(int64(1)))
1835+
1836+
// Verify key was deleted
1837+
get := client.Get(ctx, "temp-key")
1838+
Expect(get.Err()).To(Equal(redis.Nil))
1839+
})
1840+
1841+
It("should DelExArgs with IFNE", func() {
1842+
SkipBeforeRedisVersion(8.4, "CAS/CAD commands require Redis >= 8.4")
1843+
1844+
// Set initial value
1845+
err := client.Set(ctx, "key", "temporary", 0).Err()
1846+
Expect(err).NotTo(HaveOccurred())
1847+
1848+
// Delete only if value is NOT "permanent"
1849+
args := redis.DelExArgs{
1850+
Mode: "IFNE",
1851+
MatchValue: "permanent",
1852+
}
1853+
deleted := client.DelExArgs(ctx, "key", args)
1854+
Expect(deleted.Err()).NotTo(HaveOccurred())
1855+
Expect(deleted.Val()).To(Equal(int64(1)))
1856+
1857+
// Verify key was deleted
1858+
get := client.Get(ctx, "key")
1859+
Expect(get.Err()).To(Equal(redis.Nil))
1860+
})
1861+
1862+
It("should DelExArgs with IFNE fail when value matches", func() {
1863+
SkipBeforeRedisVersion(8.4, "CAS/CAD commands require Redis >= 8.4")
1864+
1865+
// Set initial value
1866+
err := client.Set(ctx, "key", "permanent", 0).Err()
1867+
Expect(err).NotTo(HaveOccurred())
1868+
1869+
// Try to delete but value matches (should fail)
1870+
args := redis.DelExArgs{
1871+
Mode: "IFNE",
1872+
MatchValue: "permanent",
1873+
}
1874+
deleted := client.DelExArgs(ctx, "key", args)
1875+
Expect(deleted.Err()).NotTo(HaveOccurred())
1876+
Expect(deleted.Val()).To(Equal(int64(0)))
1877+
1878+
// Verify key was NOT deleted
1879+
val, err := client.Get(ctx, "key").Result()
1880+
Expect(err).NotTo(HaveOccurred())
1881+
Expect(val).To(Equal("permanent"))
1882+
})
1883+
1884+
It("should Digest", func() {
1885+
SkipBeforeRedisVersion(8.4, "CAS/CAD commands require Redis >= 8.4")
1886+
1887+
// Set a value
1888+
err := client.Set(ctx, "my-key", "my-value", 0).Err()
1889+
Expect(err).NotTo(HaveOccurred())
1890+
1891+
// Get digest
1892+
digest := client.Digest(ctx, "my-key")
1893+
Expect(digest.Err()).NotTo(HaveOccurred())
1894+
Expect(digest.Val()).NotTo(BeEmpty())
1895+
1896+
// Digest should be consistent
1897+
digest2 := client.Digest(ctx, "my-key")
1898+
Expect(digest2.Err()).NotTo(HaveOccurred())
1899+
Expect(digest2.Val()).To(Equal(digest.Val()))
1900+
})
1901+
1902+
It("should Digest on non-existent key", func() {
1903+
SkipBeforeRedisVersion(8.4, "CAS/CAD commands require Redis >= 8.4")
1904+
1905+
// Get digest of non-existent key
1906+
digest := client.Digest(ctx, "nonexistent")
1907+
Expect(digest.Err()).To(Equal(redis.Nil))
1908+
})
1909+
1910+
It("should use Digest with SetArgs IFDEQ", func() {
1911+
SkipBeforeRedisVersion(8.4, "CAS/CAD commands require Redis >= 8.4")
1912+
1913+
// Set initial value
1914+
err := client.Set(ctx, "key", "value1", 0).Err()
1915+
Expect(err).NotTo(HaveOccurred())
1916+
1917+
// Get digest
1918+
digest := client.Digest(ctx, "key")
1919+
Expect(digest.Err()).NotTo(HaveOccurred())
1920+
1921+
// Update using digest
1922+
args := redis.SetArgs{
1923+
Mode: "IFDEQ",
1924+
MatchDigest: digest.Val(),
1925+
}
1926+
result := client.SetArgs(ctx, "key", "value2", args)
1927+
Expect(result.Err()).NotTo(HaveOccurred())
1928+
Expect(result.Val()).To(Equal("OK"))
1929+
1930+
// Verify value was updated
1931+
val, err := client.Get(ctx, "key").Result()
1932+
Expect(err).NotTo(HaveOccurred())
1933+
Expect(val).To(Equal("value2"))
1934+
})
1935+
1936+
It("should use Digest with DelExArgs IFDEQ", func() {
1937+
SkipBeforeRedisVersion(8.4, "CAS/CAD commands require Redis >= 8.4")
1938+
1939+
// Set initial value
1940+
err := client.Set(ctx, "key", "value", 0).Err()
1941+
Expect(err).NotTo(HaveOccurred())
1942+
1943+
// Get digest
1944+
digest := client.Digest(ctx, "key")
1945+
Expect(digest.Err()).NotTo(HaveOccurred())
1946+
1947+
// Delete using digest
1948+
args := redis.DelExArgs{
1949+
Mode: "IFDEQ",
1950+
MatchDigest: digest.Val(),
1951+
}
1952+
deleted := client.DelExArgs(ctx, "key", args)
1953+
Expect(deleted.Err()).NotTo(HaveOccurred())
1954+
Expect(deleted.Val()).To(Equal(int64(1)))
1955+
1956+
// Verify key was deleted
1957+
get := client.Get(ctx, "key")
1958+
Expect(get.Err()).To(Equal(redis.Nil))
1959+
})
1960+
17761961
It("should Incr", func() {
17771962
set := client.Set(ctx, "key", "10", 0)
17781963
Expect(set.Err()).NotTo(HaveOccurred())
@@ -2320,6 +2505,172 @@ var _ = Describe("Commands", func() {
23202505
Expect(ttl).NotTo(Equal(-1))
23212506
})
23222507

2508+
It("should SetIFEQ when value matches", func() {
2509+
if RedisVersion < 8.4 {
2510+
Skip("CAS/CAD commands require Redis >= 8.4")
2511+
}
2512+
2513+
// Set initial value
2514+
err := client.Set(ctx, "key", "old-value", 0).Err()
2515+
Expect(err).NotTo(HaveOccurred())
2516+
2517+
// Update only if current value is "old-value"
2518+
result := client.SetIFEQ(ctx, "key", "new-value", "old-value", 0)
2519+
Expect(result.Err()).NotTo(HaveOccurred())
2520+
Expect(result.Val()).To(Equal("OK"))
2521+
2522+
// Verify value was updated
2523+
val, err := client.Get(ctx, "key").Result()
2524+
Expect(err).NotTo(HaveOccurred())
2525+
Expect(val).To(Equal("new-value"))
2526+
})
2527+
2528+
It("should SetIFEQ fail when value does not match", func() {
2529+
if RedisVersion < 8.4 {
2530+
Skip("CAS/CAD commands require Redis >= 8.4")
2531+
}
2532+
2533+
// Set initial value
2534+
err := client.Set(ctx, "key", "current-value", 0).Err()
2535+
Expect(err).NotTo(HaveOccurred())
2536+
2537+
// Try to update with wrong match value
2538+
result := client.SetIFEQ(ctx, "key", "new-value", "wrong-value", 0)
2539+
Expect(result.Err()).To(Equal(redis.Nil))
2540+
2541+
// Verify value was NOT updated
2542+
val, err := client.Get(ctx, "key").Result()
2543+
Expect(err).NotTo(HaveOccurred())
2544+
Expect(val).To(Equal("current-value"))
2545+
})
2546+
2547+
It("should SetIFEQ with expiration", func() {
2548+
SkipBeforeRedisVersion(8.4, "CAS/CAD commands require Redis >= 8.4")
2549+
2550+
// Set initial value
2551+
err := client.Set(ctx, "key", "token-123", 0).Err()
2552+
Expect(err).NotTo(HaveOccurred())
2553+
2554+
// Update with expiration
2555+
result := client.SetIFEQ(ctx, "key", "token-456", "token-123", 500*time.Millisecond)
2556+
Expect(result.Err()).NotTo(HaveOccurred())
2557+
Expect(result.Val()).To(Equal("OK"))
2558+
2559+
// Verify value was updated
2560+
val, err := client.Get(ctx, "key").Result()
2561+
Expect(err).NotTo(HaveOccurred())
2562+
Expect(val).To(Equal("token-456"))
2563+
2564+
// Wait for expiration
2565+
Eventually(func() error {
2566+
return client.Get(ctx, "key").Err()
2567+
}, "1s", "100ms").Should(Equal(redis.Nil))
2568+
})
2569+
2570+
It("should SetIFNE when value does not match", func() {
2571+
SkipBeforeRedisVersion(8.4, "CAS/CAD commands require Redis >= 8.4")
2572+
2573+
// Set initial value
2574+
err := client.Set(ctx, "key", "pending", 0).Err()
2575+
Expect(err).NotTo(HaveOccurred())
2576+
2577+
// Update only if current value is NOT "completed"
2578+
result := client.SetIFNE(ctx, "key", "processing", "completed", 0)
2579+
Expect(result.Err()).NotTo(HaveOccurred())
2580+
Expect(result.Val()).To(Equal("OK"))
2581+
2582+
// Verify value was updated
2583+
val, err := client.Get(ctx, "key").Result()
2584+
Expect(err).NotTo(HaveOccurred())
2585+
Expect(val).To(Equal("processing"))
2586+
})
2587+
2588+
It("should SetIFNE fail when value matches", func() {
2589+
SkipBeforeRedisVersion(8.4, "CAS/CAD commands require Redis >= 8.4")
2590+
2591+
// Set initial value
2592+
err := client.Set(ctx, "key", "completed", 0).Err()
2593+
Expect(err).NotTo(HaveOccurred())
2594+
2595+
// Try to update but value matches (should fail)
2596+
result := client.SetIFNE(ctx, "key", "processing", "completed", 0)
2597+
Expect(result.Err()).To(Equal(redis.Nil))
2598+
2599+
// Verify value was NOT updated
2600+
val, err := client.Get(ctx, "key").Result()
2601+
Expect(err).NotTo(HaveOccurred())
2602+
Expect(val).To(Equal("completed"))
2603+
})
2604+
2605+
It("should SetArgs with IFEQ", func() {
2606+
SkipBeforeRedisVersion(8.4, "CAS/CAD commands require Redis >= 8.4")
2607+
2608+
// Set initial value
2609+
err := client.Set(ctx, "counter", "100", 0).Err()
2610+
Expect(err).NotTo(HaveOccurred())
2611+
2612+
// Update with IFEQ
2613+
args := redis.SetArgs{
2614+
Mode: "IFEQ",
2615+
MatchValue: "100",
2616+
TTL: 1 * time.Hour,
2617+
}
2618+
result := client.SetArgs(ctx, "counter", "200", args)
2619+
Expect(result.Err()).NotTo(HaveOccurred())
2620+
Expect(result.Val()).To(Equal("OK"))
2621+
2622+
// Verify value was updated
2623+
val, err := client.Get(ctx, "counter").Result()
2624+
Expect(err).NotTo(HaveOccurred())
2625+
Expect(val).To(Equal("200"))
2626+
})
2627+
2628+
It("should SetArgs with IFEQ and GET", func() {
2629+
SkipBeforeRedisVersion(8.4, "CAS/CAD commands require Redis >= 8.4")
2630+
2631+
// Set initial value
2632+
err := client.Set(ctx, "key", "old", 0).Err()
2633+
Expect(err).NotTo(HaveOccurred())
2634+
2635+
// Update with IFEQ and GET old value
2636+
args := redis.SetArgs{
2637+
Mode: "IFEQ",
2638+
MatchValue: "old",
2639+
Get: true,
2640+
}
2641+
result := client.SetArgs(ctx, "key", "new", args)
2642+
Expect(result.Err()).NotTo(HaveOccurred())
2643+
Expect(result.Val()).To(Equal("old"))
2644+
2645+
// Verify value was updated
2646+
val, err := client.Get(ctx, "key").Result()
2647+
Expect(err).NotTo(HaveOccurred())
2648+
Expect(val).To(Equal("new"))
2649+
})
2650+
2651+
It("should SetArgs with IFNE", func() {
2652+
SkipBeforeRedisVersion(8.4, "CAS/CAD commands require Redis >= 8.4")
2653+
2654+
// Set initial value
2655+
err := client.Set(ctx, "status", "pending", 0).Err()
2656+
Expect(err).NotTo(HaveOccurred())
2657+
2658+
// Update with IFNE
2659+
args := redis.SetArgs{
2660+
Mode: "IFNE",
2661+
MatchValue: "completed",
2662+
TTL: 30 * time.Minute,
2663+
}
2664+
result := client.SetArgs(ctx, "status", "processing", args)
2665+
Expect(result.Err()).NotTo(HaveOccurred())
2666+
Expect(result.Val()).To(Equal("OK"))
2667+
2668+
// Verify value was updated
2669+
val, err := client.Get(ctx, "status").Result()
2670+
Expect(err).NotTo(HaveOccurred())
2671+
Expect(val).To(Equal("processing"))
2672+
})
2673+
23232674
It("should SetRange", func() {
23242675
set := client.Set(ctx, "key", "Hello World", 0)
23252676
Expect(set.Err()).NotTo(HaveOccurred())

0 commit comments

Comments
 (0)