Skip to content
Draft
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions src/commands/cmd_key.cc
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,30 @@ class CommandDel : public Commander {
}
};

class CommandDelPrefix : public Commander {
public:
Status Execute(Server *server, Connection *conn,
std::vector<std::string> args) override {
if (args.size() != 2) {
return {Status::RedisParseErr,
"wrong number of arguments for 'delprefix' command"};
}

std::string prefix = args[1];
auto db = conn->GetNamespace();
auto keys = server->storage->GetKeysWithPrefix(db, prefix);

int deleted_count = 0;
for (const auto &key : keys) {
auto s = server->storage->Del(db, key);
if (s.ok())
deleted_count++;
}

return ReplyInteger(deleted_count);
}
};

class CommandRename : public Commander {
public:
Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override {
Expand Down Expand Up @@ -569,6 +593,7 @@ REDIS_REGISTER_COMMANDS(Key, MakeCmdAttr<CommandTTL>("ttl", 2, "read-only", 1, 1
MakeCmdAttr<CommandPExpireTime>("pexpiretime", 2, "read-only", 1, 1, 1),
MakeCmdAttr<CommandDel>("del", -2, "write no-dbsize-check", 1, -1, 1),
MakeCmdAttr<CommandDel>("unlink", -2, "write no-dbsize-check", 1, -1, 1),
MakeCmdAttr<CommandDelPrefix>("delprefix", 2, "write", 1, 1, 1),
MakeCmdAttr<CommandRename>("rename", 3, "write", 1, 2, 1),
MakeCmdAttr<CommandRenameNX>("renamenx", 3, "write", 1, 2, 1),
MakeCmdAttr<CommandCopy>("copy", -3, "write", 1, 2, 1),
Expand Down
43 changes: 43 additions & 0 deletions tests/persistence/delprefix.tcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
source tests/includes/init-tests.tcl

start_server {tags {"delprefix"}} {
r flushdb

# Adding keys with different prefixes
r set user:1 "Alice"
r set user:2 "Bob"
r set order:1 "Order123"
r set order:2 "Order456"
r set random "SomeValue"

# Ensure the keys exist
assert_equal "Alice" [r get user:1]
assert_equal "Bob" [r get user:2]
assert_equal "Order123" [r get order:1]
assert_equal "Order456" [r get order:2]
assert_equal "SomeValue" [r get random]

# Delete keys with prefix "user:"
assert_equal 2 [r delprefix user:]

# Ensure the correct keys were deleted
assert_equal {nil} [r get user:1]
assert_equal {nil} [r get user:2]
assert_equal "Order123" [r get order:1]
assert_equal "Order456" [r get order:2]
assert_equal "SomeValue" [r get random]

# Delete keys with prefix "order:"
assert_equal 2 [r delprefix order:]

# Ensure the correct keys were deleted
assert_equal {nil} [r get order:1]
assert_equal {nil} [r get order:2]
assert_equal "SomeValue" [r get random]

# Delete a non-existent prefix
assert_equal 0 [r delprefix nonexisting:]

# Ensure "random" key still exists
assert_equal "SomeValue" [r get random]
}
43 changes: 43 additions & 0 deletions tests/test_helper.tcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#!/usr/bin/env tclsh

# Basic test helper for Kvrocks
set ::test_server "127.0.0.1"
set ::test_port 6666
set ::kvrocks_path "../src/kvrocks"
set ::kvrocks_conf "../kvrocks.conf"

proc start_kvrocks {} {
global test_server test_port kvrocks_path kvrocks_conf
puts "Starting Kvrocks on $test_server:$test_port..."
if {[catch {exec $kvrocks_path -c $kvrocks_conf &} result]} {
puts "Error starting Kvrocks: $result"
exit 1
}
after 2000 ;# Wait for Kvrocks to start
}

proc stop_kvrocks {} {
puts "Stopping Kvrocks..."
if {[catch {exec pkill -f kvrocks} result]} {
puts "Error stopping Kvrocks: $result"
exit 1
}
after 1000
}

proc run_test {test_script} {
start_kvrocks
puts "Running test: $test_script"
if {[catch {source $test_script} result]} {
puts "Error running test script: $result"
stop_kvrocks
exit 1
}
stop_kvrocks
}

if {[llength $argv] == 2 && [lindex $argv 0] eq "--single"} {
run_test [lindex $argv 1]
} else {
puts "Usage: ./test_helper.tcl --single tests/<your_test_script>.tcl"
}