package com.megatim.fdxcommons.tools.database.queries; import com.megatim.fdxcommons.model.enumeration.TypeDonnee; import static com.megatim.fdxcommons.model.enumeration.TypeDonnee.ALPHANUMERIQUE; import static com.megatim.fdxcommons.model.enumeration.TypeDonnee.DATE; import static com.megatim.fdxcommons.model.enumeration.TypeDonnee.DECIMAL; import static com.megatim.fdxcommons.model.enumeration.TypeDonnee.NUMERIQUE; import com.megatim.fdxcommons.model.integration.ColumnDefinition; import com.megatim.fdxcommons.tools.database.contrat.AppColumnDefinition; import com.megatim.fdxcommons.tools.database.contrat.QueryMetaData; import com.megatim.fdxcommons.tools.database.contrat.TableName; import com.megatim.fdxcommons.tools.database.exceptions.BadColumnTypeException; import com.megatim.fdxcommons.tools.database.tables.appcolumns.AppColumnDefinitions; import java.sql.Connection; import java.sql.JDBCType; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.Collections; import java.util.List; import javax.naming.NamingException; /** * * @author Gabuntu */ public class CreateTableIfNotExistQuery implements QueryMetaData { private final Connection connection; private final AppColumnDefinitions appColumnDefinitions; private final TableName tableName; private final List columnDefinitions; public CreateTableIfNotExistQuery( TableName tableName, List columnDefinitions, AppColumnDefinitions appColumnDefinitions, Connection connection ) { this.connection = connection; this.appColumnDefinitions = appColumnDefinitions; this.tableName = tableName; this.columnDefinitions = columnDefinitions; } @Override public Void execute() throws SQLException, NamingException, BadColumnTypeException { String query = query(tableName, columnDefinitions); try ( Statement stmt = connection.createStatement()) { stmt.execute(query); } return null; } private String query(TableName tableName, List columns) throws BadColumnTypeException, SQLException { StringBuilder query = new StringBuilder("CREATE TABLE IF NOT EXISTS " + tableName.name(connection) + "("); List primaryKeys = new ArrayList<>(); //Ordonner les colonnes par ordre croissant des positions, afin de les insérer dans cet ordre Collections.sort(columns, (ColumnDefinition c1, ColumnDefinition c2) -> Integer.valueOf(c1.getPosition()).compareTo(c2.getPosition())); for (ColumnDefinition columnDefinition : columns) { query.append(columnDefinition.getName().toLowerCase()).append(" ").append(sqlColumnType(columnDefinition)).append(", "); } for (AppColumnDefinition appColumnDefinition : appColumnDefinitions.appColumns()) { query.append(columnDefinitonString(appColumnDefinition)).append(", "); if (appColumnDefinition.isPrimaryKey()) { primaryKeys.add(appColumnDefinition); } } if (!primaryKeys.isEmpty()) { query.append(" PRIMARY KEY("); primaryKeys.stream().forEach(pk -> query.append(pk.name()).append(", ")); //Retirer la dernière virgule query.replace(query.length() - 2, query.length(), "));"); } else { //Retirer la dernière virgule query.replace(query.length() - 2, query.length(), ");"); } return query.toString(); } private String sqlColumnType(ColumnDefinition column) throws BadColumnTypeException { switch (TypeDonnee.fromValeur(column.getTypeDonnee())) { case ALPHANUMERIQUE: return jdbcType(column) + "(" + column.getTaille() + ")"; case NUMERIQUE: return jdbcType(column).getName(); case DATE: return jdbcType(column).getName() + " NULL"; case DECIMAL: return jdbcType(column) + "(" + column.getTaille() + "," + column.getTaillePartieDecimale() + ")"; } throw new BadColumnTypeException("Type de colonne incorrect " + column.getTypeDonnee()); } private JDBCType jdbcType(ColumnDefinition column) throws BadColumnTypeException { switch (TypeDonnee.fromValeur(column.getTypeDonnee())) { case NUMERIQUE: return column.getTaille() < 5 ? JDBCType.SMALLINT : JDBCType.BIGINT; case DECIMAL: return JDBCType.DECIMAL; case DATE: return JDBCType.TIMESTAMP; case ALPHANUMERIQUE: return JDBCType.VARCHAR; } throw new BadColumnTypeException("Type de colonne incorrect " + column.getName()); } private String columnDefinitonString(AppColumnDefinition column) throws BadColumnTypeException { StringBuilder definition = new StringBuilder(); definition .append(column.name().toLowerCase()) .append(" ") .append(column.type()) .append(" ") .append(column.isNull() ? "NULL " : "NOT NULL "); if (column.defaultValue() != null) { definition .append("DEFAULT ") .append(column.defaultValue()); } return definition.toString(); } }