diff --git a/databind/src/main/java/tech/ydb/yoj/InternalApi.java b/databind/src/main/java/tech/ydb/yoj/InternalApi.java
index 2f5183e6..8cc97d78 100644
--- a/databind/src/main/java/tech/ydb/yoj/InternalApi.java
+++ b/databind/src/main/java/tech/ydb/yoj/InternalApi.java
@@ -18,7 +18,7 @@
* Annotates internal YOJ implementation details (classes, interfaces, methods, fields, constants, etc.) that need to be
* {@code public} to be used from different and/or multiple packages, but are not stable even across minor YOJ releases.
*
Non-{@code public} (e.g., package-private) classes, interfaces, methods, fields, constants etc. in YOJ are assumed
- * to be internal implementation details regardless of the presence of an {@code @InternalApi} annotation on them.
+ * to be internal implementation details regardless of the presence of an {@code @InternalApi} annotation on them.
*/
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, ANNOTATION_TYPE, PACKAGE, MODULE, RECORD_COMPONENT})
@Retention(SOURCE)
diff --git a/databind/src/main/java/tech/ydb/yoj/databind/schema/reflect/StdReflector.java b/databind/src/main/java/tech/ydb/yoj/databind/schema/reflect/StdReflector.java
index c1c357b0..8b78c03f 100644
--- a/databind/src/main/java/tech/ydb/yoj/databind/schema/reflect/StdReflector.java
+++ b/databind/src/main/java/tech/ydb/yoj/databind/schema/reflect/StdReflector.java
@@ -49,7 +49,7 @@ public ReflectType> reflectFieldType(Type genericType, FieldValueType bindingT
}
private ReflectType> reflectFor(Type type, FieldValueType fvt) {
- Class> rawType = TypeToken.of(type).getRawType();
+ Class> rawType = type instanceof Class> clazz ? clazz : TypeToken.of(type).getRawType();
for (TypeFactory m : matchers) {
if (m.matches(rawType, fvt)) {
return m.create(this, rawType, fvt);
diff --git a/repository-inmemory/src/main/java/tech/ydb/yoj/repository/test/inmemory/InMemoryDataShard.java b/repository-inmemory/src/main/java/tech/ydb/yoj/repository/test/inmemory/InMemoryDataShard.java
index 7ad8de6b..f406b55a 100644
--- a/repository-inmemory/src/main/java/tech/ydb/yoj/repository/test/inmemory/InMemoryDataShard.java
+++ b/repository-inmemory/src/main/java/tech/ydb/yoj/repository/test/inmemory/InMemoryDataShard.java
@@ -2,7 +2,6 @@
import tech.ydb.yoj.databind.schema.Schema;
import tech.ydb.yoj.repository.db.Entity;
-import tech.ydb.yoj.repository.db.EntityIdSchema;
import tech.ydb.yoj.repository.db.EntitySchema;
import tech.ydb.yoj.repository.db.Range;
import tech.ydb.yoj.repository.db.Table;
@@ -18,18 +17,19 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.SortedMap;
import java.util.TreeMap;
/*package*/ final class InMemoryDataShard> {
private final TableDescriptor tableDescriptor;
private final EntitySchema schema;
- private final TreeMap, InMemoryEntityLine> entityLines;
+ private final SortedMap, InMemoryEntityLine> entityLines;
private final Map>> uncommited = new HashMap<>();
private InMemoryDataShard(
TableDescriptor tableDescriptor,
EntitySchema schema,
- TreeMap, InMemoryEntityLine> entityLines
+ SortedMap, InMemoryEntityLine> entityLines
) {
this.tableDescriptor = tableDescriptor;
this.schema = schema;
@@ -39,18 +39,24 @@ private InMemoryDataShard(
public InMemoryDataShard(TableDescriptor tableDescriptor) {
this(
tableDescriptor,
- EntitySchema.of(tableDescriptor.entityType()),
- createEmptyLines(tableDescriptor.entityType())
+ EntitySchema.of(tableDescriptor.entityType())
);
}
- private static > TreeMap, InMemoryEntityLine> createEmptyLines(Class type) {
- return new TreeMap<>(EntityIdSchema.getIdComparator(type));
+ private InMemoryDataShard(
+ TableDescriptor tableDescriptor,
+ EntitySchema schema
+ ) {
+ this(tableDescriptor, schema, createEmptyLines(schema));
+ }
+
+ private static > SortedMap, InMemoryEntityLine> createEmptyLines(EntitySchema schema) {
+ return new TreeMap<>(schema.getIdSchema());
}
public synchronized InMemoryDataShard createSnapshot() {
- TreeMap, InMemoryEntityLine> snapshotLines = createEmptyLines(tableDescriptor.entityType());
- for (Map.Entry, InMemoryEntityLine> entry : entityLines.entrySet()) {
+ var snapshotLines = createEmptyLines(schema);
+ for (var entry : entityLines.entrySet()) {
snapshotLines.put(entry.getKey(), entry.getValue().createSnapshot());
}
return new InMemoryDataShard<>(tableDescriptor, schema, snapshotLines);
diff --git a/repository-inmemory/src/main/java/tech/ydb/yoj/repository/test/inmemory/InMemoryRepositoryTransaction.java b/repository-inmemory/src/main/java/tech/ydb/yoj/repository/test/inmemory/InMemoryRepositoryTransaction.java
index 67e2d917..a0059f31 100644
--- a/repository-inmemory/src/main/java/tech/ydb/yoj/repository/test/inmemory/InMemoryRepositoryTransaction.java
+++ b/repository-inmemory/src/main/java/tech/ydb/yoj/repository/test/inmemory/InMemoryRepositoryTransaction.java
@@ -3,6 +3,7 @@
import com.google.common.base.Stopwatch;
import com.google.common.collect.Iterables;
import lombok.Getter;
+import tech.ydb.yoj.DeprecationWarnings;
import tech.ydb.yoj.repository.BaseDb;
import tech.ydb.yoj.repository.db.Entity;
import tech.ydb.yoj.repository.db.RepositoryTransaction;
@@ -57,7 +58,7 @@ private long getVersion() {
@Override
public > Table table(Class c) {
- return new InMemoryTable<>(getMemory(c));
+ return new InMemoryTable<>(this, c);
}
@Override
@@ -65,8 +66,13 @@ public > Table table(TableDescriptor tableDescriptor)
return new InMemoryTable<>(this, tableDescriptor);
}
- @Deprecated // use other constructor of InMemoryTable
+ /**
+ * @deprecated {@code DbMemory} and this method will be removed in YOJ 3.0.0.
+ */
+ @Deprecated(forRemoval = true)
public final > InMemoryTable.DbMemory getMemory(Class c) {
+ DeprecationWarnings.warnOnce("InMemoryTable.getMemory",
+ "InMemoryTable.getMemory(Class) will be removed in YOJ 3.0.0. Please stop using this method");
return new InMemoryTable.DbMemory<>(c, this);
}
diff --git a/repository-inmemory/src/main/java/tech/ydb/yoj/repository/test/inmemory/InMemoryTable.java b/repository-inmemory/src/main/java/tech/ydb/yoj/repository/test/inmemory/InMemoryTable.java
index b4c2f084..e47f5014 100644
--- a/repository-inmemory/src/main/java/tech/ydb/yoj/repository/test/inmemory/InMemoryTable.java
+++ b/repository-inmemory/src/main/java/tech/ydb/yoj/repository/test/inmemory/InMemoryTable.java
@@ -3,6 +3,7 @@
import com.google.common.base.Preconditions;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
+import tech.ydb.yoj.DeprecationWarnings;
import tech.ydb.yoj.databind.expression.FilterExpression;
import tech.ydb.yoj.databind.expression.OrderExpression;
import tech.ydb.yoj.databind.schema.ObjectSchema;
@@ -14,6 +15,7 @@
import tech.ydb.yoj.repository.db.Range;
import tech.ydb.yoj.repository.db.Table;
import tech.ydb.yoj.repository.db.TableDescriptor;
+import tech.ydb.yoj.repository.db.TableQueryBuilder;
import tech.ydb.yoj.repository.db.TableQueryImpl;
import tech.ydb.yoj.repository.db.ViewSchema;
import tech.ydb.yoj.repository.db.cache.FirstLevelCache;
@@ -32,19 +34,28 @@
import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toUnmodifiableMap;
import static java.util.stream.Collectors.toUnmodifiableSet;
+import static tech.ydb.yoj.repository.db.TableQueryImpl.getEntityByIdComparator;
public class InMemoryTable> implements Table {
private final EntitySchema schema;
private final TableDescriptor tableDescriptor;
private final InMemoryRepositoryTransaction transaction;
- @Deprecated // Don't use DbMemory, use other constructor instead
+ /**
+ * @deprecated {@code DbMemory} and this constructor will be removed in YOJ 3.0.0.
+ * Please use other constructors instead.
+ */
+ @Deprecated(forRemoval = true)
public InMemoryTable(DbMemory memory) {
this(memory.transaction(), memory.type());
+ DeprecationWarnings.warnOnce("new InMemoryTable(DbMemory)",
+ "Please do not use the InMemoryTable(DbMemory) constructor, it will be removed in YOJ 3.0.0");
}
public InMemoryTable(InMemoryRepositoryTransaction transaction, Class type) {
- this(transaction, TableDescriptor.from(EntitySchema.of(type)));
+ this.schema = EntitySchema.of(type);
+ this.tableDescriptor = TableDescriptor.from(schema);
+ this.transaction = transaction;
}
public InMemoryTable(InMemoryRepositoryTransaction transaction, TableDescriptor tableDescriptor) {
@@ -53,6 +64,11 @@ public InMemoryTable(InMemoryRepositoryTransaction transaction, TableDescriptor<
this.transaction = transaction;
}
+ @Override
+ public TableQueryBuilder query() {
+ return new TableQueryBuilder<>(this, schema);
+ }
+
@Override
public List findAll() {
transaction.getWatcher().markTableRead(tableDescriptor);
@@ -103,7 +119,7 @@ public List find(
@Nullable Long offset
) {
// NOTE: InMemoryTable doesn't handle index.
- return InMemoryQueries.find(() -> findAll().stream(), filter, orderBy, limit, offset);
+ return TableQueryImpl.find(() -> findAll().stream(), schema, filter, orderBy, limit, offset);
}
@Override
@@ -173,8 +189,8 @@ public TableDescriptor getTableDescriptor() {
@Override
public T find(Entity.Id id) {
- if (id.isPartial()) {
- throw new IllegalArgumentException("Cannot use partial id in find method");
+ if (TableQueryImpl.isPartialId(id, schema)) {
+ throw new IllegalArgumentException("Cannot use partial ID in Table.find() method");
}
return transaction.getTransactionLocal().firstLevelCache(tableDescriptor).get(id, __ -> {
markKeyRead(id);
@@ -185,13 +201,13 @@ public T find(Entity.Id id) {
@Override
public > List find(Set ids) {
- return TableQueryImpl.find(this, getFirstLevelCache(), ids);
+ return TableQueryImpl.find(this, schema, getFirstLevelCache(), ids);
}
@Override
public V find(Class viewType, Entity.Id id) {
- if (id.isPartial()) {
- throw new IllegalArgumentException("Cannot use partial id in find method");
+ if (TableQueryImpl.isPartialId(id, schema)) {
+ throw new IllegalArgumentException("Cannot use partial ID in Table.find() method");
}
FirstLevelCache cache = transaction.getTransactionLocal().firstLevelCache(tableDescriptor);
@@ -208,10 +224,13 @@ public V find(Class viewType, Entity.Id id) {
@Override
@SuppressWarnings("unchecked")
public > List find(Range range) {
- transaction.getWatcher().markRangeRead(tableDescriptor, range);
+ Preconditions.checkArgument(range.getType() == schema.getIdSchema(),
+ "ID schema mismatch: Range was constructed with a different ID schema than the YdbTable");
+
+ markRangeRead(range);
return findAll0().stream()
.filter(e -> range.contains((ID) e.getId()))
- .sorted(EntityIdSchema.SORT_ENTITY_BY_ID)
+ .sorted(getEntityByIdComparator(schema))
.collect(toList());
}
@@ -232,7 +251,7 @@ public > List find(Class viewType,
@Override
public > List find(Class viewType, Set ids) {
- return find(viewType, ids, null, EntityExpressions.defaultOrder(getType()), null);
+ return find(viewType, ids, null, EntityExpressions.defaultOrder(schema), null);
}
@Override
@@ -404,9 +423,10 @@ private boolean isPrefixedFields(List keyFields, Set fields) {
private > void markKeyRead(ID id) {
EntityIdSchema> idSchema = schema.getIdSchema();
- if (idSchema.flattenFieldNames().size() != idSchema.flatten(id).size()) {
+ Map eqMap = idSchema.flatten(id);
+ if (idSchema.flattenFieldNames().size() != eqMap.size()) {
// Partial key, will throw error when not searching by PK prefix
- transaction.getWatcher().markRangeRead(tableDescriptor, Range.create(id, id));
+ transaction.getWatcher().markRangeRead(tableDescriptor, Range.create(idSchema, eqMap));
} else {
transaction.getWatcher().markRowRead(tableDescriptor, id);
}
@@ -475,7 +495,7 @@ public > Stream streamPartial(ID partial, int batchSi
Preconditions.checkArgument(1 <= batchSize && batchSize <= 5000,
"batchSize must be in range [1, 5000], got %s", batchSize);
- Range range = partial == null ? null : Range.create(partial);
+ Range range = rangeForPartialId(partial);
markRangeRead(range);
return streamPartial0(range);
@@ -508,13 +528,13 @@ public > Stream streamPartialIds(ID partial, int bat
Preconditions.checkArgument(1 <= batchSize && batchSize <= 10000,
"batchSize must be in range [1, 10000], got %s", batchSize);
- Range range = partial == null ? null : Range.create(partial);
+ Range range = rangeForPartialId(partial);
markRangeRead(range);
return streamPartial0(range).map(e -> (ID) e.getId());
}
- private > void markRangeRead(Range range) {
+ private > void markRangeRead(@Nullable Range range) {
if (range == null) {
transaction.getWatcher().markTableRead(tableDescriptor);
} else {
@@ -522,6 +542,12 @@ private > void markRangeRead(Range range) {
}
}
+ @Nullable
+ private > Range rangeForPartialId(ID partial) {
+ EntityIdSchema idSchema = schema.getIdSchema();
+ return partial == null ? null : Range.create(idSchema, idSchema.flatten(partial));
+ }
+
private > Stream readTableStream(ReadTableParams params) {
if (!transaction.getOptions().getIsolationLevel().isReadOnly()) {
throw new IllegalTransactionIsolationLevelException("readTable", transaction.getOptions().getIsolationLevel());
@@ -533,7 +559,7 @@ private > Stream readTableStream(ReadTableParams
.stream()
.filter(e -> readTableFilter(e, params));
if (params.isOrdered()) {
- stream = stream.sorted(EntityIdSchema.SORT_ENTITY_BY_ID);
+ stream = stream.sorted(getEntityByIdComparator(schema));
}
if (params.getRowLimit() > 0) {
stream = stream.limit(params.getRowLimit());
@@ -542,18 +568,20 @@ private > Stream readTableStream(ReadTableParams
}
private > boolean readTableFilter(T e, ReadTableParams params) {
+ EntityIdSchema idSchema = schema.getIdSchema();
+
@SuppressWarnings("unchecked")
ID id = (ID) e.getId();
ID from = params.getFromKey();
if (from != null) {
- int compare = EntityIdSchema.ofEntity(id.getType()).compare(id, from);
+ int compare = idSchema.compare(id, from);
if (params.isFromInclusive() ? compare < 0 : compare <= 0) {
return false;
}
}
ID to = params.getToKey();
if (to != null) {
- int compare = EntityIdSchema.ofEntity(id.getType()).compare(id, to);
+ int compare = idSchema.compare(id, to);
return params.isToInclusive() ? compare <= 0 : compare < 0;
}
return true;
@@ -587,7 +615,12 @@ private static > V toView(
}
- @Deprecated // Legacy. Using only for creating InMemoryTable. Use constructor of InMemoryTable instead
+ /**
+ * @deprecated Legacy class, used only for creating {@code InMemoryTable}.
+ * This class will be removed in YOJ 3.0.0.
+ * Please use other constructors of {@code InMemoryTable} instead.
+ */
+ @Deprecated(forRemoval = true)
public record DbMemory>(
Class type,
InMemoryRepositoryTransaction transaction
diff --git a/repository-inmemory/src/test/java/tech/ydb/yoj/repository/test/inmemory/TestInMemoryRepository.java b/repository-inmemory/src/test/java/tech/ydb/yoj/repository/test/inmemory/TestInMemoryRepository.java
index 75cdcac5..6ac89c05 100644
--- a/repository-inmemory/src/test/java/tech/ydb/yoj/repository/test/inmemory/TestInMemoryRepository.java
+++ b/repository-inmemory/src/test/java/tech/ydb/yoj/repository/test/inmemory/TestInMemoryRepository.java
@@ -105,7 +105,7 @@ public SupabubbleTable supabubbles() {
@Override
public Supabubble2Table supabubbles2() {
- return new Supabubble2InMemoryTable(getMemory(Supabubble2.class));
+ return new Supabubble2InMemoryTable(this, Supabubble2.class);
}
@Override
@@ -145,8 +145,8 @@ public Table multiWrappedEntities2() {
}
private static class Supabubble2InMemoryTable extends InMemoryTable implements TestEntityOperations.Supabubble2Table {
- public Supabubble2InMemoryTable(DbMemory memory) {
- super(memory);
+ public Supabubble2InMemoryTable(InMemoryRepositoryTransaction transaction, Class type) {
+ super(transaction, type);
}
}
diff --git a/repository-test/src/main/java/tech/ydb/yoj/repository/test/ListingTest.java b/repository-test/src/main/java/tech/ydb/yoj/repository/test/ListingTest.java
index 90c615ca..8a280878 100644
--- a/repository-test/src/main/java/tech/ydb/yoj/repository/test/ListingTest.java
+++ b/repository-test/src/main/java/tech/ydb/yoj/repository/test/ListingTest.java
@@ -1,6 +1,5 @@
package tech.ydb.yoj.repository.test;
-import org.assertj.core.api.Assertions;
import org.junit.Test;
import tech.ydb.yoj.databind.expression.FilterExpression;
import tech.ydb.yoj.databind.expression.OrderExpression;
@@ -10,7 +9,6 @@
import tech.ydb.yoj.repository.db.list.ListRequest;
import tech.ydb.yoj.repository.db.list.ListRequest.ListingParams;
import tech.ydb.yoj.repository.db.list.ListResult;
-import tech.ydb.yoj.repository.db.list.ViewListResult;
import tech.ydb.yoj.repository.test.entity.TestEntities;
import tech.ydb.yoj.repository.test.sample.TestDb;
import tech.ydb.yoj.repository.test.sample.TestDbImpl;
@@ -65,28 +63,28 @@ public void basic() {
OrderExpression orderBy = newOrderBuilder(Project.class).orderBy("name").descending().build();
FilterExpression filter = newFilterBuilder(Project.class).where("name").in("AAA", "XXX", "ZZZ").build();
db.tx(() -> {
- ListResult page1 = listProjects(ListRequest.builder(Project.class)
+ ListResult page1 = db.projects().list(ListRequest.builder(Project.class)
.pageSize(1)
.orderBy(orderBy)
.filter(filter)
.build());
- Assertions.assertThat(page1).containsExactly(p3);
+ assertThat(page1).containsExactly(p3);
- ListResult page2 = listProjects(ListRequest.builder(Project.class)
+ ListResult page2 = db.projects().list(ListRequest.builder(Project.class)
.pageSize(1)
.orderBy(orderBy)
.filter(filter)
.offset(1)
.build());
- Assertions.assertThat(page2).containsExactly(p2);
+ assertThat(page2).containsExactly(p2);
- ListResult page3 = listProjects(ListRequest.builder(Project.class)
+ ListResult page3 = db.projects().list(ListRequest.builder(Project.class)
.pageSize(1)
.orderBy(orderBy)
.filter(filter)
.offset(2)
.build());
- Assertions.assertThat(page3).containsExactly(p1);
+ assertThat(page3).containsExactly(p1);
assertThat(page3.isLastPage()).isTrue();
});
}
@@ -100,11 +98,11 @@ public void complexIdRange() {
db.tx(() -> db.complexes().insert(c1, c2, c3, c4));
db.tx(() -> {
- ListResult page = listComplex(ListRequest.builder(Complex.class)
+ ListResult page = db.complexes().list(ListRequest.builder(Complex.class)
.pageSize(3)
.filter(fb -> fb.where("id.a").eq(999_999))
.build());
- Assertions.assertThat(page).containsExactly(c3, c2, c1);
+ assertThat(page).containsExactly(c3, c2, c1);
assertThat(page.isLastPage()).isTrue();
});
}
@@ -118,11 +116,11 @@ public void complexIdFullScan() {
db.tx(() -> db.complexes().insert(c1, c2, c3, c4));
db.tx(() -> {
- ListResult page = listComplex(ListRequest.builder(Complex.class)
+ ListResult page = db.complexes().list(ListRequest.builder(Complex.class)
.pageSize(3)
.filter(fb -> fb.where("id.c").eq("UUU"))
.build());
- Assertions.assertThat(page).containsExactly(c2);
+ assertThat(page).containsExactly(c2);
assertThat(page.isLastPage()).isTrue();
});
}
@@ -131,7 +129,7 @@ public void complexIdFullScan() {
public void failOnZeroPageSize() {
db.tx(() -> {
assertThatExceptionOfType(BadPageSize.class).isThrownBy(() ->
- listProjects(ListRequest.builder(Project.class)
+ db.projects().list(ListRequest.builder(Project.class)
.pageSize(0)
.build()));
});
@@ -141,7 +139,7 @@ public void failOnZeroPageSize() {
public void failOnTooLargePageSize() {
db.tx(() -> {
assertThatExceptionOfType(BadPageSize.class).isThrownBy(() ->
- listProjects(ListRequest.builder(Project.class)
+ db.projects().list(ListRequest.builder(Project.class)
.pageSize(100_000)
.build()));
});
@@ -151,7 +149,7 @@ public void failOnTooLargePageSize() {
public void failOnTooLargeOffset() {
db.tx(() -> {
assertThatExceptionOfType(BadOffset.class).isThrownBy(() ->
- listProjects(ListRequest.builder(Project.class)
+ db.projects().list(ListRequest.builder(Project.class)
.offset(10_001)
.build()));
});
@@ -166,10 +164,10 @@ public void defaultOrderingIsByIdAscending() {
db.tx(() -> db.complexes().insert(c1, c2, c3, c4));
db.tx(() -> {
- ListResult page = listComplex(ListRequest.builder(Complex.class)
+ ListResult page = db.complexes().list(ListRequest.builder(Complex.class)
.pageSize(4)
.build());
- Assertions.assertThat(page).containsExactly(c4, c3, c2, c1);
+ assertThat(page).containsExactly(c4, c3, c2, c1);
assertThat(page.isLastPage()).isTrue();
});
}
@@ -184,11 +182,11 @@ public void and() {
db.tx(() -> db.complexes().insert(c1, c2, c3, notInOutput));
db.tx(() -> {
- ListResult page = listComplex(ListRequest.builder(Complex.class)
+ ListResult page = db.complexes().list(ListRequest.builder(Complex.class)
.pageSize(3)
.filter(fb -> fb.where("id.a").eq(1).and("id.b").gte(100L).and("id.b").lte(300L))
.build());
- Assertions.assertThat(page).containsExactly(c1, c2, c3);
+ assertThat(page).containsExactly(c1, c2, c3);
assertThat(page.isLastPage()).isTrue();
});
}
@@ -220,7 +218,7 @@ public void embeddedNulls() {
.pageSize(1)
.build()));
- Assertions.assertThat(lst).isEmpty();
+ assertThat(lst).isEmpty();
assertThat(lst.isLastPage()).isTrue();
}
@@ -263,12 +261,12 @@ public void simpleIdIn() {
FilterExpression filter = newFilterBuilder(Project.class).where("id").in("uuid777", "uuid001", "uuid002").build();
OrderExpression orderBy = newOrderBuilder(Project.class).orderBy("id").ascending().build();
db.tx(() -> {
- ListResult page = listProjects(ListRequest.builder(Project.class)
+ ListResult page = db.projects().list(ListRequest.builder(Project.class)
.pageSize(100)
.filter(filter)
.orderBy(orderBy)
.build());
- Assertions.assertThat(page).containsExactlyInAnyOrder(p1, p2, p3);
+ assertThat(page).containsExactlyInAnyOrder(p1, p2, p3);
assertThat(page.isLastPage()).isTrue();
});
}
@@ -282,17 +280,17 @@ public void complexIdIn() {
db.tx(() -> db.complexes().insert(c1, c2, c3, c4));
db.tx(() -> {
- ListResult page = listComplex(ListRequest.builder(Complex.class)
+ ListResult page = db.complexes().list(ListRequest.builder(Complex.class)
.pageSize(100)
.filter(fb -> fb
- .where("id.a").in(999_999,999_000)
+ .where("id.a").in(999_999, 999_000)
.and("id.b").in(15L, 13L)
.and("id.c").in("AAA", "CCC")
.and("id.d").in(Complex.Status.OK, Complex.Status.FAIL)
)
.orderBy(ob -> ob.orderBy("id").descending())
.build());
- Assertions.assertThat(page).containsExactly(c1, c3);
+ assertThat(page).containsExactly(c1, c3);
assertThat(page.isLastPage()).isTrue();
});
}
@@ -309,12 +307,12 @@ public void complexUnixTimestampRelational() {
db.tx(() -> db.complexes().insert(c1, c2, c3));
db.tx(() -> {
- ListResult page = listComplex(ListRequest.builder(Complex.class)
+ ListResult page = db.complexes().list(ListRequest.builder(Complex.class)
.pageSize(100)
- .filter(fb -> fb.where("id.a").in(999_999,999_000).and("id.b").gte(now).and("id.b").lt(nowPlus2))
+ .filter(fb -> fb.where("id.a").in(999_999, 999_000).and("id.b").gte(now).and("id.b").lt(nowPlus2))
.orderBy(ob -> ob.orderBy("id.a").descending())
.build());
- Assertions.assertThat(page).containsExactlyInAnyOrder(c1, c2);
+ assertThat(page).containsExactlyInAnyOrder(c1, c2);
assertThat(page.isLastPage()).isTrue();
});
}
@@ -331,12 +329,12 @@ public void complexUnixTimestampIn() {
db.tx(() -> db.complexes().insert(c1, c2, c3));
db.tx(() -> {
- ListResult page = listComplex(ListRequest.builder(Complex.class)
+ ListResult page = db.complexes().list(ListRequest.builder(Complex.class)
.pageSize(100)
- .filter(fb -> fb.where("id.a").in(999_999,999_000).and("id.b").in(now, nowPlus2))
+ .filter(fb -> fb.where("id.a").in(999_999, 999_000).and("id.b").in(now, nowPlus2))
.orderBy(ob -> ob.orderBy("id.a").descending())
.build());
- Assertions.assertThat(page).containsExactly(c1, c3);
+ assertThat(page).containsExactly(c1, c3);
assertThat(page.isLastPage()).isTrue();
});
}
@@ -349,13 +347,13 @@ public void or() {
db.tx(() -> db.projects().insert(p1, p2, notInOutput));
db.tx(() -> {
- ListResult page = listProjects(ListRequest.builder(Project.class)
+ ListResult page = db.projects().list(ListRequest.builder(Project.class)
.pageSize(100)
.filter(newFilterBuilder(Project.class)
.where("id").eq("uuid002").or("id").eq("uuid777")
.build())
.build());
- Assertions.assertThat(page).containsExactly(p1, p2);
+ assertThat(page).containsExactly(p1, p2);
assertThat(page.isLastPage()).isTrue();
});
}
@@ -368,13 +366,13 @@ public void notOr() {
db.tx(() -> db.projects().insert(p1, p2, inOutput));
db.tx(() -> {
- ListResult page = listProjects(ListRequest.builder(Project.class)
+ ListResult page = db.projects().list(ListRequest.builder(Project.class)
.pageSize(100)
.filter(not(newFilterBuilder(Project.class)
.where("id").eq("uuid002").or("id").eq("uuid777")
.build()))
.build());
- Assertions.assertThat(page).containsExactly(inOutput);
+ assertThat(page).containsExactly(inOutput);
assertThat(page.isLastPage()).isTrue();
});
}
@@ -387,13 +385,13 @@ public void notRel() {
db.tx(() -> db.projects().insert(p1, p2, inOutput));
db.tx(() -> {
- ListResult page = listProjects(ListRequest.builder(Project.class)
+ ListResult page = db.projects().list(ListRequest.builder(Project.class)
.pageSize(100)
.filter(not(newFilterBuilder(Project.class)
.where("id").gt("uuid002")
.build()))
.build());
- Assertions.assertThat(page).containsExactly(p1);
+ assertThat(page).containsExactly(p1);
assertThat(page.isLastPage()).isTrue();
});
}
@@ -406,13 +404,13 @@ public void notIn() {
db.tx(() -> db.projects().insert(p1, p2, inOutput));
db.tx(() -> {
- ListResult page = listProjects(ListRequest.builder(Project.class)
+ ListResult page = db.projects().list(ListRequest.builder(Project.class)
.pageSize(100)
.filter(not(newFilterBuilder(Project.class)
.where("id").in("uuid002", "uuid777")
.build()))
.build());
- Assertions.assertThat(page).containsExactly(inOutput);
+ assertThat(page).containsExactly(inOutput);
assertThat(page.isLastPage()).isTrue();
});
}
@@ -462,13 +460,13 @@ public void listByNamesWithUnderscores() {
db.tx(() -> db.typeFreaks().insert(tf));
db.tx(() -> {
- ListResult page = listTypeFreak(ListRequest.builder(TypeFreak.class)
+ ListResult page = db.typeFreaks().list(ListRequest.builder(TypeFreak.class)
.pageSize(50)
.filter(newFilterBuilder(TypeFreak.class)
.where("customNamedColumn").eq("CUSTOM NAMED COLUMN")
.build())
.build());
- Assertions.assertThat(page).containsExactly(tf);
+ assertThat(page).containsExactly(tf);
assertThat(page.isLastPage()).isTrue();
});
}
@@ -479,7 +477,7 @@ public void listStringValuedFilteredByString() {
db.tx(() -> db.typeFreaks().insert(typeFreak));
db.tx(() -> {
- ListResult page = listTypeFreak(ListRequest.builder(TypeFreak.class)
+ ListResult page = db.typeFreaks().list(ListRequest.builder(TypeFreak.class)
.pageSize(100)
.filter(newFilterBuilder(TypeFreak.class)
.where("ticket").eq("CLOUD-100500")
@@ -496,7 +494,7 @@ public void listStringValuedFilteredByString2() {
db.tx(() -> db.typeFreaks().insert(typeFreak));
db.tx(() -> {
- ListResult page = listTypeFreak(ListRequest.builder(TypeFreak.class)
+ ListResult page = db.typeFreaks().list(ListRequest.builder(TypeFreak.class)
.pageSize(100)
.filter(newFilterBuilder(TypeFreak.class)
.where("stringValueWrapper").eq("svw 123")
@@ -514,7 +512,7 @@ public void listStringValuedFilteredByStruct() {
db.tx(() -> db.typeFreaks().insert(typeFreak));
db.tx(() -> {
- ListResult page = listTypeFreak(ListRequest.builder(TypeFreak.class)
+ ListResult page = db.typeFreaks().list(ListRequest.builder(TypeFreak.class)
.pageSize(100)
.filter(newFilterBuilder(TypeFreak.class)
.where("ticket").eq(ticket)
@@ -534,7 +532,7 @@ public void contains() {
db.tx(() -> db.logEntries().insert(e1, e2, notInOutput, e3));
db.tx(() -> {
- ListResult page = listLogEntries(ListRequest.builder(LogEntry.class)
+ ListResult page = db.logEntries().list(ListRequest.builder(LogEntry.class)
.pageSize(100)
.filter(fb -> fb.where("message").contains("msg"))
.build());
@@ -552,7 +550,7 @@ public void notContains() {
db.tx(() -> db.logEntries().insert(e1, e2, inOutput, e3));
db.tx(() -> {
- ListResult page = listLogEntries(ListRequest.builder(LogEntry.class)
+ ListResult page = db.logEntries().list(ListRequest.builder(LogEntry.class)
.pageSize(100)
.filter(fb -> fb.where("message").doesNotContain("msg"))
.build());
@@ -570,7 +568,7 @@ public void containsEscaped() {
db.tx(() -> db.logEntries().insert(e1, e2, notInOutput, e3));
db.tx(() -> {
- ListResult page = listLogEntries(ListRequest.builder(LogEntry.class)
+ ListResult page = db.logEntries().list(ListRequest.builder(LogEntry.class)
.pageSize(100)
.filter(fb -> fb.where("message").contains("%_"))
.build());
@@ -588,7 +586,7 @@ public void startsWith() {
db.tx(() -> db.logEntries().insert(e1, e2, notInOutput, e3));
db.tx(() -> {
- ListResult page = listLogEntries(ListRequest.builder(LogEntry.class)
+ ListResult page = db.logEntries().list(ListRequest.builder(LogEntry.class)
.pageSize(100)
.filter(fb -> fb.where("message").startsWith("#tag"))
.build());
@@ -606,7 +604,7 @@ public void startsWithEscaped() {
db.tx(() -> db.logEntries().insert(e1, e2, notInOutput, e3));
db.tx(() -> {
- ListResult page = listLogEntries(ListRequest.builder(LogEntry.class)
+ ListResult page = db.logEntries().list(ListRequest.builder(LogEntry.class)
.pageSize(100)
.filter(fb -> fb.where("message").startsWith("%_"))
.build());
@@ -624,7 +622,7 @@ public void endsWith() {
db.tx(() -> db.logEntries().insert(e1, e2, inOutput, e3));
db.tx(() -> {
- ListResult page = listLogEntries(ListRequest.builder(LogEntry.class)
+ ListResult page = db.logEntries().list(ListRequest.builder(LogEntry.class)
.pageSize(100)
.filter(fb -> fb.where("message").endsWith(" #tag"))
.build());
@@ -642,7 +640,7 @@ public void endsWithEscaped() {
db.tx(() -> db.logEntries().insert(e1, e2, notInOutput, e3));
db.tx(() -> {
- ListResult page = listLogEntries(ListRequest.builder(LogEntry.class)
+ ListResult page = db.logEntries().list(ListRequest.builder(LogEntry.class)
.pageSize(100)
.filter(fb -> fb.where("message").endsWith("%_"))
.build());
@@ -650,24 +648,4 @@ public void endsWithEscaped() {
assertThat(page.isLastPage()).isTrue();
});
}
-
- protected final ListResult listProjects(ListRequest request) {
- return db.projects().list(request);
- }
-
- protected final ListResult listComplex(ListRequest request) {
- return db.complexes().list(request);
- }
-
- protected final ListResult listTypeFreak(ListRequest request) {
- return db.typeFreaks().list(request);
- }
-
- protected final ListResult listLogEntries(ListRequest request) {
- return db.logEntries().list(request);
- }
-
- protected final ViewListResult listLogMessages(ListRequest request) {
- return db.logEntries().list(LogEntry.Message.class, request);
- }
}
diff --git a/repository-test/src/main/java/tech/ydb/yoj/repository/test/TableQueryBuilderTest.java b/repository-test/src/main/java/tech/ydb/yoj/repository/test/TableQueryBuilderTest.java
index df8d5751..4d14937c 100644
--- a/repository-test/src/main/java/tech/ydb/yoj/repository/test/TableQueryBuilderTest.java
+++ b/repository-test/src/main/java/tech/ydb/yoj/repository/test/TableQueryBuilderTest.java
@@ -1,12 +1,7 @@
package tech.ydb.yoj.repository.test;
-import lombok.NonNull;
-import org.assertj.core.api.Assertions;
import org.junit.Test;
-import tech.ydb.yoj.repository.db.Entity;
import tech.ydb.yoj.repository.db.Repository;
-import tech.ydb.yoj.repository.db.Table;
-import tech.ydb.yoj.repository.db.TableQueryBuilder;
import tech.ydb.yoj.repository.test.entity.TestEntities;
import tech.ydb.yoj.repository.test.sample.TestDb;
import tech.ydb.yoj.repository.test.sample.TestDbImpl;
@@ -48,10 +43,6 @@ protected final Repository createRepository() {
protected abstract Repository createTestRepository();
- protected > TableQueryBuilder createQueryBuilder(@NonNull Class entityClass) {
- return getQueryBuilder(db.table(entityClass));
- }
-
@Test
public void basic() {
Project p1 = new Project(new Project.Id("uuid002"), "AAA");
@@ -61,36 +52,36 @@ public void basic() {
db.tx(() -> db.projects().insert(p1, p2, notInOutput, p3));
db.tx(() -> {
- List page1 = projectQuery()
+ List page1 = db.projects().query()
.limit(1)
.orderBy(ob -> ob.orderBy("name").descending())
.filter(fb -> fb.where("name").in("AAA", "XXX", "ZZZ"))
.find();
- Assertions.assertThat(page1).containsExactly(p3);
+ assertThat(page1).containsExactly(p3);
- List page2 = projectQuery()
+ List page2 = db.projects().query()
.limit(1)
.orderBy(ob -> ob.orderBy("name").descending())
.filter(fb -> fb.where("name").in("AAA", "XXX", "ZZZ"))
.offset(1)
.find();
- Assertions.assertThat(page2).containsExactly(p2);
+ assertThat(page2).containsExactly(p2);
- List page3 = projectQuery()
+ List page3 = db.projects().query()
.limit(1)
.orderBy(ob -> ob.orderBy("name").descending())
.filter(fb -> fb.where("name").in("AAA", "XXX", "ZZZ"))
.offset(2)
.find();
- Assertions.assertThat(page3).containsExactly(p1);
+ assertThat(page3).containsExactly(p1);
- List page4 = projectQuery()
+ List page4 = db.projects().query()
.limit(1)
.orderBy(ob -> ob.orderBy("name").descending())
.filter(fb -> fb.where("name").in("AAA", "XXX", "ZZZ"))
.offset(3)
.find();
- Assertions.assertThat(page4).isEmpty();
+ assertThat(page4).isEmpty();
});
}
@@ -103,11 +94,11 @@ public void complexIdRange() {
db.tx(() -> db.complexes().insert(c1, c2, c3, c4));
db.tx(() -> {
- List page = complexQuery()
+ List page = db.complexes().query()
.limit(3)
.filter(fb -> fb.where("id.a").eq(999_999))
.find();
- Assertions.assertThat(page).containsExactly(c3, c2, c1);
+ assertThat(page).containsExactly(c3, c2, c1);
});
}
@@ -120,11 +111,11 @@ public void complexIdFullScan() {
db.tx(() -> db.complexes().insert(c1, c2, c3, c4));
db.tx(() -> {
- List page = complexQuery()
+ List page = db.complexes().query()
.limit(3)
.filter(fb -> fb.where("id.c").eq("UUU"))
.find();
- Assertions.assertThat(page).containsExactly(c2);
+ assertThat(page).containsExactly(c2);
});
}
@@ -137,10 +128,10 @@ public void defaultOrderingIsByIdAscending() {
db.tx(() -> db.complexes().insert(c1, c2, c3, c4));
db.tx(() -> {
- List page = complexQuery()
+ List page = db.complexes().query()
.limit(4)
.find();
- Assertions.assertThat(page).containsExactly(c4, c3, c2, c1);
+ assertThat(page).containsExactly(c4, c3, c2, c1);
});
}
@@ -154,17 +145,17 @@ public void and() {
db.tx(() -> db.complexes().insert(c1, c2, c3, notInOutput));
db.tx(() -> {
- List page = complexQuery()
+ List page = db.complexes().query()
.limit(4)
.filter(fb -> fb.where("id.a").eq(1).and("id.b").gte(100L).and("id.b").lte(300L))
.find();
- Assertions.assertThat(page).containsExactly(c1, c2, c3);
+ assertThat(page).containsExactly(c1, c2, c3);
});
}
@Test
public void enumParsing() {
- db.tx(() -> getQueryBuilder(db.typeFreaks())
+ db.tx(() -> db.typeFreaks().query()
.where("status").eq(Status.DRAFT)
.orderBy(ob -> ob.orderBy("status").descending())
.limit(1)
@@ -176,7 +167,7 @@ public void flattenedIsNull() {
var tf = new TypeFreak(new TypeFreak.Id("b1p", 1), false, (byte) 0, (byte) 0, (short) 0, 0, 0, 0.0f, 0.0, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null);
db.tx(() -> db.typeFreaks().insert(tf));
- List lst = db.tx(() -> getQueryBuilder(db.typeFreaks())
+ List lst = db.tx(() -> db.typeFreaks().query()
.where("jsonEmbedded").isNull()
.limit(100)
.find());
@@ -188,7 +179,7 @@ public void flattenedIsNotNull() {
var tf = new TypeFreak(new TypeFreak.Id("b1p", 1), false, (byte) 0, (byte) 0, (short) 0, 0, 0, 0.0f, 0.0, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, new TypeFreak.Embedded(new TypeFreak.A("A"), new TypeFreak.B("B")), null, null, null, null, null, null, null, null, null, null, null);
db.tx(() -> db.typeFreaks().insert(tf));
- List lst = db.tx(() -> getQueryBuilder(db.typeFreaks())
+ List lst = db.tx(() -> db.typeFreaks().query()
.where("jsonEmbedded").isNotNull()
.limit(100)
.find());
@@ -199,12 +190,12 @@ public void flattenedIsNotNull() {
public void filterStringValuedByString() {
TypeFreak typeFreak = new TypeFreak(new TypeFreak.Id("b1p", 1), false, (byte) 0, (byte) 0, (short) 0, 0, 0, 0.0f, 0.0, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, new TypeFreak.Ticket("CLOUD", 100500));
db.tx(() -> db.typeFreaks().insert(typeFreak));
- List lst = db.tx(() -> getQueryBuilder(db.typeFreaks())
+ List lst = db.tx(() -> db.typeFreaks().query()
.filter(fb -> fb.where("ticket").eq("CLOUD-100500"))
.limit(1)
.find());
- Assertions.assertThat(lst).containsOnly(typeFreak);
+ assertThat(lst).containsOnly(typeFreak);
}
@Test
@@ -212,14 +203,14 @@ public void filterStringValuedByStruct() {
TypeFreak.Ticket ticket = new TypeFreak.Ticket("CLOUD", 100500);
TypeFreak typeFreak = new TypeFreak(new TypeFreak.Id("b1p", 1), false, (byte) 0, (byte) 0, (short) 0, 0, 0, 0.0f, 0.0, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, ticket);
db.tx(() -> db.typeFreaks().insert(typeFreak));
- List lst = db.tx(() -> getQueryBuilder(db.typeFreaks())
+ List lst = db.tx(() -> db.typeFreaks().query()
.filter(newFilterBuilder(TypeFreak.class)
.where("ticket").eq(ticket)
.build())
.limit(1)
.find());
- Assertions.assertThat(lst).containsOnly(typeFreak);
+ assertThat(lst).containsOnly(typeFreak);
}
@Test
@@ -227,12 +218,12 @@ public void embeddedNulls() {
db.tx(() -> db.typeFreaks().insert(
new TypeFreak(new TypeFreak.Id("b1p", 1), false, (byte) 0, (byte) 0, (short) 0, 0, 0, 0.0f, 0.0, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null)
));
- List lst = db.tx(() -> getQueryBuilder(db.typeFreaks())
+ List lst = db.tx(() -> db.typeFreaks().query()
.filter(fb -> fb.where("embedded.a.a").eq("myfqdn"))
.limit(1)
.find());
- Assertions.assertThat(lst).isEmpty();
+ assertThat(lst).isEmpty();
}
@Test
@@ -244,12 +235,12 @@ public void simpleIdIn() {
db.tx(() -> db.projects().insert(p1, p2, notInOutput, p3));
db.tx(() -> {
- List page = projectQuery()
+ List page = db.projects().query()
.limit(100)
.filter(fb -> fb.where("id").in("uuid777", "uuid001", "uuid002"))
.orderBy(ob -> ob.orderBy("id").ascending())
.find();
- Assertions.assertThat(page).containsExactlyInAnyOrder(p1, p2, p3);
+ assertThat(page).containsExactlyInAnyOrder(p1, p2, p3);
});
}
@@ -262,7 +253,7 @@ public void complexIdIn() {
db.tx(() -> db.complexes().insert(c1, c2, c3, c4));
db.tx(() -> {
- List page = complexQuery()
+ List page = db.complexes().query()
.limit(100)
.filter(fb -> fb
.where("id.a").in(999_999,999_000)
@@ -272,7 +263,7 @@ public void complexIdIn() {
)
.orderBy(ob -> ob.orderBy("id").descending())
.find();
- Assertions.assertThat(page).containsExactly(c1, c3);
+ assertThat(page).containsExactly(c1, c3);
});
}
@@ -288,12 +279,12 @@ public void complexUnixTimestampRelational() {
db.tx(() -> db.complexes().insert(c1, c2, c3));
db.tx(() -> {
- List page = complexQuery()
+ List page = db.complexes().query()
.limit(100)
.filter(fb -> fb.where("id.a").in(999_999,999_000).and("id.b").gte(now).and("id.b").lt(nowPlus2))
.orderBy(ob -> ob.orderBy("id.a").descending())
.find();
- Assertions.assertThat(page).containsExactlyInAnyOrder(c1, c2);
+ assertThat(page).containsExactlyInAnyOrder(c1, c2);
});
}
@@ -309,12 +300,12 @@ public void complexUnixTimestampIn() {
db.tx(() -> db.complexes().insert(c1, c2, c3));
db.tx(() -> {
- List page = complexQuery()
+ List page = db.complexes().query()
.limit(100)
.filter(fb -> fb.where("id.a").in(999_999, 999_000).and("id.b").in(now, nowPlus2))
.orderBy(ob -> ob.orderBy("id.a").descending())
.find();
- Assertions.assertThat(page).containsExactly(c1, c3);
+ assertThat(page).containsExactly(c1, c3);
});
}
@@ -326,12 +317,12 @@ public void or() {
db.tx(() -> db.projects().insert(p1, p2, notInOutput));
db.tx(() -> {
- List page = projectQuery()
+ List page = db.projects().query()
.where("id").eq("uuid002")
.or("id").eq("uuid777")
.limit(100)
.find();
- Assertions.assertThat(page).containsExactly(p1, p2);
+ assertThat(page).containsExactly(p1, p2);
});
}
@@ -343,13 +334,13 @@ public void notOr() {
db.tx(() -> db.projects().insert(p1, p2, inOutput));
db.tx(() -> {
- List page = projectQuery()
+ List page = db.projects().query()
.limit(100)
.filter(not(newFilterBuilder(Project.class)
.where("id").eq("uuid002").or("id").eq("uuid777")
.build()))
.find();
- Assertions.assertThat(page).containsExactly(inOutput);
+ assertThat(page).containsExactly(inOutput);
});
}
@@ -361,13 +352,13 @@ public void notRel() {
db.tx(() -> db.projects().insert(p1, p2, inOutput));
db.tx(() -> {
- List page = projectQuery()
+ List page = db.projects().query()
.limit(100)
.filter(not(newFilterBuilder(Project.class)
.where("id").gt("uuid002")
.build()))
.find();
- Assertions.assertThat(page).containsExactly(p1);
+ assertThat(page).containsExactly(p1);
});
}
@@ -379,13 +370,13 @@ public void notIn() {
db.tx(() -> db.projects().insert(p1, p2, inOutput));
db.tx(() -> {
- List page = projectQuery()
+ List page = db.projects().query()
.limit(100)
.filter(not(newFilterBuilder(Project.class)
.where("id").in("uuid002", "uuid777")
.build()))
.find();
- Assertions.assertThat(page).containsExactly(inOutput);
+ assertThat(page).containsExactly(inOutput);
});
}
@@ -434,11 +425,11 @@ public void listByNamesWithUnderscores() {
db.tx(() -> db.typeFreaks().insert(tf));
db.tx(() -> {
- List page = typeFreakQuery()
+ List page = db.typeFreaks().query()
.limit(50)
.where("customNamedColumn").eq("CUSTOM NAMED COLUMN")
.find();
- Assertions.assertThat(page).containsExactly(tf);
+ assertThat(page).containsExactly(tf);
assertThat(page.size() < 50).isTrue();
});
}
@@ -512,20 +503,4 @@ public void whereAndEquivalenceWithOr2() {
.find()
)).isEmpty();
}
-
- protected > TableQueryBuilder getQueryBuilder(@NonNull Table table) {
- return new TableQueryBuilder<>(table);
- }
-
- protected final TableQueryBuilder projectQuery() {
- return createQueryBuilder(Project.class);
- }
-
- protected final TableQueryBuilder complexQuery() {
- return createQueryBuilder(Complex.class);
- }
-
- protected final TableQueryBuilder typeFreakQuery() {
- return createQueryBuilder(TypeFreak.class);
- }
}
diff --git a/repository-ydb-v2/src/main/java/tech/ydb/yoj/repository/ydb/statement/FindRangeStatement.java b/repository-ydb-v2/src/main/java/tech/ydb/yoj/repository/ydb/statement/FindRangeStatement.java
index d85775c4..c91a5f29 100644
--- a/repository-ydb-v2/src/main/java/tech/ydb/yoj/repository/ydb/statement/FindRangeStatement.java
+++ b/repository-ydb-v2/src/main/java/tech/ydb/yoj/repository/ydb/statement/FindRangeStatement.java
@@ -1,5 +1,6 @@
package tech.ydb.yoj.repository.ydb.statement;
+import com.google.common.base.Preconditions;
import lombok.AllArgsConstructor;
import lombok.Getter;
import tech.ydb.proto.ValueProtos;
@@ -31,6 +32,9 @@ public FindRangeStatement(
Range range
) {
super(tableDescriptor, schema, outSchema);
+ Preconditions.checkArgument(range.getType() == schema.getIdSchema(),
+ "ID schema mismatch: Range was constructed with a different ID schema than the YdbTable");
+
this.params = Stream.of(RangeBound.values())
.flatMap(b -> toParams(b.map(range).keySet(), b))
.collect(toList());
diff --git a/repository-ydb-v2/src/main/java/tech/ydb/yoj/repository/ydb/table/BatchFindSpliterator.java b/repository-ydb-v2/src/main/java/tech/ydb/yoj/repository/ydb/table/BatchFindSpliterator.java
index 1e2e8287..f4896a72 100644
--- a/repository-ydb-v2/src/main/java/tech/ydb/yoj/repository/ydb/table/BatchFindSpliterator.java
+++ b/repository-ydb-v2/src/main/java/tech/ydb/yoj/repository/ydb/table/BatchFindSpliterator.java
@@ -3,7 +3,6 @@
import tech.ydb.yoj.databind.schema.Schema;
import tech.ydb.yoj.repository.db.Entity;
import tech.ydb.yoj.repository.db.EntityIdSchema;
-import tech.ydb.yoj.repository.db.Range;
import tech.ydb.yoj.repository.ydb.yql.YqlLimit;
import tech.ydb.yoj.repository.ydb.yql.YqlOrderBy;
import tech.ydb.yoj.repository.ydb.yql.YqlPredicate;
@@ -32,13 +31,9 @@ abstract class BatchFindSpliterator, ID extends Entity.Id
protected abstract List find(YqlStatementPart> part, YqlStatementPart>... otherParts);
- BatchFindSpliterator(Class entityType, int batchSize) {
- this(entityType, null, batchSize);
- }
-
- BatchFindSpliterator(Class entityType, ID partial, int batchSize) {
+ BatchFindSpliterator(EntityIdSchema idSchema, ID partial, int batchSize) {
this.batchSize = batchSize;
- this.idSchema = EntityIdSchema.ofEntity(entityType);
+ this.idSchema = idSchema;
this.orderById = YqlOrderBy.orderBy(this.idSchema
.flattenFields().stream()
.map(s -> new YqlOrderBy.SortKey(s.getPath(), YqlOrderBy.SortOrder.ASC))
@@ -46,8 +41,8 @@ abstract class BatchFindSpliterator, ID extends Entity.Id
);
this.top = YqlLimit.top(batchSize);
if (partial != null) {
- Range range = Range.create(partial);
- Map eqMap = range.getEqMap();
+ // NB: Schema.flatten() does *not* write null-valued columns to the map
+ Map eqMap = idSchema.flatten(partial);
this.initialPartialPredicates = this.idSchema
.flattenFields().stream()
.filter(f -> eqMap.containsKey(f.getName()))
@@ -85,8 +80,8 @@ public boolean tryAdvance(Consumer super R> action) {
private List next() {
if (lastPartialId.size() != 0 && lastPartialId.size() <= initialPartialPredicates.size()) {
- // we need this if because YDB has bug for queries like
- // SELECT * FROM table WHERE id = 'id' and id > 'id'
+ // We need this because certain versions of YDB have a bug for queries like
+ // SELECT * FROM table WHERE id = 'id' AND id > 'id'
return List.of();
}
diff --git a/repository-ydb-v2/src/main/java/tech/ydb/yoj/repository/ydb/table/YdbTable.java b/repository-ydb-v2/src/main/java/tech/ydb/yoj/repository/ydb/table/YdbTable.java
index e99fe392..328ce6a2 100644
--- a/repository-ydb-v2/src/main/java/tech/ydb/yoj/repository/ydb/table/YdbTable.java
+++ b/repository-ydb-v2/src/main/java/tech/ydb/yoj/repository/ydb/table/YdbTable.java
@@ -4,6 +4,7 @@
import com.google.common.collect.Sets;
import com.google.common.reflect.TypeToken;
import lombok.NonNull;
+import tech.ydb.yoj.DeprecationWarnings;
import tech.ydb.yoj.InternalApi;
import tech.ydb.yoj.databind.expression.FilterExpression;
import tech.ydb.yoj.databind.expression.OrderExpression;
@@ -14,6 +15,7 @@
import tech.ydb.yoj.repository.db.Range;
import tech.ydb.yoj.repository.db.Table;
import tech.ydb.yoj.repository.db.TableDescriptor;
+import tech.ydb.yoj.repository.db.TableQueryBuilder;
import tech.ydb.yoj.repository.db.TableQueryImpl;
import tech.ydb.yoj.repository.db.Tx;
import tech.ydb.yoj.repository.db.ViewSchema;
@@ -78,7 +80,16 @@ public YdbTable(Class type, QueryExecutor executor) {
this.tableDescriptor = TableDescriptor.from(schema);
}
+ /**
+ * @deprecated This {@code YdbTable} constructor uses reflection tricks to determine entity type,
+ * and will be removed in YOJ 2.7.0.
+ * Please migrate to {@link YdbTable#YdbTable(Class, QueryExecutor)} or
+ * {@link YdbTable#YdbTable(TableDescriptor, QueryExecutor)}.
+ */
+ @Deprecated(forRemoval = true)
protected YdbTable(QueryExecutor executor) {
+ DeprecationWarnings.warnOnce("new YdbTable(QueryExecutor)",
+ "Single-arg new YdbTable(QueryExecutor) will be removed in YOJ 2.7.0. Please use the two-arg constructors instead");
this.type = resolveEntityType();
this.executor = new CheckingQueryExecutor(executor);
this.schema = EntitySchema.of(type);
@@ -122,6 +133,11 @@ private static List toList(E first, E... rest) {
return concat(Stream.of(first), stream(rest)).collect(Collectors.toList());
}
+ @Override
+ public TableQueryBuilder query() {
+ return new TableQueryBuilder<>(this, schema);
+ }
+
@Override
public List findAll() {
var statement = new FindAllYqlStatement<>(tableDescriptor, schema, schema);
@@ -179,7 +195,8 @@ private Stream streamPartial(
BiFunction, YqlStatementPart>[], List> findMethod
) {
Preconditions.checkArgument(1 <= batchSize && batchSize <= 5000, "batchSize must be in range [1, 5000], got %s", batchSize);
- return StreamSupport.stream(new BatchFindSpliterator<>(type, partial, batchSize) {
+ EntityIdSchema> idSchema = schema.getIdSchema();
+ return StreamSupport.stream(new BatchFindSpliterator<>(idSchema, partial, batchSize) {
@Override
protected Entity.Id getId(R r) {
return idMapper.apply(r);
@@ -200,7 +217,8 @@ public > Stream streamAllIds(int batchSize) {
@Override
public > Stream streamPartialIds(ID partial, int batchSize) {
Preconditions.checkArgument(1 <= batchSize && batchSize <= 10000, "batchSize must be in range [1, 10000], got %s", batchSize);
- return StreamSupport.stream(new BatchFindSpliterator<>(type, partial, batchSize) {
+ EntityIdSchema