From 8eadc95c242dc691c129d53dec941fb2300ada62 Mon Sep 17 00:00:00 2001 From: Moritz Staudinger <moritz.staudinger@tuwien.ac.at> Date: Thu, 3 Mar 2022 02:44:01 +0100 Subject: [PATCH] refactored execute to use re-execute, limited on resultnumber Former-commit-id: 60fdf6dccf16c9687cc1c58fda0f634683bf26cb --- .../at/tuwien/endpoint/QueryEndpoint.java | 6 +-- .../endpoint/QueryEndpointUnitTest.java | 8 ++-- .../service/QueryServiceIntegrationTest.java | 5 ++- .../java/at/tuwien/service/QueryService.java | 2 +- .../java/at/tuwien/service/StoreService.java | 5 +++ .../tuwien/service/impl/QueryServiceImpl.java | 40 +++---------------- .../tuwien/service/impl/StoreServiceImpl.java | 39 ++++++++++++++++++ 7 files changed, 61 insertions(+), 44 deletions(-) diff --git a/fda-query-service/rest-service/src/main/java/at/tuwien/endpoint/QueryEndpoint.java b/fda-query-service/rest-service/src/main/java/at/tuwien/endpoint/QueryEndpoint.java index 4b61ff7963..2b0266168f 100644 --- a/fda-query-service/rest-service/src/main/java/at/tuwien/endpoint/QueryEndpoint.java +++ b/fda-query-service/rest-service/src/main/java/at/tuwien/endpoint/QueryEndpoint.java @@ -53,9 +53,9 @@ public class QueryEndpoint { public ResponseEntity<QueryResultDto> execute(@NotNull @PathVariable("id") Long id, @NotNull @PathVariable("databaseId") Long databaseId, @Valid @RequestBody ExecuteStatementDto data, - @RequestParam("page") Long page, @RequestParam("size") Long size) + @RequestParam(value = "page", required = false ) Long page, @RequestParam(value = "size", required = false) Long size) throws DatabaseNotFoundException, ImageNotSupportedException, QueryStoreException, QueryMalformedException, - TableNotFoundException, ContainerNotFoundException { + TableNotFoundException, ContainerNotFoundException, SQLException, JSQLParserException { /* validation */ if (data.getStatement() == null || data.getStatement().isBlank()) { log.error("Query is empty"); @@ -103,7 +103,7 @@ public class QueryEndpoint { public ResponseEntity<QueryResultDto> reExecute(@NotNull @PathVariable("id") Long id, @NotNull @PathVariable("databaseId") Long databaseId, @NotNull @PathVariable("queryId") Long queryId, - @RequestParam("page") Long page, @RequestParam("size") Long size) + @RequestParam(value = "page", required = false) Long page, @RequestParam(value = "size", required = false) Long size) throws QueryStoreException, QueryNotFoundException, DatabaseNotFoundException, ImageNotSupportedException, TableNotFoundException, QueryMalformedException, ContainerNotFoundException, SQLException, JSQLParserException { final Query query = storeService.findOne(id, databaseId, queryId); diff --git a/fda-query-service/rest-service/src/test/java/at/tuwien/endpoint/QueryEndpointUnitTest.java b/fda-query-service/rest-service/src/test/java/at/tuwien/endpoint/QueryEndpointUnitTest.java index 2b8bd543cc..6aaedeb4ca 100644 --- a/fda-query-service/rest-service/src/test/java/at/tuwien/endpoint/QueryEndpointUnitTest.java +++ b/fda-query-service/rest-service/src/test/java/at/tuwien/endpoint/QueryEndpointUnitTest.java @@ -10,6 +10,7 @@ import at.tuwien.exception.*; import at.tuwien.service.StoreService; import at.tuwien.service.impl.QueryServiceImpl; import lombok.extern.log4j.Log4j2; +import net.sf.jsqlparser.JSQLParserException; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; @@ -19,6 +20,7 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.test.context.junit.jupiter.SpringExtension; +import java.sql.SQLException; import java.time.Instant; import java.util.List; import java.util.Map; @@ -45,7 +47,7 @@ public class QueryEndpointUnitTest extends BaseUnitTest { @Test public void execute_succeeds() throws TableNotFoundException, QueryStoreException, QueryMalformedException, - DatabaseNotFoundException, ImageNotSupportedException, ContainerNotFoundException { + DatabaseNotFoundException, ImageNotSupportedException, ContainerNotFoundException, SQLException, JSQLParserException { final ExecuteStatementDto request = ExecuteStatementDto.builder() .statement(QUERY_1_STATEMENT) .build(); @@ -71,7 +73,7 @@ public class QueryEndpointUnitTest extends BaseUnitTest { @Test public void execute_emptyResult_succeeds() throws TableNotFoundException, QueryStoreException, - QueryMalformedException, DatabaseNotFoundException, ImageNotSupportedException, ContainerNotFoundException { + QueryMalformedException, DatabaseNotFoundException, ImageNotSupportedException, ContainerNotFoundException, SQLException, JSQLParserException { final ExecuteStatementDto request = ExecuteStatementDto.builder() .statement(QUERY_1_STATEMENT) .build(); @@ -97,7 +99,7 @@ public class QueryEndpointUnitTest extends BaseUnitTest { @Test public void execute_tableNotFound_fails() throws TableNotFoundException, QueryMalformedException, - DatabaseNotFoundException, ImageNotSupportedException, ContainerNotFoundException, QueryStoreException { + DatabaseNotFoundException, ImageNotSupportedException, ContainerNotFoundException, QueryStoreException, SQLException, JSQLParserException { final ExecuteStatementDto request = ExecuteStatementDto.builder() .statement(QUERY_1_STATEMENT) .build(); diff --git a/fda-query-service/rest-service/src/test/java/at/tuwien/service/QueryServiceIntegrationTest.java b/fda-query-service/rest-service/src/test/java/at/tuwien/service/QueryServiceIntegrationTest.java index 0c3ad1d614..13d99fdd74 100644 --- a/fda-query-service/rest-service/src/test/java/at/tuwien/service/QueryServiceIntegrationTest.java +++ b/fda-query-service/rest-service/src/test/java/at/tuwien/service/QueryServiceIntegrationTest.java @@ -17,6 +17,7 @@ import com.github.dockerjava.api.model.Bind; import com.github.dockerjava.api.model.Network; import lombok.SneakyThrows; import lombok.extern.log4j.Log4j2; +import net.sf.jsqlparser.JSQLParserException; import org.junit.Rule; import org.junit.rules.Timeout; import org.junit.jupiter.api.*; @@ -173,7 +174,7 @@ public class QueryServiceIntegrationTest extends BaseUnitTest { @Test public void execute_succeeds() throws DatabaseNotFoundException, ImageNotSupportedException, InterruptedException, - QueryMalformedException, TableNotFoundException, QueryStoreException, ContainerNotFoundException { + QueryMalformedException, TableNotFoundException, QueryStoreException, ContainerNotFoundException, SQLException, JSQLParserException { final ExecuteStatementDto request = ExecuteStatementDto.builder() .statement(QUERY_1_STATEMENT) .build(); @@ -207,7 +208,7 @@ public class QueryServiceIntegrationTest extends BaseUnitTest { @Disabled public void execute_modifyData_fails() throws DatabaseNotFoundException, ImageNotSupportedException, InterruptedException, QueryMalformedException, TableNotFoundException, QueryStoreException, - ContainerNotFoundException { + ContainerNotFoundException, SQLException, JSQLParserException { final ExecuteStatementDto request = ExecuteStatementDto.builder() .statement("DELETE FROM `weather_aus`;") .build(); diff --git a/fda-query-service/services/src/main/java/at/tuwien/service/QueryService.java b/fda-query-service/services/src/main/java/at/tuwien/service/QueryService.java index 3e1280f054..774748022e 100644 --- a/fda-query-service/services/src/main/java/at/tuwien/service/QueryService.java +++ b/fda-query-service/services/src/main/java/at/tuwien/service/QueryService.java @@ -32,7 +32,7 @@ public interface QueryService { * @throws ImageNotSupportedException */ QueryResultDto execute(Long containerId, Long databaseId, ExecuteStatementDto query, Long page, Long size) throws TableNotFoundException, - QueryStoreException, QueryMalformedException, DatabaseNotFoundException, ImageNotSupportedException, ContainerNotFoundException; + QueryStoreException, QueryMalformedException, DatabaseNotFoundException, ImageNotSupportedException, ContainerNotFoundException, SQLException, JSQLParserException; /** * Re-Executes an arbitrary query on the database container. We allow the user to only view the data, therefore the diff --git a/fda-query-service/services/src/main/java/at/tuwien/service/StoreService.java b/fda-query-service/services/src/main/java/at/tuwien/service/StoreService.java index ed49db862f..12368f14b0 100644 --- a/fda-query-service/services/src/main/java/at/tuwien/service/StoreService.java +++ b/fda-query-service/services/src/main/java/at/tuwien/service/StoreService.java @@ -6,6 +6,7 @@ import at.tuwien.api.database.query.SaveStatementDto; import at.tuwien.exception.*; import at.tuwien.querystore.Query; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import java.time.Instant; import java.util.List; @@ -69,4 +70,8 @@ public interface StoreService { Instant execution) throws QueryStoreException, DatabaseNotFoundException, ImageNotSupportedException, ContainerNotFoundException; + @Transactional(readOnly = true) + Query update(Long containerId, Long databaseId, QueryResultDto result, Long resultNumber, Query metadata) + throws QueryStoreException, DatabaseNotFoundException, ImageNotSupportedException, + ContainerNotFoundException; } diff --git a/fda-query-service/services/src/main/java/at/tuwien/service/impl/QueryServiceImpl.java b/fda-query-service/services/src/main/java/at/tuwien/service/impl/QueryServiceImpl.java index 22a5a66f50..ccbf4f5ff6 100644 --- a/fda-query-service/services/src/main/java/at/tuwien/service/impl/QueryServiceImpl.java +++ b/fda-query-service/services/src/main/java/at/tuwien/service/impl/QueryServiceImpl.java @@ -61,42 +61,12 @@ public class QueryServiceImpl extends HibernateConnector implements QueryService @Override @Transactional public QueryResultDto execute(Long containerId, Long databaseId, ExecuteStatementDto statement, Long page, Long size) - throws DatabaseNotFoundException, ImageNotSupportedException, QueryMalformedException, QueryStoreException, ContainerNotFoundException { - /* find */ - final Database database = databaseService.find(databaseId); - if (!database.getContainer().getImage().getRepository().equals("mariadb")) { - throw new ImageNotSupportedException("Currently only MariaDB is supported"); - } - /* run query */ - final long startSession = System.currentTimeMillis(); - final SessionFactory factory = getSessionFactory(database); - final Session session = factory.openSession(); - log.debug("opened hibernate session in {} ms", System.currentTimeMillis() - startSession); - session.beginTransaction(); - /* prepare the statement */ + throws DatabaseNotFoundException, ImageNotSupportedException, QueryMalformedException, QueryStoreException, ContainerNotFoundException, TableNotFoundException, SQLException, JSQLParserException { Instant i = Instant.now(); - final NativeQuery<?> query = session.createSQLQuery(queryMapper.queryToRawTimestampedQuery(statement.getStatement(), database, i)); - final int affectedTuples; - try { - log.debug("execute raw view-only query {}", statement); - affectedTuples = query.executeUpdate(); - log.info("Execution on database id {} affected {} rows", databaseId, affectedTuples); - session.getTransaction() - .commit(); - } catch (SQLGrammarException e) { - session.close(); - factory.close(); - throw new QueryMalformedException("Query not valid for this database", e); - } - /* map the result to the tables (with respective columns) from the statement metadata */ - final List<TableColumn> columns = parseColumns(databaseId, statement); - final QueryResultDto result = queryMapper.resultListToQueryResultDto(columns, query.getResultList()); - /* Save query in the querystore */ - Query q = storeService.insert(containerId, databaseId, result, statement, i); - result.setId(q.getId()); - session.close(); - factory.close(); - log.debug("query id {}", result.getId()); + Query q = storeService.insert(containerId, databaseId, null, statement, i); + final QueryResultDto result = this.reExecute(containerId,databaseId,q,page,size); + Long resultNumber = 0L; + q = storeService.update(containerId,databaseId,result, resultNumber,q); return result; } diff --git a/fda-query-service/services/src/main/java/at/tuwien/service/impl/StoreServiceImpl.java b/fda-query-service/services/src/main/java/at/tuwien/service/impl/StoreServiceImpl.java index 7fbda87023..992a0767f1 100644 --- a/fda-query-service/services/src/main/java/at/tuwien/service/impl/StoreServiceImpl.java +++ b/fda-query-service/services/src/main/java/at/tuwien/service/impl/StoreServiceImpl.java @@ -146,4 +146,43 @@ public class StoreServiceImpl extends HibernateConnector implements StoreService return query; } + @Override + @Transactional(readOnly = true) + public Query update(Long containerId, Long databaseId, QueryResultDto result, Long resultNumber, Query metadata) + throws QueryStoreException, DatabaseNotFoundException, ImageNotSupportedException, + ContainerNotFoundException { + /* find */ + final Container container = containerService.find(containerId); + final Database database = databaseService.find(databaseId); + if (!database.getContainer().getImage().getRepository().equals("mariadb")) { + throw new ImageNotSupportedException("Currently only MariaDB is supported"); + } + + log.debug("Update database id {}, metadata {}", databaseId, metadata); + /* save */ + final SessionFactory factory = getSessionFactory(database, true); + final Session session = factory.openSession(); + final Transaction transaction = session.beginTransaction(); + final Query query = Query.builder() + .cid(containerId) + .dbid(databaseId) + .query(metadata.getQuery()) + .queryNormalized(metadata.getQuery()) + .queryHash(DigestUtils.sha256Hex(metadata.getQuery())) + .resultNumber(resultNumber) + .resultHash(storeMapper.queryResultDtoToString(result)) + .execution(metadata.getExecution()) + .build(); + session.update(query); + transaction.commit(); + /* store the result in the query store */ + log.info("Update query with id {}", query.getId()); + log.debug("saved query {}", query); + session.close(); + factory.close(); + return query; + } + + + } -- GitLab