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

Consider supporting Enum type in Namespace Entity #17

Merged
merged 1 commit into from
Dec 26, 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 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
Loading