aerospike / aerospike-client-java

Aerospike Java Client Library
Other
236 stars 212 forks source link

Support for Enums in the Value class #182

Closed mikecaulley closed 3 years ago

mikecaulley commented 3 years ago

Summary

I'd like to use Enums in Java code and have the values saved as Strings in Aerospike. When creating new repository functions with Spring Data Aerospike, AerospikeQueryCreator and Value classes should use the enum.toString() function to properly generate the query.

Example

Given

@Repository
public interface UserRepository extends ReactiveAerospikeRepository<User, UUID> {

  Flux<User> findAllByStatus(Status status);
}

and

@AllArgsConstructor
public enum Status{
  ACTIVE,
  INACTIVE
}

and

@Data
@Document(collection = "user")
@Builder
@AllArgsConstructor
public class User {
  @Id UUID id;

  @Indexed(type = IndexType.STRING)
  @Field
  Status status;
}

When calling the repository function repository.findAllByStatus(Status.PENDING) the generated query would be select * from test.user where status="ACTIVE"

BrianNichols commented 3 years ago

Are you proposing changing the query wire protocol to pass string statements to the server?

The current wire protocol is text for INFO commands and binary for everything else. Aerospike servers do not parse query string statements. AQL uses string statements, but all string parsing is done directly in AQL and not in the server.

mikecaulley commented 3 years ago

I'm using spring data aerospike and it uses this client. In the example above the status field of the User document is an Enum. Using the spring-data repository, the field is saved as a String in Aerospike. On a query, using the repository, the POJO gets built correctly. But the bit that doesn't work is when a query is constructed using a filter on the enum backed field. Spring data Aerospike calls the Value.java class of the client. And the switch statement does not check for an enum type.

Should something like

        if (value instanceof Enum) {
            return new StringValue(value.toString());
        }

get added into Value.java or should there be a change to the spring-data-aerospike library to do the conversion itself to a String before calling Value.get(v1)?

BrianNichols commented 3 years ago

Ok. We will add those 3 lines plus this new method in the next client release.

    /**
     * Get enum value string instance.
     */
    public static Value get(Enum<?> value) {
        return new StringValue(value.toString());
    }
mikecaulley commented 3 years ago

Great! That should fix our issue. Thank you for the fast response!

I created a pull request, if that makes it easier.

mikecaulley commented 3 years ago

Support added as of version 5.0.6 by https://github.com/aerospike/aerospike-client-java/commit/e348185573c9a872a06a4fe0ad3b1e0c606d6277.

Thank you!