/* * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template */ package com.megatim.fdxcommons.tools.database.queries; import com.megatim.fdxcommons.model.pojo.JsonTableDefinition; import com.megatim.fdxcommons.tools.database.contrat.DefaultPreparedStatementProcessor; import com.megatim.fdxcommons.tools.database.contrat.QueryMetaData; import com.megatim.fdxcommons.tools.database.queries.metadata.QueryCriterion; import com.megatim.fdxcommons.tools.database.queries.metadata.WhereQueryParameters; import com.megatim.fdxcommons.tools.database.tables.appcolumns.IndexColumnDefinition; import com.megatim.fdxcommons.tools.database.tables.appcolumns.ParentIdColumnDefinition; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.naming.NamingException; /** * * @author ASUS */ public class JsonSelectQuery implements QueryMetaData> { private final JsonTableDefinition tableDefinition; private final QueryCriterion queryCriterion; private final Connection connection; private final Map tablesNameToAlias; private final int limit; private final int offset; public JsonSelectQuery(JsonTableDefinition tableDefinition, QueryCriterion queryCriterion, Connection connection, Map tablesNameToAlias) { this(tableDefinition, queryCriterion, connection, tablesNameToAlias, -1, -1); } public JsonSelectQuery(JsonTableDefinition tableDefinition, QueryCriterion queryCriterion, Connection connection, Map tablesNameToAlias, int limit, int offset) { this.tableDefinition = tableDefinition; this.queryCriterion = queryCriterion; this.connection = connection; this.tablesNameToAlias = tablesNameToAlias; this.limit = limit; this.offset = offset; } @Override public Map execute() throws Exception { return result(); } private Map result() throws NamingException, SQLException { Map finalData = new HashMap<>(); String query = selectString() + fromString() + joinString() + whereString() + pagination(); System.out.println("------------------------------------------------------------------------------------"); System.out.println(query); System.out.println("------------------------------------------------------------------------------------"); try ( PreparedStatement statement = connection.prepareStatement(query)) { new DefaultPreparedStatementProcessor().process(statement, new WhereQueryParameters(queryCriterion).parameters()); ResultSet resultSet = statement.executeQuery(); List indexes = new ArrayList<>(); while (resultSet.next()) { indexes.add(resultSet.getLong(new IndexColumnDefinition().name())); } for (Long l : indexes) { Map data = selectData(l, tableDefinition.getTableName()); for (JsonTableDefinition t : tableDefinition.getTablesDefinition()) { data.put(t.getParentFieldName().toLowerCase(), selectChildren(l, t)); } finalData.put(l, data); } } return finalData; } private Map selectData(Long index, String tableName) throws SQLException { Map data = new HashMap<>(); String query = "SELECT * FROM " + tableName + " WHERE " + new IndexColumnDefinition().name() + " = ?"; try ( PreparedStatement statement = connection.prepareStatement(query)) { statement.setLong(1, index); ResultSet resultSet = statement.executeQuery(); ResultSetMetaData metaData = resultSet.getMetaData(); int columnCount = metaData.getColumnCount(); if (resultSet.next()) { for (int i = 1; i <= columnCount; i++) { data.put(metaData.getColumnName(i).trim().toLowerCase(), resultSet.getObject(i)); } } } return data; } private Map selectChildren(Long index, JsonTableDefinition tableDef) throws SQLException { Map finalData = new HashMap<>(); String query = "SELECT * FROM " + tableDef.getTableName() + " WHERE " + new ParentIdColumnDefinition().name() + " = ?"; try ( PreparedStatement statement = connection.prepareStatement(query)) { statement.setLong(1, index); ResultSet resultSet = statement.executeQuery(); Map data = retrieveData(resultSet); if (!tableDef.getTablesDefinition().isEmpty()) { for (Map.Entry entry : data.entrySet()) { Map map = new HashMap<>(); map.putAll((Map) entry.getValue()); for (JsonTableDefinition t : tableDef.getTablesDefinition()) { map.put(t.getParentFieldName().toLowerCase(), selectChildren(entry.getKey(), t)); } finalData.put(entry.getKey(), map); } } else { finalData.putAll(data); } } return finalData; } private Map retrieveData(ResultSet resultSet) throws SQLException { Map data = new HashMap<>(); ResultSetMetaData metaData = resultSet.getMetaData(); int columnCount = metaData.getColumnCount(); while (resultSet.next()) { Map datum = new HashMap<>(); for (int i = 1; i <= columnCount; i++) { datum.put(metaData.getColumnName(i).trim().toLowerCase(), resultSet.getObject(i)); } data.put(resultSet.getLong(new IndexColumnDefinition().name()), datum); } return data; } private String whereString() { return "\n" + new WhereQueryString(queryCriterion).query(); } private String pagination() { if (limit > 0 && offset >= 0) { return " LIMIT " + limit + " OFFSET " + offset; } return ""; } private String fromString() { StringBuilder fromPart = new StringBuilder("\nFROM "); fromPart .append(tableDefinition.getTableName()) .append(" ") .append(tablesNameToAlias.get(tableDefinition.getTableName())); return fromPart.toString(); } private String joinString() { return joinString(tableDefinition.getTablesDefinition()); } private String joinString(List tablesDef) { StringBuilder joinPart = new StringBuilder(""); if (tablesNameToAlias.size() > 1) { for (JsonTableDefinition t : tablesDef) { joinPart.append(joinString(t)); joinPart.append(joinString(t.getTablesDefinition())); } } return joinPart.toString(); } private String joinString(JsonTableDefinition tableDef) { StringBuilder joinPart = new StringBuilder("\nJOIN "); joinPart.append(tableDef.getTableName()) .append(" ") .append(tablesNameToAlias.get(tableDef.getTableName())) .append(" ON ") .append(tablesNameToAlias.get(tableDef.getTableName())) .append(".") .append(new ParentIdColumnDefinition().name()) .append(" = ") .append(tablesNameToAlias.get(tableDef.getParentTableName())) .append(".") .append(new IndexColumnDefinition().name()); return joinPart.toString(); } private String selectString() { return "SELECT " + columnsToSelect(); } private String columnsToSelect() { StringBuilder columnsToSelect = new StringBuilder(""); columnsToSelect .append("DISTINCT(") .append(tablesNameToAlias.get(tableDefinition.getTableName())) .append(".") .append(new IndexColumnDefinition().name()) .append(")"); return columnsToSelect.toString(); } }