From b3ee6b3a414d34e5e6a6ea354b40b4f6b2418395 Mon Sep 17 00:00:00 2001 From: Marc Maynou Date: Tue, 27 Feb 2024 18:31:17 +0100 Subject: [PATCH] Some refactor --- .../.idea/.gitignore | 3 + .../IntentSpecification2WorkflowGenerator.iml | 10 + .../api/api_main.py | 4 + .../api/temp_files/knime/Decision Tree 1.knwf | Bin 7516 -> 0 bytes .../api/temp_files/knime/Decision Tree 2.knwf | Bin 7509 -> 0 bytes .../api/temp_files/knime/Decision Tree 3.knwf | Bin 7491 -> 0 bytes .../dataset_annotator/annotator.py | 2 +- .../implementations/CSVBootstrap.java | 9 +- .../implementations/JSONBootstrap.java | 28 ++- .../implementations/SQLBootstrap.java | 5 +- .../upc/essi/dtim/nextiabs/utils/Utils.java | 37 ++++ .../NextiaDataLayer/dataLayer/DLDuckDB.java | 10 +- .../NextiaDataLayer/dataLayer/DLSpark.java | 2 +- .../NextiaDataLayer/dataLayer/DataLayer.java | 4 +- .../calculateQuality/CalculateQuality.java | 2 +- .../dataProducts/DataProductController.java | 29 +++ .../odin/dataProducts/DataProductService.java | 61 +++++- .../dtim/odin/datasets/DatasetService.java | 33 +++- .../nextiaDataLayer/DataLayerImpl.java | 5 +- .../nextiaDataLayer/DataLayerInterface.java | 2 +- .../nextiaQR/qrModuleImpl.java | 7 +- .../graphStore/GraphStoreInterface.java | 8 + .../graphStore/GraphStoreJenaImpl.java | 59 ++++++ .../odin/repositories/RepositoryService.java | 4 +- .../edu/upc/essi/dtim/odin/utils/Utils.java | 33 ++++ .../RepositoryForms/Local_Repository.json | 2 +- .../relationalStore/ORMStoreJpaImplTest.java | 178 +++++++++--------- frontend/src/api/dataProductsAPI.js | 6 + .../components/forms/ManualAlignmentsForm.vue | 3 - .../stepper/DatasetIntegrationStep.vue | 1 + .../components/tables/TableDataProducts.vue | 1 + .../components/tables/TableQueryResult.vue | 36 ---- frontend/src/pages/Query.vue | 15 +- frontend/src/stores/dataProductsStore.js | 27 ++- frontend/src/stores/integrationStore.js | 35 ++-- frontend/src/stores/intentsStore.js | 2 +- 36 files changed, 474 insertions(+), 189 deletions(-) create mode 100644 Modules/IntentSpecification2WorkflowGenerator/.idea/.gitignore create mode 100644 Modules/IntentSpecification2WorkflowGenerator/.idea/IntentSpecification2WorkflowGenerator.iml delete mode 100644 Modules/IntentSpecification2WorkflowGenerator/api/temp_files/knime/Decision Tree 1.knwf delete mode 100644 Modules/IntentSpecification2WorkflowGenerator/api/temp_files/knime/Decision Tree 2.knwf delete mode 100644 Modules/IntentSpecification2WorkflowGenerator/api/temp_files/knime/Decision Tree 3.knwf create mode 100644 Modules/NextiaBS/src/main/java/edu/upc/essi/dtim/nextiabs/utils/Utils.java diff --git a/Modules/IntentSpecification2WorkflowGenerator/.idea/.gitignore b/Modules/IntentSpecification2WorkflowGenerator/.idea/.gitignore new file mode 100644 index 00000000..26d33521 --- /dev/null +++ b/Modules/IntentSpecification2WorkflowGenerator/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/Modules/IntentSpecification2WorkflowGenerator/.idea/IntentSpecification2WorkflowGenerator.iml b/Modules/IntentSpecification2WorkflowGenerator/.idea/IntentSpecification2WorkflowGenerator.iml new file mode 100644 index 00000000..74d515a0 --- /dev/null +++ b/Modules/IntentSpecification2WorkflowGenerator/.idea/IntentSpecification2WorkflowGenerator.iml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/Modules/IntentSpecification2WorkflowGenerator/api/api_main.py b/Modules/IntentSpecification2WorkflowGenerator/api/api_main.py index 6f2d4370..16d04414 100644 --- a/Modules/IntentSpecification2WorkflowGenerator/api/api_main.py +++ b/Modules/IntentSpecification2WorkflowGenerator/api/api_main.py @@ -104,6 +104,10 @@ def download_knime(): plan_graph = Graph().parse(data=request.json.get("graph", ""), format='turtle') ontology = Graph().parse(data=request.json.get('ontology', ''), format='turtle') + plan_graph.print() + print("--------------") + # ontology.print() + file_path = os.path.join(files_folder, f'{uuid.uuid4()}.ttl') plan_graph.serialize(file_path, format='turtle') diff --git a/Modules/IntentSpecification2WorkflowGenerator/api/temp_files/knime/Decision Tree 1.knwf b/Modules/IntentSpecification2WorkflowGenerator/api/temp_files/knime/Decision Tree 1.knwf deleted file mode 100644 index 33c8b37dcc523a53a54bb9eeb37da760f5fa93b5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7516 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 Zpqk>V-%9`h0P**2@LNfb{{4ess!FK=v diff --git a/Modules/IntentSpecification2WorkflowGenerator/api/temp_files/knime/Decision Tree 2.knwf b/Modules/IntentSpecification2WorkflowGenerator/api/temp_files/knime/Decision Tree 2.knwf deleted file mode 100644 index 28c2c55cbe4d5033026671cf67fa7e3eea5ac6e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7509 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

42mk~T{?8hv@8#(I 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 VC;bNiQ2yLTe}?J7zqY1;{{^4#aUK8w diff --git a/Modules/IntentSpecification2WorkflowGenerator/api/temp_files/knime/Decision Tree 3.knwf b/Modules/IntentSpecification2WorkflowGenerator/api/temp_files/knime/Decision Tree 3.knwf deleted file mode 100644 index 38d0d4df11def4d740a492aa1b5633fc39e21dc5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7491 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 diff --git a/Modules/IntentSpecification2WorkflowGenerator/dataset_annotator/annotator.py b/Modules/IntentSpecification2WorkflowGenerator/dataset_annotator/annotator.py index b4acf7d3..72beaf5e 100644 --- a/Modules/IntentSpecification2WorkflowGenerator/dataset_annotator/annotator.py +++ b/Modules/IntentSpecification2WorkflowGenerator/dataset_annotator/annotator.py @@ -10,7 +10,7 @@ def add_dataset_info(dataset_path, graph, label): dataset_node = ab.term(path.basename(dataset_path)) graph.add((dataset_node, RDF.type, dmop.TabularDataset)) - dataset = pd.read_csv(dataset_path) + dataset = pd.read_csv(dataset_path, encoding='latin', delimiter=";") add_csv_info(dataset_path, dataset, dataset_node, graph) add_column_info(dataset_path, dataset, dataset_node, graph, label) diff --git a/Modules/NextiaBS/src/main/java/edu/upc/essi/dtim/nextiabs/implementations/CSVBootstrap.java b/Modules/NextiaBS/src/main/java/edu/upc/essi/dtim/nextiabs/implementations/CSVBootstrap.java index 0040ee88..a702ffaf 100644 --- a/Modules/NextiaBS/src/main/java/edu/upc/essi/dtim/nextiabs/implementations/CSVBootstrap.java +++ b/Modules/NextiaBS/src/main/java/edu/upc/essi/dtim/nextiabs/implementations/CSVBootstrap.java @@ -17,9 +17,12 @@ import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; +import java.util.Arrays; +import java.util.Objects; import java.util.stream.Collectors; import static edu.upc.essi.dtim.nextiabs.utils.DF_MMtoRDFS.productionRulesDataframe_to_RDFS; +import static edu.upc.essi.dtim.nextiabs.utils.Utils.reformatName; /** * Generates an RDFS-compliant representation of a CSV file schema @@ -58,15 +61,15 @@ public Graph bootstrapSchema(Boolean generateMetadata) { G_target.addTriple(createIRI(name), RDF.type, DataFrame_MM.DataFrame); G_target.addTripleLiteral(createIRI(name), RDFS.label, name); parser.getHeaderNames().forEach(h -> { - String h2 = h.replace("\"", "").trim(); + String h2 = reformatName(h); G_target.addTriple(createIRI(h2),RDF.type,DataFrame_MM.Data); G_target.addTripleLiteral(createIRI(h2), RDFS.label,h2 ); G_target.addTriple(createIRI(name),DataFrame_MM.hasData,createIRI(h2)); G_target.addTriple(createIRI(h2),DataFrame_MM.hasDataType,DataFrame_MM.String); }); - String select = parser.getHeaderNames().stream().map(a -> a + " AS `" + a.replace(".","_") + "`").collect(Collectors.joining(", ")); - wrapper = "SELECT " + select + " FROM " + name; + String select = parser.getHeaderNames().stream().map(a -> a + " AS " + reformatName(a)).collect(Collectors.joining(", ")); + wrapper = "SELECT " + select + " FROM `" + name + "`"; //TODO: implement metadata // if(generateMetadata) diff --git a/Modules/NextiaBS/src/main/java/edu/upc/essi/dtim/nextiabs/implementations/JSONBootstrap.java b/Modules/NextiaBS/src/main/java/edu/upc/essi/dtim/nextiabs/implementations/JSONBootstrap.java index 4a24fe2a..14937ec0 100644 --- a/Modules/NextiaBS/src/main/java/edu/upc/essi/dtim/nextiabs/implementations/JSONBootstrap.java +++ b/Modules/NextiaBS/src/main/java/edu/upc/essi/dtim/nextiabs/implementations/JSONBootstrap.java @@ -14,10 +14,7 @@ import org.apache.commons.compress.utils.Lists; import org.apache.commons.lang3.tuple.Pair; -import javax.json.Json; -import javax.json.JsonArray; -import javax.json.JsonObject; -import javax.json.JsonValue; +import javax.json.*; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; @@ -27,6 +24,7 @@ import java.util.stream.Collectors; import static edu.upc.essi.dtim.nextiabs.utils.DF_MMtoRDFS.productionRulesDataframe_to_RDFS; +import static edu.upc.essi.dtim.nextiabs.utils.Utils.reformatName; public class JSONBootstrap extends DataSource implements IBootstrap, BootstrapODIN { // Using DataFrame_MM and without Jena @@ -67,7 +65,7 @@ public Graph bootstrapSchema(Boolean generateMetadata) { String SELECT = attributesSWJ.entrySet().stream().map( p -> { if (p.getKey().equals(p.getValue().getKey())) return p.getValue().getPath() + " AS `" + p.getKey() + "`"; - return p.getValue().getPath() + " AS `" + p.getValue().getLabel() + "`"; + return p.getValue().getPath() + " AS " + reformatName(p.getValue().getLabel()); }).collect(Collectors.joining(", ")); @@ -76,8 +74,8 @@ public Graph bootstrapSchema(Boolean generateMetadata) { // System.out.println(s.getLeft() + " ---- " + s.getRight()); // } - String LATERAL = lateralViews.stream().map(p -> "LATERAL VIEW explode(" + p.getLeft() + ") AS " + p.getRight()).collect(Collectors.joining("\n")); - wrapper = "SELECT " + SELECT + " FROM " + name + " " + LATERAL; + String LATERAL = lateralViews.stream().map(p -> "LATERAL VIEW explode(" + p.getLeft() + ") AS " + reformatName(p.getRight())).collect(Collectors.joining("\n")); + wrapper = "SELECT " + SELECT + " FROM `" + name + "` " + LATERAL; //generateMetadata(); @@ -128,9 +126,21 @@ private void Document(String path, String D) { throw new RuntimeException("File not found"); } - G_source.addTriple(createIRI(D), RDF.type, DataFrame_MM.DataSource); - Object(Json.createReader(fis).readValue().asJsonObject(),new JSON_Aux(D,"","")); + // Step 1: Read data from fis and store it in a JSON array + JsonReader reader = Json.createReader(fis); + JsonArray jsonArray = reader.readArray(); + reader.close(); + // Step 2: Extract the JSON object from the JSON array + if (jsonArray.size() > 0) { + JsonObject jsonObject = jsonArray.getJsonObject(0); // Assuming jsonArray contains only one object + System.out.println(jsonObject); + + // Step 3: Call the object method with the JSON object + Object(jsonObject, new JSON_Aux(D, "", "")); + } else { + throw new RuntimeException("Empty JSON array"); + } } private void DataType(JsonValue D, JSON_Aux p) { diff --git a/Modules/NextiaBS/src/main/java/edu/upc/essi/dtim/nextiabs/implementations/SQLBootstrap.java b/Modules/NextiaBS/src/main/java/edu/upc/essi/dtim/nextiabs/implementations/SQLBootstrap.java index c63b6d15..12fa020b 100644 --- a/Modules/NextiaBS/src/main/java/edu/upc/essi/dtim/nextiabs/implementations/SQLBootstrap.java +++ b/Modules/NextiaBS/src/main/java/edu/upc/essi/dtim/nextiabs/implementations/SQLBootstrap.java @@ -18,6 +18,7 @@ import java.util.List; import static edu.upc.essi.dtim.nextiabs.utils.DF_MMtoRDFS.productionRulesDataframe_to_RDFS; +import static edu.upc.essi.dtim.nextiabs.utils.Utils.reformatName; /** * Generates an instance of a DataFrame_Metamodel representation of a postgresSQL database @@ -58,10 +59,10 @@ public Graph bootstrapSchema(Boolean generateMetadata) { List columns = new LinkedList<>(); for (Pair col: tableData.getColumns()) { - columns.add(col.getLeft() + " AS `" + col.getLeft() + "`"); + columns.add(col.getLeft() + " AS " + reformatName(col.getLeft())); } String columnNames = String.join(", ", columns); - wrapper = "SELECT " + columnNames + " FROM " + tableName; + wrapper = "SELECT " + columnNames + " FROM `" + tableName + "`"; if (generateMetadata) { generateMetadata(); diff --git a/Modules/NextiaBS/src/main/java/edu/upc/essi/dtim/nextiabs/utils/Utils.java b/Modules/NextiaBS/src/main/java/edu/upc/essi/dtim/nextiabs/utils/Utils.java new file mode 100644 index 00000000..50214ea8 --- /dev/null +++ b/Modules/NextiaBS/src/main/java/edu/upc/essi/dtim/nextiabs/utils/Utils.java @@ -0,0 +1,37 @@ +package edu.upc.essi.dtim.nextiabs.utils; + +import java.util.Arrays; +import java.util.Objects; + +public class Utils { + public static String reformatName(String tableName) { + // Trim whitespaces at the end and the beginning + tableName = tableName.trim(); + // Remove characters that might case problems + String pattern = "[!@#$%^&*)-+=\\[\\]{}\\\\|;:'\"<>,.?/]"; + tableName = tableName.replaceAll(pattern, ""); + // Pass the string to camel case + tableName = toCamelCase(tableName); + + return tableName; + } + + public static String toCamelCase(String inputString) { + StringBuilder camelCaseString = new StringBuilder(); + String[] words = inputString.split("\\s+|(?<=\\()|(?=\\))"); // Split the input string by whitespace or parenthesis + words = Arrays.stream(words).filter(str -> !Objects.equals(str, "(")).toArray(String[]::new); + words = Arrays.stream(words).map(str -> str.replace("(", "")).toArray(String[]::new); + + for (int i = 0; i < words.length; i++) { + String word = words[i]; + if (i == 0) { + camelCaseString.append(word.toLowerCase()); // Convert the first word to lowercase + } else { + camelCaseString.append(Character.toUpperCase(word.charAt(0))); // Capitalize the first letter + camelCaseString.append(word.substring(1).toLowerCase()); // Convert the rest to lowercase + } + } + + return camelCaseString.toString(); + } +} diff --git a/Modules/NextiaDataLayer/src/main/java/edu/upc/essi/dtim/NextiaDataLayer/dataLayer/DLDuckDB.java b/Modules/NextiaDataLayer/src/main/java/edu/upc/essi/dtim/NextiaDataLayer/dataLayer/DLDuckDB.java index 2e736857..da932282 100644 --- a/Modules/NextiaDataLayer/src/main/java/edu/upc/essi/dtim/NextiaDataLayer/dataLayer/DLDuckDB.java +++ b/Modules/NextiaDataLayer/src/main/java/edu/upc/essi/dtim/NextiaDataLayer/dataLayer/DLDuckDB.java @@ -208,19 +208,19 @@ else if (repo.getRepositoryType().equals("RelationalJDBCRepository")) { // TODO: extend this to different formats and zones @Override - public String materialize(Dataset dataset, String zone, String format) { - String csvFilePath = Paths.get(dataStorePath, "tmp", dataset.getUUID() + ".csv").toString(); + public String materialize(String UUID, String zone, String format) { + String csvFilePath = Paths.get(dataStorePath, "tmp", UUID + ".csv").toString(); // As of now, we assume that it is always a csv // String extension = "." + format; try { - ResultSet rs = stmt.executeQuery("SELECT * FROM " + zone + "_" + dataset.getUUID()); + ResultSet rs = stmt.executeQuery("SELECT * FROM " + zone + "_" + UUID); try (FileWriter writer = new FileWriter(csvFilePath)) { // Header int columnCount = rs.getMetaData().getColumnCount(); for (int i = 1; i <= columnCount; i++) { writer.append(rs.getMetaData().getColumnName(i)); if (i < columnCount) { - writer.append(","); + writer.append(";"); } } writer.append("\n"); @@ -230,7 +230,7 @@ public String materialize(Dataset dataset, String zone, String format) { Object value = rs.getObject(i); writer.append(value != null ? value.toString() : "null"); if (i < columnCount) { - writer.append(","); + writer.append(";"); } } writer.append("\n"); diff --git a/Modules/NextiaDataLayer/src/main/java/edu/upc/essi/dtim/NextiaDataLayer/dataLayer/DLSpark.java b/Modules/NextiaDataLayer/src/main/java/edu/upc/essi/dtim/NextiaDataLayer/dataLayer/DLSpark.java index 3b806e1e..0a2a6ea3 100644 --- a/Modules/NextiaDataLayer/src/main/java/edu/upc/essi/dtim/NextiaDataLayer/dataLayer/DLSpark.java +++ b/Modules/NextiaDataLayer/src/main/java/edu/upc/essi/dtim/NextiaDataLayer/dataLayer/DLSpark.java @@ -72,7 +72,7 @@ public void removeFromExploitationZone(String tableName) { } @Override - public String materialize(Dataset dataset, String zone, String format) { + public String materialize(String UUID, String zone, String format) { return null; } diff --git a/Modules/NextiaDataLayer/src/main/java/edu/upc/essi/dtim/NextiaDataLayer/dataLayer/DataLayer.java b/Modules/NextiaDataLayer/src/main/java/edu/upc/essi/dtim/NextiaDataLayer/dataLayer/DataLayer.java index 5faf0e8d..d8432c29 100644 --- a/Modules/NextiaDataLayer/src/main/java/edu/upc/essi/dtim/NextiaDataLayer/dataLayer/DataLayer.java +++ b/Modules/NextiaDataLayer/src/main/java/edu/upc/essi/dtim/NextiaDataLayer/dataLayer/DataLayer.java @@ -64,7 +64,7 @@ else if (d.getClass().equals(SQLDataset.class)) { } // we use the name because the wrapper is expecting the sql table to have the name of the dataset assert df != null; - df.createOrReplaceTempView(d.getDatasetName()); + df.createOrReplaceTempView("`" + d.getDatasetName() + "`"); return spark.sql(d.getWrapper()); } @@ -117,7 +117,7 @@ public String storeTemporalFile(InputStream inputFile, String newFileDirectory) return storeTemporalFile(dataStorePath + "tmp", inputFile, newFileDirectory); } - public abstract String materialize(Dataset dataset, String zone, String format); + public abstract String materialize(String UUID, String zone, String format); // ---------------- Others diff --git a/Modules/NextiaJD/src/main/java/edu/upc/essi/dtim/NextiaJD/calculateQuality/CalculateQuality.java b/Modules/NextiaJD/src/main/java/edu/upc/essi/dtim/NextiaJD/calculateQuality/CalculateQuality.java index 7fe9d75f..ec6891fe 100644 --- a/Modules/NextiaJD/src/main/java/edu/upc/essi/dtim/NextiaJD/calculateQuality/CalculateQuality.java +++ b/Modules/NextiaJD/src/main/java/edu/upc/essi/dtim/NextiaJD/calculateQuality/CalculateQuality.java @@ -8,7 +8,7 @@ public class CalculateQuality { public CalculateQuality(Double l, double s) {this.l = l; this.s = s;} public double calculateQualityDiscrete(double c, double k){ - if (c == 1 && k == 1) return 1.0; +// if (c == 1 && k == 1) return 1.0; for (double i = 0; i= 1-(i/l)) && (k >= Math.pow(0.5, i))) { return (l-i+1)/l; diff --git a/api/src/main/java/edu/upc/essi/dtim/odin/dataProducts/DataProductController.java b/api/src/main/java/edu/upc/essi/dtim/odin/dataProducts/DataProductController.java index fb582a9e..42374ce8 100644 --- a/api/src/main/java/edu/upc/essi/dtim/odin/dataProducts/DataProductController.java +++ b/api/src/main/java/edu/upc/essi/dtim/odin/dataProducts/DataProductController.java @@ -5,10 +5,14 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.FileSystemResource; +import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import java.io.File; import java.util.List; @RestController @@ -101,4 +105,29 @@ public ResponseEntity materializeDataProduct(@PathVariable("dataProductI String pathOfMaterializedDataProduct = dataProductService.materializeDataProduct(dataProductID); return new ResponseEntity<>(pathOfMaterializedDataProduct, HttpStatus.OK); } + + /** + * Downloads a (temporal) DataProduct content's as a CSV file. + * + * @param dataProductUUID The UUID of the data product to be materialized + * @return If the task was successful return a ResponseEntity with an OK HTTP code. + */ + @PostMapping("/project/{projectID}/download-temporal-data-product/{dataProductUUID}") + public ResponseEntity downloadTemporalDataProduct(@PathVariable("dataProductUUID") String dataProductUUID) { + logger.info("Downloading data product"); + return dataProductService.downloadTemporalDataProduct(dataProductUUID); + } + + /** + * Downloads a DataProduct content's as a CSV file. + * + * @param dataProductID The UUID of the data product to be materialized + * @return If the task was successful return a ResponseEntity with an OK HTTP code. + */ + @PostMapping("/project/{projectID}/data-product/{dataProductID}/download") + public ResponseEntity downloadDataProduct(@PathVariable("dataProductID") String dataProductID) { + logger.info("Downloading data product"); + return dataProductService.downloadDataProduct(dataProductID); + } + } diff --git a/api/src/main/java/edu/upc/essi/dtim/odin/dataProducts/DataProductService.java b/api/src/main/java/edu/upc/essi/dtim/odin/dataProducts/DataProductService.java index f1d0beb4..acbb362e 100644 --- a/api/src/main/java/edu/upc/essi/dtim/odin/dataProducts/DataProductService.java +++ b/api/src/main/java/edu/upc/essi/dtim/odin/dataProducts/DataProductService.java @@ -11,8 +11,13 @@ import edu.upc.essi.dtim.odin.projects.ProjectService; import edu.upc.essi.dtim.odin.projects.pojo.Project; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.FileSystemResource; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; +import java.io.File; import java.util.LinkedList; import java.util.List; import java.util.NoSuchElementException; @@ -136,18 +141,62 @@ public List getDataProductsOfProject(String projectID) { return project.getDataProducts(); } - // ---------------- Other operations + // ------------ Download/materialize operations /** - * Materializes a data product into a CSV file, mainly to be ingested by the intent generation pipeline. + * Materializes a data product into a CSV file. * - * @param dataProductID The ID of the data product to be materialized - * @return If the task was successful return a ResponseEntity with an OK HTTP code. + * @param dataProductID The ID of the data product to be materialized + * @return If the task was successful returns a path were the materialized file resides */ public String materializeDataProduct(String dataProductID) { - // Own function to get the data product DataProduct dp = ormDataResource.findById(DataProduct.class, dataProductID); DataLayerInterface dataLayerInterFace = new DataLayerImpl(appConfig); - return dataLayerInterFace.materialize(dp, "exp", "csv"); + return dataLayerInterFace.materialize(dp.getUUID(), "exp", "csv"); + } + + /** + * Downloads a temporal data product. That is, just after executing a query over the data and before the data product + * has been stored in ODIN. + * + * @param dataProductUUID The UUID of the data product to be downloaded + * @return If the task was successful returns a ResponseEntity with the file to download + */ + public ResponseEntity downloadTemporalDataProduct(String dataProductUUID) { + DataLayerInterface dataLayerInterFace = new DataLayerImpl(appConfig); + String pathOfMaterializedDataProduct = dataLayerInterFace.materialize(dataProductUUID, "tmp_exp", "csv"); + return downloadCSVFile(pathOfMaterializedDataProduct); + } + + /** + * Downloads a data product. + * + * @param dataProductID The ID of the data product to be downloaded + * @return If the task was successful returns a ResponseEntity with the file to download + */ + public ResponseEntity downloadDataProduct(String dataProductID) { + String pathOfMaterializedDataProduct = materializeDataProduct(dataProductID); + return downloadCSVFile(pathOfMaterializedDataProduct); + } + + /** + * Downloads a CSV file generated from a data product + * + * @param pathOfMaterializedDataProduct Path of the data product (in CSV format) to download + * @return If the task was successful returns a ResponseEntity with the file to download + */ + public ResponseEntity downloadCSVFile(String pathOfMaterializedDataProduct) { + // Create a FileSystemResource to represent the CSV file + FileSystemResource file = new FileSystemResource(new File(pathOfMaterializedDataProduct)); + + // Set headers to trigger file download + HttpHeaders headers = new HttpHeaders(); + headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=file.csv"); + + // Set the content type + headers.setContentType(MediaType.parseMediaType("text/csv")); + + // Return ResponseEntity with the file content and headers + return ResponseEntity.ok().headers(headers).body(file); } } diff --git a/api/src/main/java/edu/upc/essi/dtim/odin/datasets/DatasetService.java b/api/src/main/java/edu/upc/essi/dtim/odin/datasets/DatasetService.java index a0b5c6af..7d5acb80 100644 --- a/api/src/main/java/edu/upc/essi/dtim/odin/datasets/DatasetService.java +++ b/api/src/main/java/edu/upc/essi/dtim/odin/datasets/DatasetService.java @@ -28,6 +28,8 @@ import edu.upc.essi.dtim.odin.repositories.RepositoryService; import org.apache.jena.rdf.model.Model; +import org.apache.jena.rdf.model.Statement; +import org.apache.jena.rdf.model.StmtIterator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.ByteArrayResource; import org.springframework.core.io.InputStreamResource; @@ -49,6 +51,7 @@ import java.util.NoSuchElementException; import static edu.upc.essi.dtim.odin.utils.Utils.generateUUID; +import static edu.upc.essi.dtim.odin.utils.Utils.reformatName; @Service public class DatasetService { @@ -125,6 +128,7 @@ public void postLocalDataset(List attachFiles, String datasetDesc // Get only the file name to add it to the dataset instance (we need it to execute the bootstrap) int slashIndex = fullFileName.lastIndexOf("/"); String datasetName = fullFileName.substring(slashIndex >= 0 ? slashIndex + 1 : 0, dotIndex); + datasetName = reformatName(datasetName); String newFileName = UUID + "." + format; // New file name using the UUID @@ -161,6 +165,8 @@ public void postAPIDataset(List attachFiles, String datasetDescri // Reconstruct file from the Multipart file (i.e. store the file in the temporal zone to be accessed later) String filePath = storeTemporalFile(attachFile, newFileName); + apiDatasetName = reformatName(apiDatasetName); + // Generate dataset, set UUID parameter and save it (to assign an id) Dataset dataset = generateDataset(filePath, apiDatasetName, datasetDescription, repositoryID, endpoint, "api"); dataset.setUUID(UUID); @@ -182,6 +188,7 @@ public void postJDBCDataset(List attachTables, String datasetDescription for (String tableName : attachTables) { // Extract data from datasource file, set UUID parameter and save it (to assign an id) String UUID = generateUUID(); // Unique universal identifier (UUID) of the dataset + tableName = reformatName(tableName); Dataset dataset = generateDataset(null, tableName, datasetDescription, repositoryID, null, "sql"); dataset.setUUID(UUID); dataset = saveDataset(dataset); @@ -292,6 +299,7 @@ private void handleDataset(Dataset dataset, String repositoryID, String projectI } catch (Exception e) { deleteDatasetFromProject(projectID, dataset.getId()); + e.printStackTrace(); throw new InternalServerErrorException("Error when uploading the data to the data layer", e.getMessage()); } } @@ -305,11 +313,19 @@ private void handleDataset(Dataset dataset, String repositoryID, String projectI */ public List getAttributesFromWrapper(String wrapper) { List attributes = new ArrayList<>(); - int backtickIndex = wrapper.indexOf("`"); - while (backtickIndex != -1) { - int nextBacktickIndex = wrapper.indexOf("`", backtickIndex + 1); - attributes.add(generateAttribute(wrapper.substring(backtickIndex + 1, nextBacktickIndex))); - backtickIndex = wrapper.indexOf("`", nextBacktickIndex + 1); + int startIndex = wrapper.indexOf(" AS "); + + while (startIndex != -1) { + startIndex += 4; // Move to the character after " AS " + int endIndex = wrapper.indexOf(',', startIndex); + + if (endIndex != -1) { + String extractedString = wrapper.substring(startIndex, endIndex).trim(); + attributes.add(generateAttribute(extractedString)); + startIndex = wrapper.indexOf(" AS ", endIndex); // Move to the next " AS " + } else { + break; // If no comma found, exit loop + } } return attributes; } @@ -441,9 +457,16 @@ public List getDatasetsOfProject(String projectID) { public void putDataset(String datasetID, String datasetName, String datasetDescription) { Dataset originalDataset = getDataset(datasetID); + // Not working (it should replace the name in the schema) + GraphStoreInterface graphStore = GraphStoreFactory.getInstance(appConfig); + graphStore.changeGraphName(originalDataset.getLocalGraph().getGraphName(), originalDataset.getDatasetName(), datasetName); + + originalDataset = getDataset(datasetID); + originalDataset.setDatasetName(datasetName); originalDataset.setDatasetDescription(datasetDescription); + saveDataset(originalDataset); } diff --git a/api/src/main/java/edu/upc/essi/dtim/odin/nextiaInterfaces/nextiaDataLayer/DataLayerImpl.java b/api/src/main/java/edu/upc/essi/dtim/odin/nextiaInterfaces/nextiaDataLayer/DataLayerImpl.java index 9845cfb2..61e4d8a2 100644 --- a/api/src/main/java/edu/upc/essi/dtim/odin/nextiaInterfaces/nextiaDataLayer/DataLayerImpl.java +++ b/api/src/main/java/edu/upc/essi/dtim/odin/nextiaInterfaces/nextiaDataLayer/DataLayerImpl.java @@ -25,6 +25,7 @@ public void uploadToDataLayer(Dataset dataset) { dl.uploadToFormattedZone(dataset, dataset.getUUID()); } catch (Exception e) { + e.printStackTrace(); throw new InternalServerErrorException("Error when uploading the data to the data layer", e.getMessage()); } } @@ -73,8 +74,8 @@ public void copyToExploitationZone(String UUID) { } @Override - public String materialize(Dataset dataset, String zone, String format) { + public String materialize(String UUID, String zone, String format) { DataLayer dl = DataLayerSingleton.getInstance(appConfig); - return dl.materialize(dataset, zone, format); + return dl.materialize(UUID, zone, format); } } diff --git a/api/src/main/java/edu/upc/essi/dtim/odin/nextiaInterfaces/nextiaDataLayer/DataLayerInterface.java b/api/src/main/java/edu/upc/essi/dtim/odin/nextiaInterfaces/nextiaDataLayer/DataLayerInterface.java index cb32eec6..075f6010 100644 --- a/api/src/main/java/edu/upc/essi/dtim/odin/nextiaInterfaces/nextiaDataLayer/DataLayerInterface.java +++ b/api/src/main/java/edu/upc/essi/dtim/odin/nextiaInterfaces/nextiaDataLayer/DataLayerInterface.java @@ -40,5 +40,5 @@ public interface DataLayerInterface { void copyToExploitationZone(String UUID); - String materialize(Dataset dataset, String zone, String format); + String materialize(String UUID, String zone, String format); } diff --git a/api/src/main/java/edu/upc/essi/dtim/odin/nextiaInterfaces/nextiaQR/qrModuleImpl.java b/api/src/main/java/edu/upc/essi/dtim/odin/nextiaInterfaces/nextiaQR/qrModuleImpl.java index 81ed267b..292bf8cf 100644 --- a/api/src/main/java/edu/upc/essi/dtim/odin/nextiaInterfaces/nextiaQR/qrModuleImpl.java +++ b/api/src/main/java/edu/upc/essi/dtim/odin/nextiaInterfaces/nextiaQR/qrModuleImpl.java @@ -37,10 +37,13 @@ public QueryResult makeQuery(IntegratedGraphJenaImpl integratedGraph, List " + +// "DELETE {?s ?p ?o} " + +// "INSERT {?s ?p ?oNew} " + +// "WHERE {?s ?p ?o . BIND(REPLACE(str(?o), '" + oldString + "', '" + newString + "', 'i') AS ?oNew)}"; +// +// // Execute the update inside a transaction +// try { +// dataset.begin(ReadWrite.WRITE); +// UpdateProcessor processor = UpdateExecutionFactory.create(sparqlUpdate, dataset); +// processor.execute(); +// dataset.commit(); +// } finally { +// dataset.end(); +// } + + + + +// try { +// // Define the update query +// String updateQuery = +// "PREFIX rdf: " + +// "PREFIX rdfs: " + +// "PREFIX yourGraphURI: " + +// "DELETE {?s ?p ?o} " + +// "INSERT {?s ?p ?oNew} " + +// "WHERE {?s ?p ?o . BIND(REPLACE(str(?o), '" + oldString + "', '" + newString + "', 'i') AS ?oNew)}"; +// +// // Execute the update query +// UpdateFactory.create(updateQuery).execute(dataset); +// +// // Commit the changes +// dataset.commit(); +// } finally { +// dataset.end(); +// } + + // Close the dataset when done +// dataset.commit(); +// dataset.end(); + + return null; + } + } diff --git a/api/src/main/java/edu/upc/essi/dtim/odin/repositories/RepositoryService.java b/api/src/main/java/edu/upc/essi/dtim/odin/repositories/RepositoryService.java index f949e503..31e8282b 100644 --- a/api/src/main/java/edu/upc/essi/dtim/odin/repositories/RepositoryService.java +++ b/api/src/main/java/edu/upc/essi/dtim/odin/repositories/RepositoryService.java @@ -192,7 +192,7 @@ public List retrieveTablesInfo(String repositoryId) { while (resultSet.next()) { // For each table, get the number of rows of the table String tableName = resultSet.getString("table_name"); - String rowCountQuery = "SELECT COUNT(*) FROM " + tableName + ";"; + String rowCountQuery = "SELECT COUNT(*) FROM \"" + tableName + "\";"; try (ResultSet rowCountResultSet = statementLines.executeQuery(rowCountQuery)) { if (rowCountResultSet.next()) { @@ -201,7 +201,7 @@ public List retrieveTablesInfo(String repositoryId) { rowCountResultSet.close(); // Size of the table - String tableSizeQuery = "SELECT pg_size_pretty(pg_total_relation_size('" + tableName + "')) AS total_size;"; + String tableSizeQuery = "SELECT pg_size_pretty(pg_total_relation_size('\"" + tableName + "\"')) AS total_size;"; try (ResultSet sizeResultSet = statementSize.executeQuery(tableSizeQuery)) { if (sizeResultSet.next()) { String tableSize = sizeResultSet.getString("total_size"); diff --git a/api/src/main/java/edu/upc/essi/dtim/odin/utils/Utils.java b/api/src/main/java/edu/upc/essi/dtim/odin/utils/Utils.java index 75054c74..e7acb58d 100644 --- a/api/src/main/java/edu/upc/essi/dtim/odin/utils/Utils.java +++ b/api/src/main/java/edu/upc/essi/dtim/odin/utils/Utils.java @@ -1,6 +1,8 @@ package edu.upc.essi.dtim.odin.utils; import java.security.SecureRandom; +import java.util.Arrays; +import java.util.Objects; public class Utils { /** @@ -18,4 +20,35 @@ public static String generateUUID() { } return sb.toString(); } + + public static String reformatName(String tableName) { + // Trim whitespaces at the end and the beginning + tableName = tableName.trim(); + // Remove characters that might case problems + String pattern = "[!@#$%^&*)-+=\\[\\]{}\\\\|;:'\"<>,.?/]"; + tableName = tableName.replaceAll(pattern, ""); + // Pass the string to camel case + tableName = toCamelCase(tableName); + + return tableName; + } + + public static String toCamelCase(String inputString) { + StringBuilder camelCaseString = new StringBuilder(); + String[] words = inputString.split("\\s+|(?<=\\()|(?=\\))"); // Split the input string by whitespace or parenthesis + words = Arrays.stream(words).filter(str -> !Objects.equals(str, "(")).toArray(String[]::new); + words = Arrays.stream(words).map(str -> str.replace("(", "")).toArray(String[]::new); + + for (int i = 0; i < words.length; i++) { + String word = words[i]; + if (i == 0) { + camelCaseString.append(word.toLowerCase()); // Convert the first word to lowercase + } else { + camelCaseString.append(Character.toUpperCase(word.charAt(0))); // Capitalize the first letter + camelCaseString.append(word.substring(1).toLowerCase()); // Convert the rest to lowercase + } + } + + return camelCaseString.toString(); + } } diff --git a/api/src/main/resources/frontend-schemas/RepositoryForms/Local_Repository.json b/api/src/main/resources/frontend-schemas/RepositoryForms/Local_Repository.json index bc3c0ec4..fbd2c8bf 100644 --- a/api/src/main/resources/frontend-schemas/RepositoryForms/Local_Repository.json +++ b/api/src/main/resources/frontend-schemas/RepositoryForms/Local_Repository.json @@ -4,7 +4,7 @@ "properties": { "path": { "type": "string", - "label": "Path", + "label": "Path (Optional)", "maxLength": 50 } }, diff --git a/api/src/test/java/edu/upc/essi/dtim/odin/nextiaStore/relationalStore/ORMStoreJpaImplTest.java b/api/src/test/java/edu/upc/essi/dtim/odin/nextiaStore/relationalStore/ORMStoreJpaImplTest.java index e35f0a4d..e1cb42b2 100644 --- a/api/src/test/java/edu/upc/essi/dtim/odin/nextiaStore/relationalStore/ORMStoreJpaImplTest.java +++ b/api/src/test/java/edu/upc/essi/dtim/odin/nextiaStore/relationalStore/ORMStoreJpaImplTest.java @@ -9,93 +9,93 @@ import javax.persistence.Persistence; class ORMStoreJpaImplTest { - - private EntityManagerFactory emf; - private ORMStoreJpaImpl ormImplementation; - private Project entity; - - @BeforeEach - void setUp() { - emf = Persistence.createEntityManagerFactory("ORMPersistenceUnit"); - ormImplementation = new ORMStoreJpaImpl(); - this.entity = new Project(); - this.entity.setProjectId("testID"); - this.entity.setProjectName("testName"); - this.entity.setProjectDescription("testDescription"); - this.entity.setProjectColor("testColor"); - this.entity.setProjectPrivacy("testPrivacy"); - this.entity.setCreatedBy("Victor Asenjo Testing"); - - } - - @AfterEach - void tearDown() { - ormImplementation.deleteOne(Project.class, this.entity.getProjectId()); - } - - @Test - void testSave() { - - // Call the save method - Project savedEntity = ormImplementation.save(entity); - - // Verify if the object is saved and returned successfully - Assertions.assertNotNull(savedEntity); - Assertions.assertEquals(entity.getProjectId(), savedEntity.getProjectId()); - Assertions.assertEquals(entity.getProjectName(), savedEntity.getProjectName()); - } - - @Test - void testFindById() { - // Save the object using EntityManager - EntityManager em = emf.createEntityManager(); - EntityTransaction tx = em.getTransaction(); - tx.begin(); - em.persist(entity); - tx.commit(); - em.close(); - - // Call the getProjectById method - Project foundEntity = ormImplementation.findById(Project.class, entity.getProjectId()); - - // Verify if the object is found successfully - Assertions.assertNotNull(foundEntity); - Assertions.assertEquals(entity.getProjectId(), foundEntity.getProjectId()); - Assertions.assertEquals(entity.getProjectName(), foundEntity.getProjectName()); - } - - @Test - void testFindById_error() { - - // Call the getProjectById method - Project foundEntity = ormImplementation.findById(Project.class, "invented"); - - // Verify if the object is found successfully - Assertions.assertNull(foundEntity); - } - - @Test - void testDeleteOne() { - // Save the object using EntityManager - EntityManager em = emf.createEntityManager(); - EntityTransaction tx = em.getTransaction(); - tx.begin(); - em.persist(entity); - tx.commit(); - em.close(); - - // Call the deleteOne method - boolean deleted = ormImplementation.deleteOne(Project.class, entity.getProjectId()); - - // Verify if the object is deleted successfully - Assertions.assertTrue(deleted); - - // Try to find the object after deletion - EntityManager emAfterDeletion = emf.createEntityManager(); - Project deletedEntity = emAfterDeletion.find(Project.class, entity.getProjectId()); - emAfterDeletion.close(); - - // Verify if the object is not found after deletion - Assertions.assertNull(deletedEntity); - } +// +// private EntityManagerFactory emf; +// private ORMStoreJpaImpl ormImplementation; +// private Project entity; +// +// @BeforeEach +// void setUp() { +// emf = Persistence.createEntityManagerFactory("ORMPersistenceUnit"); +// ormImplementation = new ORMStoreJpaImpl(); +// this.entity = new Project(); +// this.entity.setProjectId("testID"); +// this.entity.setProjectName("testName"); +// this.entity.setProjectDescription("testDescription"); +// this.entity.setProjectColor("testColor"); +// this.entity.setProjectPrivacy("testPrivacy"); +// this.entity.setCreatedBy("Victor Asenjo Testing"); +// +// } +// +// @AfterEach +// void tearDown() { +// ormImplementation.deleteOne(Project.class, this.entity.getProjectId()); +// } +// +// @Test +// void testSave() { +// +// // Call the save method +// Project savedEntity = ormImplementation.save(entity); +// +// // Verify if the object is saved and returned successfully +// Assertions.assertNotNull(savedEntity); +// Assertions.assertEquals(entity.getProjectId(), savedEntity.getProjectId()); +// Assertions.assertEquals(entity.getProjectName(), savedEntity.getProjectName()); +// } +// +// @Test +// void testFindById() { +// // Save the object using EntityManager +// EntityManager em = emf.createEntityManager(); +// EntityTransaction tx = em.getTransaction(); +// tx.begin(); +// em.persist(entity); +// tx.commit(); +// em.close(); +// +// // Call the getProjectById method +// Project foundEntity = ormImplementation.findById(Project.class, entity.getProjectId()); +// +// // Verify if the object is found successfully +// Assertions.assertNotNull(foundEntity); +// Assertions.assertEquals(entity.getProjectId(), foundEntity.getProjectId()); +// Assertions.assertEquals(entity.getProjectName(), foundEntity.getProjectName()); +// } +// +// @Test +// void testFindById_error() { +// +// // Call the getProjectById method +// Project foundEntity = ormImplementation.findById(Project.class, "invented"); +// +// // Verify if the object is found successfully +// Assertions.assertNull(foundEntity); +// } +// +// @Test +// void testDeleteOne() { +// // Save the object using EntityManager +// EntityManager em = emf.createEntityManager(); +// EntityTransaction tx = em.getTransaction(); +// tx.begin(); +// em.persist(entity); +// tx.commit(); +// em.close(); +// +// // Call the deleteOne method +// boolean deleted = ormImplementation.deleteOne(Project.class, entity.getProjectId()); +// +// // Verify if the object is deleted successfully +// Assertions.assertTrue(deleted); +// +// // Try to find the object after deletion +// EntityManager emAfterDeletion = emf.createEntityManager(); +// Project deletedEntity = emAfterDeletion.find(Project.class, entity.getProjectId()); +// emAfterDeletion.close(); +// +// // Verify if the object is not found after deletion +// Assertions.assertNull(deletedEntity); +// } } diff --git a/frontend/src/api/dataProductsAPI.js b/frontend/src/api/dataProductsAPI.js index 30b2e3d3..33b04b9c 100644 --- a/frontend/src/api/dataProductsAPI.js +++ b/frontend/src/api/dataProductsAPI.js @@ -16,4 +16,10 @@ export default { putDataProduct(projectID, dataProductID, data) { return odinApi.put('/project/' + projectID + '/data-product/' + dataProductID, data) }, + downloadTemporalDataProduct(projectID, dataProductUUID) { + return odinApi.post('/project/' + projectID + '/download-temporal-data-product/' + dataProductUUID) + }, + downloadDataProduct(projectID, dataProductID) { + return odinApi.post('/project/' + projectID + '/data-product/' + dataProductID + '/download') + }, } diff --git a/frontend/src/components/forms/ManualAlignmentsForm.vue b/frontend/src/components/forms/ManualAlignmentsForm.vue index dcff7ed6..ea360337 100644 --- a/frontend/src/components/forms/ManualAlignmentsForm.vue +++ b/frontend/src/components/forms/ManualAlignmentsForm.vue @@ -82,11 +82,9 @@ import {ref, reactive} from "vue"; import Graph from 'components/graph/Graph.vue' import {useIntegrationStore} from 'src/stores/integrationStore.js' import {useProjectsStore} from 'src/stores/projectsStore.js' -import { useNotify } from "src/use/useNotify"; const integrationStore = useIntegrationStore() const projectsStore = useProjectsStore() -const notify = useNotify() const props = defineProps({ dsA: {type: Object, default: {id: "", name: "", type: "", graphicalGraph: "", iri: "", path: ""}}, @@ -152,7 +150,6 @@ const addAlignment = () => { integrationStore.addAlignment(alignment, true) resetRA() resetRB() - notify.positive("Alignment added") } const setAlignmentA = (resource) => { diff --git a/frontend/src/components/stepper/DatasetIntegrationStep.vue b/frontend/src/components/stepper/DatasetIntegrationStep.vue index 8d860f53..3ddbc0aa 100644 --- a/frontend/src/components/stepper/DatasetIntegrationStep.vue +++ b/frontend/src/components/stepper/DatasetIntegrationStep.vue @@ -88,6 +88,7 @@ const clickOk = () => { switch (step.value) { case 1: step.value++ + integrationStore.alignments = [] // reset the alignments left from other integrations break; case 2: integrationStore.integrate(function () { diff --git a/frontend/src/components/tables/TableDataProducts.vue b/frontend/src/components/tables/TableDataProducts.vue index 51e64e38..761f6925 100644 --- a/frontend/src/components/tables/TableDataProducts.vue +++ b/frontend/src/components/tables/TableDataProducts.vue @@ -22,6 +22,7 @@ @@ -18,7 +17,6 @@ diff --git a/frontend/src/pages/Query.vue b/frontend/src/pages/Query.vue index afc1b505..91ae3a20 100644 --- a/frontend/src/pages/Query.vue +++ b/frontend/src/pages/Query.vue @@ -22,8 +22,9 @@ - + + @@ -52,6 +53,9 @@ import Graph from 'components/graph/Graph.vue' import {useProjectsStore} from 'src/stores/projectsStore.js' import {useQueriesStore} from 'src/stores/queriesStore.js' import {useDataProductsStore} from 'src/stores/dataProductsStore.js' +import { useQuasar } from "quasar"; + +const $q = useQuasar() const queriesStore = useQueriesStore(); const dataProductsStore = useDataProductsStore(); @@ -112,6 +116,7 @@ const setGlobalSchema = () => { } const queryGraph = (data) => { + $q.loading.show({message: 'Executing query...'}) data.graphID = graphID.value data.graphType = graphType @@ -122,6 +127,7 @@ const queryGraph = (data) => { } queriesStore.queryGraph(projectsStore.currentProject.projectId, data, successCallback) + $q.loading.hide() } const postDataProduct = () => { @@ -134,6 +140,10 @@ const postDataProduct = () => { dataProductsStore.postDataProduct(projectsStore.currentProject.projectId, data) } +const downloadTemporalDataProduct = () => { + dataProductsStore.downloadTemporalDataProduct(projectsStore.currentProject.projectId, dataProductUUID.value) +} + onBeforeMount(async () => { setGlobalSchema(); }) @@ -142,7 +152,6 @@ onBeforeMount(async () => { diff --git a/frontend/src/stores/dataProductsStore.js b/frontend/src/stores/dataProductsStore.js index 2f11704f..92cc3373 100644 --- a/frontend/src/stores/dataProductsStore.js +++ b/frontend/src/stores/dataProductsStore.js @@ -1,6 +1,7 @@ import { defineStore } from 'pinia'; import { useNotify } from 'src/use/useNotify.js'; import dataProductAPI from "src/api/dataProductsAPI"; +import download from 'downloadjs'; const notify = useNotify(); @@ -55,8 +56,8 @@ export const useDataProductsStore = defineStore('dataProducts', { } }, - // ------------ Other operations - async materializeDataProduct(projectID, dataProductID) { + // ------------ Download/materialize operations + async materializeDataProduct(projectID, dataProductID) { // To be ingested by the intent API try { const response = await dataProductAPI.materializeDataProduct(projectID, dataProductID); this.selectedDataProductPath = response.data; @@ -64,6 +65,28 @@ export const useDataProductsStore = defineStore('dataProducts', { notify.negative("Error materializing the data"); console.error("Error:", error); } + }, + + async downloadTemporalDataProduct(projectID, dataProductUUID) { // The user downloads it from the frontend + try { + const response = await dataProductAPI.downloadTemporalDataProduct(projectID, dataProductUUID); + const content = response.headers['content-type']; + download(response.data, "result.csv", content); + } catch (error) { + notify.negative("Error downloading the data"); + console.error("Error:", error); + } + }, + + async downloadDataProduct(projectID, dataProduct) { // The user downloads it from the frontend + try { + const response = await dataProductAPI.downloadDataProduct(projectID, dataProduct.id); + const content = response.headers['content-type']; + download(response.data, dataProduct.datasetName + ".csv", content); + } catch (error) { + notify.negative("Error downloading the data"); + console.error("Error:", error); + } } } }); \ No newline at end of file diff --git a/frontend/src/stores/integrationStore.js b/frontend/src/stores/integrationStore.js index e1eeda6f..2b967fc7 100644 --- a/frontend/src/stores/integrationStore.js +++ b/frontend/src/stores/integrationStore.js @@ -53,17 +53,28 @@ export const useIntegrationStore = defineStore('integration', { }, addAlignment(alignment, refactor) { - const a = refactor ? { - iriA: alignment.resourceA.iri, - labelA: alignment.resourceA.label, - iriB: alignment.resourceB.iri, - labelB: alignment.resourceB.label, - l: alignment.integratedLabel, - type: alignment.type, - similarity: alignment.similarity - } : alignment; - - this.alignments.push(a); + let newAlignment = true + console.log(this.alignments) + this.alignments.map(schemaAlignment => { + if (schemaAlignment.iriA === alignment.resourceA.iri && schemaAlignment.iriB === alignment.resourceB.iri) { + newAlignment = false + notify.negative("Alignment already defined"); + } + }) + if (newAlignment) { + const a = refactor ? { + iriA: alignment.resourceA.iri, + labelA: alignment.resourceA.label, + iriB: alignment.resourceB.iri, + labelB: alignment.resourceB.label, + l: alignment.integratedLabel, + type: alignment.type, + similarity: alignment.similarity + } : alignment; + + this.alignments.push(a); + notify.positive("Alignment added") + } }, deleteAlignment(alignment) { @@ -122,6 +133,8 @@ export const useIntegrationStore = defineStore('integration', { await integrationAPI.persistIntegration(projectsStore.currentProject.projectId); notify.positive("Integration saved successfully"); projectsStore.updateCurrentProject(); + this.alignments = [] + this.joinAlignments = [] } catch (error) { console.error("Error:", error); notify.negative("Something went wrong when persisting the integration " + error); diff --git a/frontend/src/stores/intentsStore.js b/frontend/src/stores/intentsStore.js index f600e207..f64fb013 100644 --- a/frontend/src/stores/intentsStore.js +++ b/frontend/src/stores/intentsStore.js @@ -174,7 +174,7 @@ export const useIntentsStore = defineStore('intents', { }, async downloadKNIME(plan) { - const data = {"graph": plan.graphs, "ontology": this.ontology} + const data = {"graph": plan.graph, "ontology": this.ontology} try { const response = await intentsAPI.downloadKNIME(data); FileSaver.saveAs(new Blob([response.data]), `${plan.id}.knwf`);