Skip to content

SET IFEQ command implemented in Java + tests - #2978

Merged
Maayanshani25 merged 8 commits into
valkey-io:mainfrom
Maayanshani25:ifeq-java
Feb 3, 2025
Merged

Maayanshani25 merged 8 commits into
valkey-io:mainfrom
Maayanshani25:ifeq-java

Conversation

@Maayanshani25

@Maayanshani25 Maayanshani25 commented Jan 19, 2025

Copy link
Copy Markdown
Collaborator

Issue link

This Pull Request is linked to issue (URL): [/issues/2811]

Description

This pull Request is implemented the IFEQ option in the SET commamnd. Tests were added, and docstring to the command and the related method.

Checklist

Before submitting the PR make sure the following are checked:

  • This Pull Request is related to one issue.
  • Commit message has a detailed description of what changed and why.
  • Tests are added or updated.
  • CHANGELOG.md and documentation files are updated.
  • Destination branch is correct - main or release
  • Create merge commit if merging release branch into main, squash otherwise.

@Maayanshani25
Maayanshani25 requested a review from a team as a code owner January 19, 2025 10:28
@Maayanshani25

Copy link
Copy Markdown
Collaborator Author

@Yury-Fridlyand
I found the implementation of java a bit different than node.
Do you think it's possible to this the also here? #2909 (comment)

@Yury-Fridlyand Yury-Fridlyand added the java ☕ issues and fixes related to the java client label Jan 20, 2025
@Yury-Fridlyand

Yury-Fridlyand commented Jan 20, 2025

Copy link
Copy Markdown

Java is not so flexible, unfortunately.
But it is still possible to do if you customize the setter in the SetOptions builder. Probably, you can keep exposed ConditionalSet with 2 options, but under the hood have another one with 3 options.
Need to be careful to avoid breaking changes while doing refactoring.
StandaloneSubscriptionConfigurationBuilder is a nice example of a customized builder.

@Maayanshani25

Maayanshani25 commented Jan 22, 2025

Copy link
Copy Markdown
Collaborator Author

So for now I see two options.

  1. The implementation I did in the pr for now. If the user chooses the conditionalSet ONLY_IF_EQUAL, it makes sure comparisonValue isnt null and push them both to the args.
    If comparisonValue is set but The condionalSet is not ONLY_IF_EQUAL, throws an error

  2. Removing ONLY_IF_EQUAL from conditionalSet options and use it this way:

if (conditionalSet != null) {
            optionArgs.add(conditionalSet.valkeyApi);
} else if (comparisonValue != null) {
            optionArgs.add("IFEQ", comparisonValue);

}

What do you think is better?

Comment thread java/client/src/main/java/glide/api/commands/StringBaseCommands.java Outdated
@Maayanshani25
Maayanshani25 force-pushed the ifeq-java branch 2 times, most recently from 5b73b9f to 97041b8 Compare January 23, 2025 19:45
Comment thread java/client/src/main/java/glide/api/commands/StringBaseCommands.java Outdated
Comment thread java/client/src/main/java/glide/api/models/commands/SetOptions.java Outdated
Comment thread java/client/src/main/java/glide/api/models/commands/SetOptions.java Outdated
Comment thread java/client/src/main/java/glide/api/models/commands/SetOptions.java Outdated
Comment thread java/client/src/main/java/glide/api/models/commands/SetOptions.java
@Maayanshani25

Copy link
Copy Markdown
Collaborator Author

@Yury-Fridlyand
Is it good? anything else or can you approve?

Comment thread java/client/src/main/java/glide/api/models/commands/SetOptions.java Outdated
Comment thread java/client/src/main/java/glide/api/models/commands/SetOptions.java Outdated
Comment thread java/client/src/main/java/glide/api/models/commands/SetOptions.java Outdated
Comment thread java/client/src/main/java/glide/api/models/commands/SetOptions.java Outdated
@Yury-Fridlyand

Copy link
Copy Markdown

LGTM, I applied minor doc updates. Need a second approval.

@ikolomi
ikolomi self-requested a review January 28, 2025 09:33
* String value = client.set("key", "value", options).get();
* assert value.equals("OK");
* }</pre>
* <pre>{@code

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apparently addition of IFEQ out-dates the @return doc above.
Since it becomes complicated to explain all the implications introduced by the new options, perhaps the return doc string should only mention that the set options affect the return behavior. In case you prefer to keep the full explanation in the return doc, extend it with IFEQ

* of {@link ConditionalSet#ONLY_IF_EXISTS} or {@link ConditionalSet#ONLY_IF_DOES_NOT_EXIST}
* conditions, return <code>null</code>. If {@link SetOptionsBuilder#returnOldValue(boolean)}
* is set, return the old value as a <code>String</code>.
* or {@link ConditionalSet#ONLY_IF_EQUAL} conditions, return <code>null</code>. If {@link

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above

* API.
*/
ONLY_IF_DOES_NOT_EXIST("NX");
ONLY_IF_DOES_NOT_EXIST("NX"),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here a confusion starts - are these mutual exclusive? You should doc it

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not possible for a key to both exist and not exist at the same time, so the user can specify only one condition. In the Valkey API, you can choose SET key value [NX | XX | IFEQ comparison-value].
There is no contradiction between the XX and IFEQ comparison-value conditions but in the API of valkey they chose to apply only one of them.
In Java, it's a bit complicated to enforce this. In Node.js, I created a new type to apply only one of the conditionals, but here it's a bit different. I think it's okay to use the format we did and as Yuri mentioned above:

SetOptions.builder().conditionalSetIfEqualTo("abc").conditionalSet(ONLY_IF_DOES_NOT_EXIST).build(); // should not fail
SetOptions.builder().conditionalSet(ONLY_IF_EQUAL).build(); // should fail

In this approach, the last condition set will be the one that applies.

@ikolomi what do you think?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need to enforce the mutual exclusiveness by throwing from the builder's setters

* @param value The value to compare.
* @return This builder instance.
*/
public SetOptionsBuilder conditionalSetIfEqualTo(@NonNull String value) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suspect we want these conditions to be mutual exclusive ? If so, we should enforce it by throwing

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

``
public SetOptionsBuilder conditionalIfExistst() {
}

public SetOptionsBuilder conditionalIfNotExistst() {
}

public SetOptionsBuilder conditionalIfEqual(@nonnull String value) {
}
``

Lest the methods to override the current value + describe in the docs that the conditions are mutual exclusive

@ikolomi

ikolomi commented Jan 28, 2025

Copy link
Copy Markdown
Contributor

@Maayanshani25 please dont forget to squash

@Maayanshani25
Maayanshani25 force-pushed the ifeq-java branch 2 times, most recently from 1becf23 to 9cecbad Compare January 29, 2025 09:15
Signed-off-by: Maayan Shani <maayan.shani@mail.huji.ac.il>
Signed-off-by: Maayan Shani <maayan.shani@mail.huji.ac.il>
Signed-off-by: Maayan Shani <maayan.shani@mail.huji.ac.il>
Signed-off-by: Maayan Shani <maayan.shani@mail.huji.ac.il>
…to NonNull

Signed-off-by: Maayan Shani <maayan.shani@mail.huji.ac.il>
Signed-off-by: Maayan Shani <maayan.shani@mail.huji.ac.il>
Signed-off-by: Maayan Shani <maayan.shani@mail.huji.ac.il>
* @param value The value to compare.
* @return This builder instance.
*/
public SetOptionsBuilder conditionalSetIfEqualTo(@NonNull String value) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

``
public SetOptionsBuilder conditionalIfExistst() {
}

public SetOptionsBuilder conditionalIfNotExistst() {
}

public SetOptionsBuilder conditionalIfEqual(@nonnull String value) {
}
``

Lest the methods to override the current value + describe in the docs that the conditions are mutual exclusive

@Maayanshani25
Maayanshani25 merged commit 7b77603 into valkey-io:main Feb 3, 2025
liorsve pushed a commit to liorsve/valkey-glide that referenced this pull request Mar 30, 2025
* start ifeq in java

Signed-off-by: Maayan Shani <maayan.shani@mail.huji.ac.il>

* set option + two tests

Signed-off-by: Maayan Shani <maayan.shani@mail.huji.ac.il>

* add docstring, throw errors, changelog

Signed-off-by: Maayan Shani <maayan.shani@mail.huji.ac.il>

* add conditionalSetIfEqualTo builder

Signed-off-by: Maayan Shani <maayan.shani@mail.huji.ac.il>

* add conditionalSet builder for OXX and NX and change comparisonValue to NonNull

Signed-off-by: Maayan Shani <maayan.shani@mail.huji.ac.il>

* Enforce mutual exclusive + yuri fixes

* mutual exclusive

Signed-off-by: Maayan Shani <maayan.shani@mail.huji.ac.il>

* docstring and lint

Signed-off-by: Maayan Shani <maayan.shani@mail.huji.ac.il>

---------

Signed-off-by: Maayan Shani <maayan.shani@mail.huji.ac.il>
@v3rm0n v3rm0n mentioned this pull request Dec 10, 2025
6 tasks
affonsov pushed a commit that referenced this pull request Aug 21, 2026
* start ifeq in java

Signed-off-by: Maayan Shani <maayan.shani@mail.huji.ac.il>

* set option + two tests

Signed-off-by: Maayan Shani <maayan.shani@mail.huji.ac.il>

* add docstring, throw errors, changelog

Signed-off-by: Maayan Shani <maayan.shani@mail.huji.ac.il>

* add conditionalSetIfEqualTo builder

Signed-off-by: Maayan Shani <maayan.shani@mail.huji.ac.il>

* add conditionalSet builder for OXX and NX and change comparisonValue to NonNull

Signed-off-by: Maayan Shani <maayan.shani@mail.huji.ac.il>

* Enforce mutual exclusive + yuri fixes

* mutual exclusive

Signed-off-by: Maayan Shani <maayan.shani@mail.huji.ac.il>

* docstring and lint

Signed-off-by: Maayan Shani <maayan.shani@mail.huji.ac.il>

---------

Signed-off-by: Maayan Shani <maayan.shani@mail.huji.ac.il>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

java ☕ issues and fixes related to the java client

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants