[New] Added new SearchExpressions.paramOnBagType()

This allows to search to have a search, where multiple bags of the same type having a parameter with a given ID, yet different values is searched using the .isIn().

For example:

    paramOnBagType("Owner", "name").isIn("Felix", "Jill")

This allows for one less where clause with lambdas.
This commit is contained in:
Robert von Burg 2024-01-11 12:33:51 +01:00
parent 8b20e4392d
commit ce22f180af
Signed by: eitch
GPG Key ID: 75DB9C85C74331F7
4 changed files with 89 additions and 28 deletions

View File

@ -70,6 +70,9 @@ public interface ExpressionBuilder {
default <T extends StrolchRootElement> SearchExpression<T> isIn(Object right) { default <T extends StrolchRootElement> SearchExpression<T> isIn(Object right) {
return element -> PredicatesSupport.isIn(right).matches(extract(element)); return element -> PredicatesSupport.isIn(right).matches(extract(element));
} }
default <T extends StrolchRootElement> SearchExpression<T> isIn(Object... right) {
return element -> PredicatesSupport.isIn(right).matches(extract(element));
}
default <T extends StrolchRootElement> SearchExpression<T> isInIgnoreCase(Object right) { default <T extends StrolchRootElement> SearchExpression<T> isInIgnoreCase(Object right) {
return element -> PredicatesSupport.isInIgnoreCase(right).matches(extract(element)); return element -> PredicatesSupport.isInIgnoreCase(right).matches(extract(element));

View File

@ -7,6 +7,7 @@ import li.strolch.model.parameter.StringParameter;
import li.strolch.persistence.api.StrolchTransaction; import li.strolch.persistence.api.StrolchTransaction;
import li.strolch.utils.iso8601.ISO8601FormatFactory; import li.strolch.utils.iso8601.ISO8601FormatFactory;
import java.util.List;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Supplier; import java.util.function.Supplier;
@ -148,6 +149,19 @@ public class ExpressionsSupport {
}; };
} }
public static <T extends StrolchRootElement> ExpressionBuilder paramOnBagType(String bagType, String paramId) {
return element -> {
List<Object> result = element
.streamOfParameterBagsByType(bagType)
.filter(b -> b.isParamSet(paramId))
.map(b -> b.getParameter(paramId, true).getValue())
.toList();
if (result.size() == 1)
return result.getFirst();
return result.toArray();
};
}
public static <T extends StrolchRootElement> ExpressionBuilder extract(Function<T, Object> extractor) { public static <T extends StrolchRootElement> ExpressionBuilder extract(Function<T, Object> extractor) {
return element -> { return element -> {
@SuppressWarnings("unchecked") T e = (T) element; @SuppressWarnings("unchecked") T e = (T) element;

View File

@ -110,6 +110,10 @@ public interface SearchExpressions {
return ExpressionsSupport.paramNull(bagId, paramId); return ExpressionsSupport.paramNull(bagId, paramId);
} }
default ExpressionBuilder paramOnBagType(String bagType, String paramId) {
return ExpressionsSupport.paramOnBagType(bagType, paramId);
}
default ExpressionBuilder relationName(StrolchTransaction tx, String paramId) { default ExpressionBuilder relationName(StrolchTransaction tx, String paramId) {
return ExpressionsSupport.relationName(tx, paramId); return ExpressionsSupport.relationName(tx, paramId);
} }

View File

@ -24,6 +24,7 @@ import org.slf4j.LoggerFactory;
import java.time.Instant; import java.time.Instant;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.util.Arrays;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -66,6 +67,11 @@ public class StrolchSearchTest {
bag.addParameter(new StringParameter("status", "Status", "bla")); bag.addParameter(new StringParameter("status", "Status", "bla"));
bag.addParameter(new StringParameter("color", "Color", "yellow")); bag.addParameter(new StringParameter("color", "Color", "yellow"));
ball.addParameterBag(new ParameterBag("owner1", "Owner", "Owner"));
ball.setString("owner1", "name", "Felix");
ball.addParameterBag(new ParameterBag("owner2", "Owner", "Owner"));
ball.setString("owner2", "name", "Fox");
tx.add(ball); tx.add(ball);
} }
@ -82,6 +88,11 @@ public class StrolchSearchTest {
bag.addParameter(new StringListParameter("stateList", "Status", bag.addParameter(new StringListParameter("stateList", "Status",
asList(State.EXECUTION.name(), State.EXECUTED.name()))); asList(State.EXECUTION.name(), State.EXECUTED.name())));
ball.addParameterBag(new ParameterBag("owner1", "Owner", "Owner"));
ball.setString("owner1", "name", "Jill");
ball.addParameterBag(new ParameterBag("owner2", "Owner", "Owner"));
ball.setString("owner2", "name", "Jane");
tx.add(ball); tx.add(ball);
} }
@ -139,8 +150,10 @@ public class StrolchSearchTest {
try (StrolchTransaction tx = realm.openTx(cert, StrolchSearchTest.class, true)) { try (StrolchTransaction tx = realm.openTx(cert, StrolchSearchTest.class, true)) {
List<JsonObject> result = new BallSearch("the-id", "STATUS", "yellow").where( List<JsonObject> result = new BallSearch("the-id", "STATUS", "yellow")
element -> element.hasTimedState(STATE_FLOAT_ID)).search(tx).map(a -> a.accept(toJsonVisitor)) .where(element -> element.hasTimedState(STATE_FLOAT_ID))
.search(tx)
.map(a -> a.accept(toJsonVisitor))
.toList(); .toList();
assertEquals(2, result.size()); assertEquals(2, result.size());
@ -174,12 +187,18 @@ public class StrolchSearchTest {
StrolchRealm realm = runtimeMock.getAgent().getContainer().getRealm(cert); StrolchRealm realm = runtimeMock.getAgent().getContainer().getRealm(cert);
try (StrolchTransaction tx = realm.openTx(cert, StrolchSearchTest.class, true)) { try (StrolchTransaction tx = realm.openTx(cert, StrolchSearchTest.class, true)) {
assertEquals(4, assertEquals(4, new ResourceSearch()
new ResourceSearch().types().where(param(BAG_ID, PARAM_STRING_ID, contains("rol"))).search(tx) .types()
.toList().size()); .where(param(BAG_ID, PARAM_STRING_ID, contains("rol")))
assertEquals(4, .search(tx)
new ResourceSearch().types().where(param(BAG_ID, PARAM_STRING_ID, startsWithIgnoreCase("STR"))) .toList()
.search(tx).toList().size()); .size());
assertEquals(4, new ResourceSearch()
.types()
.where(param(BAG_ID, PARAM_STRING_ID, startsWithIgnoreCase("STR")))
.search(tx)
.toList()
.size());
} }
} }
@ -230,11 +249,14 @@ public class StrolchSearchTest {
@Override @Override
public void define() { public void define() {
DateRange dateRange = new DateRange().from(ISO8601.parseToZdt("2012-01-01T00:00:00.000+01:00"), DateRange dateRange = new DateRange()
true).to(ISO8601.parseToZdt("2013-01-01T00:00:00.000+01:00"), true); .from(ISO8601.parseToZdt("2012-01-01T00:00:00.000+01:00"), true)
.to(ISO8601.parseToZdt("2013-01-01T00:00:00.000+01:00"), true);
types().where(date().isEqualTo(Instant.ofEpochMilli(1384929777699L).atZone(systemDefault())) types().where(date()
.or(state().isEqualTo(State.CREATED) .isEqualTo(Instant.ofEpochMilli(1384929777699L).atZone(systemDefault()))
.or(state()
.isEqualTo(State.CREATED)
.and(param(BAG_ID, PARAM_STRING_ID).isEqualTo("Strolch")) .and(param(BAG_ID, PARAM_STRING_ID).isEqualTo("Strolch"))
.and(param(BAG_ID, PARAM_DATE_ID).inRange(dateRange)))); .and(param(BAG_ID, PARAM_DATE_ID).inRange(dateRange))));
} }
@ -286,18 +308,30 @@ public class StrolchSearchTest {
try (StrolchTransaction tx = realm.openTx(cert, StrolchSearchTest.class, true)) { try (StrolchTransaction tx = realm.openTx(cert, StrolchSearchTest.class, true)) {
ZonedDateTime dateTime = ISO8601.parseToZdt("2013-11-20T07:42:57.699+01:00"); ZonedDateTime dateTime = ISO8601.parseToZdt("2013-11-20T07:42:57.699+01:00");
assertEquals(0, assertEquals(0, new OrderSearch()
new OrderSearch().types("TestType").where(date().isBefore(dateTime, false)).search(tx).toList() .types("TestType")
.size()); .where(date().isBefore(dateTime, false))
assertEquals(1, .search(tx)
new OrderSearch().types("TestType").where(date().isBefore(dateTime, true)).search(tx).toList() .toList()
.size()); .size());
assertEquals(0, assertEquals(1, new OrderSearch()
new OrderSearch().types("TestType").where(date().isAfter(dateTime, false)).search(tx).toList() .types("TestType")
.size()); .where(date().isBefore(dateTime, true))
assertEquals(1, .search(tx)
new OrderSearch().types("TestType").where(date().isAfter(dateTime, true)).search(tx).toList() .toList()
.size()); .size());
assertEquals(0, new OrderSearch()
.types("TestType")
.where(date().isAfter(dateTime, false))
.search(tx)
.toList()
.size());
assertEquals(1, new OrderSearch()
.types("TestType")
.where(date().isAfter(dateTime, true))
.search(tx)
.toList()
.size());
} }
} }
@ -349,8 +383,12 @@ public class StrolchSearchTest {
StrolchRealm realm = runtimeMock.getAgent().getContainer().getRealm(cert); StrolchRealm realm = runtimeMock.getAgent().getContainer().getRealm(cert);
try (StrolchTransaction tx = realm.openTx(cert, StrolchSearchTest.class, true)) { try (StrolchTransaction tx = realm.openTx(cert, StrolchSearchTest.class, true)) {
assertEquals(1, new ActivitySearch().types("sdf", "ActivityType") assertEquals(1, new ActivitySearch()
.where(element -> element.getActionsByType("Use").size() == 4).search(tx).toList().size()); .types("sdf", "ActivityType")
.where(element -> element.getActionsByType("Use").size() == 4)
.search(tx)
.toList()
.size());
} }
} }
@ -405,8 +443,8 @@ public class StrolchSearchTest {
public void define() { public void define() {
types("Ball").where(id(isEqualTo(this.id)).or( // types("Ball").where(id(isEqualTo(this.id)).or( //
param("parameters", "status", isEqualTo(this.status)).and( param("parameters", "status", isEqualTo(this.status))
not(param("parameters", "color", isEqualTo(this.color)))) .and(not(param("parameters", "color", isEqualTo(this.color))))
.and(param("parameters", "state", isEqualTo(State.EXECUTION))) .and(param("parameters", "state", isEqualTo(State.EXECUTION)))
.and(param("parameters", "state", isEqualToIgnoreCase(State.EXECUTION))) .and(param("parameters", "state", isEqualToIgnoreCase(State.EXECUTION)))
@ -469,6 +507,8 @@ public class StrolchSearchTest {
.and(param(BAG_ID, PARAM_LIST_STRING_ID, listContains("World"))) .and(param(BAG_ID, PARAM_LIST_STRING_ID, listContains("World")))
.and(param(BAG_ID, PARAM_LIST_STRING_ID, listContains("World1")).not()) .and(param(BAG_ID, PARAM_LIST_STRING_ID, listContains("World1")).not())
.and(paramOnBagType("Owner", "name").isIn("Felix", "Jill"))
.and(paramNull(BAG_ID, "non-existant")) .and(paramNull(BAG_ID, "non-existant"))
// //
)); ));