core_dataquality.generation.dataquality.pure Maven / Gradle / Ivy
import meta::pure::metamodel::relation::*;
import meta::pure::dataQuality::*;
import meta::pure::metamodel::serialization::grammar::*;
import meta::pure::lineage::scanProperties::*;
import meta::external::dataquality::*;
import meta::pure::graphFetch::*;
import meta::pure::functions::collection::*;
import meta::pure::functions::meta::*;
import meta::pure::graphFetch::execution::*;
import meta::core::runtime::*;
import meta::pure::executionPlan::*;
import meta::pure::mapping::*;
import meta::pure::functions::boolean::*;
import meta::pure::metamodel::constraint::*;
import meta::pure::lineage::scanProperties::propertyTree::*;
Class meta::external::dataquality::MilestoningContext
{
rootBusinessTemporal: Boolean[1];
rootProcessingTemporal: Boolean[1];
nonRootBusinessTemporal: Boolean[1];
nonRootProcessingTemporal: Boolean[1];
businessTemporal(){
$this.rootBusinessTemporal || $this.nonRootBusinessTemporal
}:Boolean[1];
processingTemporal(){
$this.rootProcessingTemporal || $this.nonRootProcessingTemporal
}:Boolean[1];
}
function meta::external::dataquality::generateDataQualityQuery(dataquality:meta::external::dataquality::DataQuality[1], limit: Integer[0..1]): LambdaFunction[1]
{
generateDataQualityQuery($dataquality, $limit, true);
}
function meta::external::dataquality::getMilestoningContext(tree:RootGraphFetchTree[1]): MilestoningContext[1]
{
let properties = getAllProperties($tree);
let propertyTypes = $properties.genericType.rawType;
^MilestoningContext(
rootBusinessTemporal = $tree.class->meta::pure::milestoning::isBusinessTemporal(),
rootProcessingTemporal = $tree.class->meta::pure::milestoning::isProcessingTemporal(),
nonRootBusinessTemporal = $propertyTypes->exists(t | $t->meta::pure::milestoning::isBusinessTemporal()),
nonRootProcessingTemporal = $propertyTypes->exists(t | $t->meta::pure::milestoning::isProcessingTemporal())
);
}
function meta::external::dataquality::addMilestoningParameters(tree:GraphFetchTree[1]):GraphFetchTree[1]
{
$tree->match([
p:PropertyGraphFetchTree[1] |
let parameters = if ($p.parameters->isEmpty(),
| let isBusinessTemporal = $p.property.genericType.rawType->toOne()->meta::pure::milestoning::isBusinessTemporal();
let isProcessingTemporal = $p.property.genericType.rawType->toOne()->meta::pure::milestoning::isProcessingTemporal();
getTemporalParameters($isProcessingTemporal, $isBusinessTemporal);,
| $p.parameters
);
^$p(
subTrees = $p.subTrees->map(t | addMilestoningParameters($t)),
parameters = $parameters,
subTypeTrees = $p.subTypeTrees->map(t | addMilestoningParameters($t))->cast(@SubTypeGraphFetchTree)
);,
g:GraphFetchTree[1] |
^$g(
subTrees = $g.subTrees->map(t | addMilestoningParameters($t)),
subTypeTrees = $g.subTypeTrees->map(t | addMilestoningParameters($t))->cast(@SubTypeGraphFetchTree)
)
])
}
function meta::external::dataquality::generateDataQualityQuery(dataquality:meta::external::dataquality::DataQuality[1], limit: Integer[0..1], useFrom:Boolean[1]): LambdaFunction[1]
{
$dataquality.validationTree->validateTreeForNestedConstraints(true);
let milestonedTree = $dataquality.validationTree->addMilestoningParameters();
// 1. enrich tree with selected constraint properties
let enrichedTree = $milestonedTree->ensureFunctionRequirementsForDataQuality($dataquality.validationTree.constraints, $dataquality.validationTree.class, [], true)->cast(@RootGraphFetchTree);
let milestoningContext = getMilestoningContext($enrichedTree);
// 2. build query
let getAll = $dataquality.validationTree.class->createGetAll($milestoningContext.rootProcessingTemporal, $milestoningContext.rootBusinessTemporal);
let getExpr = if ($dataquality.filter->isNotEmpty(),
| $dataquality.validationTree.class->generateFilterQuery($getAll, $dataquality.filter->toOne());,
| $getAll);
let dqRootConstraints = $dataquality.validationTree.constraints;
let constraintQueryExpr = $dataquality.validationTree.class->meta::external::dataquality::generateConstraintsNegatedORQuery($getExpr, ^List(values=$dqRootConstraints));
let limitQueryExpr = if ($limit->isNotEmpty(),
| $constraintQueryExpr->buildLimitFilterExpression($limit->toOne(), ^GenericType(rawType=$dataquality.validationTree.class)),
| $constraintQueryExpr);
let graphFetchChecked = ^SimpleFunctionExpression(func=graphFetchChecked_T_MANY__RootGraphFetchTree_1__Checked_MANY_ ,
parametersValues=[$limitQueryExpr, ^InstanceValue(values=$enrichedTree, genericType=^GenericType(rawType=RootGraphFetchTree), multiplicity=PureOne)],
functionName=graphFetchChecked_T_MANY__RootGraphFetchTree_1__Checked_MANY_.name,
genericType=^GenericType(rawType=Checked, typeArguments=^GenericType(rawType=$dataquality.validationTree.class)),
multiplicity = ZeroMany,
importGroup=system::imports::coreImport);
// 2.1
let serialized = ^SimpleFunctionExpression(func=serialize_Checked_MANY__RootGraphFetchTree_1__String_1_,
functionName=serialize_Checked_MANY__RootGraphFetchTree_1__String_1_.name,
importGroup=system::imports::coreImport,
genericType=^GenericType(rawType=String),
multiplicity=ZeroMany,
parametersValues=[$graphFetchChecked, ^InstanceValue(values=$enrichedTree, genericType=^GenericType(rawType=RootGraphFetchTree), multiplicity=PureOne)])->evaluateAndDeactivate();
// 2.2 extract mapping and runtime here
let mappingAndRuntime = $dataquality.context->getMappingAndRuntime();
let deactivatedMapping = ^InstanceValue(values=$mappingAndRuntime.first->evaluateAndDeactivate(), genericType=^GenericType(rawType=Mapping), multiplicity=PureOne) ;
let deactivatedRuntime = ^InstanceValue(values=$mappingAndRuntime.second->evaluateAndDeactivate(), genericType=^GenericType(rawType=NonExecutableValueSpecification), multiplicity=PureOne);
let from = if ($useFrom, | ^SimpleFunctionExpression(func=from_T_m__Mapping_1__Runtime_1__T_m_,
functionName=from_T_m__Mapping_1__Runtime_1__T_m_.name,
importGroup=system::imports::coreImport,
genericType=^GenericType(rawType=String),
multiplicity=ZeroMany,
parametersValues=[$serialized, $deactivatedMapping, $deactivatedRuntime])->evaluateAndDeactivate(), | $serialized);
// 3. build lambda
createLambda($from, $milestoningContext.processingTemporal, $milestoningContext.businessTemporal);
}
function meta::external::dataquality::validateTreeForNestedConstraints(node:GraphFetchTree[1], isRoot:Boolean[1]): Boolean[1]
{
if ($isRoot->isFalse() && $node->cast(@DataQualityPropertyGraphFetchTree).constraints->isNotEmpty(),
| fail('Nested constraints are not currently supported!'),
| ''
);
$node.subTrees->fold({subtree, isValid | $isValid && $subtree->validateTreeForNestedConstraints(false)}, true);
}
function meta::external::dataquality::ensureFunctionRequirementsForDataQuality(node:GraphFetchTree[1], constraints:Constraint[*], class:Class[1], processed:Class[*], ensureConstraintsForSubTrees:Boolean[1]): GraphFetchTree[1]
{
let constraintResult = pathsForConstraintFunctions($class, $constraints.functionDefinition->concatenate($constraints.messageFunction));
let qualifiedPropertyPaths = $constraintResult->filter(path| $path.values->exists(x| $x.property->instanceOf(QualifiedProperty))); //QualifiedProperty/derived property - methods within a class - first try with inline properties, milestoning properties - used in loans usecase
let inlinedPropertyTree = $constraintResult->meta::pure::lineage::scanProperties::propertyTree::buildPropertyTree()->meta::pure::lineage::scanProperties::inlineQualifiedPropertyNodes();
let inlinedGraphTree = $inlinedPropertyTree->propertyTreeToGraphFetchTree($class);
let inlinedPropertyGraphTrees = $inlinedGraphTree.subTrees->cast(@PropertyGraphFetchTree);
let withFoundProperties = $node->addSubTrees($inlinedPropertyGraphTrees);
let updatedForClass = $qualifiedPropertyPaths->fold({path, gt| $gt->meta::external::dataquality::recordQualifiedProperties($path)}, $withFoundProperties);
let updatedProcessed = $processed->add($class);
if($ensureConstraintsForSubTrees,
{|
let newSubTrees = $updatedForClass.subTrees->map({st|
let returns = if($st->cast(@PropertyGraphFetchTree).subType->isEmpty(),
| $st->cast(@PropertyGraphFetchTree).property->functionReturnType().rawType->toOne(),
| $st->cast(@PropertyGraphFetchTree).subType->toOne()
);
if($returns->instanceOf(Class) && !$updatedProcessed->contains($returns),
| $st->ensureFunctionRequirementsForDataQuality($constraints, $returns->cast(@Class), $updatedProcessed, $ensureConstraintsForSubTrees),
| $st
);
});
^$updatedForClass(subTrees=$newSubTrees);
},
| $updatedForClass
);
}
function <> meta::external::dataquality::createGetAll(c: Class[1]):FunctionExpression[1]
{
let getAllExpression = ^SimpleFunctionExpression
(
func = getAll_Class_1__T_MANY_,
functionName = getAll_Class_1__T_MANY_.name,
importGroup = system::imports::coreImport,
genericType = ^GenericType(rawType = $c),
multiplicity = ZeroMany,
parametersValues = ^InstanceValue( genericType = ^GenericType(rawType = Class, typeArguments = ^GenericType(rawType = $c)),
multiplicity = PureOne,
values = $c
))->evaluateAndDeactivate();
let classifierGenericType = ^GenericType(rawType = LambdaFunction, typeArguments = ^GenericType(rawType = ^FunctionType(returnMultiplicity = ZeroMany, returnType = ^GenericType(rawType = $c))));
let lambda = {|[]};
^$lambda(classifierGenericType=$classifierGenericType, expressionSequence = $getAllExpression).expressionSequence->at(0)->cast(@FunctionExpression);
}
function <> meta::external::dataquality::getAllProperties(tree:GraphFetchTree[1]):AbstractProperty[*]
{
let properties = $tree->match([
p:PropertyGraphFetchTree[1] | $p.property,
g:GraphFetchTree[1] | []
]);
$tree.subTrees->concatenate($tree.subTypeTrees)
->map(t | $t->getAllProperties())
->concatenate($properties);
}
function meta::external::dataquality::createLambda(body:ValueSpecification[1], processingTemporal:Boolean[1], businessTemporal:Boolean[1]):LambdaFunction[1]
{
let parameters = getTemporalParameters($processingTemporal, $businessTemporal);
let functionType = ^FunctionType(returnMultiplicity = $body.multiplicity, returnType = $body.genericType, parameters = $parameters);
let lambda = newLambdaFunction($functionType);
^$lambda(expressionSequence = $body);
}
function <> meta::external::dataquality::createGetAll(c: Class[1], processingTemporal:Boolean[1], businessTemporal:Boolean[1]):FunctionExpression[1]
{
let func = [
pair($processingTemporal && $businessTemporal, getAll_Class_1__Date_1__Date_1__T_MANY_),
pair($processingTemporal || $businessTemporal, getAll_Class_1__Date_1__T_MANY_),
pair(true, getAll_Class_1__T_MANY_)
]->filter(t | $t.first == true)->at(0).second;
let parameters = getTemporalParameters($processingTemporal, $businessTemporal);
^SimpleFunctionExpression
(
func = $func,
functionName = $func.name,
importGroup = system::imports::coreImport,
genericType = ^GenericType(rawType = $c),
multiplicity = ZeroMany,
parametersValues = ^InstanceValue( genericType = ^GenericType(rawType = Class, typeArguments = ^GenericType(rawType = $c)),
multiplicity = PureOne,
values = $c
)->concatenate($parameters)
)->evaluateAndDeactivate();
}
function <> meta::external::dataquality::getTemporalParameters(processingTemporal:Boolean[1], businessTemporal:Boolean[1]):VariableExpression[*]
{
[
pair($processingTemporal, ^VariableExpression(name='processingDate', genericType=^GenericType(rawType=Date), multiplicity=PureOne)->evaluateAndDeactivate()),
pair($businessTemporal, ^VariableExpression(name='businessDate', genericType=^GenericType(rawType=Date), multiplicity=PureOne)->evaluateAndDeactivate())
]->filter(f | $f.first).second->evaluateAndDeactivate();
}
function meta::external::dataquality::generateFilterQuery(c:Class[1], f: FunctionExpression[1], filter:LambdaFunction<{T[1]->Boolean[1]}>[1]):FunctionExpression[1] {
let dummyLambda = {|'ok'};
^SimpleFunctionExpression
(
func = filter_T_MANY__Function_1__T_MANY_,
multiplicity = ZeroMany,
genericType = ^GenericType(rawType = $c),
importGroup = system::imports::coreImport,
parametersValues =
[ $f,
^InstanceValue (
genericType = ^GenericType(rawType=LambdaFunction, typeArguments=^GenericType(rawType=^FunctionType(parameters=^VariableExpression(name='x', genericType=^GenericType(rawType = $c), multiplicity=PureOne), returnMultiplicity=PureOne, returnType=^GenericType(rawType=Boolean)))),
multiplicity = PureOne,
values = lambda(functionType('x', $c, PureOne, Boolean, ZeroMany), $filter.expressionSequence->evaluateAndDeactivate()->replaceVariableWithVariable('this', 'x'))
)
]
)->evaluateAndDeactivate();
}
function meta::external::dataquality::lambda(functionType:FunctionType[1], expressionSequence:ValueSpecification[*]):LambdaFunction[1]
{
let lambda = meta::pure::functions::meta::newLambdaFunction($functionType);
^$lambda(expressionSequence = $expressionSequence->toOneMany());
}
function meta::external::dataquality::functionType(name:String[1], type:Type[1], multiplicity:Multiplicity[1], returnType:Type[1], returnMultiplicity:Multiplicity[1]):FunctionType[1]
{
functionType($name, ^GenericType(rawType = $type), $multiplicity, ^GenericType(rawType = $returnType), $returnMultiplicity);
}
function meta::external::dataquality::functionType(name:String[1], type:GenericType[1], multiplicity:Multiplicity[1], returnType:GenericType[1], returnMultiplicity:Multiplicity[1]):FunctionType[1]
{
^FunctionType(parameters = ^VariableExpression(genericType = $type, name = $name, multiplicity = $multiplicity), returnMultiplicity = $returnMultiplicity, returnType = $returnType);
}
function meta::external::dataquality::functionType(parameters:VariableExpression[*], returnType:GenericType[1], returnMultiplicity:Multiplicity[1]):FunctionType[1]
{
^FunctionType(parameters = $parameters, returnMultiplicity = $returnMultiplicity, returnType = $returnType);
}
function meta::external::dataquality::generateConstraintsNegatedORQuery(c:Class[1], f: FunctionExpression[1], constraints: List[1]):FunctionExpression[1] {
if ($constraints.values->isEmpty(),
| $f ,
| if ($constraints.values->size() == 1,
| $c->generateConstraintNegatedQuery($f, $constraints.values->at(0)) ,
| $c->generateORNegatedQuery($f, $constraints)
);
);
}
function meta::external::dataquality::generateORNegatedQuery(c:Class[1], f: FunctionExpression[1], constraints: List[1]):FunctionExpression[1]
{
let c1 = $constraints.values->at(0);
let c2 = $constraints.values->at(1);
let c1_negatedExprSequence = $c1.functionDefinition.expressionSequence->evaluateAndDeactivate()->toOne()->negatedFunctionExpression();
let c2_negatedExprSequence = $c2.functionDefinition.expressionSequence->evaluateAndDeactivate()->toOne()->negatedFunctionExpression();
let c1_c2_or_expr = $c1_negatedExprSequence->orFunctionExpression($c2_negatedExprSequence);
let final_expr = $constraints.values->drop(2)->fold({c3, curr_or_exp |
let c3_negatedExprSequence = $c3.functionDefinition.expressionSequence->evaluateAndDeactivate()->toOne()->negatedFunctionExpression();
$c3_negatedExprSequence->orFunctionExpression($curr_or_exp);}, $c1_c2_or_expr);
^SimpleFunctionExpression
(
func = filter_T_MANY__Function_1__T_MANY_,
multiplicity = ZeroMany,
genericType = ^GenericType(rawType = $c),
importGroup = system::imports::coreImport,
parametersValues =
[ $f,
^InstanceValue (
genericType = $c1.functionDefinition.classifierGenericType->toOne(),
multiplicity = PureOne,
values = lambda(functionType('x', $c, PureOne, Boolean, ZeroMany), $final_expr->evaluateAndDeactivate()->replaceVariableWithVariable('this', 'x'))
)
]
)->evaluateAndDeactivate();
}
function meta::external::dataquality::replaceVariableWithVariable(v:ValueSpecification[1..*], from:String[1], to:String[1]):ValueSpecification[1..*]
{
$v->map(a | $a->replaceVariableWithVariable($from, $to))
}
function meta::external::dataquality::replaceVariableWithVariable(v:ValueSpecification[1], from:String[1], to:String[1]):ValueSpecification[1]
{
$v->match([
v:VariableExpression[1] | if ($v.name == $from, | ^$v(name = $to), | $v),
s:SimpleFunctionExpression[1] | ^$s(parametersValues = $s.parametersValues->map(p | replaceVariableWithVariable($p, $from, $to))),
i:InstanceValue[1] | ^$i(values = $i.values->map(v | $v->replaceVariableWithVariable($from, $to)))
])
}
function meta::external::dataquality::replaceVariableWithVariable(l:FunctionDefinition[1], from:String[1], to:String[1]):FunctionDefinition[1]
{
^$l(expressionSequence = $l.expressionSequence->replaceVariableWithVariable($from, $to))
}
function meta::external::dataquality::replaceVariableWithVariable(a:Any[1], from:String[1], to:String[1]):Any[1]
{
$a->match([
v:ValueSpecification[1] | $v->replaceVariableWithVariable($from, $to),
l:LambdaFunction[1] | $l->replaceVariableWithVariable($from, $to),
a:Any[1] | $a
])
}
function meta::external::dataquality::generateConstraintNegatedQuery(c:Class[1], f: FunctionExpression[1], constraint: Constraint[1]):FunctionExpression[1]
{
let constraintExprSequence = $constraint.functionDefinition.expressionSequence->evaluateAndDeactivate()->toOne();
let negatedExprSequence = $constraintExprSequence->negatedFunctionExpression();
^SimpleFunctionExpression
(
func = filter_T_MANY__Function_1__T_MANY_,
multiplicity = ZeroMany,
genericType = ^GenericType(rawType = $c),
importGroup = system::imports::coreImport,
parametersValues =
[ $f,
^InstanceValue (
genericType = $constraint.functionDefinition.classifierGenericType->toOne(),
multiplicity = PureOne,
values = lambda(functionType('x', $c, PureOne, Boolean, ZeroMany), $negatedExprSequence->evaluateAndDeactivate()->replaceVariableWithVariable('this', 'x'))
)
]
)->evaluateAndDeactivate();
}
function <> {doc.doc = 'Genrates a "!$f" query'}
meta::external::dataquality::negatedFunctionExpression(f: ValueSpecification[1]):ValueSpecification[1]
{
if($f->instanceOf(SimpleFunctionExpression) && $f->cast(@SimpleFunctionExpression).func->evaluateAndDeactivate() == not_Boolean_1__Boolean_1_,
| $f->cast(@SimpleFunctionExpression).parametersValues->evaluateAndDeactivate()->at(0),
| ^SimpleFunctionExpression
(
func = not_Boolean_1__Boolean_1_, //native function meta::pure::functions::boolean::not(bool:Boolean[1]):Boolean[1];
multiplicity = PureOne,
genericType = ^GenericType(rawType = Boolean),
importGroup = system::imports::coreImport,
parametersValues = $f
)->evaluateAndDeactivate()
)
}
function {doc.doc = 'Generates a OR query'}
meta::external::dataquality::orFunctionExpression(f1: ValueSpecification[1], f2: ValueSpecification[1]):ValueSpecification[1]
{
^SimpleFunctionExpression
(
func = meta::pure::functions::boolean::or_Boolean_1__Boolean_1__Boolean_1_ , // meta::pure::functions::boolean::or **use OR**
multiplicity = PureOne,
genericType = ^GenericType(rawType = Boolean), // check types
importGroup = system::imports::coreImport,
parametersValues = [$f1, $f2]
)->evaluateAndDeactivate();
}
function {doc.doc = 'Generates a AND query'}
meta::external::dataquality::andFunctionExpression(f1: ValueSpecification[1], f2: ValueSpecification[1]):ValueSpecification[1]
{
^SimpleFunctionExpression
(
func = meta::pure::functions::boolean::and_Boolean_1__Boolean_1__Boolean_1_ ,
multiplicity = PureOne,
genericType = ^GenericType(rawType = Boolean),
importGroup = system::imports::coreImport,
parametersValues = [$f1, $f2]
)->evaluateAndDeactivate();
}
function meta::external::dataquality::getMappingAndRuntime(context: DataQualityExecutionContext[1]):Pair[1] {
if($context->instanceOf(MappingAndRuntimeDataQualityExecutionContext),
| let mappingAndRuntimeContext = $context->cast(@MappingAndRuntimeDataQualityExecutionContext);
^Pair(first=$mappingAndRuntimeContext.mapping, second=$mappingAndRuntimeContext.runtime);,
| let dataSpaceDataQualityExecutionContext = $context->cast(@DataSpaceDataQualityExecutionContext);
let dataSpaceExecutionContext = $dataSpaceDataQualityExecutionContext.dataSpace.executionContexts->filter(execContext| $execContext.name == $dataSpaceDataQualityExecutionContext.contextName)->toOne();
^Pair(first=$dataSpaceExecutionContext.mapping, second=$dataSpaceExecutionContext.defaultRuntime.runtimeValue);
);
}
function meta::external::dataquality::recordQualifiedProperties(tree:GraphFetchTree[1], path:List[1]): GraphFetchTree[1]
{
if($path.values->isEmpty(),
| $tree,
{|
let head = $path.values->at(0);
let tail = if($head.property->instanceOf(QualifiedProperty),
| list($head.nestedQualifierReturn.values->tail()->concatenate($path.values->tail())),
| list($path.values->tail())
);
let nextProperty = if($head.property->instanceOf(QualifiedProperty),
| $head.nestedQualifierReturn.values->first().property,
| $head.property
);
let withQp = if($head.property->instanceOf(QualifiedProperty),
{|
let qp = $head.property->cast(@QualifiedProperty);
$tree->match([
ergft: ExtendedRootGraphFetchTree[1] | ^$ergft(requiredQualifiedProperties=$ergft.requiredQualifiedProperties->concatenate($qp)->removeDuplicates()),
epgft: ExtendedPropertyGraphFetchTree[1] | ^$epgft(requiredQualifiedProperties=$epgft.requiredQualifiedProperties->concatenate($qp)->removeDuplicates()),
rgft : RootGraphFetchTree[1] | ^ExtendedRootGraphFetchTree(requiredQualifiedProperties=$qp, class=$rgft.class, subTrees=$rgft.subTrees),
pgft : PropertyGraphFetchTree[1] | ^ExtendedPropertyGraphFetchTree(requiredQualifiedProperties=$qp, property=$pgft.property, subTrees=$pgft.subTrees)
]);
},
| $tree;
);
^$withQp(subTrees=$tree.subTrees->cast(@PropertyGraphFetchTree)->map(st|if($st.property == $nextProperty, |$st->meta::external::dataquality::recordQualifiedProperties($tail), |$st)));
}
);
}
function meta::external::dataquality::getEnrichedTreeForStructuralValidations(validationTree:meta::external::dataquality::DataQualityRootGraphFetchTree[1]): RootGraphFetchTree[1]
{
// 1. enrich tree with selected constraint properties
$validationTree->ensureFunctionRequirementsForDataQuality($validationTree.constraints, $validationTree.class, [], true)->cast(@RootGraphFetchTree);
}
function meta::external::dataquality::generateDQMetaDataForDQValidation(dataquality:meta::external::dataquality::DataQuality[1]): DataQualityRule[*]
{
let enrichedTree = ensureFunctionRequirementsForDataQuality($dataquality.validationTree, $dataquality.validationTree.constraints, $dataquality.validationTree.class, [], true)->cast(@RootGraphFetchTree);
$dataquality.validationTree->nodeToDqRule(true, '')->concatenate($enrichedTree->nodeToDqRule(false, ''));
}
function meta::external::dataquality::nodeToDqRule(node:GraphFetchTree[1], processOnlyConstraints:Boolean[1], path:String[*]):DataQualityRule[*]
{
let dqRules = $node->match([
dr: DataQualityRootGraphFetchTree[1] | $dr->rootNodeToDqRule($processOnlyConstraints),
dp: DataQualityPropertyGraphFetchTree[1] | $dp->propertyNodeToDqRule($processOnlyConstraints, $path),
r : RootGraphFetchTree[1] | $r->rootNodeToDqRule($processOnlyConstraints),
p : PropertyGraphFetchTree[1] | $p->propertyNodeToDqRule($processOnlyConstraints, $path)
]);
$dqRules->concatenate($node.subTrees->map(st|$st->nodeToDqRule($processOnlyConstraints, if ($dqRules->isEmpty(), | [], | $dqRules->at(0).propertyPath))));
}
function <> meta::external::dataquality::rootNodeToDqRule(node:RootGraphFetchTree[1], processOnlyConstraints: Boolean[1]):DataQualityRule[*]
{
if ( $processOnlyConstraints,
| $node->cast(@DataQualityRootGraphFetchTree).constraints->map(c|$c->constraintToDqRule($node.class.name->toOne())),
| ^DataQualityRule(constraintName=$node.class.name->toOne(), constraintGrammar='Class', constraintType='Alloy_Class_Validation', propertyPath=$node.class.name->toOne())
);
}
function <> meta::external::dataquality::propertyNodeToDqRule(node:PropertyGraphFetchTree[1], processOnlyConstraints: Boolean[1], path:String[*]):DataQualityRule[*]
{
if ( $processOnlyConstraints,
| $node->cast(@DataQualityPropertyGraphFetchTree).constraints->map(c|$c->constraintToDqRule($path->concatenate($node.property.name->toOne())->joinStrings('::'))),
| ^DataQualityRule(constraintName=$node.property.name->toOne(), constraintGrammar=$node.property.multiplicity->printMultiplicity(), constraintType='Alloy_Structural_Validation', propertyPath=$path->concatenate($node.property.name->toOne())->joinStrings('::'))
);
}
function <> meta::external::dataquality::constraintToDqRule(constraint:Constraint[1], path:String[1]):DataQualityRule[1]
{
^DataQualityRule(constraintName=$constraint.name->toOne(), constraintGrammar=$constraint.functionDefinition->replaceVariableWithVariable('this', 'x')->meta::pure::metamodel::serialization::grammar::printFunctionDefinitionExpressions('')->toOne(), constraintType='Alloy_Constraint_Validation', propertyPath=$path);
}
function meta::external::dataquality::generateDataqualityRelationValidationLambda(dqRelationValidation: meta::external::dataquality::DataQualityRelationValidation[1], validationName: String[1], resultLimit:Integer[0..1]): LambdaFunction[1]
{
$dqRelationValidation->generateDataqualityRelationValidationLambda($validationName, $resultLimit, true);
}
function meta::external::dataquality::generateDataqualityRelationValidationLambda(dqRelationValidation: meta::external::dataquality::DataQualityRelationValidation[1], validationName: String[1], resultLimit:Integer[0..1], useFrom:Boolean[1]): LambdaFunction[1]
{
let lambda = $dqRelationValidation.query;
let relationType = $dqRelationValidation.query->evaluateAndDeactivate()->functionReturnType().typeArguments.rawType->toOne();
let withValidationFilterExpression = $dqRelationValidation->buildRelationFilterExpression($validationName, $relationType);
let withLimitExpression = if($resultLimit->isEmpty(),
| $withValidationFilterExpression,
| $withValidationFilterExpression->buildLimitFilterExpression($resultLimit->toOne(), ^GenericType(rawType=Relation, typeArguments = ^GenericType(rawType=$relationType)))
);
let withFromRuntimeExpression = if(!$useFrom || $dqRelationValidation.runtime->isEmpty(),
| $withLimitExpression,
| $withLimitExpression->buildFromRuntimeExpression($dqRelationValidation.runtime->toOne(), ^GenericType(rawType=Relation, typeArguments = ^GenericType(rawType=$relationType)))
);
^$lambda(expressionSequence=$withFromRuntimeExpression);
}
function meta::external::dataquality::buildRelationFilterExpression(dqRelationValidation: meta::external::dataquality::DataQualityRelationValidation[1], validationName: String[1], relationType:Type[1]):FunctionExpression[1]
{
let assertion = $dqRelationValidation.validations->filter(val| $val.name == $validationName)->toOne().assertion;
^SimpleFunctionExpression
(
func = filter_Relation_1__Function_1__Relation_1_,
multiplicity = PureOne,
genericType = ^GenericType(rawType=Relation, typeArguments = ^GenericType(rawType=$relationType)),
importGroup = system::imports::coreImport,
parametersValues =
[ $dqRelationValidation.query->evaluateAndDeactivate()->toOne().expressionSequence->toOne(),
^InstanceValue (
genericType = ^GenericType(rawType=LambdaFunction, typeArguments=^GenericType(rawType=^FunctionType(parameters=^VariableExpression(name='validationFilter', genericType=^GenericType(rawType=$relationType), multiplicity=PureOne), returnMultiplicity=PureOne, returnType=^GenericType(rawType=Boolean)))),
multiplicity = PureOne,
values = meta::external::dataquality::lambda(^FunctionType(returnMultiplicity = PureOne, returnType = ^GenericType(rawType = Boolean), parameters = [^VariableExpression(multiplicity=PureOne,genericType=^GenericType(rawType=$relationType),name=$assertion->meta::pure::metamodel::serialization::grammar::printLambdaParameters())]),
$assertion.expressionSequence->evaluateAndDeactivate()->toOne()->negatedFunctionExpression())
)
]
)->evaluateAndDeactivate();
}
function meta::external::dataquality::buildLimitFilterExpression(f: FunctionExpression[1], limit: Integer[1], returnType:GenericType[1]):FunctionExpression[1]
{
^SimpleFunctionExpression(func=take_T_MANY__Integer_1__T_MANY_,
parametersValues=[$f, ^InstanceValue(values=$limit->toOne(), genericType=^GenericType(rawType=Integer), multiplicity=PureOne)],
functionName=take_T_MANY__Integer_1__T_MANY_.name,
genericType=$returnType,
multiplicity = ZeroMany,
importGroup=system::imports::coreImport)->evaluateAndDeactivate();
}
function meta::external::dataquality::buildFromRuntimeExpression(f: FunctionExpression[1], runtime: Runtime[1], returnType:GenericType[1]):FunctionExpression[1]
{
^SimpleFunctionExpression(func=from_T_m__Runtime_1__T_m_,
functionName=from_T_m__Runtime_1__T_m_.name,
importGroup=system::imports::coreImport,
genericType=$returnType,
multiplicity=$f.multiplicity,
parametersValues=[$f, ^InstanceValue(values=$runtime->evaluateAndDeactivate(), genericType=$runtime->genericType(), multiplicity=PureOne)]->evaluateAndDeactivate());
}
function meta::external::dataquality::isFromFunctionPresent(func: FunctionDefinition[1]):Boolean[1]
{
let getExprList = $func->findExpressionsForFunctionInFunctionDefinition([meta::pure::mapping::from_T_m__Runtime_1__T_m_]);
!$getExprList->isEmpty();
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy