Skip to content

Commit

Permalink
Query multiple tables using one entity
Browse files Browse the repository at this point in the history
  • Loading branch information
Sergei Galiamichev committed Dec 27, 2024
1 parent 286b5b9 commit 127e982
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 7 deletions.
3 changes: 2 additions & 1 deletion databind/src/main/java/tech/ydb/yoj/ExperimentalApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.CONSTRUCTOR;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
Expand All @@ -14,7 +15,7 @@
* Annotates <em>experimental features</em>. These features are not part of the stable YOJ API: they can change incompatibly,
* or even disappear entirely <em>in any release</em>.
*/
@Target({TYPE, FIELD, METHOD, PARAMETER, ANNOTATION_TYPE})
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, ANNOTATION_TYPE})
@Retention(SOURCE)
public @interface ExperimentalApi {
/**
Expand Down
1 change: 1 addition & 0 deletions repository-ydb-v2/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ java_test_suite(
"@java_contribs_stable//:tech_ydb_test_ydb_tests_common",
"@java_contribs_stable//:tech_ydb_ydb_auth_api",
"@java_contribs_stable//:tech_ydb_ydb_proto_api",
"@java_contribs_stable//:tech_ydb_ydb_sdk_common",
"@java_contribs_stable//:tech_ydb_ydb_sdk_core",
"@java_contribs_stable//:tech_ydb_ydb_sdk_scheme",
"@java_contribs_stable//:tech_ydb_ydb_sdk_table",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,16 @@ public <T extends Entity<T>> Table<T> table(Class<T> c) {
return new YdbTable<>(c, this);
}

/**
* WARNING!!! This method won't work if id's in different tables have intersections. The restriction will be eliminated in future
* versions
*/
@Override
@ExperimentalApi(issue = "https://github.com/ydb-platform/yoj-project/issues/32")
public <T extends Entity<T>> Table<T> table(@NonNull TableDescriptor<T> descriptor) {
return new YdbTable<>(descriptor, this);
}

@Override
public <T extends Entity<T>> Table<T> table(TableDescriptor<T> tableDescriptor) {
return new YdbTable<>(tableDescriptor, this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import tech.ydb.yoj.databind.DbType;
import tech.ydb.yoj.repository.db.Entity;
import tech.ydb.yoj.repository.db.EntitySchema;
import tech.ydb.yoj.repository.db.TableDescriptor;
import tech.ydb.yoj.repository.ydb.YdbConfig;
import tech.ydb.yoj.repository.ydb.YdbRepository;
import tech.ydb.yoj.repository.ydb.client.YdbPaths;
Expand All @@ -42,7 +43,7 @@
public final class YdbSchemaCompatibilityChecker {
private static final Logger log = LoggerFactory.getLogger(YdbSchemaCompatibilityChecker.class);

private final List<Class<? extends Entity>> entities;
private final List<TableDescriptor<? extends Entity>> descriptors;
private final Config config;
private final YdbRepository repository;
private final YdbConfig repositoryConfig;
Expand All @@ -51,12 +52,20 @@ public final class YdbSchemaCompatibilityChecker {
private final List<String> canExecuteMessages = new ArrayList<>();
private final List<String> incompatibleMessages = new ArrayList<>();

public YdbSchemaCompatibilityChecker(YdbRepository repository, List<TableDescriptor<? extends Entity>> descriptors) {
this(repository, descriptors, Config.DEFAULT);
}

public YdbSchemaCompatibilityChecker(List<Class<? extends Entity>> entities, YdbRepository repository) {
this(entities, repository, Config.DEFAULT);
}

public YdbSchemaCompatibilityChecker(List<Class<? extends Entity>> entities, YdbRepository repository, Config config) {
this.entities = entities;
this(repository, toDescriptors(entities), config);
}

public YdbSchemaCompatibilityChecker(YdbRepository repository, List<TableDescriptor<? extends Entity>> descriptors, Config config) {
this.descriptors = descriptors;
this.config = config;
this.repository = repository;
this.repositoryConfig = this.repository.getConfig();
Expand Down Expand Up @@ -147,16 +156,16 @@ private String getEndpoint() {

@SneakyThrows
private Map<String, YdbSchemaOperations.Table> generateSchemeFromCode() {
return entities.stream()
return descriptors.stream()
.map(this::tableForEntity)
.collect(toMap(YdbSchemaOperations.Table::getName, Function.identity()));
}

@SuppressWarnings("unchecked")
private YdbSchemaOperations.Table tableForEntity(Class<? extends Entity> c) {
EntitySchema<?> schema = EntitySchema.of(c);
private YdbSchemaOperations.Table tableForEntity(TableDescriptor<? extends Entity<?>> c) {
EntitySchema<?> schema = EntitySchema.of(c.entityType());
return repository.getSchemaOperations()
.describeTable(schema.getName(), schema.flattenFields(), schema.flattenId(),
.describeTable(c.tableName(), schema.flattenFields(), schema.flattenId(),
schema.getGlobalIndexes(), schema.getTtlModifier());
}

Expand Down Expand Up @@ -466,6 +475,12 @@ private boolean containsPrefix(String globalName, Set<String> prefixes) {
.anyMatch(realName::startsWith);
}

private static List<TableDescriptor<? extends Entity>> toDescriptors(List<Class<? extends Entity>> entities) {
List<TableDescriptor<? extends Entity>> descriptors = new ArrayList<>();
entities.forEach(e -> descriptors.add(TableDescriptor.from(EntitySchema.of(e))));
return descriptors;
}

@Value
@Builder
@With
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import com.google.common.reflect.TypeToken;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NonNull;
import tech.ydb.yoj.ExperimentalApi;
import tech.ydb.yoj.databind.expression.FilterExpression;
import tech.ydb.yoj.databind.expression.OrderExpression;
import tech.ydb.yoj.repository.BaseDb;
Expand All @@ -26,6 +28,12 @@ protected AbstractDelegatingTable() {
this.target = BaseDb.current(BaseDb.class).table(resolveEntityType());
}

@ExperimentalApi(issue = "https://github.com/ydb-platform/yoj-project/issues/32")
protected AbstractDelegatingTable(@NonNull String tableName) {
EntitySchema<T> schema = EntitySchema.of(resolveEntityType());
this.target = BaseDb.current(BaseDb.class).table(new TableDescriptor<T>(schema.getType(), tableName));
}

@SuppressWarnings("unchecked")
private Class<T> resolveEntityType() {
return (Class<T>) (new TypeToken<T>(getClass()) {
Expand Down

0 comments on commit 127e982

Please sign in to comment.