Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Java: Adding command COPY #1532

Merged
merged 1 commit into from
Jun 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion glide-core/src/client/value_conversion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -698,7 +698,7 @@ pub(crate) fn expected_type_for_cmd(cmd: &Cmd) -> Option<ExpectedReturnType> {
}),
b"INCRBYFLOAT" | b"HINCRBYFLOAT" | b"ZINCRBY" => Some(ExpectedReturnType::Double),
b"HEXISTS" | b"HSETNX" | b"EXPIRE" | b"EXPIREAT" | b"PEXPIRE" | b"PEXPIREAT"
| b"SISMEMBER" | b"PERSIST" | b"SMOVE" | b"RENAMENX" | b"MOVE" => {
| b"SISMEMBER" | b"PERSIST" | b"SMOVE" | b"RENAMENX" | b"MOVE" | b"COPY" => {
Some(ExpectedReturnType::Boolean)
}
b"SMISMEMBER" => Some(ExpectedReturnType::ArrayOfBools),
Expand Down
1 change: 1 addition & 0 deletions glide-core/src/protobuf/redis_request.proto
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ enum RequestType {
BitFieldReadOnly = 173;
Move = 174;
SInterCard = 175;
Copy = 178;
}

message Command {
Expand Down
3 changes: 3 additions & 0 deletions glide-core/src/request_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ pub enum RequestType {
BitFieldReadOnly = 173,
Move = 174,
SInterCard = 175,
Copy = 178,
}

fn get_two_word_command(first: &str, second: &str) -> Cmd {
Expand Down Expand Up @@ -360,6 +361,7 @@ impl From<::protobuf::EnumOrUnknown<ProtobufRequestType>> for RequestType {
ProtobufRequestType::BitFieldReadOnly => RequestType::BitFieldReadOnly,
ProtobufRequestType::Move => RequestType::Move,
ProtobufRequestType::SInterCard => RequestType::SInterCard,
ProtobufRequestType::Copy => RequestType::Copy,
ProtobufRequestType::Sort => RequestType::Sort,
}
}
Expand Down Expand Up @@ -538,6 +540,7 @@ impl RequestType {
RequestType::BitFieldReadOnly => Some(cmd("BITFIELD_RO")),
RequestType::Move => Some(cmd("MOVE")),
RequestType::SInterCard => Some(cmd("SINTERCARD")),
RequestType::Copy => Some(cmd("COPY")),
RequestType::Sort => Some(cmd("SORT")),
}
}
Expand Down
17 changes: 17 additions & 0 deletions java/client/src/main/java/glide/api/BaseClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import static redis_request.RedisRequestOuterClass.RequestType.BitFieldReadOnly;
import static redis_request.RedisRequestOuterClass.RequestType.BitOp;
import static redis_request.RedisRequestOuterClass.RequestType.BitPos;
import static redis_request.RedisRequestOuterClass.RequestType.Copy;
import static redis_request.RedisRequestOuterClass.RequestType.Decr;
import static redis_request.RedisRequestOuterClass.RequestType.DecrBy;
import static redis_request.RedisRequestOuterClass.RequestType.Del;
Expand Down Expand Up @@ -1733,4 +1734,20 @@ public CompletableFuture<Long> sintercard(@NonNull String[] keys, long limit) {
new String[] {SET_LIMIT_REDIS_API, Long.toString(limit)});
return commandManager.submitNewCommand(SInterCard, arguments, this::handleLongResponse);
}

@Override
public CompletableFuture<Boolean> copy(
@NonNull String source, @NonNull String destination, boolean replace) {
String[] arguments = new String[] {source, destination};
if (replace) {
arguments = ArrayUtils.add(arguments, REPLACE_REDIS_API);
}
return commandManager.submitNewCommand(Copy, arguments, this::handleBooleanResponse);
}

@Override
public CompletableFuture<Boolean> copy(@NonNull String source, @NonNull String destination) {
String[] arguments = new String[] {source, destination};
return commandManager.submitNewCommand(Copy, arguments, this::handleBooleanResponse);
}
}
21 changes: 21 additions & 0 deletions java/client/src/main/java/glide/api/RedisClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import static redis_request.RedisRequestOuterClass.RequestType.ConfigResetStat;
import static redis_request.RedisRequestOuterClass.RequestType.ConfigRewrite;
import static redis_request.RedisRequestOuterClass.RequestType.ConfigSet;
import static redis_request.RedisRequestOuterClass.RequestType.Copy;
import static redis_request.RedisRequestOuterClass.RequestType.CustomCommand;
import static redis_request.RedisRequestOuterClass.RequestType.DBSize;
import static redis_request.RedisRequestOuterClass.RequestType.Echo;
Expand Down Expand Up @@ -42,6 +43,7 @@
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import lombok.NonNull;
import org.apache.commons.lang3.ArrayUtils;

/**
* Async (non-blocking) client for Redis in Standalone mode. Use {@link #CreateClient} to request a
Expand Down Expand Up @@ -238,4 +240,23 @@ public CompletableFuture<String> functionDelete(@NonNull String libName) {
return commandManager.submitNewCommand(
FunctionDelete, new String[] {libName}, this::handleStringResponse);
}

@Override
public CompletableFuture<Boolean> copy(
@NonNull String source, @NonNull String destination, long destinationDB) {
String[] arguments =
new String[] {source, destination, DB_REDIS_API, Long.toString(destinationDB)};
return commandManager.submitNewCommand(Copy, arguments, this::handleBooleanResponse);
}

@Override
public CompletableFuture<Boolean> copy(
@NonNull String source, @NonNull String destination, long destinationDB, boolean replace) {
String[] arguments =
new String[] {source, destination, DB_REDIS_API, Long.toString(destinationDB)};
if (replace) {
arguments = ArrayUtils.add(arguments, REPLACE_REDIS_API);
}
return commandManager.submitNewCommand(Copy, arguments, this::handleBooleanResponse);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
* @see <a href="https://redis.io/commands/?group=generic">Generic Commands</a>
*/
public interface GenericBaseCommands {
/** Redis API keyword used to replace the destination key. */
String REPLACE_REDIS_API = "REPLACE";

/**
* Removes the specified <code>keys</code> from the database. A key is ignored if it does not
Expand Down Expand Up @@ -542,4 +544,50 @@ CompletableFuture<Boolean> pexpireAt(
* }</pre>
*/
CompletableFuture<Long> touch(String[] keys);

/**
* Copies the value stored at the <code>source</code> to the <code>destination</code> key if the
* <code>destination</code> key does not yet exist.
*
* @apiNote When in cluster mode, both <code>source</code> and <code>destination</code> must map
* to the same hash slot.
* @since Redis 6.2.0 and above.
* @see <a href="https://redis.io/commands/copy/">redis.io</a> for details.
* @param source The key to the source value.
* @param destination The key where the value should be copied to.
* @return <code>true</code> if <code>source</code> was copied, <code>false</code> if <code>source
* </code> was not copied.
* @example
* <pre>{@code
* client.set("test1", "one").get();
* client.set("test2", "two").get();
* assert !client.copy("test1", "test2").get();
* assert client.copy("test1", "test2").get();
* }</pre>
*/
CompletableFuture<Boolean> copy(String source, String destination);

/**
* Copies the value stored at the <code>source</code> to the <code>destination</code> key. When
* <code>replace</code> is true, removes the <code>destination</code> key first if it already
* exists, otherwise performs no action.
*
* @apiNote When in cluster mode, both <code>source</code> and <code>destination</code> must map
* to the same hash slot.
* @since Redis 6.2.0 and above.
* @see <a href="https://redis.io/commands/copy/">redis.io</a> for details.
* @param source The key to the source value.
* @param destination The key where the value should be copied to.
* @param replace If the destination key should be removed before copying the value to it.
* @return <code>true</code> if <code>source</code> was copied, <code>false</code> if <code>source
* </code> was not copied.
* @example
* <pre>{@code
* client.set("test1", "one").get();
* client.set("test2", "two").get();
* assert !client.copy("test1", "test2", false).get();
* assert client.copy("test1", "test2", true).get();
* }</pre>
*/
CompletableFuture<Boolean> copy(String source, String destination, boolean replace);
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
* @see <a href="https://redis.io/commands/?group=generic">Generic Commands</a>
*/
public interface GenericCommands {
/** Redis API keyword used to denote the destination db index. */
String DB_REDIS_API = "DB";

/**
* Executes a single command, without checking inputs. Every part of the command, including
Expand Down Expand Up @@ -72,4 +74,46 @@ public interface GenericCommands {
* }</pre>
*/
CompletableFuture<Boolean> move(String key, long dbIndex);

/**
* Copies the value stored at the <code>source</code> to the <code>destination</code> key on
* <code>destinationDB</code>. When <code>replace</code> is true, removes the <code>destination
* </code> key first if it already exists, otherwise performs no action.
*
* @since Redis 6.2.0 and above.
* @see <a href="https://redis.io/commands/copy/">redis.io</a> for details.
* @param source The key to the source value.
* @param destination The key where the value should be copied to.
* @param destinationDB The alternative logical database index for the destination key.
* @param replace If the destination key should be removed before copying the value to it.
* @return <code>true</code> if <code>source</code> was copied, <code>false</code> if <code>source
* </code> was not copied.
* @example
* <pre>{@code
* client.set("test1", "one").get();
* assert client.copy("test1", "test2", 1, false).get();
* }</pre>
*/
CompletableFuture<Boolean> copy(
String source, String destination, long destinationDB, boolean replace);

/**
* Copies the value stored at the <code>source</code> to the <code>destination</code> key on
* <code>destinationDB</code>. When <code>replace</code> is true, removes the <code>destination
* </code> key first if it already exists, otherwise performs no action.
*
* @since Redis 6.2.0 and above.
* @see <a href="https://redis.io/commands/copy/">redis.io</a> for details.
* @param source The key to the source value.
* @param destination The key where the value should be copied to.
* @param destinationDB The alternative logical database index for the destination key.
* @return <code>true</code> if <code>source</code> was copied, <code>false</code> if <code>source
* </code> was not copied.
* @example
* <pre>{@code
* client.set("test1", "one").get();
* assert client.copy("test1", "test2", 1).get();
* }</pre>
*/
CompletableFuture<Boolean> copy(String source, String destination, long destinationDB);
}
40 changes: 40 additions & 0 deletions java/client/src/main/java/glide/api/models/BaseTransaction.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/** Copyright GLIDE-for-Redis Project Contributors - SPDX Identifier: Apache-2.0 */
package glide.api.models;

import static glide.api.commands.GenericBaseCommands.REPLACE_REDIS_API;
import static glide.api.commands.HashBaseCommands.WITH_VALUES_REDIS_API;
import static glide.api.commands.ListBaseCommands.COUNT_FOR_LIST_REDIS_API;
import static glide.api.commands.ServerManagementCommands.VERSION_REDIS_API;
Expand Down Expand Up @@ -37,6 +38,7 @@
import static redis_request.RedisRequestOuterClass.RequestType.ConfigResetStat;
import static redis_request.RedisRequestOuterClass.RequestType.ConfigRewrite;
import static redis_request.RedisRequestOuterClass.RequestType.ConfigSet;
import static redis_request.RedisRequestOuterClass.RequestType.Copy;
import static redis_request.RedisRequestOuterClass.RequestType.CustomCommand;
import static redis_request.RedisRequestOuterClass.RequestType.DBSize;
import static redis_request.RedisRequestOuterClass.RequestType.Decr;
Expand Down Expand Up @@ -3456,6 +3458,44 @@ public T touch(@NonNull String[] keys) {
return getThis();
}

/**
* Copies the value stored at the <code>source</code> to the <code>destination</code> key. When
* <code>replace</code> is true, removes the <code>destination</code> key first if it already
* exists, otherwise performs no action.
*
* @since Redis 6.2.0 and above.
* @see <a href="https://redis.io/commands/copy/">redis.io</a> for details.
* @param source The key to the source value.
* @param destination The key where the value should be copied to.
* @param replace If the destination key should be removed before copying the value to it.
* @return Command Response - <code>1L</code> if <code>source</code> was copied, <code>0L</code>
* if <code>source</code> was not copied.
*/
public T copy(@NonNull String source, @NonNull String destination, boolean replace) {
String[] args = new String[] {source, destination};
if (replace) {
args = ArrayUtils.add(args, REPLACE_REDIS_API);
}
ArgsArray commandArgs = buildArgs(args);
protobufTransaction.addCommands(buildCommand(Copy, commandArgs));
return getThis();
}

/**
* Copies the value stored at the <code>source</code> to the <code>destination</code> key if the
* <code>destination</code> key does not yet exist.
*
* @since Redis 6.2.0 and above.
* @see <a href="https://redis.io/commands/copy/">redis.io</a> for details.
* @param source The key to the source value.
* @param destination The key where the value should be copied to.
* @return Command Response - <code>true</code> if <code>source</code> was copied, <code>false
* </code> if <code>source</code> was not copied.
*/
public T copy(@NonNull String source, @NonNull String destination) {
return copy(source, destination, false);
}

/**
* Counts the number of set bits (population counting) in a string stored at <code>key</code>.
*
Expand Down
47 changes: 47 additions & 0 deletions java/client/src/main/java/glide/api/models/Transaction.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
/** Copyright GLIDE-for-Redis Project Contributors - SPDX Identifier: Apache-2.0 */
package glide.api.models;

import static glide.api.commands.GenericBaseCommands.REPLACE_REDIS_API;
import static glide.api.commands.GenericCommands.DB_REDIS_API;
import static redis_request.RedisRequestOuterClass.RequestType.Copy;
import static redis_request.RedisRequestOuterClass.RequestType.Move;
import static redis_request.RedisRequestOuterClass.RequestType.Select;

import lombok.AllArgsConstructor;
import lombok.NonNull;
import org.apache.commons.lang3.ArrayUtils;
import redis_request.RedisRequestOuterClass.Command.ArgsArray;

/**
Expand Down Expand Up @@ -64,4 +69,46 @@ public Transaction move(String key, long dbIndex) {
protobufTransaction.addCommands(buildCommand(Move, commandArgs));
return this;
}

/**
* Copies the value stored at the <code>source</code> to the <code>destination</code> key on
* <code>destinationDB</code>. When <code>replace</code> is true, removes the <code>destination
* </code> key first if it already exists, otherwise performs no action.
*
* @since Redis 6.2.0 and above.
* @see <a href="https://redis.io/commands/copy/">redis.io</a> for details.
* @param source The key to the source value.
* @param destination The key where the value should be copied to.
* @param destinationDB The alternative logical database index for the destination key.
* @return Command Response - <code>true</code> if <code>source</code> was copied, <code>false
* </code> if <code>source</code> was not copied.
*/
public Transaction copy(@NonNull String source, @NonNull String destination, long destinationDB) {
return copy(source, destination, destinationDB, false);
}

/**
* Copies the value stored at the <code>source</code> to the <code>destination</code> key on
* <code>destinationDB</code>. When <code>replace</code> is true, removes the <code>destination
* </code> key first if it already exists, otherwise performs no action.
*
* @since Redis 6.2.0 and above.
* @see <a href="https://redis.io/commands/copy/">redis.io</a> for details.
* @param source The key to the source value.
* @param destination The key where the value should be copied to.
* @param destinationDB The alternative logical database index for the destination key.
* @param replace If the destination key should be removed before copying the value to it.
* @return Command Response - <code>true</code> if <code>source</code> was copied, <code>false
* </code> if <code>source</code> was not copied.
*/
public Transaction copy(
@NonNull String source, @NonNull String destination, long destinationDB, boolean replace) {
String[] args = new String[] {source, destination, DB_REDIS_API, Long.toString(destinationDB)};
if (replace) {
args = ArrayUtils.add(args, REPLACE_REDIS_API);
}
ArgsArray commandArgs = buildArgs(args);
protobufTransaction.addCommands(buildCommand(Copy, commandArgs));
return this;
}
}
Loading
Loading