diff --git a/src/main/java/fr/inra/oresing/checker/ReferenceLineCheckerDisplay.java b/src/main/java/fr/inra/oresing/checker/ReferenceLineCheckerDisplay.java new file mode 100644 index 0000000000000000000000000000000000000000..dfc37562218281444a27f609da8f62569806334f --- /dev/null +++ b/src/main/java/fr/inra/oresing/checker/ReferenceLineCheckerDisplay.java @@ -0,0 +1,30 @@ +package fr.inra.oresing.checker; + +import fr.inra.oresing.model.Datum; +import fr.inra.oresing.model.ReferenceDatum; +import fr.inra.oresing.model.ReferenceValue; +import fr.inra.oresing.rest.ValidationCheckResult; +import lombok.Value; + +import java.util.Set; + +@Value +public class ReferenceLineCheckerDisplay implements LineChecker { + ReferenceLineChecker referenceLineChecker; + ReferenceValue referenceValues; + + @Override + public ValidationCheckResult check(Datum values) { + return null; + } + + @Override + public Set<ValidationCheckResult> checkReference(ReferenceDatum referenceDatum) { + return null; + } + + @Override + public LineCheckerConfiguration getConfiguration() { + return null; + } +} \ No newline at end of file diff --git a/src/main/java/fr/inra/oresing/persistence/ReferenceValueRepository.java b/src/main/java/fr/inra/oresing/persistence/ReferenceValueRepository.java index 2fad2065be466c7cc64d14f16a1a225d2cbedca0..29fb39b6b2cd8c52539ecf9878ce6a2ecaf01a07 100644 --- a/src/main/java/fr/inra/oresing/persistence/ReferenceValueRepository.java +++ b/src/main/java/fr/inra/oresing/persistence/ReferenceValueRepository.java @@ -3,12 +3,7 @@ package fr.inra.oresing.persistence; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterators; -import fr.inra.oresing.model.Application; -import fr.inra.oresing.model.ReferenceColumn; -import fr.inra.oresing.model.ReferenceColumnSingleValue; -import fr.inra.oresing.model.ReferenceColumnValue; -import fr.inra.oresing.model.ReferenceDatum; -import fr.inra.oresing.model.ReferenceValue; +import fr.inra.oresing.model.*; import fr.inra.oresing.rest.ApplicationResult; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.config.ConfigurableBeanFactory; @@ -20,11 +15,7 @@ import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import java.sql.PreparedStatement; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.UUID; +import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Function; import java.util.stream.Collectors; @@ -79,26 +70,26 @@ public class ReferenceValueRepository extends JsonTableInApplicationSchemaReposi AtomicInteger i = new AtomicInteger(); // kv.value='LPF' OR t.refvalues @> '{"esp_nom":"ALO"}'::jsonb String cond = params.entrySet().stream().flatMap(e -> { - String k = e.getKey(); - if (StringUtils.equalsAnyIgnoreCase("_row_id_", k)) { - String collect = e.getValue().stream().map(v -> { + String k = e.getKey(); + if (StringUtils.equalsAnyIgnoreCase("_row_id_", k)) { + String collect = e.getValue().stream().map(v -> { + String arg = ":arg" + i.getAndIncrement(); + paramSource.addValue(arg, v); + return String.format("'%s'::uuid", v); + }) + .collect(Collectors.joining(", ")); + return Stream.ofNullable(String.format("array[id]::uuid[] <@ array[%s]::uuid[]", collect)); + } else if (StringUtils.equalsAnyIgnoreCase("any", k)) { + return e.getValue().stream().map(v -> { String arg = ":arg" + i.getAndIncrement(); paramSource.addValue(arg, v); - return String.format("'%s'::uuid", v); - }) - .collect(Collectors.joining(", ")); - return Stream.ofNullable(String.format("array[id]::uuid[] <@ array[%s]::uuid[]", collect)); - }else if (StringUtils.equalsAnyIgnoreCase("any", k)) { - return e.getValue().stream().map(v -> { - String arg = ":arg" + i.getAndIncrement(); - paramSource.addValue(arg, v); - return "kv.value=" + arg; - }); - } else { - return e.getValue().stream().map(v -> "t.refvalues @> '{\"" + k + "\":\"" + v + "\"}'::jsonb"); - } - }) - .filter(k->k!=null). + return "kv.value=" + arg; + }); + } else { + return e.getValue().stream().map(v -> "t.refvalues @> '{\"" + k + "\":\"" + v + "\"}'::jsonb"); + } + }) + .filter(k -> k != null). collect(Collectors.joining(" OR ")); if (StringUtils.isNotBlank(cond)) { @@ -121,7 +112,7 @@ public class ReferenceValueRepository extends JsonTableInApplicationSchemaReposi " )displays\n" + "where referencetype = :refType\n" + "group by naturalkey"; - Map<String, Map<String, String>> displayForNaturalKey = new HashMap<>(); + Map<String, Map<String, String>> displayForNaturalKey = new HashMap<>(); List result = getNamedParameterJdbcTemplate().query(query, new MapSqlParameterSource("refType", refType), getJsonRowMapper()); for (Object o : result) { final Map<String, List<Map<String, String>>> o1 = (Map<String, List<Map<String, String>>>) o; @@ -143,14 +134,18 @@ public class ReferenceValueRepository extends JsonTableInApplicationSchemaReposi public List<List<String>> findReferenceValue(String refType, String column) { AtomicInteger ai = new AtomicInteger(0); + final MapSqlParameterSource mapSqlParameterSource = new MapSqlParameterSource("applicationId", getApplication().getId()).addValue("refType", refType); String select = Stream.of(column.split(",")) - .map(c -> String.format("refValues->>'%1$s' as \"%1$s"+ai.getAndIncrement()+"\"", new StringBuilder(), c, false)) + .map(c -> { + mapSqlParameterSource.addValue("v" + ai.get(), c); + return "refValues->>:v" + ai.get() + " as \"%1$s" + ai.getAndIncrement() + "\""; + }) .collect(Collectors.joining(", ")); String sqlPattern = " SELECT %s " + " FROM " + getTable().getSqlIdentifier() + " t" + " WHERE application=:applicationId::uuid AND referenceType=:refType"; String query = String.format(sqlPattern, select); - List<List<String>> result = getNamedParameterJdbcTemplate().queryForList(query, new MapSqlParameterSource("applicationId", getApplication().getId()).addValue("refType", refType)) + List<List<String>> result = getNamedParameterJdbcTemplate().queryForList(query, mapSqlParameterSource) .stream() .map(m -> m.values().stream().map(v -> (String) v).collect(Collectors.toList())) .collect(Collectors.toList()); @@ -179,10 +174,10 @@ public class ReferenceValueRepository extends JsonTableInApplicationSchemaReposi return findAllByReferenceType(referenceType).stream().collect(ImmutableMap.toImmutableMap(ReferenceValue::getHierarchicalKey, ReferenceValue::getId)); } - public List<ApplicationResult.ReferenceSynthesis> buildReferenceSynthesis(){ + public List<ApplicationResult.ReferenceSynthesis> buildReferenceSynthesis() { String query = "select \n" + "referencetype referenceType, count(*) lineCount \n" + - "from "+getTable().getSqlIdentifier()+"\n" + + "from " + getTable().getSqlIdentifier() + "\n" + "group by referencetype"; return getNamedParameterJdbcTemplate().query(query, ImmutableMap.of(), BeanPropertyRowMapper.newInstance(ApplicationResult.ReferenceSynthesis.class)); } @@ -196,8 +191,33 @@ public class ReferenceValueRepository extends JsonTableInApplicationSchemaReposi , "where id in (:ids)" , "ON CONFLICT ON CONSTRAINT \"Reference_Reference_PK\" DO NOTHING" ); - String sql = String.join(";", insertSql, deleteSql); + String sql = String.join(";", deleteSql, insertSql); Iterators.partition(uuids.stream().iterator(), Short.MAX_VALUE - 1) .forEachRemaining(uuidsByBatch -> getNamedParameterJdbcTemplate().execute(sql, ImmutableMap.of("ids", uuidsByBatch), PreparedStatement::execute)); } -} + + public Map<Ltree, List<ReferenceValue>> getReferenceDisplaysById(Set<String> listOfIds) { + if(listOfIds.isEmpty()){ + return new HashMap<>(); + } + String sql = "SELECT DISTINCT '" + ReferenceValue.class.getName() + "' as \"@class\", to_jsonb(r) as json \n" + + "from "+getSchema().getSqlIdentifier()+".data_reference dr\n" + + "join "+getSchema().getSqlIdentifier()+".\"data\" d on dr.dataid = d.id\n" + + "join "+getTable().getSqlIdentifier()+" r on dr.referencedby = r.id\n"+ + "where d.rowid in (:list)"; + final List<ReferenceValue> list = getNamedParameterJdbcTemplate() + .query(sql, new MapSqlParameterSource().addValue("list", listOfIds), getJsonRowMapper()); + final Map<Ltree, List<ReferenceValue>> referencesValuesMap = list.stream() + .collect(Collectors.groupingBy( + ReferenceValue::getNaturalKey + ) + ); + referencesValuesMap.putAll(list.stream() + .collect(Collectors.groupingBy( + ReferenceValue::getHierarchicalKey + ) + ) + ); + return referencesValuesMap; + } +} \ No newline at end of file diff --git a/src/main/java/fr/inra/oresing/rest/GetDataResult.java b/src/main/java/fr/inra/oresing/rest/GetDataResult.java index bbe42c63d47a02b2b41ed2ec7d133d34f2563109..aed1657bbbb952f559af0a424d1baa432a8bfbb1 100644 --- a/src/main/java/fr/inra/oresing/rest/GetDataResult.java +++ b/src/main/java/fr/inra/oresing/rest/GetDataResult.java @@ -1,8 +1,6 @@ package fr.inra.oresing.rest; -import com.google.common.collect.ImmutableSet; import fr.inra.oresing.checker.LineChecker; -import fr.inra.oresing.model.VariableComponentKey; import fr.inra.oresing.persistence.DataRow; import lombok.Value; @@ -16,5 +14,4 @@ public class GetDataResult { List<DataRow> rows; Long totalRows; Map<String, Map<String, LineChecker>> checkedFormatVariableComponents; - Map<String, Map<String, Map<String, String>>> entitiesTranslations; -} +} \ No newline at end of file diff --git a/src/main/java/fr/inra/oresing/rest/OreSiResources.java b/src/main/java/fr/inra/oresing/rest/OreSiResources.java index 93181ce63529dcec484be0dc57cb52c71eaf9657..1cc3db7c6b78b475d91885049002422bd8c674bd 100644 --- a/src/main/java/fr/inra/oresing/rest/OreSiResources.java +++ b/src/main/java/fr/inra/oresing/rest/OreSiResources.java @@ -5,9 +5,12 @@ import com.google.common.base.Preconditions; import com.google.common.collect.*; import fr.inra.oresing.checker.InvalidDatasetContentException; import fr.inra.oresing.checker.LineChecker; +import fr.inra.oresing.checker.ReferenceLineChecker; +import fr.inra.oresing.checker.ReferenceLineCheckerDisplay; import fr.inra.oresing.model.*; import fr.inra.oresing.model.chart.OreSiSynthesis; import fr.inra.oresing.persistence.DataRow; +import fr.inra.oresing.persistence.Ltree; import fr.inra.oresing.persistence.OreSiRepository; import org.assertj.core.util.Strings; import org.springframework.beans.factory.annotation.Autowired; @@ -286,8 +289,23 @@ public class OreSiResources { .collect(ImmutableSet.toImmutableSet()); Long totalRows = list.stream().limit(1).map(dataRow -> dataRow.getTotalRows()).findFirst().orElse(-1L); Map<String, Map<String, LineChecker>> checkedFormatVariableComponents = service.getcheckedFormatVariableComponents(nameOrId, dataType); - Map<String, Map<String, Map<String, String>>> entitiesTranslation = service.getEntitiesTranslation(nameOrId, locale, dataType, checkedFormatVariableComponents); - return ResponseEntity.ok(new GetDataResult(variables, list, totalRows, checkedFormatVariableComponents, entitiesTranslation)); + final Set<String> listOfDataIds = list.stream() + .map(DataRow::getRowId) + .collect(Collectors.toSet()); + Map<Ltree, List<ReferenceValue>> requiredreferencesValues = service.getReferenceDisplaysById(service.getApplication(nameOrId), listOfDataIds); + for (Map.Entry<String, LineChecker> referenceCheckersByVariableComponentKey : checkedFormatVariableComponents.get(ReferenceLineChecker.class.getSimpleName()).entrySet()) { + String variableComponentKey = referenceCheckersByVariableComponentKey.getKey(); + ReferenceLineChecker referenceLineChecker = (ReferenceLineChecker) referenceCheckersByVariableComponentKey.getValue(); + for (Map.Entry<Ltree, UUID> ltreeUUIDEntry : referenceLineChecker.getReferenceValues().entrySet()) { + + final ReferenceValue referenceValue = requiredreferencesValues.getOrDefault(ltreeUUIDEntry.getKey(), List.of()) + .stream() + .findFirst().orElse(null); + checkedFormatVariableComponents.get(ReferenceLineChecker.class.getSimpleName()) + .put(variableComponentKey, new ReferenceLineCheckerDisplay(referenceLineChecker, referenceValue)); + } + } + return ResponseEntity.ok(new GetDataResult(variables, list, totalRows, checkedFormatVariableComponents)); } private LinkedHashSet<String> buildOrderedVariables(String nameOrId, String dataType) { diff --git a/src/main/java/fr/inra/oresing/rest/OreSiService.java b/src/main/java/fr/inra/oresing/rest/OreSiService.java index 7c74ceacf2bc6b472095869c321e3773538cb38f..5e8a320a4125d71d5650447d2c6b4e06b4d89af2 100644 --- a/src/main/java/fr/inra/oresing/rest/OreSiService.java +++ b/src/main/java/fr/inra/oresing/rest/OreSiService.java @@ -518,7 +518,7 @@ public class OreSiService { AtomicLong lines = new AtomicLong(); final Instant debut = Instant.now(); final DataRepository dataRepository = repo.getRepository(app).data(); - dataRepository + final List<UUID> uuids = dataRepository .storeAll( dataStream .filter(Objects::nonNull) @@ -528,6 +528,7 @@ public class OreSiService { } }) ); + dataRepository.updateConstraintForeigData(uuids); errors.addAll(uniquenessBuilder.getErrors()); InvalidDatasetContentException.checkErrorsIsEmpty(errors); } @@ -1394,6 +1395,10 @@ public class OreSiService { return repo.getRepository(application).referenceValue().buildReferenceSynthesis(); } + public Map<Ltree, List<ReferenceValue>> getReferenceDisplaysById(Application application, Set<String> listOfDataIds) { + return repo.getRepository(application).referenceValue(). getReferenceDisplaysById(listOfDataIds); + } + @Value private static class RowWithData { int lineNumber; diff --git a/ui/src/views/datatype/DataTypeTableView.vue b/ui/src/views/datatype/DataTypeTableView.vue index ec37b2e7d7ec52a7fbb5b548651b08b28b2c76d1..55c4a59fb89eea623da8bc5a00b609f022d0b465 100644 --- a/ui/src/views/datatype/DataTypeTableView.vue +++ b/ui/src/views/datatype/DataTypeTableView.vue @@ -546,6 +546,7 @@ export default class DataTypeTableView extends Vue { this.params ); this.referenceLineCheckers = dataTypes.checkedFormatVariableComponents.ReferenceLineChecker; + this.translations = dataTypes.entitiesTranslations; this.data; this.refsLinkedTo = dataTypes.rows.reduce((acc, d) => { @@ -604,26 +605,31 @@ export default class DataTypeTableView extends Vue { } getTranslation(row, component) { - let reference = component.checker.refType; - let translations = this.translations?.[reference]; - console.log(translations); let translation = row[component.variable][component.component]; return translation; } async getReferenceValues(row, component) { const rowId = this.getRefsLinkedToId(row, component); - const variable = component.checker.refType; + const refType = component.checker.referenceLineChecker.refType; + const key = component.key; if (!this.loadedReferences[rowId]) { - let params = { _row_id_: [rowId] }; - if (!variable) { - params.any = true; + let refvalues; + if (this.referenceLineCheckers[key]){ + refvalues = this.referenceLineCheckers[key].referenceValues.refValues.evaluationContext.datum } - const reference = await this.referenceService.getReferenceValues( - this.applicationName, - variable, - params - ); - const data = Object.entries(reference.referenceValues[0].values) + if (!refvalues){ + let params = { _row_id_: [rowId] }; + if (!refType) { + params.any = true; + } + const reference = await this.referenceService.getReferenceValues( + this.applicationName, + refType, + params + ); + refvalues = reference.referenceValues[0].values + } + const data = Object.entries(refvalues) .map((entry) => ({ colonne: entry[0], valeur: entry[1] })) .reduce((acc, entry) => { acc.push(entry); @@ -643,7 +649,7 @@ export default class DataTypeTableView extends Vue { }, ], active: true, - reference: variable, + reference: refType, }; this.loadedReferences = { ...this.loadedReferences, @@ -778,9 +784,10 @@ export default class DataTypeTableView extends Vue { getDisplay(row, variable, component) { var key = variable + "_" + component; var value = row[variable][component]; + var lang = '__display_'+localStorage.getItem('lang') if (this.referenceLineCheckers[key]) { - if (this.referenceLineCheckers[key].display) { - var display = this.referenceLineCheckers[key].display[value]; + if (this.referenceLineCheckers[key].referenceValue && this.referenceLineCheckers[key].referenceValue.refValues ) { + var display = this.referenceLineCheckers[key].referenceValue.refValues.evaluationContext.datum[lang]; return display ? display : value; } } @@ -895,4 +902,4 @@ $row-variable-height: 60px; .columns { margin: 0; } -</style> +</style> \ No newline at end of file