Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/dev' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
lukashornych committed Dec 6, 2023
2 parents 015f3e6 + d35708e commit b6a36c3
Show file tree
Hide file tree
Showing 36 changed files with 343 additions and 204 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ protected Class<GlobalAttributeSchemaContract> getAttributeSchemaType() {
@Override
@Nonnull
public GlobalAttributeSchemaBuilder uniqueGlobally() {
this.mutations.add(
this.updatedSchemaDirty = addMutations(
new SetAttributeSchemaGloballyUniqueMutation(
toInstance().getName(),
GlobalAttributeUniquenessType.UNIQUE_WITHIN_CATALOG
Expand All @@ -111,7 +111,7 @@ public GlobalAttributeSchemaBuilder uniqueGlobally() {
@Override
@Nonnull
public GlobalAttributeSchemaBuilder uniqueGloballyWithinLocale() {
this.mutations.add(
this.updatedSchemaDirty = addMutations(
new SetAttributeSchemaGloballyUniqueMutation(
toInstance().getName(),
GlobalAttributeUniquenessType.UNIQUE_WITHIN_CATALOG_LOCALE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import io.evitadb.api.requestResponse.schema.SealedCatalogSchema;
import io.evitadb.api.requestResponse.schema.dto.EntitySchema;
import io.evitadb.api.requestResponse.schema.dto.EntitySchemaProvider;
import io.evitadb.api.requestResponse.schema.mutation.CatalogSchemaMutation.CatalogSchemaWithImpactOnEntitySchemas;
import io.evitadb.api.requestResponse.schema.mutation.LocalCatalogSchemaMutation;
import io.evitadb.api.requestResponse.schema.mutation.attribute.RemoveAttributeSchemaMutation;
import io.evitadb.api.requestResponse.schema.mutation.catalog.AllowEvolutionModeInCatalogSchemaMutation;
Expand Down Expand Up @@ -331,10 +332,11 @@ public CatalogSchemaContract toInstance() {
// apply the mutations not reflected in the schema
for (int i = lastMutationReflectedInSchema + 1; i < this.mutations.size(); i++) {
final LocalCatalogSchemaMutation mutation = this.mutations.get(i);
currentSchema = mutation.mutate(currentSchema, updatedEntitySchemaAccessor);
if (currentSchema == null) {
final CatalogSchemaWithImpactOnEntitySchemas mutationImpact = mutation.mutate(currentSchema, updatedEntitySchemaAccessor);
if (mutationImpact == null || mutationImpact.updatedCatalogSchema() == null) {
throw new EvitaInternalError("Catalog schema unexpectedly removed from inside!");
}
currentSchema = mutationImpact.updatedCatalogSchema();
}
this.updatedSchema = currentSchema;
this.updatedSchemaDirty = MutationImpact.NO_IMPACT;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@
package io.evitadb.api.requestResponse.schema.mutation;

import io.evitadb.api.requestResponse.schema.CatalogSchemaContract;
import io.evitadb.api.requestResponse.schema.mutation.catalog.ModifyEntitySchemaMutation;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
import javax.annotation.concurrent.ThreadSafe;
Expand All @@ -46,6 +48,23 @@ public interface CatalogSchemaMutation extends SchemaMutation {
* @param catalogSchema current version of the schema as an input to mutate
*/
@Nullable
CatalogSchemaContract mutate(@Nullable CatalogSchemaContract catalogSchema);
CatalogSchemaWithImpactOnEntitySchemas mutate(@Nullable CatalogSchemaContract catalogSchema);

/**
* Result object of the {@link #mutate(CatalogSchemaContract)} method allowing to return both the modified catalog
* schema and the list of entity schema mutations that were caused by the catalog schema mutation and needs to be
* propagated to the entity schemas.
*
* @param updatedCatalogSchema modified catalog schema
* @param entitySchemaMutations list of entity schema mutations that were caused by the catalog schema mutation
*/
record CatalogSchemaWithImpactOnEntitySchemas(
@Nonnull CatalogSchemaContract updatedCatalogSchema,
@Nullable ModifyEntitySchemaMutation[] entitySchemaMutations
) {
public CatalogSchemaWithImpactOnEntitySchemas(@Nonnull CatalogSchemaContract updatedCatalogSchema) {
this(updatedCatalogSchema, null);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public interface LocalCatalogSchemaMutation extends CatalogSchemaMutation {

@Nullable
@Override
default CatalogSchemaContract mutate(@Nullable CatalogSchemaContract catalogSchema) {
default CatalogSchemaWithImpactOnEntitySchemas mutate(@Nullable CatalogSchemaContract catalogSchema) {
return mutate(catalogSchema, MutationEntitySchemaAccessor.INSTANCE);
}

Expand All @@ -52,9 +52,9 @@ default CatalogSchemaContract mutate(@Nullable CatalogSchemaContract catalogSche
* operation produces the opposite. Modification operations always accept and produce non-NULL values.
*
* @param catalogSchema current version of the schema as an input to mutate
* @param entitySchemaAccessor
* @param entitySchemaAccessor entity schema provider allowing to access list of entity schemas in the catalog
*/
@Nullable
CatalogSchemaContract mutate(@Nullable CatalogSchemaContract catalogSchema, @Nonnull EntitySchemaProvider entitySchemaAccessor);
CatalogSchemaWithImpactOnEntitySchemas mutate(@Nullable CatalogSchemaContract catalogSchema, @Nonnull EntitySchemaProvider entitySchemaAccessor);

}
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,18 @@ public class CreateGlobalAttributeSchemaMutation
@Getter @Nullable private final Serializable defaultValue;
@Getter private final int indexedDecimalPlaces;

@Nullable
private static <T> LocalCatalogSchemaMutation makeMutationIfDifferent(
@Nonnull GlobalAttributeSchemaContract createdVersion,
@Nonnull GlobalAttributeSchemaContract existingVersion,
@Nonnull Function<GlobalAttributeSchemaContract, T> propertyRetriever,
@Nonnull Function<T, LocalCatalogSchemaMutation> mutationCreator
) {
final T newValue = propertyRetriever.apply(createdVersion);
return Objects.equals(propertyRetriever.apply(existingVersion), newValue) ?
null : mutationCreator.apply(newValue);
}

public CreateGlobalAttributeSchemaMutation(
@Nonnull String name,
@Nullable String description,
Expand Down Expand Up @@ -140,7 +152,7 @@ public MutationCombinationResult<LocalCatalogSchemaMutation> combineWith(@Nonnul
makeMutationIfDifferent(
createdVersion, existingVersion,
NamedSchemaWithDeprecationContract::getDeprecationNotice,
newValue -> new ModifyAttributeSchemaDeprecationNoticeMutation( name, newValue)
newValue -> new ModifyAttributeSchemaDeprecationNoticeMutation(name, newValue)
),
makeMutationIfDifferent(
createdVersion, existingVersion,
Expand Down Expand Up @@ -196,58 +208,48 @@ public MutationCombinationResult<LocalCatalogSchemaMutation> combineWith(@Nonnul
}
}

@Nullable
private static <T> LocalCatalogSchemaMutation makeMutationIfDifferent(
@Nonnull GlobalAttributeSchemaContract createdVersion,
@Nonnull GlobalAttributeSchemaContract existingVersion,
@Nonnull Function<GlobalAttributeSchemaContract, T> propertyRetriever,
@Nonnull Function<T, LocalCatalogSchemaMutation> mutationCreator
) {
final T newValue = propertyRetriever.apply(createdVersion);
return Objects.equals(propertyRetriever.apply(existingVersion), newValue) ?
null : mutationCreator.apply(newValue);
}

@Nonnull
@Override
public <S extends AttributeSchemaContract> S mutate(@Nullable CatalogSchemaContract catalogSchema, @Nullable S attributeSchema, @Nonnull Class<S> schemaType) {
//noinspection unchecked,rawtypes
return (S) GlobalAttributeSchema._internalBuild(
name, description, deprecationNotice,
unique, uniqueGlobally, filterable, sortable, localized, nullable, representative,
(Class)type, defaultValue,
(Class) type, defaultValue,
indexedDecimalPlaces
);
}

@Nullable
@Override
public CatalogSchemaContract mutate(@Nullable CatalogSchemaContract catalogSchema, @Nonnull EntitySchemaProvider entitySchemaAccessor) {
public CatalogSchemaWithImpactOnEntitySchemas mutate(@Nullable CatalogSchemaContract catalogSchema, @Nonnull EntitySchemaProvider entitySchemaAccessor) {
Assert.isPremiseValid(catalogSchema != null, "Catalog schema is mandatory!");
final GlobalAttributeSchemaContract newAttributeSchema = mutate(catalogSchema, null, GlobalAttributeSchemaContract.class);
final GlobalAttributeSchemaContract existingAttributeSchema = catalogSchema.getAttribute(name).orElse(null);
if (existingAttributeSchema == null) {
return CatalogSchema._internalBuild(
catalogSchema.getVersion() + 1,
catalogSchema.getName(),
catalogSchema.getNameVariants(),
catalogSchema.getDescription(),
catalogSchema.getCatalogEvolutionMode(),
Stream.concat(
catalogSchema.getAttributes().values().stream(),
Stream.of(newAttributeSchema)
)
.collect(
Collectors.toMap(
GlobalAttributeSchemaContract::getName,
Function.identity()
return new CatalogSchemaWithImpactOnEntitySchemas(
CatalogSchema._internalBuild(
catalogSchema.getVersion() + 1,
catalogSchema.getName(),
catalogSchema.getNameVariants(),
catalogSchema.getDescription(),
catalogSchema.getCatalogEvolutionMode(),
Stream.concat(
catalogSchema.getAttributes().values().stream(),
Stream.of(newAttributeSchema)
)
),
entitySchemaAccessor
.collect(
Collectors.toMap(
GlobalAttributeSchemaContract::getName,
Function.identity()
)
),
entitySchemaAccessor
)
);
} else if (existingAttributeSchema.equals(newAttributeSchema)) {
// the mutation must have been applied previously - return the schema we don't need to alter
return catalogSchema;
return new CatalogSchemaWithImpactOnEntitySchemas(catalogSchema);
} else {
// ups, there is conflict in attribute settings
throw new InvalidSchemaMutationException(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import io.evitadb.api.requestResponse.schema.dto.EntitySchemaProvider;
import io.evitadb.api.requestResponse.schema.mutation.AttributeSchemaMutation;
import io.evitadb.api.requestResponse.schema.mutation.CatalogSchemaMutation;
import io.evitadb.api.requestResponse.schema.mutation.catalog.ModifyEntitySchemaMutation;

import javax.annotation.Nonnull;
import java.util.function.Function;
Expand All @@ -48,33 +49,45 @@ public interface GlobalAttributeSchemaMutation extends AttributeSchemaMutation,
* the non-changed, original catalog schema is returned.
*/
@Nonnull
default CatalogSchemaContract replaceAttributeIfDifferent(
default CatalogSchemaWithImpactOnEntitySchemas replaceAttributeIfDifferent(
@Nonnull CatalogSchemaContract catalogSchema,
@Nonnull GlobalAttributeSchemaContract existingAttributeSchema,
@Nonnull GlobalAttributeSchemaContract updatedAttributeSchema,
@Nonnull EntitySchemaProvider entitySchemaAccessor
@Nonnull EntitySchemaProvider entitySchemaAccessor,
@Nonnull EntityAttributeSchemaMutation attributeSchemaMutation
) {
if (existingAttributeSchema.equals(updatedAttributeSchema)) {
// we don't need to update entity schema - the associated data already contains the requested change
return catalogSchema;
return new CatalogSchemaWithImpactOnEntitySchemas(catalogSchema);
} else {
return CatalogSchema._internalBuild(
catalogSchema.getVersion() + 1,
catalogSchema.getName(),
catalogSchema.getNameVariants(),
catalogSchema.getDescription(),
catalogSchema.getCatalogEvolutionMode(),
Stream.concat(
catalogSchema.getAttributes().values().stream().filter(it -> !updatedAttributeSchema.getName().equals(it.getName())),
Stream.of(updatedAttributeSchema)
)
.collect(
Collectors.toMap(
AttributeSchemaContract::getName,
Function.identity()
return new CatalogSchemaWithImpactOnEntitySchemas(
CatalogSchema._internalBuild(
catalogSchema.getVersion() + 1,
catalogSchema.getName(),
catalogSchema.getNameVariants(),
catalogSchema.getDescription(),
catalogSchema.getCatalogEvolutionMode(),
Stream.concat(
catalogSchema.getAttributes().values().stream().filter(it -> !updatedAttributeSchema.getName().equals(it.getName())),
Stream.of(updatedAttributeSchema)
)
),
.collect(
Collectors.toMap(
AttributeSchemaContract::getName,
Function.identity()
)
),
entitySchemaAccessor
),
entitySchemaAccessor
.getEntitySchemas()
.stream()
.filter(it -> it.getAttributes().containsKey(existingAttributeSchema.getName()))
.map(it -> new ModifyEntitySchemaMutation(
it.getName(),
attributeSchemaMutation
))
.toArray(ModifyEntitySchemaMutation[]::new)
);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ public <S extends AttributeSchemaContract> S mutate(@Nullable CatalogSchemaContr

@Nullable
@Override
public CatalogSchemaContract mutate(@Nullable CatalogSchemaContract catalogSchema, @Nonnull EntitySchemaProvider entitySchemaAccessor) {
public CatalogSchemaWithImpactOnEntitySchemas mutate(@Nullable CatalogSchemaContract catalogSchema, @Nonnull EntitySchemaProvider entitySchemaAccessor) {
Assert.isPremiseValid(catalogSchema != null, "Catalog schema is mandatory!");
final GlobalAttributeSchemaContract existingAttributeSchema = catalogSchema.getAttribute(name)
.orElseThrow(() -> new InvalidSchemaMutationException(
Expand All @@ -170,7 +170,7 @@ public CatalogSchemaContract mutate(@Nullable CatalogSchemaContract catalogSchem
try {
final GlobalAttributeSchemaContract updatedAttributeSchema = mutate(catalogSchema, existingAttributeSchema, GlobalAttributeSchemaContract.class);
return replaceAttributeIfDifferent(
catalogSchema, existingAttributeSchema, updatedAttributeSchema, entitySchemaAccessor
catalogSchema, existingAttributeSchema, updatedAttributeSchema, entitySchemaAccessor, this
);
} catch (UnsupportedDataTypeException ex) {
throw new InvalidSchemaMutationException(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ public <S extends AttributeSchemaContract> S mutate(@Nullable CatalogSchemaContr

@Nullable
@Override
public CatalogSchemaContract mutate(@Nullable CatalogSchemaContract catalogSchema, @Nonnull EntitySchemaProvider entitySchemaAccessor) {
public CatalogSchemaWithImpactOnEntitySchemas mutate(@Nullable CatalogSchemaContract catalogSchema, @Nonnull EntitySchemaProvider entitySchemaAccessor) {
Assert.isPremiseValid(catalogSchema != null, "Catalog schema is mandatory!");
final GlobalAttributeSchemaContract existingAttributeSchema = catalogSchema.getAttribute(name)
.orElseThrow(() -> new InvalidSchemaMutationException(
Expand All @@ -164,7 +164,7 @@ public CatalogSchemaContract mutate(@Nullable CatalogSchemaContract catalogSchem

final GlobalAttributeSchemaContract updatedAttributeSchema = mutate(catalogSchema, existingAttributeSchema, GlobalAttributeSchemaContract.class);
return replaceAttributeIfDifferent(
catalogSchema, existingAttributeSchema, updatedAttributeSchema, entitySchemaAccessor
catalogSchema, existingAttributeSchema, updatedAttributeSchema, entitySchemaAccessor, this
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ public <S extends AttributeSchemaContract> S mutate(@Nullable CatalogSchemaContr

@Nullable
@Override
public CatalogSchemaContract mutate(@Nullable CatalogSchemaContract catalogSchema, @Nonnull EntitySchemaProvider entitySchemaAccessor) {
public CatalogSchemaWithImpactOnEntitySchemas mutate(@Nullable CatalogSchemaContract catalogSchema, @Nonnull EntitySchemaProvider entitySchemaAccessor) {
Assert.isPremiseValid(catalogSchema != null, "Catalog schema is mandatory!");
final GlobalAttributeSchemaContract existingAttributeSchema = catalogSchema.getAttribute(name)
.orElseThrow(() -> new InvalidSchemaMutationException(
Expand All @@ -163,7 +163,7 @@ public CatalogSchemaContract mutate(@Nullable CatalogSchemaContract catalogSchem

final GlobalAttributeSchemaContract updatedAttributeSchema = mutate(catalogSchema, existingAttributeSchema, GlobalAttributeSchemaContract.class);
return replaceAttributeIfDifferent(
catalogSchema, existingAttributeSchema, updatedAttributeSchema, entitySchemaAccessor
catalogSchema, existingAttributeSchema, updatedAttributeSchema, entitySchemaAccessor, this
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ public <S extends AttributeSchemaContract> S mutate(@Nullable CatalogSchemaContr

@Nullable
@Override
public CatalogSchemaContract mutate(@Nullable CatalogSchemaContract catalogSchema, @Nonnull EntitySchemaProvider entitySchemaAccessor) {
public CatalogSchemaWithImpactOnEntitySchemas mutate(@Nullable CatalogSchemaContract catalogSchema, @Nonnull EntitySchemaProvider entitySchemaAccessor) {
Assert.isPremiseValid(catalogSchema != null, "Catalog schema is mandatory!");
final GlobalAttributeSchemaContract existingAttributeSchema = catalogSchema.getAttribute(name)
.orElseThrow(() -> new InvalidSchemaMutationException(
Expand All @@ -163,7 +163,7 @@ public CatalogSchemaContract mutate(@Nullable CatalogSchemaContract catalogSchem

final GlobalAttributeSchemaContract updatedAttributeSchema = mutate(catalogSchema, existingAttributeSchema, GlobalAttributeSchemaContract.class);
return replaceAttributeIfDifferent(
catalogSchema, existingAttributeSchema, updatedAttributeSchema, entitySchemaAccessor
catalogSchema, existingAttributeSchema, updatedAttributeSchema, entitySchemaAccessor, this
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ public <S extends AttributeSchemaContract> S mutate(@Nullable CatalogSchemaContr

@Nullable
@Override
public CatalogSchemaContract mutate(@Nullable CatalogSchemaContract catalogSchema, @Nonnull EntitySchemaProvider entitySchemaAccessor) {
public CatalogSchemaWithImpactOnEntitySchemas mutate(@Nullable CatalogSchemaContract catalogSchema, @Nonnull EntitySchemaProvider entitySchemaAccessor) {
Assert.isPremiseValid(catalogSchema != null, "Catalog schema is mandatory!");
final GlobalAttributeSchemaContract existingAttributeSchema = catalogSchema.getAttribute(name)
.orElseThrow(() -> new InvalidSchemaMutationException(
Expand All @@ -203,7 +203,7 @@ public CatalogSchemaContract mutate(@Nullable CatalogSchemaContract catalogSchem

final GlobalAttributeSchemaContract updatedAttributeSchema = mutate(catalogSchema, existingAttributeSchema, GlobalAttributeSchemaContract.class);
return replaceAttributeIfDifferent(
catalogSchema, existingAttributeSchema, updatedAttributeSchema, entitySchemaAccessor
catalogSchema, existingAttributeSchema, updatedAttributeSchema, entitySchemaAccessor, this
);
}

Expand Down
Loading

0 comments on commit b6a36c3

Please sign in to comment.