MySQLQueryObject.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.utils.sql;

  21. import java.text.SimpleDateFormat;
  22. import java.util.Date;
  23. import java.util.Iterator;

  24. import org.openspcoop2.utils.TipiDatabase;
  25. import org.openspcoop2.utils.date.DateUtils;


  26. /**
  27.  * Classe dove vengono forniti utility per la conversione di comandi SQL per il database mysql
  28.  *
  29.  *
  30.  * @author Poli Andrea (apoli@link.it)
  31.  * @author $Author$
  32.  * @version $Rev$, $Date$
  33.  */
  34. public class MySQLQueryObject extends SQLQueryObjectCore{
  35.        
  36.    
  37.    
  38.     public MySQLQueryObject(TipiDatabase tipoDatabase) {
  39.         super(tipoDatabase);
  40.     }


  41.    
  42.     /**
  43.      * Ritorna una costante  di tipo 'timestamp'
  44.      *
  45.      * @param date Costante
  46.      */
  47.     @Override
  48.     public String getSelectTimestampConstantField(Date date) throws SQLQueryObjectException{
  49.         SimpleDateFormat sqlDateformat = DateUtils.getDefaultDateTimeFormatter("yyyy-MM-dd HH:mm:ss.SSS");
  50.         return "STR_TO_DATE('"+sqlDateformat.format(date)+"', '%Y-%m-%d %H:%i:%s.%f')";
  51.     }
  52.    
  53.    
  54.    
  55.    
  56.    
  57.     @Override
  58.     public String getUnixTimestampConversion(String column){
  59.         return "(UNIX_TIMESTAMP("+column+")*1000)";
  60.     }
  61.    
  62.     @Override
  63.     public String getDiffUnixTimestamp(String columnMax,String columnMin){
  64.         return "( "+getUnixTimestampConversion(columnMax)+" - "+getUnixTimestampConversion(columnMin)+" )";
  65.     }
  66.    
  67.    
  68.    
  69.     /**
  70.      * Aggiunge un field count alla select, con un alias, del campo <var>fieldAvg</var> (di tipo Timestamp)
  71.      * es: SELECT avg(fieldAvg) as alias FROM ....
  72.      *
  73.       * @param field Nome del Field
  74.      * @param alias Alias
  75.      */
  76.     @Override
  77.     public ISQLQueryObject addSelectAvgTimestampField(String field,String alias) throws SQLQueryObjectException{
  78.         if(field==null)
  79.             throw new SQLQueryObjectException(SQLQueryObjectCore.FIELD_DEVE_ESSERE_DIVERSO_NULL);
  80.         // Trasformo in UNIX_TIMESTAMP
  81.         String fieldSQL = "avg("+this.getUnixTimestampConversion(field)+")";
  82.         if(alias != null){
  83.             /**fieldSQL = fieldSQL + " as "+alias;*/
  84.             fieldSQL = fieldSQL + this.getDefaultAliasFieldKeyword()+alias;
  85.         }
  86.         this.engineAddSelectField(null,fieldSQL,null,false,true);
  87.         this.fieldNames.add(alias);
  88.         return this;
  89.     }
  90.    
  91.    
  92.     /**
  93.      * Aggiunge un field count alla select, con un alias, del campo <var>field</var> (di tipo Timestamp)
  94.      * es: SELECT max(field) as alias FROM ....
  95.      *
  96.       * @param field Nome del Field
  97.      * @param alias Alias
  98.      */
  99.     @Override
  100.     public ISQLQueryObject addSelectMaxTimestampField(String field,String alias) throws SQLQueryObjectException{
  101.         if(field==null)
  102.             throw new SQLQueryObjectException(SQLQueryObjectCore.FIELD_DEVE_ESSERE_DIVERSO_NULL);
  103.         // Trasformo in UNIX_TIMESTAMP
  104.         String fieldSQL = "max("+this.getUnixTimestampConversion(field)+")";
  105.         if(alias != null){
  106.             /**fieldSQL = fieldSQL + " as "+alias;*/
  107.             fieldSQL = fieldSQL + this.getDefaultAliasFieldKeyword()+alias;
  108.         }
  109.         this.engineAddSelectField(null,fieldSQL,null,false,true);
  110.         this.fieldNames.add(alias);
  111.         return this;
  112.     }
  113.    
  114.     /**
  115.      * Aggiunge un field count alla select, con un alias, del campo <var>field</var> (di tipo Timestamp)
  116.      * es: SELECT min(field) as alias FROM ....
  117.      *
  118.      * @param field Nome del Field
  119.      * @param alias
  120.      */
  121.     @Override
  122.     public ISQLQueryObject addSelectMinTimestampField(String field,String alias) throws SQLQueryObjectException{
  123.         if(field==null)
  124.             throw new SQLQueryObjectException(SQLQueryObjectCore.FIELD_DEVE_ESSERE_DIVERSO_NULL);
  125.         // Trasformo in UNIX_TIMESTAMP
  126.         String fieldSQL = "min("+this.getUnixTimestampConversion(field)+")";
  127.         if(alias != null){
  128.             /**fieldSQL = fieldSQL + " as "+alias;*/
  129.             fieldSQL = fieldSQL + this.getDefaultAliasFieldKeyword()+alias;
  130.         }
  131.         this.engineAddSelectField(null,fieldSQL,null,false,true);
  132.         this.fieldNames.add(alias);
  133.         return this;
  134.     }
  135.    
  136.     /**
  137.      * Aggiunge un field count alla select, con un alias, del campo <var>field</var> (di tipo Timestamp)
  138.      * es: SELECT sum(field) as alias FROM ....
  139.      *
  140.      * @param field Nome del Field
  141.      * @param alias
  142.      */
  143.     @Override
  144.     public ISQLQueryObject addSelectSumTimestampField(String field,String alias) throws SQLQueryObjectException{
  145.         if(field==null)
  146.             throw new SQLQueryObjectException(SQLQueryObjectCore.FIELD_DEVE_ESSERE_DIVERSO_NULL);
  147.         // Trasformo in UNIX_TIMESTAMP
  148.         String fieldSQL = "sum("+this.getUnixTimestampConversion(field)+")";
  149.         if(alias != null){
  150.             /**fieldSQL = fieldSQL + " as "+alias;*/
  151.             fieldSQL = fieldSQL + this.getDefaultAliasFieldKeyword()+alias;
  152.         }
  153.         this.engineAddSelectField(null,fieldSQL,null,false,true);
  154.         this.fieldNames.add(alias);
  155.         return this;
  156.     }
  157.    
  158.    
  159.     /**
  160.      * Aggiunge una tabella di ricerca del from
  161.      * es: SELECT * from ( subSelect )
  162.      *
  163.      * @param subSelect subSelect
  164.      */
  165.     @Override
  166.     public ISQLQueryObject addFromTable(ISQLQueryObject subSelect) throws SQLQueryObjectException{
  167.         StringBuilder bf = new StringBuilder();
  168.         bf.append(" ( ");
  169.         bf.append(subSelect.createSQLQuery());
  170.         bf.append(SQLQueryObjectCore.AS_SUBQUERY_SUFFIX+getSerial()+" ");
  171.         this.addFromTable(bf.toString());
  172.         return this;
  173.     }
  174.    
  175.    
  176.    
  177.     @Override
  178.     protected EscapeSQLConfiguration getEscapeSQLConfiguration(){
  179.        
  180.         EscapeSQLConfiguration config = new EscapeSQLConfiguration();
  181.         config.addCharacter('_');
  182.         config.addCharacter('%');
  183.         config.addCharacter('|');
  184.         config.setUseEscapeClausole(true);
  185.         config.setEscape('|');
  186.        
  187.         // special
  188.         config.addCharacterWithOtherEscapeChar('\\','\\');
  189.         config.addCharacterWithOtherEscapeChar('\'','\'');
  190.        
  191.         return config;
  192.     }

  193.    
  194.    
  195.    
  196.    
  197.    
  198.    
  199.    
  200.     private SQLQueryObjectException newSQLQueryObjectExceptionDayFormatEnum(DayFormatEnum dayFormat) {
  201.         return new SQLQueryObjectException("DayFormatEnum '"+dayFormat+"' unknown");
  202.     }
  203.     @Override
  204.     public String getExtractDayFormatFromTimestampFieldPrefix(DayFormatEnum dayFormat) throws SQLQueryObjectException {
  205.         if(dayFormat==null) {
  206.             throw new SQLQueryObjectException("dayFormat undefined");
  207.         }
  208.         switch (dayFormat) {
  209.         case FULL_DAY_NAME:
  210.             return "DAYNAME(";
  211.         case SHORT_DAY_NAME:
  212.             return "DATE_FORMAT(";
  213.         case DAY_OF_YEAR:
  214.             return "DAYOFYEAR(";
  215.         case DAY_OF_WEEK:
  216.             return "DAYOFWEEK(";
  217.         }
  218.         throw newSQLQueryObjectExceptionDayFormatEnum(dayFormat);
  219.     }
  220.     @Override
  221.     public String getExtractDayFormatFromTimestampFieldSuffix(DayFormatEnum dayFormat) throws SQLQueryObjectException {
  222.         if(dayFormat==null) {
  223.             throw new SQLQueryObjectException("dayFormat undefined");
  224.         }
  225.         switch (dayFormat) {
  226.         case SHORT_DAY_NAME:
  227.             return ", '%a')";
  228.         case FULL_DAY_NAME:
  229.         case DAY_OF_YEAR:
  230.         case DAY_OF_WEEK:
  231.             return ")";
  232.         }
  233.         throw newSQLQueryObjectExceptionDayFormatEnum(dayFormat);
  234.     }
  235.    
  236.    
  237.    
  238.    
  239.    
  240.    
  241.    
  242.     /**
  243.      * Crea una SQL Query con i dati dell'oggetto
  244.      *
  245.      * @return SQL Query
  246.      */
  247.     @Override
  248.     public String createSQLQuery() throws SQLQueryObjectException{
  249.         return this.createSQLQuery(false);
  250.     }
  251.     private String createSQLQuery(boolean union) throws SQLQueryObjectException{
  252.        
  253.         this.precheckBuildQuery();
  254.        
  255.         StringBuilder bf = new StringBuilder();
  256.        
  257.         bf.append("SELECT ");
  258.        
  259.         // forzatura di indici
  260.         Iterator<String> itForceIndex = this.forceIndexTableNames.iterator();
  261.         while(itForceIndex.hasNext()){
  262.             bf.append(" "+itForceIndex.next()+" ");
  263.         }
  264.        
  265.         if(this.isSelectDistinct())
  266.             bf.append(" DISTINCT ");
  267.        
  268.         // select field
  269.         if(this.fields.isEmpty()){
  270.             bf.append("*");
  271.         }else{
  272.             Iterator<String> it = this.fields.iterator();
  273.             boolean first = true;
  274.             while(it.hasNext()){
  275.                 if(!first)
  276.                     bf.append(",");
  277.                 else
  278.                     first = false;
  279.                 bf.append(it.next());
  280.             }
  281.         }
  282.        
  283.         bf.append(getSQL(false,false,false,union));
  284.        
  285.         /**if( this.offset>=0 || this.limit>=0)
  286.         //  System.out.println("SQL ["+bf.toString()+"]");*/
  287.        
  288.         return bf.toString();
  289.     }

  290.    
  291.     /**
  292.      * Crea una SQL per una operazione di Delete con i dati dell'oggetto
  293.      *
  294.      * @return SQL per una operazione di Delete
  295.      */
  296.     @Override
  297.     public String createSQLDeleteEngine() throws SQLQueryObjectException{
  298.         StringBuilder bf = new StringBuilder();
  299.                
  300.         bf.append("DELETE ");
  301.        
  302.         bf.append(getSQL(true,false,false,false));
  303.         return bf.toString();
  304.     }
  305.    
  306.    
  307.    
  308.     /**
  309.      * @return SQL
  310.      * @throws SQLQueryObjectException
  311.      */
  312.     private String getSQL(boolean delete,boolean update,boolean conditions,boolean union) throws SQLQueryObjectException {
  313.         StringBuilder bf = new StringBuilder();
  314.        
  315.         if(this.selectForUpdate){
  316.             this.checkSelectForUpdate(update, delete, union);
  317.         }
  318.        
  319.         if(!update && !conditions){
  320.             // From
  321.             bf.append(SQLQueryObjectCore.FROM_SEPARATOR);
  322.            
  323.             // Table dove effettuare la ricerca 'FromTable'
  324.             if(this.tables.isEmpty()){
  325.                 throw new SQLQueryObjectException(SQLQueryObjectCore.TABELLA_RICERCA_FROM_NON_DEFINITA);
  326.             }else{
  327.                 if(delete && this.tables.size()>2)
  328.                     throw new SQLQueryObjectException("Non e' possibile effettuare una delete con piu' di una tabella alla volta");
  329.                 Iterator<String> it = this.tables.iterator();
  330.                 boolean first = true;
  331.                 while(it.hasNext()){
  332.                     if(!first)
  333.                         bf.append(",");
  334.                     else
  335.                         first = false;
  336.                     bf.append(it.next());
  337.                 }
  338.             }
  339.         }
  340.        
  341.         // Condizioni di Where
  342.         if(!this.conditions.isEmpty()){
  343.            
  344.             if(!conditions)
  345.                 bf.append(" WHERE ");
  346.            
  347.             if(this.notBeforeConditions){
  348.                 bf.append("NOT (");
  349.             }
  350.            
  351.             for(int i=0; i<this.conditions.size(); i++){
  352.                 if(i>0){
  353.                     if(this.andLogicOperator){
  354.                         bf.append(SQLQueryObjectCore.AND_SEPARATOR);
  355.                     }else{
  356.                         bf.append(SQLQueryObjectCore.OR_SEPARATOR);
  357.                     }
  358.                 }
  359.                 bf.append(this.conditions.get(i));
  360.             }
  361.            
  362.             if(this.notBeforeConditions){
  363.                 bf.append(")");
  364.             }
  365.         }
  366.        
  367.         // Condizione GroupBy
  368.         if((!this.getGroupByConditions().isEmpty()) && (!delete) && (!update) && (!conditions)){
  369.             bf.append(SQLQueryObjectCore.GROUP_BY_SEPARATOR);
  370.             Iterator<String> it = this.getGroupByConditions().iterator();
  371.             boolean first = true;
  372.             while(it.hasNext()){
  373.                 if(!first)
  374.                     bf.append(",");
  375.                 else
  376.                     first = false;
  377.                 bf.append(it.next());
  378.             }
  379.         }
  380.        
  381.         // Condizione OrderBy
  382. /**     if(union==false){ La condizione di OrderBy DEVE essere generata. In SQLServer e MySQL viene generata durante la condizione di LIMIT/OFFSET*/
  383.             if((!this.orderBy.isEmpty()) && (!delete) && (!update) && (!conditions)){
  384.                 bf.append(SQLQueryObjectCore.ORDER_BY_SEPARATOR);
  385.                 Iterator<String> it = this.orderBy.iterator();
  386.                 boolean first = true;
  387.                 while(it.hasNext()){
  388.                     String column = it.next();
  389.                     if(!first)
  390.                         bf.append(",");
  391.                     else
  392.                         first = false;
  393.                     bf.append(column);
  394.                     boolean sortTypeAsc = this.sortTypeAsc;
  395.                     if(this.orderBySortType.containsKey(column)){
  396.                         sortTypeAsc = this.orderBySortType.get(column);
  397.                     }
  398.                     if(sortTypeAsc){
  399.                         bf.append(SQLQueryObjectCore.ASC_SEPARATOR);
  400.                     }else{
  401.                         bf.append(SQLQueryObjectCore.DESC_SEPARATOR);
  402.                     }
  403.                 }
  404.             }
  405. /**     }*/
  406.        
  407.         // Limit e Offset
  408.         /**if(this.limit>0 || this.offset>0){*/
  409.         // Rilascio vincolo di order by in caso di limit impostato.
  410.         // Il vincolo rimane per l'offset, per gestire le select annidate di qualche implementazioni come Oracle,SQLServer ...
  411.         if(this.offset>=0 &&
  412.             (this.orderBy.isEmpty())
  413.             ){
  414.             throw new SQLQueryObjectException(SQLQueryObjectCore.CONDIZIONI_ORDER_BY_RICHESTE);
  415.         }
  416.        
  417.         // Limit
  418.         if((this.limit>0) && (!delete) && (!update) && (!conditions)){
  419.             bf.append(SQLQueryObjectCore.LIMIT_SEPARATOR);
  420.             bf.append(this.limit);
  421.         }
  422.        
  423.         // Offset
  424.         if((this.offset>=0) && (!delete) && (!update) && (!conditions)){
  425.             if(this.limit<=0){
  426.                 bf.append(SQLQueryObjectCore.LIMIT_SEPARATOR);
  427.                 /**bf.append(ISQLQueryObject.LIMIT_DEFAULT_VALUE);*/
  428.                 // Ci metto un valore MOLTO ALTO in modo da essere implementato come per gli altri database quasi come se non ci fosse il limit
  429.                 bf.append(Integer.MAX_VALUE);
  430.             }
  431.             bf.append(" OFFSET ");
  432.             bf.append(this.offset);
  433.         }
  434.            
  435.         // ForUpdate
  436.         if(!conditions &&
  437.             (this.selectForUpdate)
  438.             ){
  439.             bf.append(" FOR UPDATE ");
  440.         }
  441.        
  442.         return bf.toString();
  443.     }
  444.    
  445.    
  446.    
  447.     /**
  448.      * Crea la stringa SQL per l'unione dei parametri presi in sqlQueryObject
  449.      * Il booleano 'unionAll' indica se i vari parametri devono essere uniti con 'UNION'  o con 'UNION ALL'
  450.      *
  451.      * In caso nell'oggetto viene impostato il LIMIT o OFFSET, questo viene utilizzato per effettuare LIMIT e/o OFFSET dell'unione
  452.      *
  453.      * In caso l'ORDER by viene impostato nell'oggetto, questo viene utilizzato per effettuare ORDER BY dell'unione
  454.      *
  455.      *
  456.      * Sintassi MySQL:
  457.      *
  458.      * select * FROM (
  459.      * (  SELECT fields... FROM tabella WHERE conditions  )
  460.      * UNION [ALL]
  461.      * (  SELECT fields... FROM tabella WHERE conditions  )
  462.      * ) as subquery
  463.      *
  464.      * ORDER BY gdo,tipo_fruitore,fruitore,tipo_erogatore,erogatore,tipo_servizio,servizio DESC  
  465.      * LIMIT 1000
  466.      * OFFSET 0;
  467.      *
  468.      *
  469.      * @param unionAll
  470.      * @param sqlQueryObject
  471.      * @return stringa SQL per l'unione dei parametri presi in sqlQueryObject
  472.      * @throws SQLQueryObjectException
  473.      */
  474.     @Override
  475.     public String createSQLUnion(boolean unionAll,ISQLQueryObject... sqlQueryObject) throws SQLQueryObjectException{
  476.        
  477.         // Controllo parametro su cui effettuare la UNION
  478.         this.checkUnionField(false,sqlQueryObject);
  479.        
  480.         if(this.selectForUpdate){
  481.             this.checkSelectForUpdate(false, false, true);
  482.         }
  483.        
  484.         StringBuilder bf = new StringBuilder();
  485.        
  486.         bf.append("SELECT ");
  487.        
  488.         // forzatura di indici
  489.         Iterator<String> itForceIndex = this.forceIndexTableNames.iterator();
  490.         while(itForceIndex.hasNext()){
  491.             bf.append(" "+itForceIndex.next()+" ");
  492.         }
  493.        
  494.         // Non ha senso, la union fa gia la distinct, a meno di usare la unionAll ma in quel caso non si vuole la distinct
  495.         /** if(this.isSelectDistinct())
  496.         //  bf.append(" DISTINCT ");*/
  497.        
  498.         // select field
  499.         if(this.fields.isEmpty()){
  500.             bf.append("*");
  501.         }else{
  502.             Iterator<String> it = this.fields.iterator();
  503.             boolean first = true;
  504.             while(it.hasNext()){
  505.                 if(!first)
  506.                     bf.append(",");
  507.                 else
  508.                     first = false;
  509.                 bf.append(it.next());
  510.             }
  511.         }
  512.        
  513.         bf.append(SQLQueryObjectCore.FROM_SEPARATOR_APERTURA);
  514.        
  515.         for(int i=0; i<sqlQueryObject.length; i++){
  516.            
  517.             if(((MySQLQueryObject)sqlQueryObject[i]).selectForUpdate){
  518.                 try{
  519.                     ((MySQLQueryObject)sqlQueryObject[i]).checkSelectForUpdate(false, false, true);
  520.                 }catch(Exception e){
  521.                     throw new SQLQueryObjectException("Parametro SqlQueryObject["+i+"] non valido: "+e.getMessage());
  522.                 }
  523.             }
  524.            
  525.             if(i>0){
  526.                 bf.append(" UNION ");
  527.                 if(unionAll){
  528.                     bf.append(" ALL ");
  529.                 }
  530.             }
  531.            
  532.             bf.append("( ");
  533.            
  534.             bf.append(((MySQLQueryObject)sqlQueryObject[i]).createSQLQuery(true));
  535.            
  536.             bf.append(") ");
  537.         }
  538.        
  539.         bf.append(SQLQueryObjectCore.AS_SUBQUERY_SUFFIX+getSerial()+" ");
  540.        
  541.         // Condizione GroupBy
  542.         if((!this.getGroupByConditions().isEmpty())){
  543.             bf.append(SQLQueryObjectCore.GROUP_BY_SEPARATOR);
  544.             Iterator<String> it = this.getGroupByConditions().iterator();
  545.             boolean first = true;
  546.             while(it.hasNext()){
  547.                 if(!first)
  548.                     bf.append(",");
  549.                 else
  550.                     first = false;
  551.                 bf.append(it.next());
  552.             }
  553.         }
  554.        
  555.         // Condizione OrderBy
  556.         if(!this.orderBy.isEmpty()){
  557.             bf.append(SQLQueryObjectCore.ORDER_BY_SEPARATOR);
  558.             Iterator<String> it = this.orderBy.iterator();
  559.             boolean first = true;
  560.             while(it.hasNext()){
  561.                 String column = it.next();
  562.                 if(!first)
  563.                     bf.append(",");
  564.                 else
  565.                     first = false;
  566.                 bf.append(column);
  567.                 boolean sortTypeAsc = this.sortTypeAsc;
  568.                 if(this.orderBySortType.containsKey(column)){
  569.                     sortTypeAsc = this.orderBySortType.get(column);
  570.                 }
  571.                 if(sortTypeAsc){
  572.                     bf.append(SQLQueryObjectCore.ASC_SEPARATOR);
  573.                 }else{
  574.                     bf.append(SQLQueryObjectCore.DESC_SEPARATOR);
  575.                 }
  576.             }
  577.         }
  578.        
  579.         // Limit e Offset
  580.         /**if(this.limit>0 || this.offset>0){*/
  581.         // Rilascio vincolo di order by in caso di limit impostato.
  582.         // Il vincolo rimane per l'offset, per gestire le select annidate di qualche implementazioni come Oracle,SQLServer ...
  583.         if(this.offset>=0 &&
  584.             (this.orderBy.isEmpty())
  585.             ){
  586.             throw new SQLQueryObjectException(SQLQueryObjectCore.CONDIZIONI_ORDER_BY_RICHESTE);
  587.         }
  588.        
  589.         // Limit
  590.         if(this.limit>0){
  591.             bf.append(SQLQueryObjectCore.LIMIT_SEPARATOR);
  592.             bf.append(this.limit);
  593.         }
  594.        
  595.         // Offset
  596.         if(this.offset>=0){
  597.             if(this.limit<=0){
  598.                 bf.append(SQLQueryObjectCore.LIMIT_SEPARATOR);
  599.                 /**bf.append(ISQLQueryObject.LIMIT_DEFAULT_VALUE);*/
  600.                 // Ci metto un valore MOLTO ALTO in modo da essere implementato come per gli altri database quasi come se non ci fosse il limit
  601.                 bf.append(Integer.MAX_VALUE);
  602.             }
  603.             bf.append(" OFFSET ");
  604.             bf.append(this.offset);
  605.         }
  606.        
  607.         return bf.toString();
  608.     }
  609.    
  610.     /**
  611.      * Crea la stringa SQL per l'unione dei parametri presi in sqlQueryObject (viene effettuato il count)
  612.      * Il booleano 'unionAll' indica se i vari parametri devono essere uniti con 'UNION'  o con 'UNION ALL'
  613.      *
  614.      * Sintassi MySQL:
  615.      *
  616.      * select count(*) as aliasCount FROM (
  617.      *
  618.      * (  SELECT fields... FROM tabella WHERE conditions  )
  619.      * UNION [ALL]
  620.      * (  SELECT fields... FROM tabella WHERE conditions  )
  621.      *
  622.      * ) as subquery
  623.      *
  624.      * @param unionAll
  625.      * @param sqlQueryObject
  626.      * @return stringa SQL per l'unione dei parametri presi in sqlQueryObject (viene effettuato il count)
  627.      * @throws SQLQueryObjectException
  628.      */
  629.     @Override
  630.     public String createSQLUnionCount(boolean unionAll,String aliasCount,ISQLQueryObject... sqlQueryObject) throws SQLQueryObjectException{
  631.        
  632.         // Controllo parametro su cui effettuare la UNION
  633.         this.checkUnionField(true,sqlQueryObject);
  634.        
  635.         if(aliasCount==null){
  636.             throw new SQLQueryObjectException("Alias per il count non definito");
  637.         }
  638.        
  639.         StringBuilder bf = new StringBuilder();
  640.        
  641.         bf.append("SELECT count(*) "+this.getDefaultAliasFieldKeyword()+" ");
  642.         bf.append(aliasCount);
  643.         bf.append(SQLQueryObjectCore.FROM_SEPARATOR_APERTURA);
  644.        
  645.         bf.append( this.createSQLUnion(unionAll, sqlQueryObject) );
  646.                
  647.         bf.append(SQLQueryObjectCore.AS_SUBQUERY_SUFFIX+getSerial()+" ");
  648.        
  649.         return bf.toString();
  650.        
  651.     }
  652.    
  653.    
  654.    
  655.     /**
  656.      * Crea una SQL per una operazione di Update con i dati dell'oggetto
  657.      *
  658.      * @return SQL per una operazione di Update
  659.      */
  660.     @Override
  661.     public String createSQLUpdateEngine() throws SQLQueryObjectException{
  662.        
  663.         StringBuilder bf = new StringBuilder();
  664.         bf.append("UPDATE ");
  665.         bf.append(this.updateTable);
  666.         bf.append(" SET ");
  667.         for(int i=0; i<this.updateFieldsName.size(); i++){
  668.             if(i>0)
  669.                 bf.append(" , ");
  670.             bf.append(this.updateFieldsName.get(i));
  671.             bf.append(" = ");
  672.             bf.append(this.updateFieldsValue.get(i));
  673.         }
  674.         bf.append(getSQL(false,true,false,false));
  675.         return bf.toString();
  676.     }

  677.    
  678.    
  679.    
  680.    
  681.    
  682.    
  683.     /* ---------------- WHERE CONDITIONS ------------------ */
  684.    
  685.     /**
  686.      * Crea le condizioni presenti senza anteporre il comando (INSERT,CREATE,UPDATE), le tabelle interessate e il 'WHERE'
  687.      *
  688.      * @return SQL Query
  689.      */
  690.     @Override
  691.     public String createSQLConditionsEngine() throws SQLQueryObjectException{
  692.        
  693.         StringBuilder bf = new StringBuilder();
  694.         bf.append(getSQL(false,false,true,false));
  695.         return bf.toString();
  696.     }
  697. }