Skip to content

Commit 6c250a0

Browse files
committed
noticket: Use EntitySchema to centrally retrieve ID and view schemas related to the entity
...instead of directly calling `EntityIdSchema` and `ViewSchema` static factories
1 parent 21dff7c commit 6c250a0

File tree

14 files changed

+159
-80
lines changed

14 files changed

+159
-80
lines changed

repository-inmemory/src/main/java/tech/ydb/yoj/repository/test/inmemory/InMemoryDataShard.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import tech.ydb.yoj.repository.db.Range;
88
import tech.ydb.yoj.repository.db.Table;
99
import tech.ydb.yoj.repository.db.TableDescriptor;
10-
import tech.ydb.yoj.repository.db.ViewSchema;
1110
import tech.ydb.yoj.repository.db.exception.EntityAlreadyExistsException;
1211
import tech.ydb.yoj.repository.db.exception.OptimisticLockException;
1312

@@ -39,25 +38,26 @@ private InMemoryDataShard(
3938
this.entityLines = entityLines;
4039
}
4140

42-
public InMemoryDataShard(TableDescriptor<T> tableDescriptor) {
41+
public InMemoryDataShard(TableDescriptor<T> tableDescriptor, EntitySchema<T> schema) {
4342
this(
4443
tableDescriptor,
45-
EntitySchema.of(tableDescriptor.entityType()),
46-
createEmptyLines(tableDescriptor.entityType())
44+
schema,
45+
createEmptyLines(schema)
4746
);
4847
}
4948

50-
private static <T extends Entity<T>> Map<Entity.Id<T>, InMemoryEntityLine> createEmptyLines(Class<T> type) {
49+
private static <T extends Entity<T>> Map<Entity.Id<T>, InMemoryEntityLine> createEmptyLines(EntitySchema<T> schema) {
50+
EntityIdSchema<Entity.Id<T>> idSchema = schema.getIdSchema();
5151
if ("oninsert".equals(MAP_IMPLEMENTATION)) {
52-
return new EntityIdMap<>(EntityIdSchema.getIdComparator(type));
52+
return new EntityIdMap<>(idSchema);
5353
} else if ("onget".equals(MAP_IMPLEMENTATION)) {
54-
return new EntityIdMapOnGet<>(EntityIdSchema.getIdComparator(type));
54+
return new EntityIdMapOnGet<>(idSchema);
5555
}
56-
return new TreeMap<>(EntityIdSchema.getIdComparator(type));
56+
return new TreeMap<>(idSchema);
5757
}
5858

5959
public synchronized InMemoryDataShard<T> createSnapshot() {
60-
Map<Entity.Id<T>, InMemoryEntityLine> snapshotLines = createEmptyLines(tableDescriptor.entityType());
60+
Map<Entity.Id<T>, InMemoryEntityLine> snapshotLines = createEmptyLines(schema);
6161
for (Map.Entry<Entity.Id<T>, InMemoryEntityLine> entry : entityLines.entrySet()) {
6262
snapshotLines.put(entry.getKey(), entry.getValue().createSnapshot());
6363
}
@@ -133,7 +133,7 @@ public synchronized <V extends Table.View> V find(
133133
return null;
134134
}
135135
Columns columns = entityLine.get(txId, version);
136-
return columns != null ? columns.toSchema(ViewSchema.of(viewType)) : null;
136+
return columns != null ? columns.toSchema(schema.getViewSchema(viewType)) : null;
137137
}
138138

139139
public synchronized List<T> findAll(long txId, long version, InMemoryTxLockWatcher watcher) {

repository-inmemory/src/main/java/tech/ydb/yoj/repository/test/inmemory/InMemoryStorage.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package tech.ydb.yoj.repository.test.inmemory;
22

33
import tech.ydb.yoj.repository.db.Entity;
4+
import tech.ydb.yoj.repository.db.EntitySchema;
45
import tech.ydb.yoj.repository.db.TableDescriptor;
56

67
import java.util.HashMap;
@@ -108,7 +109,10 @@ public synchronized <T extends Entity<T>> void createTable(TableDescriptor<T> ta
108109
if (containsTable(tableDescriptor)) {
109110
return;
110111
}
111-
shards.put(tableDescriptor, new InMemoryDataShard<>(tableDescriptor));
112+
113+
// TODO(nvamelichev): In the future, InMemoryStorage/SchemaOperations should take SchemaRegistry instead of assuming the default one...
114+
EntitySchema<T> schema = EntitySchema.of(tableDescriptor.entityType());
115+
shards.put(tableDescriptor, new InMemoryDataShard<>(tableDescriptor, schema));
112116
}
113117

114118
public synchronized boolean dropTable(TableDescriptor<?> tableDescriptor) {

repository-inmemory/src/main/java/tech/ydb/yoj/repository/test/inmemory/InMemoryTable.java

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,9 @@ public InMemoryTable(DbMemory<T> memory) {
5151
}
5252

5353
public InMemoryTable(InMemoryRepositoryTransaction transaction, Class<T> type) {
54-
this(transaction, TableDescriptor.from(EntitySchema.of(type)));
54+
this.schema = EntitySchema.of(type);
55+
this.tableDescriptor = TableDescriptor.from(schema);
56+
this.transaction = transaction;
5557
}
5658

5759
public InMemoryTable(InMemoryRepositoryTransaction transaction, TableDescriptor<T> tableDescriptor) {
@@ -413,7 +415,7 @@ private <ID extends Entity.Id<T>> void markKeyRead(ID id) {
413415
EntityIdSchema<Entity.Id<T>> idSchema = schema.getIdSchema();
414416
if (idSchema.flattenFieldNames().size() != idSchema.flatten(id).size()) {
415417
// Partial key, will throw error when not searching by PK prefix
416-
transaction.getWatcher().markRangeRead(tableDescriptor, Range.create(id, id));
418+
transaction.getWatcher().markRangeRead(tableDescriptor, Range.create(idSchema, id));
417419
} else {
418420
transaction.getWatcher().markRowRead(tableDescriptor, id);
419421
}
@@ -482,7 +484,8 @@ public <ID extends Entity.Id<T>> Stream<T> streamPartial(ID partial, int batchSi
482484
Preconditions.checkArgument(1 <= batchSize && batchSize <= 5000,
483485
"batchSize must be in range [1, 5000], got %s", batchSize);
484486

485-
Range<ID> range = partial == null ? null : Range.create(partial);
487+
EntityIdSchema<ID> idSchema = schema.getIdSchema();
488+
Range<ID> range = partial == null ? null : Range.create(idSchema, partial);
486489
markRangeRead(range);
487490

488491
return streamPartial0(range);
@@ -515,7 +518,8 @@ public <ID extends Entity.Id<T>> Stream<ID> streamPartialIds(ID partial, int bat
515518
Preconditions.checkArgument(1 <= batchSize && batchSize <= 10000,
516519
"batchSize must be in range [1, 10000], got %s", batchSize);
517520

518-
Range<ID> range = partial == null ? null : Range.create(partial);
521+
EntityIdSchema<ID> idSchema = schema.getIdSchema();
522+
Range<ID> range = partial == null ? null : Range.create(idSchema, partial);
519523
markRangeRead(range);
520524

521525
return streamPartial0(range).map(e -> (ID) e.getId());
@@ -552,15 +556,16 @@ private <ID extends Entity.Id<T>> boolean readTableFilter(T e, ReadTableParams<I
552556
@SuppressWarnings("unchecked")
553557
ID id = (ID) e.getId();
554558
ID from = params.getFromKey();
559+
EntityIdSchema<ID> idSchema = schema.getIdSchema();
555560
if (from != null) {
556-
int compare = EntityIdSchema.ofEntity(id.getType()).compare(id, from);
561+
int compare = idSchema.compare(id, from);
557562
if (params.isFromInclusive() ? compare < 0 : compare <= 0) {
558563
return false;
559564
}
560565
}
561566
ID to = params.getToKey();
562567
if (to != null) {
563-
int compare = EntityIdSchema.ofEntity(id.getType()).compare(id, to);
568+
int compare = idSchema.compare(id, to);
564569
return params.isToInclusive() ? compare <= 0 : compare < 0;
565570
}
566571
return true;
@@ -589,7 +594,7 @@ private static <V extends Table.View, T extends Entity<T>> V toView(
589594
return null;
590595
}
591596

592-
ViewSchema<V> viewSchema = ViewSchema.of(viewType);
597+
ViewSchema<V> viewSchema = schema.getViewSchema(viewType);
593598
return Columns.fromEntity(schema, entity).toSchema(viewSchema);
594599
}
595600

repository-test/src/main/java/tech/ydb/yoj/repository/test/ListingTest.java

Lines changed: 40 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package tech.ydb.yoj.repository.test;
22

3-
import org.assertj.core.api.Assertions;
43
import org.junit.Test;
54
import tech.ydb.yoj.databind.expression.FilterExpression;
65
import tech.ydb.yoj.databind.expression.OrderExpression;
@@ -72,23 +71,23 @@ public void basic() {
7271
.orderBy(orderBy)
7372
.filter(filter)
7473
.build());
75-
Assertions.assertThat(page1).containsExactly(p3);
74+
assertThat(page1).containsExactly(p3);
7675

7776
ListResult<Project> page2 = listProjects(ListRequest.builder(Project.class)
7877
.pageSize(1)
7978
.orderBy(orderBy)
8079
.filter(filter)
8180
.offset(1)
8281
.build());
83-
Assertions.assertThat(page2).containsExactly(p2);
82+
assertThat(page2).containsExactly(p2);
8483

8584
ListResult<Project> page3 = listProjects(ListRequest.builder(Project.class)
8685
.pageSize(1)
8786
.orderBy(orderBy)
8887
.filter(filter)
8988
.offset(2)
9089
.build());
91-
Assertions.assertThat(page3).containsExactly(p1);
90+
assertThat(page3).containsExactly(p1);
9291
assertThat(page3.isLastPage()).isTrue();
9392
});
9493
}
@@ -106,7 +105,7 @@ public void complexIdRange() {
106105
.pageSize(3)
107106
.filter(fb -> fb.where("id.a").eq(999_999))
108107
.build());
109-
Assertions.assertThat(page).containsExactly(c3, c2, c1);
108+
assertThat(page).containsExactly(c3, c2, c1);
110109
assertThat(page.isLastPage()).isTrue();
111110
});
112111
}
@@ -124,7 +123,7 @@ public void complexIdFullScan() {
124123
.pageSize(3)
125124
.filter(fb -> fb.where("id.c").eq("UUU"))
126125
.build());
127-
Assertions.assertThat(page).containsExactly(c2);
126+
assertThat(page).containsExactly(c2);
128127
assertThat(page.isLastPage()).isTrue();
129128
});
130129
}
@@ -203,7 +202,7 @@ public void defaultOrderingIsByIdAscending() {
203202
ListResult<Complex> page = listComplex(ListRequest.builder(Complex.class)
204203
.pageSize(4)
205204
.build());
206-
Assertions.assertThat(page).containsExactly(c4, c3, c2, c1);
205+
assertThat(page).containsExactly(c4, c3, c2, c1);
207206
assertThat(page.isLastPage()).isTrue();
208207
});
209208
}
@@ -222,7 +221,7 @@ public void and() {
222221
.pageSize(3)
223222
.filter(fb -> fb.where("id.a").eq(1).and("id.b").gte(100L).and("id.b").lte(300L))
224223
.build());
225-
Assertions.assertThat(page).containsExactly(c1, c2, c3);
224+
assertThat(page).containsExactly(c1, c2, c3);
226225
assertThat(page.isLastPage()).isTrue();
227226
});
228227
}
@@ -254,7 +253,7 @@ public void embeddedNulls() {
254253
.pageSize(1)
255254
.build()));
256255

257-
Assertions.assertThat(lst).isEmpty();
256+
assertThat(lst).isEmpty();
258257
assertThat(lst.isLastPage()).isTrue();
259258
}
260259

@@ -302,7 +301,7 @@ public void simpleIdIn() {
302301
.filter(filter)
303302
.orderBy(orderBy)
304303
.build());
305-
Assertions.assertThat(page).containsExactlyInAnyOrder(p1, p2, p3);
304+
assertThat(page).containsExactlyInAnyOrder(p1, p2, p3);
306305
assertThat(page.isLastPage()).isTrue();
307306
});
308307
}
@@ -326,7 +325,7 @@ public void complexIdIn() {
326325
)
327326
.orderBy(ob -> ob.orderBy("id").descending())
328327
.build());
329-
Assertions.assertThat(page).containsExactly(c1, c3);
328+
assertThat(page).containsExactly(c1, c3);
330329
assertThat(page.isLastPage()).isTrue();
331330
});
332331
}
@@ -348,7 +347,7 @@ public void complexUnixTimestampRelational() {
348347
.filter(fb -> fb.where("id.a").in(999_999, 999_000).and("id.b").gte(now).and("id.b").lt(nowPlus2))
349348
.orderBy(ob -> ob.orderBy("id.a").descending())
350349
.build());
351-
Assertions.assertThat(page).containsExactlyInAnyOrder(c1, c2);
350+
assertThat(page).containsExactlyInAnyOrder(c1, c2);
352351
assertThat(page.isLastPage()).isTrue();
353352
});
354353
}
@@ -370,7 +369,7 @@ public void complexUnixTimestampIn() {
370369
.filter(fb -> fb.where("id.a").in(999_999, 999_000).and("id.b").in(now, nowPlus2))
371370
.orderBy(ob -> ob.orderBy("id.a").descending())
372371
.build());
373-
Assertions.assertThat(page).containsExactly(c1, c3);
372+
assertThat(page).containsExactly(c1, c3);
374373
assertThat(page.isLastPage()).isTrue();
375374
});
376375
}
@@ -389,7 +388,7 @@ public void or() {
389388
.where("id").eq("uuid002").or("id").eq("uuid777")
390389
.build())
391390
.build());
392-
Assertions.assertThat(page).containsExactly(p1, p2);
391+
assertThat(page).containsExactly(p1, p2);
393392
assertThat(page.isLastPage()).isTrue();
394393
});
395394
}
@@ -408,7 +407,7 @@ public void notOr() {
408407
.where("id").eq("uuid002").or("id").eq("uuid777")
409408
.build()))
410409
.build());
411-
Assertions.assertThat(page).containsExactly(inOutput);
410+
assertThat(page).containsExactly(inOutput);
412411
assertThat(page.isLastPage()).isTrue();
413412
});
414413
}
@@ -427,7 +426,7 @@ public void notRel() {
427426
.where("id").gt("uuid002")
428427
.build()))
429428
.build());
430-
Assertions.assertThat(page).containsExactly(p1);
429+
assertThat(page).containsExactly(p1);
431430
assertThat(page.isLastPage()).isTrue();
432431
});
433432
}
@@ -446,7 +445,7 @@ public void notIn() {
446445
.where("id").in("uuid002", "uuid777")
447446
.build()))
448447
.build());
449-
Assertions.assertThat(page).containsExactly(inOutput);
448+
assertThat(page).containsExactly(inOutput);
450449
assertThat(page.isLastPage()).isTrue();
451450
});
452451
}
@@ -502,7 +501,7 @@ public void listByNamesWithUnderscores() {
502501
.where("customNamedColumn").eq("CUSTOM NAMED COLUMN")
503502
.build())
504503
.build());
505-
Assertions.assertThat(page).containsExactly(tf);
504+
assertThat(page).containsExactly(tf);
506505
assertThat(page.isLastPage()).isTrue();
507506
});
508507
}
@@ -703,6 +702,29 @@ public void endsWithEscaped() {
703702
});
704703
}
705704

705+
706+
@Test
707+
public void view() {
708+
LogEntry e1 = new LogEntry(new LogEntry.Id("log1", 1L), LogEntry.Level.ERROR, "earliest msg");
709+
LogEntry notInOutput = new LogEntry(new LogEntry.Id("log2", 2L), LogEntry.Level.DEBUG, "will be ignored");
710+
LogEntry e2 = new LogEntry(new LogEntry.Id("log1", 4L), LogEntry.Level.WARN, "middle msg");
711+
LogEntry e3 = new LogEntry(new LogEntry.Id("log1", 5L), LogEntry.Level.INFO, "latest msg");
712+
db.tx(() -> db.logEntries().insert(e1, e2, notInOutput, e3));
713+
714+
db.tx(() -> {
715+
ViewListResult<LogEntry, LogEntry.Message> page = listLogMessages(ListRequest.builder(LogEntry.class)
716+
.pageSize(100)
717+
.filter(fb -> fb.where("id.logId").eq("log1"))
718+
.build());
719+
assertThat(page).containsExactly(
720+
new LogEntry.Message(new LogEntry.Id("log1", 1L), "earliest msg"),
721+
new LogEntry.Message(new LogEntry.Id("log1", 4L), "middle msg"),
722+
new LogEntry.Message(new LogEntry.Id("log1", 5L), "latest msg")
723+
);
724+
assertThat(page.isLastPage()).isTrue();
725+
});
726+
}
727+
706728
protected final ListResult<Project> listProjects(ListRequest<Project> request) {
707729
return db.projects().list(request);
708730
}

repository-ydb-v2/src/main/java/tech/ydb/yoj/repository/ydb/table/BatchFindSpliterator.java

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,21 +32,17 @@ abstract class BatchFindSpliterator<R, T extends Entity<T>, ID extends Entity.Id
3232

3333
protected abstract List<R> find(YqlStatementPart<?> part, YqlStatementPart<?>... otherParts);
3434

35-
BatchFindSpliterator(Class<T> entityType, int batchSize) {
36-
this(entityType, null, batchSize);
37-
}
38-
39-
BatchFindSpliterator(Class<T> entityType, ID partial, int batchSize) {
35+
BatchFindSpliterator(EntityIdSchema<ID> idSchema, ID partial, int batchSize) {
4036
this.batchSize = batchSize;
41-
this.idSchema = EntityIdSchema.ofEntity(entityType);
37+
this.idSchema = idSchema;
4238
this.orderById = YqlOrderBy.orderBy(this.idSchema
4339
.flattenFields().stream()
4440
.map(s -> new YqlOrderBy.SortKey(s.getPath(), YqlOrderBy.SortOrder.ASC))
4541
.collect(toList())
4642
);
4743
this.top = YqlLimit.top(batchSize);
4844
if (partial != null) {
49-
Range<ID> range = Range.create(partial);
45+
Range<ID> range = Range.create(this.idSchema, partial);
5046
Map<String, Object> eqMap = range.getEqMap();
5147
this.initialPartialPredicates = this.idSchema
5248
.flattenFields().stream()
@@ -84,9 +80,9 @@ public boolean tryAdvance(Consumer<? super R> action) {
8480
}
8581

8682
private List<R> next() {
87-
if (lastPartialId.size() != 0 && lastPartialId.size() <= initialPartialPredicates.size()) {
88-
// we need this if because YDB has bug for queries like
89-
// SELECT * FROM table WHERE id = 'id' and id > 'id'
83+
if (!lastPartialId.isEmpty() && lastPartialId.size() <= initialPartialPredicates.size()) {
84+
// We need this short-circuiting because certain versions of YDB had a bug for queries like
85+
// SELECT * FROM table WHERE id = 'id' AND id > 'id'
9086
return List.of();
9187
}
9288

0 commit comments

Comments
 (0)