Skip to content

Commit

Permalink
Consider supporting Enum type in Namespace Entity
Browse files Browse the repository at this point in the history
Closes gh-12
  • Loading branch information
evgeniycheban committed Dec 26, 2024
1 parent 33c80da commit af5fc02
Show file tree
Hide file tree
Showing 3 changed files with 193 additions and 8 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
<java.version>17</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<reindexer.version>1.22</reindexer.version>
<reindexer.version>1.23</reindexer.version>
<spring.version>6.2.0</spring.version>
<spring-data-commons.version>3.4.0</spring-data-commons.version>
<spring-test.version>6.2.0</spring-test.version>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,19 @@
*/
package org.springframework.data.reindexer.repository.query;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import ru.rt.restream.reindexer.FieldType;
import ru.rt.restream.reindexer.Namespace;
import ru.rt.restream.reindexer.Query;
import ru.rt.restream.reindexer.Reindexer;
import ru.rt.restream.reindexer.ReindexerIndex;
import ru.rt.restream.reindexer.ReindexerNamespace;

import org.springframework.data.repository.query.ParametersParameterAccessor;
import org.springframework.data.repository.query.RepositoryQuery;
Expand All @@ -42,6 +49,8 @@ public class ReindexerRepositoryQuery implements RepositoryQuery {

private final PartTree tree;

private final Map<String, ReindexerIndex> indexes;

/**
* Creates an instance.
*
Expand All @@ -54,6 +63,10 @@ public ReindexerRepositoryQuery(ReindexerQueryMethod queryMethod, ReindexerEntit
this.namespace = reindexer.openNamespace(entityInformation.getNamespaceName(), entityInformation.getNamespaceOptions(),
entityInformation.getJavaType());
this.tree = new PartTree(queryMethod.getName(), entityInformation.getJavaType());
this.indexes = new HashMap<>();
for (ReindexerIndex index : ((ReindexerNamespace<?>) this.namespace).getIndexes()) {
this.indexes.put(index.getName(), index);
}
}

@Override
Expand Down Expand Up @@ -95,13 +108,13 @@ private Query<?> where(Part part, Query<?> criteria, Iterator<Object> parameters
String indexName = part.getProperty().toDotPath();
switch (part.getType()) {
case GREATER_THAN:
return criteria.where(indexName, Query.Condition.GT, parameters.next());
return criteria.where(indexName, Query.Condition.GT, getParameterValue(indexName, parameters.next()));
case GREATER_THAN_EQUAL:
return criteria.where(indexName, Query.Condition.GE, parameters.next());
return criteria.where(indexName, Query.Condition.GE, getParameterValue(indexName, parameters.next()));
case LESS_THAN:
return criteria.where(indexName, Query.Condition.LT, parameters.next());
return criteria.where(indexName, Query.Condition.LT, getParameterValue(indexName, parameters.next()));
case LESS_THAN_EQUAL:
return criteria.where(indexName, Query.Condition.LE, parameters.next());
return criteria.where(indexName, Query.Condition.LE, getParameterValue(indexName, parameters.next()));
case IN:
case CONTAINING:
return createInQuery(criteria, indexName, parameters);
Expand All @@ -113,20 +126,46 @@ private Query<?> where(Part part, Query<?> criteria, Iterator<Object> parameters
case IS_NULL:
return criteria.isNull(indexName);
case SIMPLE_PROPERTY:
return criteria.where(indexName, Query.Condition.EQ, parameters.next());
return criteria.where(indexName, Query.Condition.EQ, getParameterValue(indexName, parameters.next()));
case NEGATING_SIMPLE_PROPERTY:
return criteria.not().where(indexName, Query.Condition.EQ, parameters.next());
return criteria.not().where(indexName, Query.Condition.EQ, getParameterValue(indexName, parameters.next()));
default:
throw new IllegalArgumentException("Unsupported keyword!");
}
}

private Query<?> createInQuery(Query<?> criteria, String indexName, Iterator<Object> parameters) {
Object value = parameters.next();
Object value = getParameterValue(indexName, parameters.next());
Assert.isInstanceOf(Collection.class, value, () -> "Expected Collection but got " + value);
return criteria.where(indexName, Query.Condition.SET, (Collection<?>) value);
}

private Object getParameterValue(String indexName, Object value) {
if (value instanceof Enum<?>) {
ReindexerIndex index = this.indexes.get(indexName);
Assert.notNull(index, () -> "Index not found: " + indexName);
if (index.getFieldType() == FieldType.STRING) {
return ((Enum<?>) value).name();
}
return ((Enum<?>) value).ordinal();
}
if (value instanceof Collection<?> values) {
List<Object> result = new ArrayList<>();
for (Object object : values) {
result.add(getParameterValue(indexName, object));
}
return result;
}
if (value instanceof Object[] values) {
List<Object> result = new ArrayList<>();
for (Object object : values) {
result.add(getParameterValue(indexName, object));
}
return result;
}
return value;
}

@Override
public ReindexerQueryMethod getQueryMethod() {
return this.queryMethod;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
Expand All @@ -44,10 +45,12 @@
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.utility.DockerImageName;
import ru.rt.restream.reindexer.EnumType;
import ru.rt.restream.reindexer.Query.Condition;
import ru.rt.restream.reindexer.Reindexer;
import ru.rt.restream.reindexer.ReindexerConfiguration;
import ru.rt.restream.reindexer.ResultIterator;
import ru.rt.restream.reindexer.annotations.Enumerated;
import ru.rt.restream.reindexer.annotations.Reindex;

import org.springframework.beans.factory.annotation.Autowired;
Expand Down Expand Up @@ -157,6 +160,30 @@ public void findByNameOrValue() {
assertEquals(testItem.getValue(), item.getValue());
}

@Test
public void findByTestEnumString() {
TestItem testItem = this.repository.save(new TestItem(1L, "TestName", "TestValue", TestEnum.TEST_CONSTANT_1, null));
TestItem item = this.repository.findByTestEnumString(TestEnum.TEST_CONSTANT_1).orElse(null);
assertNotNull(item);
assertEquals(testItem.getId(), item.getId());
assertEquals(testItem.getName(), item.getName());
assertEquals(testItem.getValue(), item.getValue());
assertEquals(testItem.getTestEnumString(), item.getTestEnumString());
assertEquals(testItem.getTestEnumOrdinal(), item.getTestEnumOrdinal());
}

@Test
public void findByTestEnumOrdinal() {
TestItem testItem = this.repository.save(new TestItem(1L, "TestName", "TestValue", null, TestEnum.TEST_CONSTANT_1));
TestItem item = this.repository.findByTestEnumOrdinal(TestEnum.TEST_CONSTANT_1).orElse(null);
assertNotNull(item);
assertEquals(testItem.getId(), item.getId());
assertEquals(testItem.getName(), item.getName());
assertEquals(testItem.getValue(), item.getValue());
assertEquals(testItem.getTestEnumString(), item.getTestEnumString());
assertEquals(testItem.getTestEnumOrdinal(), item.getTestEnumOrdinal());
}

@Test
public void findIteratorByName() {
TestItem testItem = this.repository.save(new TestItem(1L, "TestValue", null));
Expand Down Expand Up @@ -587,6 +614,58 @@ public void findByIdNotContaining() {
assertEquals(0, foundItems.size());
}

@Test
public void findByEnumStringIn() {
List<TestItem> expectedItems = new ArrayList<>();
for (int i = 0; i < 3; i++) {
expectedItems.add(this.repository.save(new TestItem((long) i, "TestName" + i, "TestValue" + i, TestEnum.values()[i], null)));
}
List<TestItem> foundItems = this.repository.findByTestEnumStringIn(expectedItems.stream()
.map(TestItem::getTestEnumString)
.toList());
expectedItems.removeAll(foundItems);
assertEquals(0, expectedItems.size());
}

@Test
public void findByEnumStringInArray() {
List<TestItem> expectedItems = new ArrayList<>();
for (int i = 0; i < 3; i++) {
expectedItems.add(this.repository.save(new TestItem((long) i, "TestName" + i, "TestValue" + i, TestEnum.values()[i], null)));
}
List<TestItem> foundItems = this.repository.findByTestEnumStringIn(expectedItems.stream()
.map(TestItem::getTestEnumString)
.toArray(TestEnum[]::new));
expectedItems.removeAll(foundItems);
assertEquals(0, expectedItems.size());
}

@Test
public void findByEnumOrdinalIn() {
List<TestItem> expectedItems = new ArrayList<>();
for (int i = 0; i < 3; i++) {
expectedItems.add(this.repository.save(new TestItem((long) i, "TestName" + i, "TestValue" + i, null, TestEnum.values()[i])));
}
List<TestItem> foundItems = this.repository.findByTestEnumOrdinalIn(expectedItems.stream()
.map(TestItem::getTestEnumOrdinal)
.toList());
expectedItems.removeAll(foundItems);
assertEquals(0, expectedItems.size());
}

@Test
public void findByEnumOrdinalInArray() {
List<TestItem> expectedItems = new ArrayList<>();
for (int i = 0; i < 3; i++) {
expectedItems.add(this.repository.save(new TestItem((long) i, "TestName" + i, "TestValue" + i, null, TestEnum.values()[i])));
}
List<TestItem> foundItems = this.repository.findByTestEnumOrdinalIn(expectedItems.stream()
.map(TestItem::getTestEnumOrdinal)
.toArray(TestEnum[]::new));
expectedItems.removeAll(foundItems);
assertEquals(0, expectedItems.size());
}

@Configuration
@EnableReindexerRepositories(basePackageClasses = TestItemReindexerRepository.class, considerNestedRepositories = true)
@EnableTransactionManagement
Expand Down Expand Up @@ -637,6 +716,10 @@ interface TestItemReindexerRepository extends ReindexerRepository<TestItem, Long

Optional<TestItem> findByNameOrValue(String name, String value);

Optional<TestItem> findByTestEnumString(TestEnum testEnum);

Optional<TestItem> findByTestEnumOrdinal(TestEnum testEnum);

ResultIterator<TestItem> findIteratorByName(String name);

@Query("SELECT * FROM items WHERE name = ?1")
Expand Down Expand Up @@ -697,6 +780,14 @@ Optional<TestItem> findOneSqlByNameAndValueManyParams(String name1, String name2
List<TestItem> findByIdNotIn(List<Long> ids);

List<TestItem> findByIdNotContaining(List<Long> ids);

List<TestItem> findByTestEnumStringIn(List<TestEnum> values);

List<TestItem> findByTestEnumStringIn(TestEnum... values);

List<TestItem> findByTestEnumOrdinalIn(List<TestEnum> values);

List<TestItem> findByTestEnumOrdinalIn(TestEnum... values);
}

@Namespace(name = NAMESPACE_NAME)
Expand All @@ -711,6 +802,14 @@ public static class TestItem {
@Reindex(name = "value")
private String value;

@Enumerated(EnumType.STRING)
@Reindex(name = "testEnumString")
private TestEnum testEnumString;

@Enumerated(EnumType.ORDINAL)
@Reindex(name = "testEnumOrdinal")
private TestEnum testEnumOrdinal;

public TestItem() {
}

Expand All @@ -720,6 +819,14 @@ public TestItem(Long id, String name, String value) {
this.value = value;
}

public TestItem(Long id, String name, String value, TestEnum testEnumString, TestEnum testEnumOrdinal) {
this.id = id;
this.name = name;
this.value = value;
this.testEnumString = testEnumString;
this.testEnumOrdinal = testEnumOrdinal;
}

public Long getId() {
return this.id;
}
Expand All @@ -744,17 +851,56 @@ public void setValue(String value) {
this.value = value;
}

public TestEnum getTestEnumString() {
return testEnumString;
}

public void setTestEnumString(TestEnum testEnumString) {
this.testEnumString = testEnumString;
}

public TestEnum getTestEnumOrdinal() {
return testEnumOrdinal;
}

public void setTestEnumOrdinal(TestEnum testEnumOrdinal) {
this.testEnumOrdinal = testEnumOrdinal;
}

@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) {
return false;
}
TestItem testItem = (TestItem) o;
return Objects.equals(id, testItem.id) && Objects.equals(name, testItem.name) && Objects.equals(value, testItem.value)
&& testEnumString == testItem.testEnumString && testEnumOrdinal == testItem.testEnumOrdinal;
}

@Override
public int hashCode() {
return Objects.hash(id, name, value, testEnumString, testEnumOrdinal);
}

@Override
public String toString() {
return "TestItem{" +
"id=" + this.id +
", name='" + this.name + '\'' +
", value='" + this.value + '\'' +
", testEnumString=" + this.testEnumString +
", testEnumOrdinal=" + this.testEnumOrdinal +
'}';
}

}

public enum TestEnum {
TEST_CONSTANT_1,
TEST_CONSTANT_2,
TEST_CONSTANT_3,
}

public static class CreateDatabase {

private String name;
Expand Down

0 comments on commit af5fc02

Please sign in to comment.