Skip to content

Commit

Permalink
feat: moved Expression rules to initialization
Browse files Browse the repository at this point in the history
  • Loading branch information
Nolife999 committed Oct 10, 2023
1 parent d66daa7 commit 460b0ae
Show file tree
Hide file tree
Showing 6 changed files with 226 additions and 162 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package fr.insee.arc.core.service.p0initialisation.metadata;

import java.sql.Connection;
import java.util.List;
import java.util.Optional;

import fr.insee.arc.core.dataobjects.ArcPreparedStatementBuilder;
import fr.insee.arc.core.dataobjects.ColumnEnum;
import fr.insee.arc.core.dataobjects.ViewEnum;
import fr.insee.arc.core.service.global.bo.JeuDeRegle;
import fr.insee.arc.core.service.p0initialisation.metadata.dao.ApplyExpressionRulesDao;
import fr.insee.arc.utils.exception.ArcException;
import fr.insee.arc.utils.structure.GenericBean;

public class ApplyExpressionRulesOperation {

public ApplyExpressionRulesOperation() {
this.dao = new ApplyExpressionRulesDao();
}

private ApplyExpressionRulesDao dao;

public Optional<String> loopInExpressionSet(GenericBean expressions){
return loopInExpressionSet(
expressions.mapContent().get(ColumnEnum.EXPR_NOM.getColumnName()),
expressions.mapContent().get(ColumnEnum.EXPR_VALEUR.getColumnName()));
}

/** Checks whether the name is a valid expression name.
* @param the list of expression names
* @param the list of expression values, matching the other list order
* @return an empty Optional if there is no loop,
* or the loop description if there is one*/
public Optional<String> loopInExpressionSet(List<String> names, List<String> values) {
String loop = null;
for (int i = 0; i < names.size(); i++) {
String name = names.get(i);
StringBuilder potentialLoop = new StringBuilder();
potentialLoop.append("@" + name + "@->");
if (loopInExpression(potentialLoop, values.get(i), names, values)) {
return Optional.of(potentialLoop.toString());
}
}
return Optional.ofNullable(loop);
}

private boolean loopInExpression(StringBuilder potentialLoop, String value, List<String> names, List<String> values) {
for (int i = 0; i < names.size(); i++) {
String name = names.get(i);
if (value.contains("@" + name.toLowerCase() + "@")) {
String arobasedName = "@" + name + "@";
if(potentialLoop.toString().contains(arobasedName)) {
potentialLoop.append(arobasedName);
return true;
}
potentialLoop.append(arobasedName + "->");
if (loopInExpression(potentialLoop, values.get(i), names, values)) {
return true;
}
}
}
return false;
}

public GenericBean fetchExpressions(Connection connexion, String environnement, JeuDeRegle ruleSet)
throws ArcException {
return dao.execQueryFetchExpressions(connexion, environnement, ruleSet);
}

public GenericBean fetchOrderedExpressions(Connection connexion, String environment,
JeuDeRegle ruleSet) throws ArcException {
return dao.execQueryFetchOrderedExpressions(connexion, environment, ruleSet);
}



public boolean isExpressionSyntaxPresentInControl(Connection connexion, String environment,
JeuDeRegle ruleSet) throws ArcException {
return isExpressionSyntaxPresent(connexion, ViewEnum.CONTROLE_REGLE.getFullName(environment), "condition", ruleSet)
|| isExpressionSyntaxPresent(connexion, ViewEnum.CONTROLE_REGLE.getFullName(environment), "pre_action", ruleSet);
}


public boolean isExpressionSyntaxPresentInMapping(Connection connexion, String environment, JeuDeRegle ruleSet) throws ArcException {
return isExpressionSyntaxPresent(connexion, ViewEnum.MAPPING_REGLE.getFullName(environment), "expr_regle_col", ruleSet);
}



private boolean isExpressionSyntaxPresent(Connection connexion, String table, String field, JeuDeRegle ruleSet) throws ArcException {
return dao.execQueryIsExpressionSyntaxPresent(connexion, table, field, ruleSet);
}

/** Returns a request applying the given expressions to the control rules of the given ruleset.*/
public ArcPreparedStatementBuilder applyExpressionsToControl(JeuDeRegle ruleSet, GenericBean expressions, String environment) {
return (ArcPreparedStatementBuilder) applyExpressionsTo(ruleSet, expressions, ViewEnum.CONTROLE_REGLE.getFullName(environment), "condition")
.append(applyExpressionsTo(ruleSet, expressions, ViewEnum.CONTROLE_REGLE.getFullName(environment), "pre_action"));
}


/** Returns a request applying the given expressions to the mapping rules of the given ruleset.*/
public ArcPreparedStatementBuilder applyExpressionsToMapping(JeuDeRegle ruleSet, GenericBean expressions, String environment) {
return applyExpressionsTo(ruleSet, expressions, ViewEnum.MAPPING_REGLE.getFullName(environment), "expr_regle_col");
}


private ArcPreparedStatementBuilder applyExpressionsTo(JeuDeRegle ruleSet, GenericBean expressions, String table, String field) {
return dao.applyExpressionsTo(ruleSet, expressions, table, field);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
import fr.insee.arc.core.service.global.scalability.ServiceScalability;
import fr.insee.arc.core.service.p0initialisation.dbmaintenance.BddPatcher;
import fr.insee.arc.core.service.p0initialisation.metadata.dao.SynchronizeRulesAndMetadataDao;
import fr.insee.arc.core.service.p5mapping.engine.ExpressionService;
import fr.insee.arc.utils.consumer.ThrowingConsumer;
import fr.insee.arc.utils.dao.CopyObjectsToDatabase;
import fr.insee.arc.utils.exception.ArcException;
Expand Down Expand Up @@ -169,7 +168,7 @@ private void applyExpressions() throws ArcException {
String anExecutionEnvironment = sandbox.getSchema();

// Checks expression validity
ExpressionService expressionService = new ExpressionService();
ApplyExpressionRulesOperation expressionService = new ApplyExpressionRulesOperation();
List<JeuDeRegle> allRuleSets = JeuDeRegleDao.recupJeuDeRegle(connexion, ViewEnum.JEUDEREGLE.getFullName(anExecutionEnvironment));
for (JeuDeRegle ruleSet : allRuleSets) {
// Check
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package fr.insee.arc.core.service.p0initialisation.metadata.dao;

import java.sql.Connection;

import fr.insee.arc.core.dataobjects.ArcPreparedStatementBuilder;
import fr.insee.arc.core.dataobjects.ColumnEnum;
import fr.insee.arc.core.service.global.bo.JeuDeRegle;
import fr.insee.arc.utils.dao.UtilitaireDao;
import fr.insee.arc.utils.exception.ArcException;
import fr.insee.arc.utils.structure.GenericBean;

public class ApplyExpressionRulesDao {


/** Fetch the expressions in order so that if expression A includes expression B, then A comes before B.
* It is highly recommended to check for loops beforehand.*/
public GenericBean execQueryFetchOrderedExpressions(Connection connexion, String environment,
JeuDeRegle ruleSet) throws ArcException {
ArcPreparedStatementBuilder request = new ArcPreparedStatementBuilder();
request.append("WITH recursive exprs AS (select expr_nom, expr_valeur from ");
request.append(environment);
request.append(".expression WHERE ");
request.append(ruleSet.getSqlEquals());
request.append("), \n tree (expr_nom, expr_valeur, level, path)\n");
request.append("AS (SELECT m.expr_nom, m.expr_valeur, 0, m.expr_nom \n");
request.append(" FROM exprs m \n");
request.append("WHERE 1 not in (select 1 from exprs \n");
request.append(" where expr_valeur like '%{@'||m.expr_nom||'@}%') \n");
request.append(" UNION ALL \n");
request.append(" SELECT sub.expr_nom, sub.expr_valeur, t.level + 1, t.path||'>'||sub.EXPR_NOM \n");
request.append(" FROM exprs sub \n");
request.append(" INNER JOIN tree t \n");
request.append(" ON t.expr_valeur like '%{@'||sub.expr_nom||'@}%' )\n");
request.append("select expr_nom, expr_valeur, level from tree\n");
return new GenericBean(
UtilitaireDao.get(0).executeRequest(connexion, request)
);
}


/**
* return the expressions rules
* @param connexion
* @param environnement
* @param ruleSet
* @return
* @throws ArcException
*/
public GenericBean execQueryFetchExpressions(Connection connexion, String environnement, JeuDeRegle ruleSet)
throws ArcException {
ArcPreparedStatementBuilder request = new ArcPreparedStatementBuilder();
request.append("select expr_nom, expr_valeur from ");
request.append(environnement);
request.append(".expression where ");
request.append(ruleSet.getSqlEquals());
return new GenericBean(
UtilitaireDao.get(0).executeRequest(connexion, request)
);
}

/**
* Test if an expression rule is find in a rule table
* @param connexion
* @param table
* @param field
* @param ruleSet
* @return
* @throws ArcException
*/
public boolean execQueryIsExpressionSyntaxPresent(Connection connexion, String table, String field, JeuDeRegle ruleSet) throws ArcException {
ArcPreparedStatementBuilder request = new ArcPreparedStatementBuilder();
request.append("select 1 from ");
request.append(table);
request.append(" where ");
request.append(ruleSet.getSqlEquals());
request.append(" and " + field + " ~ '(?<=\\{@)(.+?)(?=@\\})'");
return UtilitaireDao.get(0).hasResults(connexion, request);
}


/**
* Build the query to replace all expressions found in a field
* @param ruleSet : the selection on rules where to expressions will be replaced
* @param expressions : the expression list
* @param table : the target rule table
* @param field : the rule where replacement will be made
* @return
*/
public ArcPreparedStatementBuilder applyExpressionsTo(JeuDeRegle ruleSet, GenericBean expressions, String table, String field) {
ArcPreparedStatementBuilder request = new ArcPreparedStatementBuilder();
for (int i = 0; i < expressions.size(); i++) {
request.append("\n UPDATE "+ table + " ");
request.append("\n set " + field + "=replace(" + field + ", ");
request.append(request.quoteText("{@"+expressions.mapContent().get(ColumnEnum.EXPR_NOM.getColumnName()).get(i)+"@}"));
request.append(",");
request.append(request.quoteText(expressions.mapContent().get(ColumnEnum.EXPR_VALEUR.getColumnName()).get(i)));
request.append(") ");
request.append("\n WHERE " + field + " like '%{@%@}%' ");
request.append("\n AND ");
request.append(ruleSet.getSqlEquals());
request.append(";");
}
return request;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import fr.insee.arc.core.model.TraitementTableParametre;
import fr.insee.arc.core.service.global.bo.JeuDeRegle;
import fr.insee.arc.core.service.global.bo.Sandbox;
import fr.insee.arc.core.service.p5mapping.engine.ExpressionService;
import fr.insee.arc.core.service.p0initialisation.metadata.ApplyExpressionRulesOperation;
import fr.insee.arc.utils.dao.UtilitaireDao;
import fr.insee.arc.utils.dataobjects.TypeEnum;
import fr.insee.arc.utils.exception.ArcException;
Expand Down Expand Up @@ -349,13 +349,13 @@ public static GenericBean execQuerySelectMetaDataOnlyFrom(Connection coordinator
}


public void execQueryApplyExpressionsToControl(ExpressionService expressionService, JeuDeRegle ruleSet,
public void execQueryApplyExpressionsToControl(ApplyExpressionRulesOperation expressionService, JeuDeRegle ruleSet,
GenericBean expressions) throws ArcException {
UtilitaireDao.get(0).executeRequest(sandbox.getConnection(),
expressionService.applyExpressionsToControl(ruleSet, expressions, sandbox.getSchema()));
}

public void execQueryApplyExpressionsToMapping(ExpressionService expressionService, JeuDeRegle ruleSet,
public void execQueryApplyExpressionsToMapping(ApplyExpressionRulesOperation expressionService, JeuDeRegle ruleSet,
GenericBean expressions) throws ArcException {
UtilitaireDao.get(0).executeRequest(sandbox.getConnection(),
expressionService.applyExpressionsToMapping(ruleSet, expressions, sandbox.getSchema()));
Expand Down
Loading

0 comments on commit 460b0ae

Please sign in to comment.