All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.chutneytesting.admin.infra.storage.DatabaseAdminServiceImpl Maven / Gradle / Ivy

package com.chutneytesting.admin.infra.storage;

import com.chutneytesting.admin.domain.DatabaseAdminService;
import com.chutneytesting.admin.domain.SqlResult;
import com.chutneytesting.admin.domain.SqlResult.Row;
import com.chutneytesting.admin.domain.SqlResult.Table;
import com.chutneytesting.tools.ImmutablePaginatedDto;
import com.chutneytesting.tools.PaginatedDto;
import com.chutneytesting.tools.PaginationRequestWrapperDto;
import com.chutneytesting.tools.SqlUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import javax.sql.DataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Component("jdbcAdminService")
class DatabaseAdminServiceImpl implements DatabaseAdminService {

    private static final Logger LOGGER = LoggerFactory.getLogger(DatabaseAdminServiceImpl.class);

    private final DataSource dataSource;

    DatabaseAdminServiceImpl(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    @Override
    public SqlResult execute(String query) {
        String cleanQuery = cleanQuery(query);
        boolean isSelect = isQuerySelect(query);

        String finalQuery = isSelect ? limit(cleanQuery, false) : cleanQuery;
        LOGGER.debug("Executing query {}", finalQuery);
        return executeQuery(finalQuery);
    }

    @Override
    public PaginatedDto paginate(PaginationRequestWrapperDto paginationRequestWrapperDto) {
        SqlResult result;
        String query = paginationRequestWrapperDto.wrappedRequest().orElse("select 1");
        String cleanQuery = cleanQuery(query);
        boolean isQuerySelect = isQuerySelect(cleanQuery);

        long totalCount = 0;
        if (isQuerySelect) {
            String countQuery = SqlUtils.count(cleanQuery);
            try (Connection connection = dataSource.getConnection();
                 Statement statement = connection.createStatement()) {
                boolean dataSelected = statement.execute(countQuery);
                if (dataSelected) {
                    try (ResultSet rs = statement.getResultSet()) {
                        rs.next();
                        totalCount = rs.getLong(1);
                    }
                }
            } catch (SQLException e) {
                result = SqlResult.error("Unable to execute statement[" + countQuery + "]: " + e.getMessage());
                return ImmutablePaginatedDto.builder()
                    .totalCount(totalCount)
                    .addData(result)
                    .build();
            }
        }

        if (isQuerySelect) {
            result = executeQuery(
                limit(cleanQuery, true),
                paginationRequestWrapperDto.elementPerPage(),
                (paginationRequestWrapperDto.pageNumber() -1) * paginationRequestWrapperDto.elementPerPage()

            );
        } else {
            result = executeQuery(cleanQuery);
        }

        return ImmutablePaginatedDto.builder()
            .totalCount(totalCount)
            .addData(result)
            .build();
    }

    private SqlResult executeQuery(String query, Integer...args) {
        SqlResult result;
        try (Connection connection = dataSource.getConnection();
             PreparedStatement statement = connection.prepareStatement(query)) {
            if (args != null && args.length == 2) {
                statement.setInt(1, args[0]);
                statement.setInt(2, args[1]);
            }
            boolean dataSelected = statement.execute();
            if (dataSelected) {
                try (ResultSet rs = statement.getResultSet()) {
                    result = SqlResult.data(resultSetToTable(rs));
                }
            } else {
                result = SqlResult.updatedRows(statement.getUpdateCount());
            }
        } catch (SQLException e) {
            result = SqlResult.error("Unable to execute statement[" + query + "]: " + e.getMessage());
        }
        return result;
    }

    private String limit(String query, boolean paginate) {
        if (query.replaceAll("\\R", " ").matches(".*(?i:limit).*[^)]")) {
            return query;
        }

        if (paginate) {
            return query + " LIMIT ? OFFSET ?";
        } else {
            return query + " LIMIT 20";
        }
    }

    private boolean isQuerySelect(String query) {
        String queryUpper = query.toUpperCase();
        return queryUpper.startsWith("SELECT");
    }

    private String cleanQuery(String query) {
        query = query.trim();
        if (query.endsWith(";")) {
            query = query.substring(0, query.length() - 1);
        }
        return query;
    }

    private Table resultSetToTable(ResultSet rs) throws SQLException {
        ResultSetMetaData metaData = rs.getMetaData();
        List columNames = getColumnNames(metaData);

        List rows = new ArrayList<>();
        while (rs.next()) {
            List values = new ArrayList<>();
            for (String columName : columNames) {
                values.add(rs.getString(columName));
            }
            rows.add(new Row(values));
        }

        return new Table(columNames, rows);
    }

    private List getColumnNames(ResultSetMetaData metaData) throws SQLException {
        int columnCount = metaData.getColumnCount();
        List columNames = new ArrayList<>();
        for (int i = 1; i <= columnCount; i++) {
            columNames.add(metaData.getColumnName(i));
        }
        return columNames;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy