|
| 1 | +package com.scriptql.api.services; |
| 2 | + |
| 3 | +import com.opencsv.CSVWriter; |
| 4 | +import com.scriptql.api.domain.entities.DatabaseConnection; |
| 5 | +import com.scriptql.api.domain.entities.Query; |
| 6 | +import com.scriptql.api.domain.enums.DatabaseDriver; |
| 7 | +import com.scriptql.api.domain.enums.QueryStatus; |
| 8 | +import com.scriptql.api.domain.repositories.QueryRepository; |
| 9 | +import org.springframework.stereotype.Service; |
| 10 | + |
| 11 | +import java.io.ByteArrayOutputStream; |
| 12 | +import java.io.IOException; |
| 13 | +import java.io.OutputStreamWriter; |
| 14 | +import java.sql.*; |
| 15 | +import java.util.concurrent.ExecutorService; |
| 16 | +import java.util.concurrent.Executors; |
| 17 | + |
| 18 | +@Service |
| 19 | +public class ExecutionService { |
| 20 | + |
| 21 | + private final QueryRepository repository; |
| 22 | + private final ExecutorService scheduler = Executors.newCachedThreadPool(); |
| 23 | + |
| 24 | + public ExecutionService(QueryRepository repository) { |
| 25 | + this.repository = repository; |
| 26 | + } |
| 27 | + |
| 28 | + public void execute(Query query) { |
| 29 | + this.scheduler.submit(() -> this.onExecute(query)); |
| 30 | + } |
| 31 | + |
| 32 | + private void onExecute(Query query) { |
| 33 | + try (Connection connection = this.open(query.getConnection())) { |
| 34 | + String sql = query.getQuery(); |
| 35 | + boolean isSelect = sql.toUpperCase().startsWith("SELECT"); |
| 36 | + if (isSelect) { |
| 37 | + connection.setReadOnly(true); |
| 38 | + } |
| 39 | + try (PreparedStatement ps = connection.prepareStatement(sql)) { |
| 40 | + if (isSelect) { |
| 41 | + try (ResultSet rs = ps.executeQuery()) { |
| 42 | + ByteArrayOutputStream stream = new ByteArrayOutputStream(); |
| 43 | + try (CSVWriter writer = new CSVWriter(new OutputStreamWriter(stream))) { |
| 44 | + writer.writeAll(rs, true, false, true); |
| 45 | + } |
| 46 | + query.setResult(stream.toByteArray()); |
| 47 | + } |
| 48 | + } else { |
| 49 | + int result = ps.executeUpdate(); |
| 50 | + ByteArrayOutputStream stream = new ByteArrayOutputStream(); |
| 51 | + try (CSVWriter writer = new CSVWriter(new OutputStreamWriter(stream))) { |
| 52 | + writer.writeNext(new String[]{"updated", String.valueOf(result)}); |
| 53 | + } |
| 54 | + query.setResult(stream.toByteArray()); |
| 55 | + } |
| 56 | + } |
| 57 | + query.setStatus(QueryStatus.DONE); |
| 58 | + } catch (SQLException | IOException e) { |
| 59 | + query.setStatus(QueryStatus.ERROR); |
| 60 | + query.setError(e.getMessage()); |
| 61 | + } finally { |
| 62 | + query.setExecutionDate(System.currentTimeMillis()); |
| 63 | + query.setUpdatedAt(System.currentTimeMillis()); |
| 64 | + this.repository.save(query); |
| 65 | + } |
| 66 | + } |
| 67 | + |
| 68 | + private Connection open(DatabaseConnection details) throws SQLException { |
| 69 | + String url; |
| 70 | + if (details.getDriver() == DatabaseDriver.MYSQL) { |
| 71 | + url = String.format("jdbc:mysql://%s:%s/%s", |
| 72 | + details.getHost(), details.getPort(), details.getDatabase()); |
| 73 | + } else { |
| 74 | + url = String.format("jdbc:postgresql://%s:%s/%s", |
| 75 | + details.getHost(), details.getPort(), details.getDatabase()); |
| 76 | + } |
| 77 | + return DriverManager.getConnection(url, details.getUsername(), details.getPassword()); |
| 78 | + } |
| 79 | + |
| 80 | +} |
0 commit comments