feat: add cmdCollCounter and cmdCollHash to repl

This commit is contained in:
dualfroz committed 2026-09-09 18:55:28 +02:00
1 parent 463ab71b9c
commit 573d2c4860
1 file changed
+149
+149
View File
@@ -788,3 +788,152 @@ pub const Repl = struct {
} }
} }
fn cmdCollCounter(self: *Repl, op: []const u8, args: []const []const u8, writer: anytype) !void {
const Counter = collectionsmod.Counter;
if (std.mem.eql(u8, op, "get")) {
if (args.len < 1) return ReplError.WrongArgCount;
const v = try Counter.get(self.db, self.allocator, args[0]);
try writer.print("{d}\n", .{v});
} else if (std.mem.eql(u8, op, "set")) {
if (args.len < 2) return ReplError.WrongArgCount;
const v = std.fmt.parseInt(i64, args[1], 10) catch return ReplError.InvalidArgument;
try Counter.set(self.db, self.allocator, args[0], v);
try writer.writeAll("OK\n");
} else if (std.mem.eql(u8, op, "incrby")) {
if (args.len < 2) return ReplError.WrongArgCount;
const delta = std.fmt.parseInt(i64, args[1], 10) catch return ReplError.InvalidArgument;
const v = try Counter.incrBy(self.db, self.allocator, args[0], delta);
try writer.print("{d}\n", .{v});
} else {
return ReplError.UnknownCollectionOp;
}
}
fn cmdCollHash(self: *Repl, op: []const u8, args: []const []const u8, writer: anytype) !void {
const Hash = collectionsmod.Hash;
if (std.mem.eql(u8, op, "set")) {
if (args.len < 3) return ReplError.WrongArgCount;
const created = try Hash.set(self.db, self.allocator, args[0], args[1], args[2]);
try writer.print("{s}\n", .{if (created) "created" else "updated"});
} else if (std.mem.eql(u8, op, "get")) {
if (args.len < 2) return ReplError.WrongArgCount;
if (try Hash.get(self.db, self.allocator, args[0], args[1])) |v| {
defer self.allocator.free(v);
try writer.print("{s}\n", .{v});
} else {
try writer.writeAll("(nil)\n");
}
} else if (std.mem.eql(u8, op, "del")) {
if (args.len < 2) return ReplError.WrongArgCount;
const existed = try Hash.del(self.db, self.allocator, args[0], args[1]);
try writer.print("{d}\n", .{@intFromBool(existed)});
} else if (std.mem.eql(u8, op, "len")) {
if (args.len < 1) return ReplError.WrongArgCount;
const n = try Hash.len(self.db, self.allocator, args[0]);
try writer.print("{d}\n", .{n});
} else if (std.mem.eql(u8, op, "getall")) {
if (args.len < 1) return ReplError.WrongArgCount;
const fields = try Hash.getAll(self.db, self.allocator, args[0]);
defer {
for (fields) |f| f.free(self.allocator);
self.allocator.free(fields);
}
for (fields) |f| try writer.print("{s}\t{s}\n", .{ f.field, f.value });
} else {
return ReplError.UnknownCollectionOp;
}
}
fn cmdCollSet(self: *Repl, op: []const u8, args: []const []const u8, writer: anytype) !void {
const Set = collectionsmod.Set;
if (std.mem.eql(u8, op, "add")) {
if (args.len < 2) return ReplError.WrongArgCount;
const added = try Set.add(self.db, self.allocator, args[0], args[1]);
try writer.print("{d}\n", .{@intFromBool(added)});
} else if (std.mem.eql(u8, op, "rem")) {
if (args.len < 2) return ReplError.WrongArgCount;
const removed = try Set.remove(self.db, self.allocator, args[0], args[1]);
try writer.print("{d}\n", .{@intFromBool(removed)});
} else if (std.mem.eql(u8, op, "ismember")) {
if (args.len < 2) return ReplError.WrongArgCount;
const is = try Set.isMember(self.db, self.allocator, args[0], args[1]);
try writer.print("{d}\n", .{@intFromBool(is)});
} else if (std.mem.eql(u8, op, "card")) {
if (args.len < 1) return ReplError.WrongArgCount;
const n = try Set.card(self.db, self.allocator, args[0]);
try writer.print("{d}\n", .{n});
} else if (std.mem.eql(u8, op, "members")) {
if (args.len < 1) return ReplError.WrongArgCount;
const ms = try Set.members(self.db, self.allocator, args[0]);
defer {
for (ms) |m| self.allocator.free(m);
self.allocator.free(ms);
}
for (ms) |m| try writer.print("{s}\n", .{m});
} else if (std.mem.eql(u8, op, "inter") or std.mem.eql(u8, op, "union")) {
if (args.len < 1) return ReplError.WrongArgCount;
_ = try collttlmod.expireIfDueMany(self.db, self.allocator, .set, args[1..], std.time.nanoTimestamp());
const ms = if (std.mem.eql(u8, op, "inter"))
try Set.intersect(self.db, self.allocator, args)
else
try Set.unionOf(self.db, self.allocator, args);
defer {
for (ms) |m| self.allocator.free(m);
self.allocator.free(ms);
}
for (ms) |m| try writer.print("{s}\n", .{m});
} else if (std.mem.eql(u8, op, "diff")) {
if (args.len < 2) return ReplError.WrongArgCount;
_ = try collttlmod.expireIfDueMany(self.db, self.allocator, .set, args[1..], std.time.nanoTimestamp());
const ms = try Set.difference(self.db, self.allocator, args[0], args[1..]);
defer {
for (ms) |m| self.allocator.free(m);
self.allocator.free(ms);
}
for (ms) |m| try writer.print("{s}\n", .{m});
} else {
return ReplError.UnknownCollectionOp;
}
}
fn cmdCollList(self: *Repl, op: []const u8, args: []const []const u8, writer: anytype) !void {
const List = collectionsmod.List;
if (std.mem.eql(u8, op, "lpush")) {
if (args.len < 2) return ReplError.WrongArgCount;
try List.pushLeft(self.db, self.allocator, args[0], args[1]);
try writer.writeAll("OK\n");
} else if (std.mem.eql(u8, op, "rpush")) {
if (args.len < 2) return ReplError.WrongArgCount;
try List.pushRight(self.db, self.allocator, args[0], args[1]);
try writer.writeAll("OK\n");
} else if (std.mem.eql(u8, op, "lpop") or std.mem.eql(u8, op, "rpop")) {
if (args.len < 1) return ReplError.WrongArgCount;
const popped = if (std.mem.eql(u8, op, "lpop"))
try List.popLeft(self.db, self.allocator, args[0])
else
try List.popRight(self.db, self.allocator, args[0]);
if (popped) |v| {
defer self.allocator.free(v);
try writer.print("{s}\n", .{v});
} else {
try writer.writeAll("(nil)\n");
}
} else if (std.mem.eql(u8, op, "len")) {
if (args.len < 1) return ReplError.WrongArgCount;
const n = try List.len(self.db, self.allocator, args[0]);
try writer.print("{d}\n", .{n});
} else if (std.mem.eql(u8, op, "range")) {
if (args.len < 3) return ReplError.WrongArgCount;
const start = std.fmt.parseInt(i64, args[1], 10) catch return ReplError.InvalidArgument;
const stop = std.fmt.parseInt(i64, args[2], 10) catch return ReplError.InvalidArgument;
const vals = try List.range(self.db, self.allocator, args[0], start, stop);
defer {
for (vals) |v| self.allocator.free(v);
self.allocator.free(vals);
}
for (vals) |v| try writer.print("{s}\n", .{v});
} else {
return ReplError.UnknownCollectionOp;
}
}