PaginatedExpressionSQL.java

  1. /*
  2.  * GovWay - A customizable API Gateway
  3.  * https://govway.org
  4.  *
  5.  * Copyright (c) 2005-2025 Link.it srl (https://link.it).
  6.  *
  7.  * This program is free software: you can redistribute it and/or modify
  8.  * it under the terms of the GNU General Public License version 3, as published by
  9.  * the Free Software Foundation.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18.  *
  19.  */
  20. package org.openspcoop2.generic_project.expression.impl.sql;

  21. import java.util.ArrayList;
  22. import java.util.Arrays;
  23. import java.util.List;
  24. import java.util.Map;

  25. import org.openspcoop2.generic_project.beans.FunctionField;
  26. import org.openspcoop2.generic_project.beans.IField;
  27. import org.openspcoop2.generic_project.beans.IModel;
  28. import org.openspcoop2.generic_project.exception.ExpressionException;
  29. import org.openspcoop2.generic_project.exception.ExpressionNotImplementedException;
  30. import org.openspcoop2.generic_project.expression.LikeMode;
  31. import org.openspcoop2.generic_project.expression.impl.BetweenExpressionImpl;
  32. import org.openspcoop2.generic_project.expression.impl.Comparator;
  33. import org.openspcoop2.generic_project.expression.impl.ComparatorExpressionImpl;
  34. import org.openspcoop2.generic_project.expression.impl.ConjunctionExpressionImpl;
  35. import org.openspcoop2.generic_project.expression.impl.DateTimePartExpressionImpl;
  36. import org.openspcoop2.generic_project.expression.impl.DayFormatExpressionImpl;
  37. import org.openspcoop2.generic_project.expression.impl.InExpressionImpl;
  38. import org.openspcoop2.generic_project.expression.impl.LikeExpressionImpl;
  39. import org.openspcoop2.generic_project.expression.impl.PaginatedExpressionImpl;
  40. import org.openspcoop2.generic_project.expression.impl.formatter.IObjectFormatter;
  41. import org.openspcoop2.utils.TipiDatabase;
  42. import org.openspcoop2.utils.sql.DateTimePartEnum;
  43. import org.openspcoop2.utils.sql.DayFormatEnum;
  44. import org.openspcoop2.utils.sql.ISQLQueryObject;

  45. /**
  46.  * PaginatedExpressionSQL
  47.  *
  48.  * @author Poli Andrea (apoli@link.it)
  49.  * @author $Author$
  50.  * @version $Rev$, $Date$
  51.  */
  52. public class PaginatedExpressionSQL extends PaginatedExpressionImpl {

  53.     private boolean throwExpressionNotInitialized = false;

  54.     private TipiDatabase databaseType;
  55.     public TipiDatabase getDatabaseType() {
  56.         return this.databaseType;
  57.     }
  58.    
  59.     private ISQLFieldConverter sqlFieldConverter;
  60.     public ISQLFieldConverter getSqlFieldConverter() {
  61.         return this.sqlFieldConverter;
  62.     }
  63.     public void setSqlFieldConverter(ISQLFieldConverter sqlFieldConverter) {
  64.         this.sqlFieldConverter = sqlFieldConverter;
  65.     }
  66.    
  67.     private boolean usedForCountExpression = false;
  68.     public boolean isUsedForCountExpression() {
  69.         return this.usedForCountExpression;
  70.     }
  71.     public void setUsedForCountExpression(boolean usedForCountExpression) {
  72.         this.usedForCountExpression = usedForCountExpression;
  73.     }
  74.    
  75.     public PaginatedExpressionSQL(ISQLFieldConverter sqlFieldConverter) throws ExpressionException {
  76.         super();
  77.         this.sqlFieldConverter = sqlFieldConverter;
  78.         if(this.sqlFieldConverter!=null){
  79.             this.databaseType = this.sqlFieldConverter.getDatabaseType();
  80.         }
  81.     }
  82.     public PaginatedExpressionSQL(ISQLFieldConverter sqlFieldConverter,IObjectFormatter objectFormatter) throws ExpressionException{
  83.         super(objectFormatter);
  84.         this.sqlFieldConverter = sqlFieldConverter;
  85.         if(this.sqlFieldConverter!=null){
  86.             this.databaseType = this.sqlFieldConverter.getDatabaseType();
  87.         }
  88.     }
  89.     public PaginatedExpressionSQL(ExpressionSQL expression) throws ExpressionException {
  90.         super(expression);
  91.         this.sqlFieldConverter = expression.getSqlFieldConverter();
  92.         this.fieldsManuallyAdd = expression.getFieldsManuallyAdd();
  93.         /**this.checkFieldManuallyAdd = expression.checkFieldManuallyAdd;*/
  94.         if(this.sqlFieldConverter!=null){
  95.             this.databaseType = this.sqlFieldConverter.getDatabaseType();
  96.         }
  97.     }
  98.    
  99.     private List<Object> fieldsManuallyAdd = new ArrayList<>();
  100.     public List<Object> getFieldsManuallyAdd() {
  101.         return this.fieldsManuallyAdd;
  102.     }
  103.     public void removeFieldManuallyAdd(Object o) {
  104.         if(this.fieldsManuallyAdd.contains(o)){
  105.             this.fieldsManuallyAdd.remove(o);
  106.         }
  107.     }
  108.    
  109.     private boolean checkFieldManuallyAdd = true;
  110.     public void setCheckFieldManuallyAdd(boolean checkFieldManuallyAdd) {
  111.         this.checkFieldManuallyAdd = checkFieldManuallyAdd;
  112.     }
  113.     @Override
  114.     public boolean inUseField(IField field,boolean checkOnlyWhereCondition) throws ExpressionNotImplementedException, ExpressionException {
  115.         return ExpressionSQL.inUse(field, checkOnlyWhereCondition, super.inUseField(field,checkOnlyWhereCondition), this.getFieldsManuallyAdd(),this.checkFieldManuallyAdd);
  116.     }
  117.     @Override
  118.     public boolean inUseModel(IModel<?> model,boolean checkOnlyWhereCondition) throws ExpressionNotImplementedException, ExpressionException {
  119.         return ExpressionSQL.inUse(model, checkOnlyWhereCondition, super.inUseModel(model,checkOnlyWhereCondition), this.getFieldsManuallyAdd(),this.checkFieldManuallyAdd);
  120.     }
  121.     @Override
  122.     public List<IField> getFields(boolean onlyWhereCondition) throws ExpressionNotImplementedException, ExpressionException{
  123.         return ExpressionSQL.getFields(onlyWhereCondition, super.getFields(onlyWhereCondition), this.getFieldsManuallyAdd(),this.checkFieldManuallyAdd);
  124.     }
  125.    
  126.    
  127.     /* ************ COMPARATOR *********** */
  128.    
  129.     @Override
  130.     protected Comparator getCorrectComparator(Comparator comparator){
  131.         return ExpressionSQL.getCorrectComparator(comparator, this.databaseType);
  132.     }
  133.    

  134.    
  135.     /* ************ TO SQL *********** */
  136.    
  137.     private String toSqlEngine(SQLMode mode,List<Object> oggettiPreparedStatement,Map<String, Object> oggettiJPA)throws ExpressionException{
  138.            
  139.         ISQLExpression sqlExpression = null;
  140.         if(this.expressionEngine!=null){
  141.             if(this.expressionEngine instanceof ISQLExpression){
  142.                 sqlExpression = (ISQLExpression)this.expressionEngine;
  143.             }else{
  144.                 throw new ExpressionException("ExpressioneEngine (type:"+this.expressionEngine.getClass().getName()+") is not as cast with "+ISQLExpression.class.getName());
  145.             }
  146.         }else{
  147.             if(this.throwExpressionNotInitialized)
  148.                 throw new ExpressionException("Expression is not initialized");
  149.         }
  150.        
  151.         String s = null;
  152.         if(this.expressionEngine!=null){
  153.             switch (mode) {
  154.             case STANDARD:
  155.                 s = sqlExpression.toSql();
  156.                 break;
  157.             case PREPARED_STATEMENT:
  158.                 s = sqlExpression.toSqlPreparedStatement(oggettiPreparedStatement);
  159.                 break;
  160.             case JPA:
  161.                 s = sqlExpression.toSqlJPA(oggettiJPA);
  162.                 break;
  163.             }
  164.         }else{
  165.             s = "";
  166.         }
  167.        
  168.         StringBuilder bf = new StringBuilder();
  169.         bf.append(s);

  170.         bf.append(ExpressionSQL.sqlGroupBy(this.sqlFieldConverter, this.getGroupByFields()));
  171.        
  172.         bf.append(ExpressionSQL.sqlOrder(this.sqlFieldConverter, this.getSortOrder(), this.getOrderedFields()));
  173.                
  174.         if(!SQLMode.JPA.equals(mode)){
  175.             if(this.getLimit()!=null && this.getLimit()>=0){
  176.                 bf.append(" LIMIT "+this.getLimit());
  177.             }
  178.             if(this.getOffset()!=null && this.getOffset()>=0){
  179.                 bf.append(" OFFSET "+this.getOffset());
  180.             }
  181.         }
  182.        
  183.         bf.append(ExpressionSQL.sqlForceIndex(this.sqlFieldConverter, this.getForceIndexes())); // Lo metto in fondo tanto sono commenti
  184.        
  185.         return bf.toString();
  186.        
  187.     }
  188.    
  189.     private void toSqlEngine(ISQLQueryObject sqlQueryObject,SQLMode mode,List<Object> oggettiPreparedStatement,Map<String, Object> oggettiJPA)throws ExpressionException{
  190.    
  191.         ISQLExpression sqlExpression = null;
  192.         if(this.expressionEngine!=null){
  193.             if(this.expressionEngine instanceof ISQLExpression){
  194.                 sqlExpression = (ISQLExpression)this.expressionEngine;
  195.             }else{
  196.                 throw new ExpressionException("ExpressioneEngine (type:"+this.expressionEngine.getClass().getName()+") is not as cast with "+ISQLExpression.class.getName());
  197.             }
  198.         }else{
  199.             if(this.throwExpressionNotInitialized)
  200.                 throw new ExpressionException("Expression is not initialized");
  201.         }
  202.        
  203.         if(this.expressionEngine!=null){
  204.             switch (mode) {
  205.             case STANDARD:
  206.                 sqlExpression.toSql(sqlQueryObject);
  207.                 break;
  208.             case PREPARED_STATEMENT:
  209.                 sqlExpression.toSqlPreparedStatement(sqlQueryObject,oggettiPreparedStatement);
  210.                 break;
  211.             case JPA:
  212.                 sqlExpression.toSqlJPA(sqlQueryObject,oggettiJPA);
  213.                 break;
  214.             }
  215.         }
  216.        
  217.         try{
  218.                
  219.             // GroupBy
  220.             ExpressionSQL.sqlGroupBy(this.sqlFieldConverter, sqlQueryObject, this.getGroupByFields());
  221.                        
  222.             // OrderBy
  223.             ExpressionSQL.sqlOrder(this.sqlFieldConverter, sqlQueryObject,this.getSortOrder(), this.getOrderedFields(), this.getGroupByFields());
  224.                        
  225.             // Aggiungo select field relativi all'aggregazione
  226.             ExpressionSQL.sqlGroupBySelectField(this.sqlFieldConverter, sqlQueryObject, this.getFieldsManuallyAdd(),
  227.                     this.getGroupByFields(), this.usedForCountExpression);
  228.                        
  229.             if(!SQLMode.JPA.equals(mode)){
  230.                 if(this.getLimit()!=null && this.getLimit()>=0){
  231.                     sqlQueryObject.setLimit(this.getLimit());
  232.                 }
  233.                
  234.                 if(this.getOffset()!=null && this.getOffset()>=0){
  235.                     sqlQueryObject.setOffset(this.getOffset());
  236.                 }
  237.             }
  238.            
  239.             // ForceIndex
  240.             ExpressionSQL.sqlForceIndex(this.sqlFieldConverter, sqlQueryObject, this.getForceIndexes());
  241.            
  242.         }catch(Exception e){
  243.             throw new ExpressionException(e);
  244.         }
  245.        
  246.     }
  247.    
  248.     public String toSql() throws ExpressionException{
  249.         return toSqlEngine(SQLMode.STANDARD, null, null);
  250.     }
  251.     protected String toSqlPreparedStatement(List<Object> oggetti) throws ExpressionException {
  252.         return toSqlEngine(SQLMode.PREPARED_STATEMENT, oggetti, null);
  253.     }
  254.     protected String toSqlJPA(Map<String, Object> oggetti) throws ExpressionException {
  255.         return toSqlEngine(SQLMode.JPA, null, oggetti);
  256.     }
  257.    
  258.     public void toSql(ISQLQueryObject sqlQueryObject)throws ExpressionException{
  259.         toSqlEngine(sqlQueryObject,SQLMode.STANDARD, null, null);
  260.     }
  261.     public void toSqlWithFromCondition(ISQLQueryObject sqlQueryObject,String tableNamePrincipale) throws ExpressionException, ExpressionNotImplementedException{
  262.        
  263.         // preparo condizione di where
  264.         this.toSql(sqlQueryObject);
  265.        
  266.         // aggiungo condizione di from
  267.         ExpressionSQL.sqlFrom(sqlQueryObject, this.getFields(false), this.getSqlFieldConverter(), tableNamePrincipale, this.getFieldsManuallyAdd(),
  268.                 this.getOrderedFields(),this.getGroupByFields());
  269.     }
  270.    
  271.     protected void toSqlPreparedStatement(ISQLQueryObject sqlQueryObject,List<Object> oggetti)throws ExpressionException{
  272.         toSqlEngine(sqlQueryObject,SQLMode.PREPARED_STATEMENT, oggetti, null);
  273.     }
  274.     protected void toSqlPreparedStatementWithFromCondition(ISQLQueryObject sqlQueryObject,List<Object> oggetti,String tableNamePrincipale) throws ExpressionException, ExpressionNotImplementedException{
  275.        
  276.         // preparo condizione di where
  277.         this.toSqlPreparedStatement(sqlQueryObject, oggetti);
  278.        
  279.         // aggiungo condizione di from
  280.         ExpressionSQL.sqlFrom(sqlQueryObject, this.getFields(false), this.getSqlFieldConverter(), tableNamePrincipale, this.getFieldsManuallyAdd(),
  281.                 this.getOrderedFields(),this.getGroupByFields());
  282.     }
  283.    
  284.     protected void toSqlJPA(ISQLQueryObject sqlQueryObject,Map<String, Object> oggetti)throws ExpressionException{
  285.         toSqlEngine(sqlQueryObject,SQLMode.JPA, null, oggetti);
  286.     }
  287.     protected void toSqlJPAWithFromCondition(ISQLQueryObject sqlQueryObject,Map<String, Object> oggetti,String tableNamePrincipale) throws ExpressionException, ExpressionNotImplementedException{
  288.        
  289.         // preparo condizione di where
  290.         this.toSqlJPA(sqlQueryObject, oggetti);
  291.        
  292.         // aggiungo condizione di from
  293.         ExpressionSQL.sqlFrom(sqlQueryObject, this.getFields(false), this.getSqlFieldConverter(), tableNamePrincipale, this.getFieldsManuallyAdd(),
  294.                 this.getOrderedFields(),this.getGroupByFields());
  295.     }
  296.    
  297.     public void addField(ISQLQueryObject sqlQueryObject, IField field, boolean appendTablePrefix)throws ExpressionException{
  298.         ExpressionSQL.addFieldEngine(sqlQueryObject,this.getSqlFieldConverter(),field, null, appendTablePrefix);
  299.         this.getFieldsManuallyAdd().add(field);
  300.     }
  301.     public void addField(ISQLQueryObject sqlQueryObject, IField field, String aliasField, boolean appendTablePrefix)throws ExpressionException{
  302.         ExpressionSQL.addFieldEngine(sqlQueryObject,this.getSqlFieldConverter(),field, aliasField, appendTablePrefix);
  303.         this.getFieldsManuallyAdd().add(field);
  304.     }
  305.     public void addAliasField(ISQLQueryObject sqlQueryObject, IField field, boolean appendTablePrefix)throws ExpressionException{
  306.         ExpressionSQL.addAliasFieldEngine(sqlQueryObject,this.getSqlFieldConverter(),field, null, appendTablePrefix);
  307.         this.getFieldsManuallyAdd().add(field);
  308.     }
  309.     public void addField(ISQLQueryObject sqlQueryObject, FunctionField field, boolean appendTablePrefix)throws ExpressionException{
  310.         ExpressionSQL.addFieldEngine(sqlQueryObject,this.getSqlFieldConverter(),field, null, appendTablePrefix);
  311.         this.getFieldsManuallyAdd().add(field);
  312.     }

  313.    
  314.    
  315.     /* ************ OBJECTS ************ */
  316.     @Override
  317.     protected ComparatorExpressionImpl getComparatorExpression(IField field, Object value, Comparator c) {
  318.         return new ComparatorExpressionSQL(this.sqlFieldConverter,this.objectFormatter,field,value,c);
  319.     }
  320.     @Override
  321.     protected BetweenExpressionImpl getBetweenExpression(IField field, Object lower, Object high) {
  322.         return new BetweenExpressionSQL(this.sqlFieldConverter,this.objectFormatter,field,lower,high);
  323.     }
  324.     @Override
  325.     protected InExpressionImpl getInExpression(IField field, Object... values) {
  326.         List<Object> lista = new ArrayList<>();
  327.         if(values!=null && values.length>0){
  328.             lista.addAll(Arrays.asList(values));
  329.         }
  330.         return new InExpressionSQL(this.sqlFieldConverter,this.objectFormatter,field, lista);
  331.     }
  332.     @Override
  333.     protected LikeExpressionImpl getLikeExpression(IField field, String value, LikeMode mode, boolean caseInsensitive) {
  334.         return new LikeExpressionSQL(this.sqlFieldConverter,this.objectFormatter,field, value, mode, caseInsensitive);
  335.     }
  336.     @Override
  337.     protected DateTimePartExpressionImpl getDateTimePartExpression(IField field, String value, DateTimePartEnum dateTimePartEnum) {
  338.         return new DateTimePartExpressionSQL(this.sqlFieldConverter,this.objectFormatter,field, value, dateTimePartEnum);
  339.     }
  340.     @Override
  341.     protected DayFormatExpressionImpl getDayFormatExpression(IField field, String value, DayFormatEnum dayFormatEnum) {
  342.         return new DayFormatExpressionSQL(this.sqlFieldConverter,this.objectFormatter,field, value, dayFormatEnum);
  343.     }
  344.     @Override
  345.     protected ConjunctionExpressionImpl getConjunctionExpression() {
  346.         return new ConjunctionExpressionSQL(this.sqlFieldConverter,this.objectFormatter);
  347.     }
  348.    
  349. }