mirror of
https://github.com/scm-manager/scm-manager.git
synced 2026-08-07 15:40:39 +02:00
Implement 'like' condition for string values
Squash commits of branch feature/like_query_for_string: - Implement 'like' condition for string values - Log change - Enhance tests - Fix JavaDoc - Add more tests
This commit is contained in:
2
gradle/changelog/like.yaml
Normal file
2
gradle/changelog/like.yaml
Normal file
@@ -0,0 +1,2 @@
|
||||
- type: added
|
||||
description: "Like" condition for string fields in queryable stores
|
||||
@@ -24,6 +24,7 @@ public enum Operator {
|
||||
LESS_OR_EQUAL,
|
||||
GREATER_OR_EQUAL,
|
||||
CONTAINS,
|
||||
LIKE,
|
||||
IN,
|
||||
NULL,
|
||||
KEY,
|
||||
|
||||
@@ -313,6 +313,18 @@ public interface QueryableStore<T> extends AutoCloseable {
|
||||
return new LeafCondition<>(this, Operator.CONTAINS, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a condition that checks if the field matches the given pattern. The pattern can contain asterisks (*) as
|
||||
* wildcards, which will match any sequence of characters.
|
||||
* <br/>For example, <code>Heart*Gold</code> will match "Heart Of Gold", "HeartGold", or "Heart of Gold" but not
|
||||
* "Heart of Gold and Silver". For now, escaping of asterisks is not supported.
|
||||
*
|
||||
* @param value The pattern to check for.
|
||||
* @return The condition to use in a query.
|
||||
*/
|
||||
public Condition<T> like(String value) {
|
||||
return new LeafCondition<>(this, Operator.LIKE, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a condition that checks if the field is equal to any of the given values.
|
||||
|
||||
@@ -73,6 +73,7 @@ class SQLCondition implements SQLNodeWithValue {
|
||||
case GREATER -> ">";
|
||||
case GREATER_OR_EQUAL -> ">=";
|
||||
case CONTAINS -> "LIKE '%' ||";
|
||||
case LIKE -> "LIKE ";
|
||||
case NULL -> "IS NULL";
|
||||
case IN -> "IN";
|
||||
case KEY -> "key =";
|
||||
@@ -106,14 +107,14 @@ class SQLCondition implements SQLNodeWithValue {
|
||||
switch (operator) {
|
||||
case NULL:
|
||||
return new SQLValue(null);
|
||||
|
||||
case IN:
|
||||
if (value instanceof Object[] valueArray) {
|
||||
return new SQLValue(valueArray);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Value for IN operator must be an array.");
|
||||
}
|
||||
|
||||
case LIKE:
|
||||
return new SQLValue(value.toString().replace('*', '%'));
|
||||
default:
|
||||
return new SQLValue(computeParameter(leafCondition));
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@ import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
import sonia.scm.group.Group;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.store.Conditions;
|
||||
@@ -66,6 +68,36 @@ class SQLiteQueryableStoreTest {
|
||||
@Nested
|
||||
class QueryClassTypes {
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {"*Of*", "Heart*Gold", "H*", "*d", "*Heart Of Gold*", "Heart Of Gold", "Heart Of *Gold"})
|
||||
void shouldWorkWithLikes(String searchString) {
|
||||
SQLiteQueryableMutableStore<Spaceship> store = new StoreTestBuilder(connectionString).forClassWithIds(Spaceship.class);
|
||||
store.put(new Spaceship("Space Shuttle", Range.SOLAR_SYSTEM));
|
||||
store.put(new Spaceship("Heart Of Gold", Range.INTER_GALACTIC));
|
||||
|
||||
List<Spaceship> all = store
|
||||
.query(SPACESHIP_NAME.like(searchString))
|
||||
.findAll();
|
||||
|
||||
assertThat(all)
|
||||
.extracting("name")
|
||||
.containsExactly("Heart Of Gold");
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {"Of", "*of*", "heart of gold"})
|
||||
void shouldNotFindNotMatchingValuesWithLike() {
|
||||
SQLiteQueryableMutableStore<Spaceship> store = new StoreTestBuilder(connectionString).forClassWithIds(Spaceship.class);
|
||||
store.put(new Spaceship("Space Shuttle", Range.SOLAR_SYSTEM));
|
||||
store.put(new Spaceship("Heart Of Gold", Range.INTER_GALACTIC));
|
||||
|
||||
List<Spaceship> all = store
|
||||
.query(SPACESHIP_NAME.like("Of"))
|
||||
.findAll();
|
||||
|
||||
assertThat(all).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldWorkWithEnums() {
|
||||
SQLiteQueryableMutableStore<Spaceship> store = new StoreTestBuilder(connectionString).forClassWithIds(Spaceship.class);
|
||||
|
||||
Reference in New Issue
Block a user