use of org.finos.legend.engine.protocol.pure.v1.model.packageableElement.mapping.ClassMapping in project legend-engine by finos.
the class RelationalCompilerExtension method getExtraClassMappingFirstPassProcessors.
@Override
public List<Function3<ClassMapping, Mapping, CompileContext, Pair<SetImplementation, RichIterable<EmbeddedSetImplementation>>>> getExtraClassMappingFirstPassProcessors() {
return Collections.singletonList((cm, parentMapping, context) -> {
if (cm instanceof RootRelationalClassMapping) {
RootRelationalClassMapping classMapping = (RootRelationalClassMapping) cm;
String id = classMapping.id != null ? classMapping.id : getElementFullPath(context.resolveClass(classMapping._class, classMapping.classSourceInformation), context.pureModel.getExecutionSupport()).replaceAll("::", "_");
final RootRelationalInstanceSetImplementation res = new Root_meta_relational_mapping_RootRelationalInstanceSetImplementation_Impl(id)._id(id);
MutableList<RelationalOperationElement> groupByColumns = ListIterate.collect(classMapping.groupBy, relationalOperationElement -> HelperRelationalBuilder.processRelationalOperationElement(relationalOperationElement, context, Maps.mutable.empty(), Lists.mutable.empty()));
org.finos.legend.pure.m3.coreinstance.meta.relational.metamodel.TableAlias mainTableAlias = null;
// user has defined main table
if (classMapping.mainTable != null) {
Relation pureTable = HelperRelationalBuilder.getRelation(classMapping.mainTable, context);
mainTableAlias = new Root_meta_relational_metamodel_TableAlias_Impl("")._relationalElement(pureTable)._database(HelperRelationalBuilder.resolveDatabase(classMapping.mainTable.getDb(), classMapping.mainTable.sourceInformation, context));
}
res._distinct(classMapping.distinct)._superSetImplementationId(classMapping.extendsClassMappingId)._root(classMapping.root)._mainTableAlias(mainTableAlias)._parent(parentMapping);
if (classMapping.mappingClass != null) {
res._mappingClass(HelperMappingBuilder.processMappingClass(classMapping.mappingClass, context, parentMapping));
}
if (!classMapping.groupBy.isEmpty()) {
res._groupBy(new Root_meta_relational_mapping_GroupByMapping_Impl("")._columns(groupByColumns));
}
MutableList<org.finos.legend.pure.m3.coreinstance.meta.relational.mapping.EmbeddedRelationalInstanceSetImplementation> embeddedRelationalPropertyMappings = Lists.mutable.empty();
MutableMap<String, TableAlias> tableAliasesMap = Maps.mutable.empty();
HelperRelationalBuilder.processRelationalClassMapping(classMapping, context, res, res, parentMapping, embeddedRelationalPropertyMappings, HelperMappingBuilder.getAllEnumerationMappings(parentMapping), tableAliasesMap);
// user has not defined mainTable and the processing of mainTableAlias is complete (done with processing of class mapping)
if (res._mainTableAlias() == null) {
MutableSet<TableAlias> tableAliases = tableAliasesMap.valuesView().toSet();
MutableSet<RelationalOperationElement> tables = tableAliases.collect(AliasAccessor::_relationalElement);
MutableSet<org.finos.legend.pure.m3.coreinstance.meta.relational.metamodel.Database> databases = tableAliases.collect(TableAliasAccessor::_database);
// if classMapping is extending another class the main table can be resolved in ExtraClassMappingSecondPassProcessors
if ((tables.size() == 0 && classMapping.extendsClassMappingId == null) || tables.size() > 1) {
throw new EngineException("Can't find the main table for class '" + classMapping.id + "'. Please specify a main table using the ~mainTable directive.");
}
if ((databases.size() == 0 && classMapping.extendsClassMappingId == null) || databases.size() > 1) {
throw new EngineException("Can't find the main table for class '" + classMapping.id + "'. Inconsistent database definitions for the mapping");
}
if (tables.size() == 1 && databases.size() == 1) {
mainTableAlias = new Root_meta_relational_metamodel_TableAlias_Impl("");
mainTableAlias._relationalElement(tables.toList().getFirst());
mainTableAlias._database(databases.toList().getFirst());
res._mainTableAlias(mainTableAlias);
HelperRelationalBuilder.enhanceEmbeddedMappingsWithRelationalOperationElement(embeddedRelationalPropertyMappings, res);
}
}
parentMapping._classMappingsAddAll(embeddedRelationalPropertyMappings);
embeddedRelationalPropertyMappings.addAll(HelperRelationalBuilder.generateMilestoningRangeEmbeddedPropertyMapping(res, res, context));
return Tuples.pair(res, Lists.immutable.empty());
}
return null;
});
}
use of org.finos.legend.engine.protocol.pure.v1.model.packageableElement.mapping.ClassMapping in project legend-engine by finos.
the class RelationalCompilerExtension method getExtraAggregationAwareClassMappingSecondPassProcessors.
@Override
public List<Procedure3<AggregationAwareClassMapping, Mapping, CompileContext>> getExtraAggregationAwareClassMappingSecondPassProcessors() {
return Collections.singletonList((cm, parentMapping, context) -> {
AggregationAwareSetImplementation asi = (AggregationAwareSetImplementation) parentMapping._classMappings().detect(c -> HelperRelationalBuilder.getClassMappingId(c).equals(HelperMappingBuilder.getClassMappingId(cm, context)));
if (cm.mainSetImplementation instanceof RootRelationalClassMapping) {
RootRelationalClassMapping classMapping = (RootRelationalClassMapping) cm.mainSetImplementation;
HelperRelationalBuilder.processRootRelationalClassMapping((RootRelationalInstanceSetImplementation) asi._mainSetImplementation(), classMapping, context);
}
for (AggregateSetImplementationContainer agg : cm.aggregateSetImplementations) {
if (agg.setImplementation instanceof RootRelationalClassMapping) {
RootRelationalClassMapping classMapping = (RootRelationalClassMapping) agg.setImplementation;
asi._aggregateSetImplementations().forEach(c -> {
if (HelperRelationalBuilder.getClassMappingId(c._setImplementation()).equals(HelperMappingBuilder.getClassMappingId(classMapping, context))) {
HelperRelationalBuilder.processRootRelationalClassMapping((RootRelationalInstanceSetImplementation) c._setImplementation(), classMapping, context);
}
});
}
}
});
}
use of org.finos.legend.engine.protocol.pure.v1.model.packageableElement.mapping.ClassMapping in project legend-engine by finos.
the class RelationalCompilerExtension method getExtraClassMappingSecondPassProcessors.
@Override
public List<Procedure3<ClassMapping, Mapping, CompileContext>> getExtraClassMappingSecondPassProcessors() {
return Collections.singletonList((cm, parentMapping, context) -> {
if (cm instanceof RootRelationalClassMapping) {
RootRelationalClassMapping classMapping = (RootRelationalClassMapping) cm;
RootRelationalInstanceSetImplementation rsi = (RootRelationalInstanceSetImplementation) parentMapping._classMappings().detect(c -> HelperRelationalBuilder.getClassMappingId(c).equals(HelperMappingBuilder.getClassMappingId(classMapping, context)));
HelperRelationalBuilder.processRootRelationalClassMapping(rsi, classMapping, context);
}
});
}
use of org.finos.legend.engine.protocol.pure.v1.model.packageableElement.mapping.ClassMapping in project legend-engine by finos.
the class RelationalGrammarComposerExtension method getExtraClassMappingComposers.
@Override
public List<Function2<ClassMapping, PureGrammarComposerContext, String>> getExtraClassMappingComposers() {
return Lists.mutable.with((classMapping, context) -> {
if (classMapping instanceof RootRelationalClassMapping) {
RelationalGrammarComposerContext ctx = RelationalGrammarComposerContext.Builder.newInstance(context).build();
RootRelationalClassMapping rootRelationalClassMapping = (RootRelationalClassMapping) classMapping;
StringBuilder builder = new StringBuilder();
builder.append(": Relational\n");
builder.append(getTabString()).append("{\n");
if (rootRelationalClassMapping.filter != null) {
appendTabString(builder, 2).append(HelperRelationalGrammarComposer.renderFilterMapping(rootRelationalClassMapping.filter)).append("\n");
}
builder.append(rootRelationalClassMapping.distinct ? (getTabString(2) + "~distinct\n") : "");
if (!rootRelationalClassMapping.groupBy.isEmpty()) {
appendTabString(builder, 2).append("~groupBy\n");
appendTabString(builder, 2).append("(\n");
builder.append(LazyIterate.collect(rootRelationalClassMapping.groupBy, op -> getTabString(3) + HelperRelationalGrammarComposer.renderRelationalOperationElement(op, ctx)).makeString(",\n"));
builder.append("\n");
appendTabString(builder, 2).append(")\n");
}
if (!rootRelationalClassMapping.primaryKey.isEmpty()) {
appendTabString(builder, 2).append("~primaryKey\n");
appendTabString(builder, 2).append("(\n");
builder.append(LazyIterate.collect(rootRelationalClassMapping.primaryKey, op -> getTabString(3) + HelperRelationalGrammarComposer.renderRelationalOperationElement(op, ctx)).makeString(",\n"));
builder.append("\n");
appendTabString(builder, 2).append(")\n");
}
if (rootRelationalClassMapping.mainTable != null) {
TablePtr tablePtr = rootRelationalClassMapping.mainTable;
appendTabString(builder, 2).append("~mainTable ");
builder.append("[").append(tablePtr.getDb()).append("]");
builder.append((tablePtr.schema != null && !tablePtr.schema.equals("default")) ? (tablePtr.schema + "." + tablePtr.table) : tablePtr.table);
builder.append("\n");
}
if (!rootRelationalClassMapping.propertyMappings.isEmpty()) {
RelationalGrammarComposerContext indentedContext = RelationalGrammarComposerContext.Builder.newInstance(ctx).withIndentation(4).build();
builder.append(LazyIterate.collect(rootRelationalClassMapping.propertyMappings, propertyMapping -> HelperRelationalGrammarComposer.renderAbstractRelationalPropertyMapping(propertyMapping, indentedContext, false)).makeString(",\n"));
builder.append("\n");
}
appendTabString(builder).append("}");
return builder.toString();
}
return null;
});
}
use of org.finos.legend.engine.protocol.pure.v1.model.packageableElement.mapping.ClassMapping in project legend-engine by finos.
the class ClassMappingSecondPassBuilder method visit.
@Override
public SetImplementation visit(PureInstanceClassMapping classMapping) {
PureInstanceSetImplementation s = (PureInstanceSetImplementation) parentMapping._classMappings().select(c -> c._id().equals(HelperMappingBuilder.getClassMappingId(classMapping, this.context))).getFirst();
s._propertyMappings().forEachWithIndex((ObjectIntProcedure<org.finos.legend.pure.m3.coreinstance.meta.pure.mapping.PropertyMapping>) ((p, i) -> {
org.finos.legend.pure.m3.coreinstance.meta.pure.mapping.modelToModel.PurePropertyMapping pm = (org.finos.legend.pure.m3.coreinstance.meta.pure.mapping.modelToModel.PurePropertyMapping) p;
org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.property.Property<?, ?> property = pm._property();
SourceInformation pSourceInformation = SourceInformationHelper.fromM3SourceInformation(p.getSourceInformation());
org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.ValueSpecification last = pm._transform()._expressionSequence().getLast();
List<Type> typesToCheck;
if (property._genericType()._rawType()._classifierGenericType()._rawType()._name().equals("Class")) {
SetImplementation setImplementation;
if (p._targetSetImplementationId() != null && !p._targetSetImplementationId().equals("")) {
setImplementation = parentMapping._classMappingByIdRecursive(Lists.fixedSize.with(p._targetSetImplementationId()), this.context.pureModel.getExecutionSupport()).getFirst();
Assert.assertTrue(setImplementation != null, () -> "Can't find class mapping '" + p._targetSetImplementationId() + "'", pSourceInformation, EngineErrorType.COMPILATION);
} else {
setImplementation = parentMapping.classMappingByClass((org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.Class<Object>) property._genericType()._rawType(), this.context.pureModel.getExecutionSupport()).getFirst();
Assert.assertTrue(setImplementation != null, () -> "Can't find class mapping for '" + HelperModelBuilder.getElementFullPath(property._genericType()._rawType(), this.context.pureModel.getExecutionSupport()) + "'", pSourceInformation, EngineErrorType.COMPILATION);
}
List<? extends InstanceSetImplementation> setImpls = core_pure_router_router_routing.Root_meta_pure_router_routing_resolveOperation_SetImplementation_MANY__Mapping_1__InstanceSetImplementation_MANY_(Lists.immutable.of(setImplementation), parentMapping, this.context.pureModel.getExecutionSupport()).toList();
typesToCheck = setImpls.stream().map(setImpl -> ((PureInstanceSetImplementation) setImpl)._srcClass()).collect(Collectors.toList());
} else if (((org.finos.legend.pure.m3.coreinstance.meta.pure.mapping.modelToModel.PurePropertyMapping) p)._transformer() != null) {
EnumerationMapping<Object> m = ((EnumerationMapping<Object>) ((org.finos.legend.pure.m3.coreinstance.meta.pure.mapping.modelToModel.PurePropertyMapping) p)._transformer());
Object val = m._enumValueMappings().getFirst()._sourceValues().getFirst();
if (val instanceof String) {
typesToCheck = Collections.singletonList(this.context.pureModel.getType("String"));
} else if (val instanceof Long) {
typesToCheck = Collections.singletonList(this.context.pureModel.getType("Integer"));
} else if (val instanceof EnumValue) {
typesToCheck = Collections.singletonList(this.context.resolveEnumeration(((EnumValue) val).fullPath, pSourceInformation));
} else if (val instanceof Enum) {
GenericType genericType = ((Enum) val)._classifierGenericType();
typesToCheck = genericType != null ? Collections.singletonList(this.context.resolveEnumeration(PackageableElement.getUserPathForPackageableElement(genericType._rawType()), pSourceInformation)) : Collections.emptyList();
} else {
typesToCheck = Collections.emptyList();
}
} else {
typesToCheck = Collections.singletonList(property._genericType()._rawType());
}
org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.multiplicity.Multiplicity multiplicityToCheck = pm._explodeProperty() != null && pm._explodeProperty() ? this.context.pureModel.getMultiplicity("zeromany") : property._multiplicity();
List<ValueSpecification> lines = ((PurePropertyMapping) classMapping.propertyMappings.get(i)).transform.body;
typesToCheck.stream().filter(Objects::nonNull).forEach(t -> HelperModelBuilder.checkTypeCompatibility(this.context, last._genericType()._rawType(), t, "Error in class mapping '" + HelperModelBuilder.getElementFullPath(parentMapping, this.context.pureModel.getExecutionSupport()) + "' for property '" + pm._property()._name() + "'", lines.get(lines.size() - 1).sourceInformation));
HelperModelBuilder.checkMultiplicityCompatibility(last._multiplicity(), multiplicityToCheck, "Error in class mapping '" + HelperModelBuilder.getElementFullPath(parentMapping, this.context.pureModel.getExecutionSupport()) + "' for property '" + pm._property()._name() + "'", lines.get(lines.size() - 1).sourceInformation);
}));
return s;
}
Aggregations