package com.megatim.fdxcommons.tools.database.tables; import com.megatim.fdxcommons.model.dataproduction.CommonDataProduction; import com.megatim.fdxcommons.tools.database.queries.*; import com.megatim.fdxcommons.tools.database.tables.appcolumns.DataProductionIdColumnDefinition; import com.megatim.fdxcommons.model.enumeration.CriteriaLogicConnector; import com.megatim.fdxcommons.model.enumeration.FonctionAggregation; import com.megatim.fdxcommons.model.enumeration.Operateur; import com.megatim.fdxcommons.model.integration.ColumnDefinition; import com.megatim.fdxcommons.tools.database.contrat.AppColumnDefinition; import com.megatim.fdxcommons.tools.database.contrat.TableName; import com.megatim.fdxcommons.tools.database.exceptions.TableNotCummulativeException; import com.megatim.fdxcommons.tools.database.exceptions.TypeFichierDataBadRequest; import com.megatim.fdxcommons.tools.database.queries.metadata.FdxTableDefinition; import com.megatim.fdxcommons.tools.database.queries.metadata.ParsedQueryCriterion; import com.megatim.fdxcommons.tools.database.queries.metadata.QueryCriterion; import com.megatim.fdxcommons.tools.database.queries.metadata.SelectQueryResult; import java.sql.Connection; import java.sql.SQLException; import java.util.Arrays; import java.util.List; import java.util.Map; import javax.naming.NamingException; /** * * @author ASUS */ public abstract class FdxTable { protected final TableName tableName; protected final String codeTypeFichier; protected final String referentielVersion; protected FdxTable(String codeTypeFichier, String referentielVersion) { this.tableName = new FdxTableName(referentielVersion, codeTypeFichier); this.codeTypeFichier = codeTypeFichier; this.referentielVersion = referentielVersion; } public boolean checkIfTableExists(Connection connection) throws SQLException { return new TableDefinitionQueries(tableName.name(connection), connection).tableExists(); } public boolean checkIfConstraintExists(Connection connection) throws SQLException { final String name = tableName.name(connection); String constraintName = name + "_pkey"; return new TableDefinitionQueries(tableName.name(connection), connection).constraintExists(constraintName); } public boolean checkIfColumnExists(Connection connection, String columnName) throws SQLException { return new TableDefinitionQueries(tableName.name(connection), connection).columnExists(columnName); } public void addAppColumn(Connection connection, AppColumnDefinition appColumn) throws SQLException { new TableDefinitionQueries(tableName.name(connection), connection).addAppColumn(appColumn); } public void dropAppColumn(Connection connection, AppColumnDefinition appColumn) throws SQLException { new TableDefinitionQueries(tableName.name(connection), connection).dropAppColumn(appColumn); } public void dropPkConstraint(Connection connection) throws SQLException { final String name = tableName.name(connection); String constraintName = name + "_pkey"; new TableDefinitionQueries(name, connection).dropConstraint(constraintName); } public void addPkConstraint(Connection connection) throws SQLException { final String name = tableName.name(connection); String constraintName = name + "_pkey"; new TableDefinitionQueries(name, connection).addPkConstraint(constraintName); } public FdxTableColumns tableColumns(Connection connection) { return new FdxTableColumns(tableName, connection); } public FdxTableDefinition tableDefinition(Connection connection) { return new FdxTableDefinition(referentielVersion, codeTypeFichier, connection); } public String latestDataProductionToken(Connection connection) throws SQLException { return new LatestDataProductionTokenQuery(connection, referentielVersion, codeTypeFichier).execute(); } public synchronized SelectQueryResult selectResult(QueryCriterion queryCriterion, Connection connection) throws NamingException, SQLException, Exception { QueryCriterion finalCriterion = tableDefinition(connection).isReferentiel() ? addLatestDataProductionCriterion(queryCriterion, connection) : queryCriterion; SelectQueryResult result = new SelectQuery(tableName.name(connection), connection, parsedQueryCriterion(finalCriterion, connection).parsedCriterion(), Arrays.asList(), false).execute(); setToken(connection, result); return result; } public synchronized SelectQueryResult selectResult(Connection connection, Long dataProductionId) throws NamingException, SQLException, Exception { QueryCriterion queryCriterion = new QueryCriterion(new DataProductionIdColumnDefinition().name(), dataProductionId, Operateur.EQUALS, CriteriaLogicConnector.AND, Arrays.asList()); SelectQueryResult result = new SelectQuery(tableName.name(connection), connection, queryCriterion, Arrays.asList(), false).execute(); setToken(connection, result); return result; } public synchronized SelectQueryResult selectResultWithAllColumns(QueryCriterion queryCriterion, Connection connection) throws NamingException, SQLException, Exception { QueryCriterion finalCriterion = tableDefinition(connection).isReferentiel() ? addLatestDataProductionCriterion(queryCriterion, connection) : queryCriterion; SelectQueryResult result = new SelectQuery(tableName.name(connection), connection, parsedQueryCriterion(finalCriterion, connection).parsedCriterion(), Arrays.asList(), true).execute(); setToken(connection, result); return result; } public synchronized SelectQueryResult selectResult(QueryCriterion queryCriterion, Connection connection, int limit, int offset) throws NamingException, SQLException, Exception { QueryCriterion finalCriterion = tableDefinition(connection).isReferentiel() ? addLatestDataProductionCriterion(queryCriterion, connection) : queryCriterion; SelectQueryResult result = new SelectQuery(tableName.name(connection), connection, parsedQueryCriterion(finalCriterion, connection).parsedCriterion(), Arrays.asList(), limit, offset, false).execute(); setToken(connection, result); return result; } public synchronized SelectQueryResult selectResultRegardlessOfNatureProduction(QueryCriterion queryCriterion, Connection connection) throws NamingException, SQLException, Exception { SelectQueryResult result = new SelectQuery(tableName.name(connection), connection, parsedQueryCriterion(queryCriterion, connection).parsedCriterion(), Arrays.asList(), true).execute(); setToken(connection, result); return result; } public synchronized Long countRegardlessOfNatureProduction(QueryCriterion queryCriterion, Connection connection) throws NamingException, SQLException, Exception { List results = new CountQuery( tableName.name(connection), connection, parsedQueryCriterion(queryCriterion, connection).parsedCriterion(), Arrays.asList() ).execute(); return !results.isEmpty() ? Long.valueOf(results.get(0)[0]) : 0; } public synchronized Long count(QueryCriterion queryCriterion, Connection connection) throws NamingException, SQLException, Exception { QueryCriterion finalCriterion = tableDefinition(connection).isReferentiel() ? addLatestDataProductionCriterion(queryCriterion, connection) : queryCriterion; List results = new CountQuery( tableName.name(connection), connection, parsedQueryCriterion(finalCriterion, connection).parsedCriterion(), Arrays.asList() ).execute(); return !results.isEmpty() ? Long.valueOf(results.get(0)[0]) : 0; } public synchronized List count(QueryCriterion queryCriterion, Connection connection, List groupingColumns) throws NamingException, SQLException, Exception { QueryCriterion finalCriterion = tableDefinition(connection).isReferentiel() ? addLatestDataProductionCriterion(queryCriterion, connection) : queryCriterion; return new CountQuery( tableName.name(connection), connection, parsedQueryCriterion(finalCriterion, connection).parsedCriterion(), groupingColumns ).execute(); } public synchronized List aggregate(Connection connection, String targetColumn, List groupingColumns, FonctionAggregation fonctionAggregation, QueryCriterion queryCriterion) throws NamingException, SQLException, Exception { return new AggregationQuery( tableName.name(connection), connection, parsedQueryCriterion(queryCriterion, connection).parsedCriterion(), targetColumn, groupingColumns, fonctionAggregation ).execute(); } public synchronized void delete(QueryCriterion queryCriterion, CommonDataProduction dataProduction, Connection connection) throws TypeFichierDataBadRequest, SQLException, NamingException, Exception { stopIfTableIsReferentiel(connection); ParsedQueryCriterion parsedQueryCriterion = parsedQueryCriterion(queryCriterion, connection); processDelete(parsedQueryCriterion.parsedCriterion(), dataProduction, connection); } public ParsedQueryCriterion parsedQueryCriterion(QueryCriterion queryCriterion, Connection connection) throws NamingException, SQLException { return new ParsedQueryCriterion(queryCriterion, tableColumns(connection), tableDefinition(connection).tableDefinition().getColumnDefinitions()); } protected void processDelete(QueryCriterion queryCriterion, CommonDataProduction dataProduction, Connection connection) throws NamingException, Exception, SQLException { new DeleteQuery(tableName.name(connection), connection, parsedQueryCriterion(queryCriterion, connection).parsedCriterion(), dataProduction).execute(); } protected void processPermanentDelete(QueryCriterion queryCriterion, Connection connection) throws NamingException, Exception, SQLException { new PermanentDeleteQuery(tableName.name(connection), connection, parsedQueryCriterion(queryCriterion, connection).parsedCriterion()).execute(); } protected void stopIfTableIsReferentiel(Connection connection) throws SQLException, NamingException, TableNotCummulativeException { if (tableDefinition(connection).isReferentiel()) { throw new TableNotCummulativeException("Opération non autorisée car la table est référentielle"); } } public abstract void createTable(List columnsDefinition, Connection connection) throws NamingException, SQLException, Exception; public abstract void deleteOne(QueryCriterion queryCriterion, CommonDataProduction dataProduction, Connection connection) throws TypeFichierDataBadRequest, SQLException, NamingException, Exception; public abstract void updateOne(Map dataToUpdate, QueryCriterion queryCriterion, CommonDataProduction dataProduction, Connection connection) throws TypeFichierDataBadRequest, SQLException, NamingException, Exception; public abstract void update(Map dataToUpdate, QueryCriterion queryCriterion, CommonDataProduction dataProduction, Connection connection) throws TypeFichierDataBadRequest, SQLException, NamingException, Exception; public TableName getTableName() { return tableName; } private QueryCriterion addLatestDataProductionCriterion(QueryCriterion queryCriterion, Connection connection) throws SQLException { Long latestDataProductionId = new MaxDataProductionIdQuery(tableName.name(connection), connection).execute(); if (latestDataProductionId > 0) { return new QueryCriterion(null, null, null, CriteriaLogicConnector.AND, Arrays.asList(queryCriterion, new QueryCriterion(new DataProductionIdColumnDefinition().name(), latestDataProductionId, Operateur.EQUALS, null, Arrays.asList()) ) ); } else { return queryCriterion; } } private void setToken(Connection connection, SelectQueryResult result) throws SQLException { String token = latestDataProductionToken(connection); result.setToken(token); } }