tech.ydb.yoj.repository.db.Range Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of yoj-repository Show documentation
Show all versions of yoj-repository Show documentation
Core YOJ (YDB ORM for Java) abstractions and APIs for domain entities, repositories, transactions etc.
package tech.ydb.yoj.repository.db;
import com.google.common.base.Preconditions;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.NonNull;
import lombok.Value;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Stream;
import static java.util.stream.Collectors.toList;
@Value
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class Range> {
EntityIdSchema type;
Map eqMap;
Map minMap;
Map maxMap;
public static > Range create(@NonNull ID partial) {
return create(partial, partial);
}
@SuppressWarnings({"unchecked"})
public static > Range create(@NonNull ID min, @NonNull ID max) {
Preconditions.checkArgument(min.getClass() == max.getClass(), "Min and max must be instances of the same class");
EntityIdSchema type = (EntityIdSchema) EntityIdSchema.of(min.getClass());
Map mn = type.flatten(min);
Map mx = type.flatten(max);
return create(type, mn, mx);
}
public static > Range create(EntityIdSchema type, Map map) {
return create(type, map, map);
}
@SuppressWarnings({"unchecked", "rawtypes"})
public static > Range create(
EntityIdSchema type, Map mn, Map mx
) {
Map eqMap = new HashMap<>();
Map minMap = new HashMap<>();
Map maxMap = new HashMap<>();
StringBuilder s = new StringBuilder();
for (String fn : type.flattenFieldNames()) {
Comparable a = (Comparable) mn.get(fn);
Comparable b = (Comparable) mx.get(fn);
if (a == null && b == null) {
s.append("0");
} else if (a == null) {
maxMap.put(fn, b);
s.append("<");
} else if (b == null) {
minMap.put(fn, a);
s.append("<");
} else if (a.compareTo(b) < 0) {
minMap.put(fn, a);
maxMap.put(fn, b);
s.append("<");
} else if (a.compareTo(b) == 0) {
s.append("=");
eqMap.put(fn, a);
} else {
throw new IllegalArgumentException("min must be less or equal to max");
}
}
Preconditions.checkArgument(s.toString().matches("=*0*"),
"Fields of min and max must be filled in specific order: (equal)*(different)?(null)*");
return new Range<>(type, eqMap, minMap, maxMap);
}
@SuppressWarnings({"unchecked", "rawtypes"})
public boolean contains(ID id) {
Map flat = type.flatten(id);
for (String fn : type.flattenFieldNames()) {
Comparable c = (Comparable) flat.get(fn);
if (c == null) {
throw new IllegalArgumentException("Id fields cannot be null: " + id);
}
Object x = eqMap.get(fn);
if (x != null && c.compareTo(x) != 0) {
return false;
}
Object a = minMap.get(fn);
if (a != null && c.compareTo(a) < 0) {
return false;
}
Object b = maxMap.get(fn);
if (b != null && c.compareTo(b) > 0) {
return false;
}
}
return true;
}
public List> getSchema() {
return Stream.of(eqMap.keySet(), minMap.keySet(), maxMap.keySet())
.collect(toList());
}
@Override
public String toString() {
ArrayList list = new ArrayList<>();
eqMap.forEach((k, v) -> list.add(k + "=" + v));
minMap.forEach((k, v) -> list.add(k + ">=" + v));
maxMap.forEach((k, v) -> list.add(k + "<=" + v));
return "Range("
+ type.getType().getName().replaceFirst(".*\\.", "")
+ ": "
+ String.join(", ", list)
+ ")";
}
}