this repo has no description
at main 235 lines 6.9 kB view raw
1//! Redis client usage examples 2//! 3//! Run with: zig build run 4//! Requires a Redis server running on localhost:6379 5 6const std = @import("std"); 7const redis = @import("redis"); 8 9pub fn main() !void { 10 var gpa = std.heap.GeneralPurposeAllocator(.{}){}; 11 defer _ = gpa.deinit(); 12 const allocator = gpa.allocator(); 13 14 // Connect to Redis 15 var client = redis.Client.connect(allocator, "localhost", 6379) catch |err| { 16 std.debug.print("Failed to connect: {}\n", .{err}); 17 return; 18 }; 19 defer client.close(); 20 21 std.debug.print("Connected to Redis\n\n", .{}); 22 23 // String operations 24 stringExamples(&client); 25 26 // Hash operations 27 hashExamples(&client); 28 29 // List operations 30 listExamples(&client); 31 32 // Set operations 33 setExamples(&client); 34 35 // Sorted set operations 36 sortedSetExamples(&client); 37 38 // Stream operations 39 streamExamples(&client); 40 41 std.debug.print("\nAll examples completed.\n", .{}); 42} 43 44fn stringExamples(client: *redis.Client) void { 45 std.debug.print("=== String Operations ===\n", .{}); 46 var str = client.strings(); 47 48 // SET and GET 49 str.set("greeting", "hello, redis!") catch return; 50 if (str.get("greeting") catch null) |val| { 51 std.debug.print("GET greeting: {s}\n", .{val}); 52 } 53 54 // INCR 55 _ = str.set("counter", "0") catch return; 56 const count = str.incr("counter") catch return; 57 std.debug.print("INCR counter: {d}\n", .{count}); 58 59 // MSET/MGET 60 str.mset(&.{ 61 .{ "key1", "value1" }, 62 .{ "key2", "value2" }, 63 }) catch return; 64 const values = str.mget(&.{ "key1", "key2", "missing" }) catch return; 65 std.debug.print("MGET: ", .{}); 66 for (values) |v| { 67 if (v.asString()) |s| { 68 std.debug.print("{s} ", .{s}); 69 } else { 70 std.debug.print("(nil) ", .{}); 71 } 72 } 73 std.debug.print("\n\n", .{}); 74} 75 76fn hashExamples(client: *redis.Client) void { 77 std.debug.print("=== Hash Operations ===\n", .{}); 78 var hash = client.hashes(); 79 80 // HSET multiple fields 81 _ = hash.hset("user:1", &.{ 82 .{ "name", "alice" }, 83 .{ "email", "alice@example.com" }, 84 .{ "score", "100" }, 85 }) catch return; 86 87 // HGET single field 88 if (hash.hget("user:1", "name") catch null) |name| { 89 std.debug.print("HGET user:1 name: {s}\n", .{name}); 90 } 91 92 // HINCRBY 93 const new_score = hash.hincrBy("user:1", "score", 50) catch return; 94 std.debug.print("HINCRBY user:1 score 50: {d}\n", .{new_score}); 95 96 // HGETALL 97 const all = hash.hgetAll("user:1") catch return; 98 std.debug.print("HGETALL user:1: ", .{}); 99 var i: usize = 0; 100 while (i + 1 < all.len) : (i += 2) { 101 const field = all[i].asString() orelse continue; 102 const value = all[i + 1].asString() orelse continue; 103 std.debug.print("{s}={s} ", .{ field, value }); 104 } 105 std.debug.print("\n\n", .{}); 106} 107 108fn listExamples(client: *redis.Client) void { 109 std.debug.print("=== List Operations ===\n", .{}); 110 var list = client.lists(); 111 112 // Clear and populate list 113 _ = client.keys().del(&.{"tasks"}) catch {}; 114 _ = list.rpush("tasks", &.{ "task1", "task2", "task3" }) catch return; 115 116 // LRANGE 117 const tasks = list.lrange("tasks", 0, -1) catch return; 118 std.debug.print("LRANGE tasks 0 -1: ", .{}); 119 for (tasks) |t| { 120 if (t.asString()) |s| { 121 std.debug.print("{s} ", .{s}); 122 } 123 } 124 std.debug.print("\n", .{}); 125 126 // LPOP 127 if (list.lpop("tasks") catch null) |first| { 128 std.debug.print("LPOP tasks: {s}\n", .{first}); 129 } 130 131 std.debug.print("\n", .{}); 132} 133 134fn setExamples(client: *redis.Client) void { 135 std.debug.print("=== Set Operations ===\n", .{}); 136 var s = client.sets(); 137 138 // SADD 139 _ = s.sadd("tags:post1", &.{ "redis", "database", "nosql" }) catch return; 140 _ = s.sadd("tags:post2", &.{ "redis", "cache", "performance" }) catch return; 141 142 // SMEMBERS 143 const members = s.smembers("tags:post1") catch return; 144 std.debug.print("SMEMBERS tags:post1: ", .{}); 145 for (members) |m| { 146 if (m.asString()) |str| { 147 std.debug.print("{s} ", .{str}); 148 } 149 } 150 std.debug.print("\n", .{}); 151 152 // SINTER 153 const common = s.sinter(&.{ "tags:post1", "tags:post2" }) catch return; 154 std.debug.print("SINTER tags:post1 tags:post2: ", .{}); 155 for (common) |c| { 156 if (c.asString()) |str| { 157 std.debug.print("{s} ", .{str}); 158 } 159 } 160 std.debug.print("\n\n", .{}); 161} 162 163fn sortedSetExamples(client: *redis.Client) void { 164 std.debug.print("=== Sorted Set Operations ===\n", .{}); 165 var zset = client.sortedSets(); 166 167 // Clear and add scores 168 _ = client.keys().del(&.{"leaderboard"}) catch {}; 169 _ = zset.zadd("leaderboard", &.{ 170 .{ .score = 100, .member = "alice" }, 171 .{ .score = 85, .member = "bob" }, 172 .{ .score = 92, .member = "charlie" }, 173 }, .{}) catch return; 174 175 // ZRANGE with scores (top 3) 176 const top = zset.zrangeWithScores("leaderboard", 0, -1, .{ .rev = true }) catch return; 177 std.debug.print("Leaderboard (high to low):\n", .{}); 178 for (top) |entry| { 179 std.debug.print(" {s}: {d}\n", .{ entry.member, entry.score }); 180 } 181 182 // ZSCORE 183 if (zset.zscore("leaderboard", "bob") catch null) |score| { 184 std.debug.print("ZSCORE leaderboard bob: {d}\n", .{score}); 185 } 186 187 std.debug.print("\n", .{}); 188} 189 190fn streamExamples(client: *redis.Client) void { 191 std.debug.print("=== Stream Operations ===\n", .{}); 192 var stream = client.streams(); 193 194 // Delete and recreate stream 195 _ = client.keys().del(&.{"events"}) catch {}; 196 197 // XADD 198 const id1 = stream.xadd("events", .auto, &.{ 199 .{ "type", "login" }, 200 .{ "user", "alice" }, 201 }) catch return; 202 std.debug.print("XADD events: {s}\n", .{id1}); 203 204 const id2 = stream.xadd("events", .auto, &.{ 205 .{ "type", "purchase" }, 206 .{ "user", "alice" }, 207 .{ "amount", "99.99" }, 208 }) catch return; 209 std.debug.print("XADD events: {s}\n", .{id2}); 210 211 // XLEN 212 const len = stream.xlen("events") catch return; 213 std.debug.print("XLEN events: {d}\n", .{len}); 214 215 // XRANGE 216 const entries = stream.xrange("events", "-", "+", null) catch return; 217 std.debug.print("XRANGE events:\n", .{}); 218 for (entries) |entry| { 219 std.debug.print(" {s}: ", .{entry.id}); 220 for (entry.fields) |field| { 221 std.debug.print("{s}={s} ", .{ field.name, field.value }); 222 } 223 std.debug.print("\n", .{}); 224 } 225 226 // Consumer group example 227 _ = stream.xgroupDestroy("events", "workers") catch {}; // cleanup 228 stream.xgroupCreate("events", "workers", "0", true) catch |err| { 229 std.debug.print("XGROUP CREATE error: {}\n", .{err}); 230 return; 231 }; 232 std.debug.print("Created consumer group 'workers'\n", .{}); 233 234 std.debug.print("\n", .{}); 235}