Skip to content
Snippets Groups Projects
Commit 8eadc95c authored by Moritz Staudinger's avatar Moritz Staudinger
Browse files

refactored execute to use re-execute, limited on resultnumber

Former-commit-id: 60fdf6dc
parent 607c8abe
No related branches found
No related tags found
No related merge requests found
......@@ -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);
......
......@@ -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();
......
......@@ -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();
......
......@@ -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
......
......@@ -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;
}
......@@ -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;
}
......
......@@ -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;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment