SQLQueryObjectCore.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.security.SecureRandom;
  22. import java.util.ArrayList;
  23. import java.util.Date;
  24. import java.util.HashMap;
  25. import java.util.Iterator;
  26. import java.util.List;
  27. import java.util.Map;

  28. import org.openspcoop2.utils.TipiDatabase;


  29. /**
  30.  * Classe dove vengono forniti utility per la conversione di comandi SQL per database diversi
  31.  *
  32.  *
  33.  * @author Poli Andrea (apoli@link.it)
  34.  * @author $Author$
  35.  * @version $Rev$, $Date$
  36.  */
  37. public abstract class SQLQueryObjectCore implements ISQLQueryObject{

  38.     private static final String LA_COLONNA_PREFIX = "La colonna ";
  39.     private static final String TABELLA_PREFIX = "Tabella ";
  40.     private static final String WHERE_CONDITION_PREFIX = "Where Condition ";
  41.     private static final String FIELD_NAME_PREFIX = "Field name ";
  42.    
  43.     private static final String ALIAS_TABELLA_INDICATO_NON_ESISTE = "L'alias indicato non corrisponde ad un alias effettivo associato ad una tabella";
  44.     private static final String NESSUN_FIELD_IMPOSTATO = "Nessun field impostato";
  45.     private static final String GIA_ESISTENTE_TRA_CONDIZIONI_WHERE = " gia' esistente tra le condizioni di where";
  46.     private static final String FIELD_NAME_IS_NULL_OR_EMPTY = "Field name is null or empty string";
  47.     protected static final String CONDIZIONI_ORDER_BY_RICHESTE = "Condizioni di OrderBy richieste";
  48.     protected static final String TABELLA_RICERCA_FROM_NON_DEFINITA = "Tabella di ricerca (... FROM Table ...) non definita";
  49.    
  50.     private static final String NOME_TABELLA_DEVE_ESSERE_DIVERSO_NULL = "nomeTabella non puo' essere null";
  51.     protected static final String FIELD_DEVE_ESSERE_DIVERSO_NULL = "field non puo' essere null";
  52.     private static final String IS_NULL_CONDITION_DEVE_ESSERE_DIVERSO_NULL = "IsNullCondition field non puo' essere null";
  53.    
  54.     private static final String LOWER_PREFIX = "( lower(";
  55.     private static final String ESCAPE_SEPARATOR = " ESCAPE ";
  56.     private static final String LIKE_SEPARATOR = " LIKE ";
  57.    
  58.     protected static final String FROM_SEPARATOR = " FROM ";
  59.     protected static final String FROM_SEPARATOR_APERTURA = " FROM ( ";
  60.     protected static final String WHERE_SEPARATOR = " WHERE ";
  61.     protected static final String AND_SEPARATOR = " AND ";
  62.     protected static final String OR_SEPARATOR = " OR ";
  63.     protected static final String ASC_SEPARATOR = " ASC ";
  64.     protected static final String DESC_SEPARATOR = " DESC ";
  65.     protected static final String GROUP_BY_SEPARATOR = " GROUP BY ";
  66.     protected static final String ORDER_BY_SEPARATOR = " ORDER BY ";
  67.     protected static final String LIMIT_SEPARATOR = " LIMIT ";
  68.     protected static final String NOT_SEPARATOR_APERTURA = " NOT ( ";
  69.    
  70.     protected static final String SELECT_SEPARATOR_CON_INIZIO_APERTURA = " ( SELECT ";
  71.    
  72.     protected static final String AS_SUBQUERY_SUFFIX = " ) as subquery";
  73.    
  74.     private static SecureRandom rndEngine = null;
  75.     private static synchronized void initRandom() {
  76.         if(rndEngine==null) {
  77.             rndEngine = new SecureRandom();
  78.         }
  79.     }
  80.     protected static java.util.Random getRandom() {
  81.         if(rndEngine==null) {
  82.             initRandom();
  83.         }
  84.         return rndEngine;
  85.     }
  86.    
  87.     /** List di Field esistenti: i nomi dei fields impostati (se e' stato utilizzato un alias ritorna comunque il nome della colonna) */
  88.     List<String> fields = new ArrayList<>();
  89.     /** List di NomiField esistenti: i nomi dei fields impostati (se e' stato utilizzato un alias ritorna il valore dell'alias) */
  90.     List<String> fieldNames = new ArrayList<>();
  91.     /** Mapping tra alias e indicazione se e' una function: i nomi dei fields impostati (se e' stato utilizzato un alias ritorna il valore dell'alias) */
  92.     Map<String, Boolean> fieldNameIsFunction = new HashMap<>();
  93.     /** Mapping tra alias (key) e field names (value) (sono presenti i mapping solo per le colonne per cui e' stato definito un alias) */
  94.     Map<String, String> alias = new HashMap<>();
  95.    
  96.     /** List di Tabelle esistenti */
  97.     List<String> tables = new ArrayList<>();
  98.     List<String> tableNames = new ArrayList<>();
  99.     List<String> tableAlias = new ArrayList<>();
  100.    
  101.     /** List di Field esistenti */
  102.     List<String> conditions = new ArrayList<>();
  103.     public int sizeConditions(){
  104.         return this.conditions.size();
  105.     }
  106.    
  107.     /** List di indici forzati */
  108.     List<String> forceIndexTableNames = new ArrayList<>();
  109.    
  110.     /** OperatorLogic */
  111.     boolean andLogicOperator = false;
  112.    
  113.     /** Not */
  114.     boolean notBeforeConditions = false;
  115.    
  116.     /** GroupBy di Field esistenti */
  117.     private List<String> groupBy = new ArrayList<>();
  118.    
  119.     /** OrderBy di Field esistenti */
  120.     List<String> orderBy = new ArrayList<>();
  121.     Map<String, Boolean> orderBySortType = new HashMap<>();
  122.    
  123.     /** Tipo di ordinamento */
  124.     boolean sortTypeAsc = true;
  125.    
  126.     /** Distinct */
  127.     private boolean distinct = false;
  128.    
  129.     /** Limit */
  130.     int limit = -1;
  131.     /** Offset */
  132.     int offset = -1;

  133.     /** SelectForUpdate */
  134.     boolean selectForUpdate = false;
  135.    
  136.     /* UPDATE */
  137.     /** List di Field per l'update */
  138.     List<String> updateFieldsName = new ArrayList<>();
  139.     List<String> updateFieldsValue = new ArrayList<>();
  140.     /** Tabella per l'update */
  141.     String updateTable = null;

  142.     /* INSERT */
  143.     /** List di Field per l'insert */
  144.     List<String> insertFieldsName = new ArrayList<>();
  145.     List<String> insertFieldsValue = new ArrayList<>();
  146.     /** Tabella per l'insert */
  147.     String insertTable = null;

  148.     /* TipoDatabase */
  149.     private TipiDatabase tipoDatabase;

  150.     /* preCheck */
  151.     private boolean precheckQuery = true;
  152.     public void setPrecheckQuery(boolean precheckQuery) {
  153.         this.precheckQuery = precheckQuery;
  154.     }

  155.     // Increment
  156.     private int serial = 0;
  157.     protected synchronized int getSerial(){
  158.         this.serial++;
  159.         return this.serial;
  160.     }

  161.     // Force to false SelectForUpdate in CRUD Method
  162.     private boolean forceSelectForUpdateDisabledForNotQueryMethod = false; // viene usato nel progetto generic forzato a true per JDBC_SQLObjectFactory
  163.     public void setForceSelectForUpdateDisabledForNotQueryMethod(boolean forceSelectForUpdateDisabledForNotQueryMethod) {
  164.         this.forceSelectForUpdateDisabledForNotQueryMethod = forceSelectForUpdateDisabledForNotQueryMethod;
  165.     }


  166.     // COSTRUTTORE
  167.     protected SQLQueryObjectCore(TipiDatabase tipoDatabase){
  168.         this.tipoDatabase = tipoDatabase;
  169.     }
  170.    
  171.    




  172.     // UTILITIES

  173.     protected void precheckBuildQuery() throws SQLQueryObjectException{

  174.         if(!this.precheckQuery){
  175.             return;
  176.         }

  177.         // Check Offset
  178.         if(this.offset>=0 &&
  179.             this.orderBy.isEmpty()){
  180.             throw new SQLQueryObjectException("Condizioni di OrderBy richieste");
  181.         }
  182.        
  183.         // Check GroupBy
  184.         precheckBuildQueryGroupBy();
  185.        
  186.         // Check Select For Update
  187.         if(this.selectForUpdate){
  188.             if(this.groupBy!=null && !this.groupBy.isEmpty()){
  189.                 throw new SQLQueryObjectException("Non è possibile abilitare il comando 'selectForUpdate' se viene utilizzata la condizione di GROUP BY");
  190.             }
  191.             else if(this.distinct){
  192.                 throw new SQLQueryObjectException("Non è possibile abilitare il comando 'selectForUpdate' se viene utilizzata la clausola DISTINCT");
  193.             }
  194.             else if(this.limit>=0){
  195.                 throw new SQLQueryObjectException("Non è possibile abilitare il comando 'selectForUpdate' se viene utilizzata la clausola LIMIT");
  196.             }
  197.             else if(this.offset>=0){
  198.                 throw new SQLQueryObjectException("Non è possibile abilitare il comando 'selectForUpdate' se viene utilizzata la clausola OFFSET");
  199.             }
  200.         }
  201.     }
  202.     private void precheckBuildQueryGroupBy() throws SQLQueryObjectException{
  203.         if(this.groupBy!=null && !this.groupBy.isEmpty()){

  204.             // verifico che tutte le condizioni di order by siano presente anche nei field di group by
  205.             precheckBuildQueryGroupByOrderBy();

  206.             // verifico che tutte le condizioni di group by siano presenti anche nei field
  207.             for (String groupByCheck : this.groupBy) {
  208.                 boolean exists = false;
  209.                 for (String field : this.fields) {
  210.                     if(normalizeField(groupByCheck).equals(normalizeField(field))){
  211.                         exists = true;
  212.                         break;
  213.                     }
  214.                 }
  215.                 if(!exists){
  216.                     throw new SQLQueryObjectException(LA_COLONNA_PREFIX+groupByCheck+" utilizzata nella condizione di GROUP BY deve essere anche selezionato come select field");
  217.                 }
  218.             }
  219.         }
  220.     }
  221.     private void precheckBuildQueryGroupByOrderBy() throws SQLQueryObjectException{
  222.         if(!this.orderBy.isEmpty()){
  223.             for (String order : this.orderBy) {
  224.                 precheckBuildQueryGroupByOrderBy(order);
  225.             }
  226.         }
  227.     }
  228.     private void precheckBuildQueryGroupByOrderBy(String order) throws SQLQueryObjectException{
  229.         boolean exists = false;
  230.         for (String groupByCheck : this.groupBy) {
  231.             if(normalizeField(groupByCheck).equals(normalizeField(order))){
  232.                 exists = true;
  233.                 break;
  234.             }
  235.         }
  236.         if(!exists){
  237.             String orderField = normalizeField(order);
  238.             try{
  239.                 if(this.isFieldNameForFunction(orderField)==null || (!this.isFieldNameForFunction(orderField).booleanValue())){
  240.                     throw new SQLQueryObjectException(LA_COLONNA_PREFIX+order+" utilizzata nella condizione di ORDER BY deve apparire anche in una condizione di GROUP BY");
  241.                 }
  242.             }catch(SQLQueryObjectException sqlObject){
  243.                 throw new SQLQueryObjectException(LA_COLONNA_PREFIX+order+" utilizzata nella condizione di ORDER BY deve apparire anche in una condizione di GROUP BY",sqlObject);
  244.             }
  245.         }
  246.     }

  247.     protected String normalizeField(String field){
  248.         return this.normalizeField(field, true);
  249.     }
  250.     protected String normalizeField(String field, boolean firstSearchFromAliasesField){

  251.         if(firstSearchFromAliasesField){
  252.             // 1. Viene fornito il nome della colonna su database.
  253.             // Potrebbe essere stato mappato con un alias nella select field.
  254.             // In tal caso deve essere ricavato ed utilizzato l'alias
  255.             Iterator<String> itRicercaAlias = this.fields.iterator();
  256.             while(itRicercaAlias.hasNext()){
  257.                 String fieldRicercaAliasa = itRicercaAlias.next();
  258.                 String [] split = null;
  259.                 if(fieldRicercaAliasa.contains(" as ")){
  260.                     split = fieldRicercaAliasa.split(" as ");
  261.                 }else if(fieldRicercaAliasa.contains(" As ")){
  262.                     split = fieldRicercaAliasa.split(" As ");
  263.                 }else if(fieldRicercaAliasa.contains(" aS ")){
  264.                     split = fieldRicercaAliasa.split(" aS ");
  265.                 }else if(fieldRicercaAliasa.contains(" AS ")){
  266.                     split = fieldRicercaAliasa.split(" AS ");
  267.                 }else if(fieldRicercaAliasa.contains(" ")){
  268.                     split = fieldRicercaAliasa.split(" ");
  269.                 }else if(fieldRicercaAliasa.contains(this.getDefaultAliasFieldKeyword())){
  270.                     split = fieldRicercaAliasa.split(this.getDefaultAliasFieldKeyword());
  271.                 }
  272.                 if(split==null){
  273.                     List<String> aliases = this.getSupportedAliasesField();
  274.                     if(aliases!=null && !aliases.isEmpty()){
  275.                         for (String aliasCheck : aliases) {
  276.                             if(fieldRicercaAliasa.contains(aliasCheck)){
  277.                                 split = fieldRicercaAliasa.split(aliasCheck);
  278.                                 break;
  279.                             }
  280.                         }
  281.                     }
  282.                 }
  283.                 if(split!=null && split.length==2){
  284.                     split[0] = split[0].trim();
  285.                     split[1] = split[1].trim();
  286.                     if(field.equals(split[0])){
  287.                         return split[1];
  288.                     }
  289.                 }
  290.             }
  291.         }

  292.         // Alcuni valori sono standard dei vendor dei database (es. gestione delle date)
  293.         // Il problema è che se contengono dei '.' o dei caratteri alias rientrano erroneamnete nei punti 2 e 3 dove invece non dovrebbero rientraci.
  294.         // Per questo motivo viene quindi prima richiesto al vendor se effettuare o meno la classica normalizzazione del field in base a tali valori
  295.         // sul field in essere
  296.         if(!this.continueNormalizeField(field)){
  297.             return field;
  298.         }
  299.        
  300.         // 2. Altrimenti devo verificare se vi e' un prefisso di tabella davanti
  301.         // Devono essere eliminati le TABELLE. e lasciare solo il field
  302.         int indexOf = field.indexOf(".");
  303.         if( (indexOf!=-1) && ((indexOf+1)<field.length()) ){
  304.             field = field.substring(indexOf+1);
  305.         }

  306.         // 3. Anche se ho eliminato il prefisso della tabella, potrei avere come field una stringa tipo 'colonna as alias'
  307.         // In tal caso devo tornare solo alias.
  308.         List<String> aliasModeSupportati = new ArrayList<>();
  309.         for (Iterator<?> iterator = this.getSupportedAliasesField().iterator(); iterator.hasNext();) {
  310.             aliasModeSupportati.add((String)iterator.next());
  311.         }
  312.         if(!aliasModeSupportati.contains(" ")){
  313.             aliasModeSupportati.add(" ");
  314.         }
  315.         if(!aliasModeSupportati.contains(" as ")){
  316.             aliasModeSupportati.add(" as ");
  317.         }
  318.         // itero su tutti gli alias (lastIndexOf utile per i casi di min/max/avg/sum timestamp field dove vengono usato anche altri alias internamente)
  319.         for (Iterator<?> iterator = aliasModeSupportati.iterator(); iterator.hasNext();) {
  320.             String aliasCheck = (String) iterator.next();
  321.             int aliasLength = aliasCheck.length(); //4
  322.             // Inoltre se vi sono alias, devono essere eliminati i field davanti agli alias e lasciati solo gli alias:
  323.             // Es. SCORRETTO :  SELECT id as IDAlias from (select id as IDAlias...)
  324.             // Es. CORRETTO :  SELECT IDAlias from (select id as IDAlias...)
  325.             String fLowerCase = field.toLowerCase();
  326.             /**indexOf = fLowerCase.lastIndexOf(" as ");*/
  327.             indexOf = fLowerCase.lastIndexOf(aliasCheck);
  328.             if( (indexOf!=-1) && ((indexOf+aliasLength)<field.length()) ){
  329.                 field = field.substring(indexOf+aliasLength);
  330.                 field = field.trim();
  331.                 break;
  332.             }
  333.         }
  334.         return field;  

  335.     }
  336.     protected boolean continueNormalizeField(String normalizeField){
  337.        
  338.         // Alcuni valori sono standard dei vendor dei database (es. gestione delle date)
  339.         // Il problema è che se contengono dei '.' o dei caratteri alias rientrano erroneamnete nei punti 2 e 3 della normalizzazione
  340.         // Per questo motivo viene quindi prima richiesto al vendor se effettuare o meno la classica normalizzazione del field in base a tali valori
  341.         // sul field in essere
  342.        
  343.         // Vedere quali database sovrascrivono questo metodo
  344.         // Ad esempio SQLServer
  345.        
  346.         if(normalizeField!=null) {
  347.             // nop
  348.         }
  349.        
  350.         return true;
  351.        
  352.     }
  353.    
  354.     protected String getCaseCondition(Case caseValue) throws SQLQueryObjectException {
  355.         if(caseValue==null) {
  356.             throw new SQLQueryObjectException("Field caseValue is null");
  357.         }
  358.         if(caseValue.getValori()==null || caseValue.getValori().isEmpty() ||
  359.                 caseValue.getCondizioni()==null || caseValue.getCondizioni().isEmpty()) {
  360.             throw new SQLQueryObjectException("Field caseValue non contiene condizioni");
  361.         }
  362.         if(caseValue.getValori().size()!=caseValue.getCondizioni().size()) {
  363.             throw new SQLQueryObjectException("Field caseValue contiene condizioni con  un numero di valori differenti dalle condizioni di where?");
  364.         }
  365.         if(caseValue.getTipoColonna()==null) {
  366.             throw new SQLQueryObjectException("Field caseValue non contiene il tipo della colonna");
  367.         }
  368.            
  369.         StringBuilder bf = new StringBuilder();
  370.         bf.append("CASE");
  371.         for (int i = 0; i < caseValue.getValori().size(); i++) {
  372.             String valore = caseValue.getValori().get(i);
  373.             String condizione = caseValue.getCondizioni().get(i);
  374.             bf.append(" WHEN ").append(condizione);
  375.             bf.append(" THEN ");
  376.             bf.append(getPrefixCastValue(caseValue.getTipoColonna(),caseValue.getDimensioneColonna()));
  377.             if(caseValue.isStringValueType()){
  378.                 bf.append("'");
  379.                 bf.append(escapeStringValue(valore));
  380.                 bf.append("'");
  381.             }
  382.             else{
  383.                 bf.append(valore);
  384.             }
  385.             bf.append(getSuffixCastValue(caseValue.getTipoColonna(),caseValue.getDimensioneColonna()));
  386.         }
  387.         if(caseValue.getValoreDefault()!=null) {
  388.             bf.append(" ELSE ");
  389.             bf.append(getPrefixCastValue(caseValue.getTipoColonna(),caseValue.getDimensioneColonna()));
  390.             if(caseValue.isStringValueType()){
  391.                 bf.append("'");
  392.                 bf.append(escapeStringValue(caseValue.getValoreDefault()));
  393.                 bf.append("'");
  394.             }
  395.             else{
  396.                 bf.append(caseValue.getValoreDefault());
  397.             }
  398.             bf.append(getSuffixCastValue(caseValue.getTipoColonna(),caseValue.getDimensioneColonna()));
  399.         }
  400.         bf.append(" END");
  401.                    
  402.         return bf.toString();
  403.     }






  404.     // SELECT FIELDS NORMALI

  405.     /**
  406.      * Aggiunge un field alla select, se non sono presenti field, viene utilizzato '*'
  407.      * es: SELECT nomeField FROM ....
  408.      *
  409.      * @param nomeField Nome del Field
  410.      */
  411.     @Override
  412.     public ISQLQueryObject addSelectField(String nomeField) throws SQLQueryObjectException{
  413.         return this.addSelectField(null,nomeField);
  414.     }
  415.     /**
  416.      * Aggiunge un field alla select, se non sono presenti field, viene utilizzato '*'
  417.      * es: SELECT nomeTabella.nomeField FROM ....
  418.      *
  419.      * @param nomeTabella Nome della tabella su cui reperire il field
  420.      * @param nomeField Nome del Field
  421.      */
  422.     @Override
  423.     public ISQLQueryObject addSelectField(String nomeTabella,String nomeField) throws SQLQueryObjectException{
  424.         return this.engineAddSelectField(nomeTabella,nomeField,null,true,false);
  425.     }
  426.     /**
  427.      * Aggiunge un field alla select, se non sono presenti field, viene utilizzato '*'
  428.      * es: SELECT nomeField FROM ....
  429.      *
  430.      * @param nomeField Nome del Field
  431.      */
  432.     @Override
  433.     public ISQLQueryObject addSelectAliasField(String nomeField,String alias) throws SQLQueryObjectException{
  434.         return this.engineAddSelectField(null,nomeField,alias,true,false);
  435.     }
  436.     /**
  437.      * Aggiunge un field alla select, se non sono presenti field, viene utilizzato '*'
  438.      * es: SELECT nomeTabella.nomeField FROM ....
  439.      *
  440.      * @param nomeTabella Nome della tabella su cui reperire il field
  441.      * @param nomeField Nome del Field
  442.      */
  443.     @Override
  444.     public ISQLQueryObject addSelectAliasField(String nomeTabella,String nomeField,String alias) throws SQLQueryObjectException{
  445.         return this.engineAddSelectField(nomeTabella,nomeField,alias,true,false);
  446.     }




  447.     // SELECT FIELDS COALESCE

  448.     /**
  449.      * Aggiunge un field alla select definendolo tramite la funzione coalesce
  450.      * es: SELECT coalesce(nomeField, 'VALORE') as alias FROM ....
  451.      *
  452.      * @param nomeField Nome del Field
  453.      * @param alias Alias
  454.      * @param valore Valore utilizzato in caso il campo sia null
  455.      */
  456.     @Override
  457.     public ISQLQueryObject addSelectCoalesceField(String nomeField,String alias,String valore) throws SQLQueryObjectException{
  458.         return engineAddSelectField(null, nomeField, alias, true, "coalesce(",",'"+escapeStringValue(valore)+"')",true);
  459.     }

  460.     /**
  461.      * Aggiunge un field alla select definendolo tramite la funzione coalesce
  462.      * es: SELECT coalesce(nomeTabella.nomeField, 'VALORE') as alias FROM ....
  463.      *
  464.      * @param aliasTabella Alias della tabella su cui reperire il field
  465.      * @param nomeField Nome del Field
  466.      * @param alias Alias
  467.      * @param valore Valore utilizzato in caso il campo sia null
  468.      */
  469.     @Override
  470.     public ISQLQueryObject addSelectCoalesceField(String aliasTabella,String nomeField,String alias,String valore) throws SQLQueryObjectException{
  471.         if(!this.tableAlias.contains(aliasTabella)){
  472.             throw new SQLQueryObjectException(ALIAS_TABELLA_INDICATO_NON_ESISTE);
  473.         }
  474.         return engineAddSelectField(aliasTabella, nomeField, alias, true, "coalesce(",",'"+escapeStringValue(valore)+"')",true);
  475.     }

  476.    
  477.    
  478.    
  479.     // SELECT FIELDS CASE
  480.    
  481.     /**
  482.      * Aggiunge un field alla select definendolo tramite la funzione coalesce
  483.      * es: SELECT coalesce(nomeField, 'VALORE') as alias FROM ....
  484.      *
  485.      * @param caseField Case
  486.      * @param alias Alias
  487.      */
  488.     @Override
  489.     public ISQLQueryObject addSelectCaseField(Case caseField, String alias) throws SQLQueryObjectException{
  490.        
  491.         if(alias==null || "".equals(alias))
  492.             throw new SQLQueryObjectException("Alias is null or empty string");
  493.        
  494.         String caseValue = this.getCaseCondition(caseField);
  495.        
  496.         String field = "("+caseValue+")"+this.getDefaultAliasFieldKeyword()+alias;
  497.         this.fields.add(field);
  498.         this.fieldNames.add(alias);
  499.         this.fieldNameIsFunction.put(alias, false);
  500.        
  501.         return this;
  502.     }
  503.    




  504.     // SELECT FIELDS COUNTS

  505.     /**
  506.      * Aggiunge un field count alla select, con un alias, del campo <var>fieldCount</var>
  507.      * es: SELECT count(*) as alias FROM ....
  508.      *
  509.      * @param alias Alias
  510.      */
  511.     @Override
  512.     public ISQLQueryObject addSelectCountField(String alias) throws SQLQueryObjectException{
  513.         String fieldSQL = "count(*)";
  514.         if(alias != null){
  515.             /**fieldSQL = fieldSQL + " as "+alias;*/
  516.             fieldSQL = fieldSQL + getDefaultAliasFieldKeyword() + alias;
  517.         }
  518.         this.engineAddSelectField(null,fieldSQL,null,false,true);
  519.         this.fieldNames.add(alias);
  520.         this.fieldNameIsFunction.put(alias, true);
  521.         return this;
  522.     }

  523.     /**
  524.      * Aggiunge un field count alla select, con un alias, del campo <var>fieldCount</var>
  525.      * es: SELECT count(fieldCount) as alias FROM ....
  526.      *
  527.      * @param fieldCount Nome del Field
  528.      * @param alias Alias
  529.      */
  530.     @Override
  531.     public ISQLQueryObject addSelectCountField(String fieldCount,String alias) throws SQLQueryObjectException{
  532.         if(fieldCount==null)
  533.             fieldCount = "*";
  534.         String fieldSQL = "count("+fieldCount+")";
  535.         if(alias != null){
  536.             /**fieldSQL = fieldSQL + " as "+alias;*/
  537.             fieldSQL = fieldSQL + getDefaultAliasFieldKeyword() + alias;
  538.         }
  539.         this.engineAddSelectField(null,fieldSQL,null,false,true);
  540.         this.fieldNames.add(alias);
  541.         this.fieldNameIsFunction.put(alias, true);
  542.         return this;
  543.     }

  544.     /**
  545.      * Aggiunge un field count alla select, con un alias, del campo <var>fieldCount</var>
  546.      * es: SELECT count(DISTINCT fieldCount) as alias FROM ....
  547.      *
  548.      * @param fieldCount Nome del Field
  549.      * @param alias Alias
  550.      */
  551.     @Override
  552.     public ISQLQueryObject addSelectCountField(String fieldCount,String alias,boolean distinct) throws SQLQueryObjectException{
  553.         if(fieldCount==null && distinct)
  554.             throw new SQLQueryObjectException("Non e' possibile utilizzare DISTINCT senza specificare un fieldCount");
  555.         if(distinct)
  556.             addSelectCountField("DISTINCT "+fieldCount,alias);
  557.         else
  558.             addSelectCountField(fieldCount,alias);
  559.         return this;
  560.     }

  561.     /**
  562.      * Aggiunge un field count alla select, con un alias, del campo <var>fieldCount</var>
  563.      * es: SELECT count(nomeTabella.fieldCount) as alias FROM ....
  564.      *
  565.      * @param aliasTabella Nome della tabella su cui reperire il field
  566.      * @param fieldCount Alias del Field
  567.      * @param alias Alias
  568.      */
  569.     @Override
  570.     public ISQLQueryObject addSelectCountField(String aliasTabella,String fieldCount,String alias) throws SQLQueryObjectException{
  571.         if(!this.tableAlias.contains(aliasTabella)){
  572.             throw new SQLQueryObjectException(ALIAS_TABELLA_INDICATO_NON_ESISTE);
  573.         }
  574.         this.addSelectCountField(aliasTabella+"."+fieldCount, alias);
  575.         return this;
  576.     }

  577.     /**
  578.      * Aggiunge un field count alla select, con un alias, del campo <var>fieldCount</var>
  579.      * es: SELECT count(DISTINCT nomeTabella.fieldCount) as alias FROM ....
  580.      *
  581.      * @param aliasTabella Alias della tabella su cui reperire il field
  582.      * @param fieldCount Nome del Field
  583.      * @param alias Alias
  584.      */
  585.     @Override
  586.     public ISQLQueryObject addSelectCountField(String aliasTabella,String fieldCount,String alias,boolean distinct) throws SQLQueryObjectException{
  587.         if(!this.tableAlias.contains(aliasTabella)){
  588.             throw new SQLQueryObjectException(ALIAS_TABELLA_INDICATO_NON_ESISTE);
  589.         }
  590.         this.addSelectCountField(aliasTabella+"."+fieldCount, alias, distinct);
  591.         return this;
  592.     }





  593.     // SELECT FIELDS AVG

  594.     /**
  595.      * Aggiunge un field count alla select, con un alias, del campo <var>fieldAvg</var>
  596.      * es: SELECT count(fieldAvg) as alias FROM ....
  597.      *
  598.      * @param field Nome del Field
  599.      * @param alias Alias
  600.      */
  601.     @Override
  602.     public ISQLQueryObject addSelectAvgField(String field,String alias) throws SQLQueryObjectException{
  603.         if(field==null)
  604.             throw new SQLQueryObjectException("field avg non puo' essere null");
  605.         engineAddSelectField(null, field, alias, true, "avg(",")",true);
  606.         return this;
  607.     }

  608.     /**
  609.      * Aggiunge un field count alla select, con un alias, del campo <var>fieldAvg</var>
  610.      * es: SELECT avg(nomeTabella.fieldAvg) as alias FROM ....
  611.      *
  612.      * @param aliasTabella Alias della tabella su cui reperire il field
  613.      * @param field Nome del Field
  614.      * @param alias Alias
  615.      */
  616.     @Override
  617.     public ISQLQueryObject addSelectAvgField(String aliasTabella,String field,String alias) throws SQLQueryObjectException{
  618.         if(field==null)
  619.             throw new SQLQueryObjectException("field avg non puo' essere null");
  620.         if(aliasTabella==null)
  621.             throw new SQLQueryObjectException(NOME_TABELLA_DEVE_ESSERE_DIVERSO_NULL);
  622.         if(!this.tableAlias.contains(aliasTabella)){
  623.             throw new SQLQueryObjectException(ALIAS_TABELLA_INDICATO_NON_ESISTE);
  624.         }
  625.         engineAddSelectField(aliasTabella, field, alias, true, "avg(",")",true);
  626.         return this;
  627.     }

  628.     /**
  629.      * Aggiunge un field count alla select, con un alias, del campo <var>fieldAvg</var> (di tipo Timestamp)
  630.      * es: SELECT avg(fieldAvg) as alias FROM ....
  631.      *
  632.      * @param field Nome del Field
  633.      * @param alias Alias
  634.      */
  635.     /**@Override
  636.     public abstract ISQLQueryObject addSelectAvgTimestampField(String field,String alias) throws SQLQueryObjectException;*/

  637.     /**
  638.      * Aggiunge un field count alla select, con un alias, del campo <var>fieldAvg</var> (di tipo Timestamp)
  639.      * es: SELECT avg(nomeTabella.fieldAvg) as alias FROM ....
  640.      *
  641.      * @param aliasTabella Alias della tabella su cui reperire il field
  642.      * @param field Nome del Field
  643.      * @param alias Alias
  644.      */
  645.     @Override
  646.     public ISQLQueryObject addSelectAvgTimestampField(String aliasTabella,String field,String alias) throws SQLQueryObjectException{
  647.         if(!this.tableAlias.contains(aliasTabella)){
  648.             throw new SQLQueryObjectException(ALIAS_TABELLA_INDICATO_NON_ESISTE);
  649.         }
  650.         addSelectAvgTimestampField(aliasTabella+"."+field, alias);
  651.         return this;
  652.     }







  653.     // SELECT FIELDS MAX

  654.     /**
  655.      * Aggiunge un field count alla select, con un alias, del campo <var>field</var>
  656.      * es: SELECT max(field) as alias FROM ....
  657.      *
  658.      * @param field Nome del Field
  659.      * @param alias Alias
  660.      */
  661.     @Override
  662.     public ISQLQueryObject addSelectMaxField(String field,String alias) throws SQLQueryObjectException{
  663.         if(field==null)
  664.             throw new SQLQueryObjectException(FIELD_DEVE_ESSERE_DIVERSO_NULL);
  665.         engineAddSelectField(null, field, alias, true, "max(",")",true);
  666.         return this;
  667.     }

  668.     /**
  669.      * Aggiunge un field count alla select, con un alias, del campo <var>field</var>
  670.      * es: SELECT max(nomeTabella.field) as alias FROM ....
  671.      *
  672.      * @param aliasTabella Alias della tabella su cui reperire il field
  673.      * @param field Nome del Field
  674.      * @param alias alias
  675.      */
  676.     @Override
  677.     public ISQLQueryObject addSelectMaxField(String aliasTabella,String field,String alias) throws SQLQueryObjectException{
  678.         if(field==null)
  679.             throw new SQLQueryObjectException(FIELD_DEVE_ESSERE_DIVERSO_NULL);
  680.         if(aliasTabella==null)
  681.             throw new SQLQueryObjectException(NOME_TABELLA_DEVE_ESSERE_DIVERSO_NULL);
  682.         if(!this.tableAlias.contains(aliasTabella)){
  683.             throw new SQLQueryObjectException(ALIAS_TABELLA_INDICATO_NON_ESISTE);
  684.         }
  685.         engineAddSelectField(aliasTabella, field, alias, true, "max(",")",true);
  686.         return this;
  687.     }

  688.     /**
  689.      * Aggiunge un field count alla select, con un alias, del campo <var>field</var> (di tipo Timestamp)
  690.      * es: SELECT max(field) as alias FROM ....
  691.      *
  692.      * @param field Nome del Field
  693.      * @param alias Alias
  694.      */
  695.     /**@Override
  696.     public abstract ISQLQueryObject addSelectMaxTimestampField(String field,String alias) throws SQLQueryObjectException;*/

  697.     /**
  698.      * Aggiunge un field count alla select, con un alias, del campo <var>field</var> (di tipo Timestamp)
  699.      * es: SELECT max(nomeTabella.field) as alias FROM ....
  700.      *
  701.      * @param aliasTabella alias della tabella su cui reperire il field
  702.      * @param field Nome del Field
  703.      * @param alias Alias
  704.      */
  705.     @Override
  706.     public ISQLQueryObject addSelectMaxTimestampField(String aliasTabella,String field,String alias) throws SQLQueryObjectException{
  707.         if(!this.tableAlias.contains(aliasTabella)){
  708.             throw new SQLQueryObjectException(ALIAS_TABELLA_INDICATO_NON_ESISTE);
  709.         }
  710.         addSelectMaxTimestampField(aliasTabella+"."+field, alias);
  711.         return this;
  712.     }











  713.     // SELECT FIELDS MIN

  714.     /**
  715.      * Aggiunge un field count alla select, con un alias, del campo <var>field</var>
  716.      * es: SELECT min(field) as alias FROM ....
  717.      *
  718.      * @param field Nome del Field
  719.      * @param alias Alias
  720.      */
  721.     @Override
  722.     public ISQLQueryObject addSelectMinField(String field,String alias) throws SQLQueryObjectException{
  723.         if(field==null)
  724.             throw new SQLQueryObjectException(FIELD_DEVE_ESSERE_DIVERSO_NULL);
  725.         engineAddSelectField(null, field, alias, true, "min(",")",true);
  726.         return this;
  727.     }

  728.     /**
  729.      * Aggiunge un field count alla select, con un alias, del campo <var>field</var>
  730.      * es: SELECT min(nomeTabella.field) as alias FROM ....
  731.      *
  732.      * @param aliasTabella Alias della tabella su cui reperire il field
  733.      * @param field Nome del Field
  734.      * @param alias
  735.      */
  736.     @Override
  737.     public ISQLQueryObject addSelectMinField(String aliasTabella,String field,String alias) throws SQLQueryObjectException{
  738.         if(field==null)
  739.             throw new SQLQueryObjectException(FIELD_DEVE_ESSERE_DIVERSO_NULL);
  740.         if(aliasTabella==null)
  741.             throw new SQLQueryObjectException(NOME_TABELLA_DEVE_ESSERE_DIVERSO_NULL);
  742.         if(!this.tableAlias.contains(aliasTabella)){
  743.             throw new SQLQueryObjectException(ALIAS_TABELLA_INDICATO_NON_ESISTE);
  744.         }
  745.         engineAddSelectField(aliasTabella, field, alias, true, "min(",")",true);
  746.         return this;
  747.     }

  748.     /**
  749.      * Aggiunge un field count alla select, con un alias, del campo <var>field</var> (di tipo Timestamp)
  750.      * es: SELECT min(field) as alias FROM ....
  751.      *
  752.      * @param field Nome del Field
  753.      * @param alias
  754.      */
  755.     /**@Override
  756.     public abstract ISQLQueryObject addSelectMinTimestampField(String field,String alias) throws SQLQueryObjectException;*/

  757.     /**
  758.      * Aggiunge un field count alla select, con un alias, del campo <var>field</var> (di tipo Timestamp)
  759.      * es: SELECT min(nomeTabella.field) as alias FROM ....
  760.      *
  761.      * @param aliasTabella Alias della tabella su cui reperire il field
  762.      * @param field Nome del Field
  763.      * @param alias
  764.      */
  765.     @Override
  766.     public ISQLQueryObject addSelectMinTimestampField(String aliasTabella,String field,String alias) throws SQLQueryObjectException{
  767.         if(!this.tableAlias.contains(aliasTabella)){
  768.             throw new SQLQueryObjectException(ALIAS_TABELLA_INDICATO_NON_ESISTE);
  769.         }
  770.         addSelectMinTimestampField(aliasTabella+"."+field, alias);
  771.         return this;
  772.     }










  773.     // SELECT FIELDS SUM

  774.     /**
  775.      * Aggiunge un field count alla select, con un alias, del campo <var>field</var>
  776.      * es: SELECT sum(field) as alias FROM ....
  777.      *
  778.      * @param field Nome del Field
  779.      * @param alias Alias
  780.      */
  781.     @Override
  782.     public ISQLQueryObject addSelectSumField(String field,String alias) throws SQLQueryObjectException{
  783.         if(field==null)
  784.             throw new SQLQueryObjectException(FIELD_DEVE_ESSERE_DIVERSO_NULL);
  785.         engineAddSelectField(null, field, alias, true, "sum(",")",true);
  786.         return this;
  787.     }

  788.     /**
  789.      * Aggiunge un field count alla select, con un alias, del campo <var>field</var>
  790.      * es: SELECT sum(nomeTabella.field) as alias FROM ....
  791.      *
  792.      * @param aliasTabella Alias della tabella su cui reperire il field
  793.      * @param field Nome del Field
  794.      * @param alias
  795.      */
  796.     @Override
  797.     public ISQLQueryObject addSelectSumField(String aliasTabella,String field,String alias) throws SQLQueryObjectException{
  798.         if(field==null)
  799.             throw new SQLQueryObjectException(FIELD_DEVE_ESSERE_DIVERSO_NULL);
  800.         if(aliasTabella==null)
  801.             throw new SQLQueryObjectException(NOME_TABELLA_DEVE_ESSERE_DIVERSO_NULL);
  802.         if(!this.tableAlias.contains(aliasTabella)){
  803.             throw new SQLQueryObjectException(ALIAS_TABELLA_INDICATO_NON_ESISTE);
  804.         }
  805.         engineAddSelectField(aliasTabella, field, alias, true, "sum(",")",true);
  806.         return this;
  807.     }

  808.     /**
  809.      * Aggiunge un field count alla select, con un alias, del campo <var>field</var> (di tipo Timestamp)
  810.      * es: SELECT sum(field) as alias FROM ....
  811.      *
  812.      * @param field Nome del Field
  813.      * @param alias
  814.      */
  815.     /**@Override
  816.     public abstract ISQLQueryObject addSelectSumTimestampField(String field,String alias) throws SQLQueryObjectException;*/

  817.     /**
  818.      * Aggiunge un field count alla select, con un alias, del campo <var>field</var> (di tipo Timestamp)
  819.      * es: SELECT sum(nomeTabella.field) as alias FROM ....
  820.      *
  821.      * @param aliasTabella Alias della tabella su cui reperire il field
  822.      * @param field Nome del Field
  823.      * @param alias
  824.      */
  825.     @Override
  826.     public ISQLQueryObject addSelectSumTimestampField(String aliasTabella,String field,String alias) throws SQLQueryObjectException{
  827.         if(!this.tableAlias.contains(aliasTabella)){
  828.             throw new SQLQueryObjectException(ALIAS_TABELLA_INDICATO_NON_ESISTE);
  829.         }
  830.         addSelectSumTimestampField(aliasTabella+"."+field, alias);
  831.         return this;
  832.     }

  833.    
  834.    
  835.    
  836.    
  837.    
  838.     // DATE TIME
  839.    
  840.     protected static final String DATE_PART_YEAR = "YEAR";
  841.     protected static final String DATE_PART_MONTH = "MONTH";
  842.     protected static final String DATE_PART_DAY = "DAY";
  843.    
  844.     protected static final String TIME_PART_HOUR = "HOUR";
  845.     protected static final String TIME_PART_MINUTE = "MINUTE";
  846.     protected static final String TIME_PART_SECOND = "SECOND";
  847.    
  848.     protected String getDateTimePart(DateTimePartEnum dateTimePart) throws SQLQueryObjectException {
  849.         switch (dateTimePart) {
  850.         case YEAR:
  851.             return DATE_PART_YEAR;
  852.         case MONTH:
  853.             return DATE_PART_MONTH;
  854.         case DAY:
  855.             return DATE_PART_DAY;
  856.         case HOUR:
  857.             return TIME_PART_HOUR;
  858.         case MINUTE:
  859.             return TIME_PART_MINUTE;
  860.         case SECOND:
  861.             return TIME_PART_SECOND;
  862.         }
  863.         throw new SQLQueryObjectException("DateTimePartEnum '"+dateTimePart+"' unknown");
  864.     }
  865.     public String getExtractDateTimePartFromTimestampFieldPrefix(DateTimePartEnum dateTimePart) throws SQLQueryObjectException {
  866.         if(dateTimePart==null) {
  867.             throw new SQLQueryObjectException("dateTimePart undefined");
  868.         }
  869.         String dateTimePartString = getDateTimePart(dateTimePart);
  870.         return "EXTRACT("+dateTimePartString+FROM_SEPARATOR;
  871.     }
  872.     public String getExtractDateTimePartFromTimestampFieldSuffix(DateTimePartEnum dateTimePart) throws SQLQueryObjectException {
  873.         if(dateTimePart==null) {
  874.             throw new SQLQueryObjectException("dateTimePart undefined");
  875.         }
  876.         return ")";
  877.     }
  878.    
  879.     private ISQLQueryObject addSelectTimestampFieldEngine(String field,String alias, DateTimePartEnum dateTimePart) throws SQLQueryObjectException{
  880.         if(field==null)
  881.             throw new SQLQueryObjectException(FIELD_DEVE_ESSERE_DIVERSO_NULL);
  882.         engineAddSelectField(null, field, alias, true,
  883.                 getExtractDateTimePartFromTimestampFieldPrefix(dateTimePart),
  884.                 getExtractDateTimePartFromTimestampFieldSuffix(dateTimePart),
  885.                 true);
  886.         return this;
  887.     }
  888.     private ISQLQueryObject addSelectTimestampFieldEngine(String aliasTabella,String field,String alias, DateTimePartEnum dateTimePart) throws SQLQueryObjectException{
  889.         if(field==null)
  890.             throw new SQLQueryObjectException(FIELD_DEVE_ESSERE_DIVERSO_NULL);
  891.         if(aliasTabella==null)
  892.             throw new SQLQueryObjectException(NOME_TABELLA_DEVE_ESSERE_DIVERSO_NULL);
  893.         if(!this.tableAlias.contains(aliasTabella)){
  894.             throw new SQLQueryObjectException(ALIAS_TABELLA_INDICATO_NON_ESISTE);
  895.         }
  896.         engineAddSelectField(aliasTabella, field, alias, true,
  897.                 getExtractDateTimePartFromTimestampFieldPrefix(dateTimePart),
  898.                 getExtractDateTimePartFromTimestampFieldSuffix(dateTimePart),
  899.                 true);
  900.         return this;
  901.     }
  902.    
  903.     /**
  904.      * Aggiunge un field alla select che si occupa di estrarre l'anno dal campo <var>field</var> (di tipo Timestamp)
  905.      * es: SELECT EXTRACT(YEAR FROM field) as alias FROM ....
  906.      *
  907.      * @param field Nome del Field
  908.      * @param alias Alias
  909.      */
  910.     @Override
  911.     public ISQLQueryObject addSelectYearTimestampField(String field,String alias) throws SQLQueryObjectException{
  912.         return addSelectTimestampFieldEngine(field, alias, DateTimePartEnum.YEAR);
  913.     }
  914.    
  915.     /**
  916.      * Aggiunge un field alla select che si occupa di estrarre l'anno dal campo <var>field</var> (di tipo Timestamp)
  917.      * es: SELECT EXTRACT(YEAR FROM nomeTabella.field) as alias FROM ....
  918.      *
  919.      * @param aliasTabella Alias della tabella su cui reperire il field
  920.      * @param field Nome del Field
  921.      * @param alias Alias
  922.      */
  923.     @Override
  924.     public ISQLQueryObject addSelectYearTimestampField(String aliasTabella,String field,String alias) throws SQLQueryObjectException{
  925.         return addSelectTimestampFieldEngine(aliasTabella, field, alias, DateTimePartEnum.YEAR);
  926.     }
  927.    
  928.     /**
  929.      * Aggiunge un field alla select che si occupa di estrarre il mese dal campo <var>field</var> (di tipo Timestamp)
  930.      * es: SELECT EXTRACT(MONTH FROM field) as alias FROM ....
  931.      *
  932.      * @param field Nome del Field
  933.      * @param alias Alias
  934.      */
  935.     @Override
  936.     public ISQLQueryObject addSelectMonthTimestampField(String field,String alias) throws SQLQueryObjectException{
  937.         return addSelectTimestampFieldEngine(field, alias, DateTimePartEnum.MONTH);
  938.     }
  939.    
  940.     /**
  941.      * Aggiunge un field alla select che si occupa di estrarre il mese dal campo <var>field</var> (di tipo Timestamp)
  942.      * es: SELECT EXTRACT(MONTH FROM nomeTabella.field) as alias FROM ....
  943.      *
  944.      * @param aliasTabella Alias della tabella su cui reperire il field
  945.      * @param field Nome del Field
  946.      * @param alias Alias
  947.      */
  948.     @Override
  949.     public ISQLQueryObject addSelectMonthTimestampField(String aliasTabella,String field,String alias) throws SQLQueryObjectException{
  950.         return addSelectTimestampFieldEngine(aliasTabella, field, alias, DateTimePartEnum.MONTH);
  951.     }
  952.    
  953.     /**
  954.      * Aggiunge un field alla select che si occupa di estrarre il giorno dal campo <var>field</var> (di tipo Timestamp)
  955.      * es: SELECT EXTRACT(DAY FROM field) as alias FROM ....
  956.      *
  957.      * @param field Nome del Field
  958.      * @param alias Alias
  959.      */
  960.     @Override
  961.     public ISQLQueryObject addSelectDayTimestampField(String field,String alias) throws SQLQueryObjectException{
  962.         return addSelectTimestampFieldEngine(field, alias, DateTimePartEnum.DAY);
  963.     }
  964.    
  965.     /**
  966.      * Aggiunge un field alla select che si occupa di estrarre il giorno dal campo <var>field</var> (di tipo Timestamp)
  967.      * es: SELECT EXTRACT(DAY FROM nomeTabella.field) as alias FROM ....
  968.      *
  969.      * @param aliasTabella Alias della tabella su cui reperire il field
  970.      * @param field Nome del Field
  971.      * @param alias Alias
  972.      */
  973.     @Override
  974.     public ISQLQueryObject addSelectDayTimestampField(String aliasTabella,String field,String alias) throws SQLQueryObjectException{
  975.         return addSelectTimestampFieldEngine(aliasTabella, field, alias, DateTimePartEnum.DAY);
  976.     }
  977.    
  978.     /**
  979.      * Aggiunge un field alla select che si occupa di estrarre l'ora dal campo <var>field</var> (di tipo Timestamp)
  980.      * es: SELECT EXTRACT(HOUR FROM field) as alias FROM ....
  981.      *
  982.      * @param field Nome del Field
  983.      * @param alias Alias
  984.      */
  985.     @Override
  986.     public ISQLQueryObject addSelectHourTimestampField(String field,String alias) throws SQLQueryObjectException{
  987.         return addSelectTimestampFieldEngine(field, alias, DateTimePartEnum.HOUR);
  988.     }
  989.    
  990.     /**
  991.      * Aggiunge un field alla select che si occupa di estrarre l'ora dal campo <var>field</var> (di tipo Timestamp)
  992.      * es: SELECT EXTRACT(HOUR FROM nomeTabella.field) as alias FROM ....
  993.      *
  994.      * @param aliasTabella Alias della tabella su cui reperire il field
  995.      * @param field Nome del Field
  996.      * @param alias Alias
  997.      */
  998.     @Override
  999.     public ISQLQueryObject addSelectHourTimestampField(String aliasTabella,String field,String alias) throws SQLQueryObjectException{
  1000.         return addSelectTimestampFieldEngine(aliasTabella, field, alias, DateTimePartEnum.HOUR);
  1001.     }
  1002.    
  1003.     /**
  1004.      * Aggiunge un field alla select che si occupa di estrarre i minuti dal campo <var>field</var> (di tipo Timestamp)
  1005.      * es: SELECT EXTRACT(MINUTE FROM field) as alias FROM ....
  1006.      *
  1007.      * @param field Nome del Field
  1008.      * @param alias Alias
  1009.      */
  1010.     @Override
  1011.     public ISQLQueryObject addSelectMinuteTimestampField(String field,String alias) throws SQLQueryObjectException{
  1012.         return addSelectTimestampFieldEngine(field, alias, DateTimePartEnum.MINUTE);
  1013.     }
  1014.    
  1015.     /**
  1016.      * Aggiunge un field alla select che si occupa di estrarre i minuti dal campo <var>field</var> (di tipo Timestamp)
  1017.      * es: SELECT EXTRACT(MINUTE FROM nomeTabella.field) as alias FROM ....
  1018.      *
  1019.      * @param aliasTabella Alias della tabella su cui reperire il field
  1020.      * @param field Nome del Field
  1021.      * @param alias Alias
  1022.      */
  1023.     @Override
  1024.     public ISQLQueryObject addSelectMinuteTimestampField(String aliasTabella,String field,String alias) throws SQLQueryObjectException{
  1025.         return addSelectTimestampFieldEngine(aliasTabella, field, alias, DateTimePartEnum.MINUTE);
  1026.     }
  1027.    
  1028.     /**
  1029.      * Aggiunge un field alla select che si occupa di estrarre i secondi dal campo <var>field</var> (di tipo Timestamp)
  1030.      * es: SELECT EXTRACT(SECOND FROM field) as alias FROM ....
  1031.      *
  1032.      * @param field Nome del Field
  1033.      * @param alias Alias
  1034.      */
  1035.     @Override
  1036.     public ISQLQueryObject addSelectSecondTimestampField(String field,String alias) throws SQLQueryObjectException{
  1037.         return addSelectTimestampFieldEngine(field, alias, DateTimePartEnum.SECOND);
  1038.     }
  1039.    
  1040.     /**
  1041.      * Aggiunge un field alla select che si occupa di estrarre i secondi dal campo <var>field</var> (di tipo Timestamp)
  1042.      * es: SELECT EXTRACT(SECOND FROM nomeTabella.field) as alias FROM ....
  1043.      *
  1044.      * @param aliasTabella Alias della tabella su cui reperire il field
  1045.      * @param field Nome del Field
  1046.      * @param alias Alias
  1047.      */
  1048.     @Override
  1049.     public ISQLQueryObject addSelectSecondTimestampField(String aliasTabella,String field,String alias) throws SQLQueryObjectException{
  1050.         return addSelectTimestampFieldEngine(aliasTabella, field, alias, DateTimePartEnum.SECOND);
  1051.     }
  1052.    
  1053.    
  1054.    
  1055.    
  1056.    
  1057.    
  1058.     private static final String DAY_FORMAT_FULL_DAY_NAME = "DAY";
  1059.     private static final String DAY_FORMAT_SHORT_DAY_NAME = "DY";
  1060.     private static final String DAY_FORMAT_DAY_OF_YEAR = "DDD";
  1061.     private static final String DAY_FORMAT_DAY_OF_WEEK = "D";
  1062.    
  1063.     protected String getDayFormat(DayFormatEnum dayFormat) throws SQLQueryObjectException {
  1064.         switch (dayFormat) {
  1065.         case FULL_DAY_NAME:
  1066.             return DAY_FORMAT_FULL_DAY_NAME;
  1067.         case SHORT_DAY_NAME:
  1068.             return DAY_FORMAT_SHORT_DAY_NAME;
  1069.         case DAY_OF_YEAR:
  1070.             return DAY_FORMAT_DAY_OF_YEAR;
  1071.         case DAY_OF_WEEK:
  1072.             return DAY_FORMAT_DAY_OF_WEEK;
  1073.         }
  1074.         throw new SQLQueryObjectException("DayFormatEnum '"+dayFormat+"' unknown");
  1075.     }
  1076.     public String getExtractDayFormatFromTimestampFieldPrefix(DayFormatEnum dayFormat) throws SQLQueryObjectException {
  1077.         if(dayFormat==null) {
  1078.             throw new SQLQueryObjectException("dayFormat undefined");
  1079.         }
  1080.         return "TO_CHAR(";
  1081.     }
  1082.     public String getExtractDayFormatFromTimestampFieldSuffix(DayFormatEnum dayFormat) throws SQLQueryObjectException {
  1083.         if(dayFormat==null) {
  1084.             throw new SQLQueryObjectException("dayFormat undefined");
  1085.         }
  1086.         String dayFormatString = getDayFormat(dayFormat);
  1087.         return ", '"+dayFormatString+"')";
  1088.     }
  1089.    
  1090.     private ISQLQueryObject addSelectTimestampFieldEngine(String field,String alias, DayFormatEnum dayFormatEnum) throws SQLQueryObjectException{
  1091.         if(field==null)
  1092.             throw new SQLQueryObjectException(FIELD_DEVE_ESSERE_DIVERSO_NULL);
  1093.         engineAddSelectField(null, field, alias, true,
  1094.                 getExtractDayFormatFromTimestampFieldPrefix(dayFormatEnum),
  1095.                 getExtractDayFormatFromTimestampFieldSuffix(dayFormatEnum),
  1096.                 true);
  1097.         return this;
  1098.     }
  1099.     private ISQLQueryObject addSelectTimestampFieldEngine(String aliasTabella,String field,String alias, DayFormatEnum dayFormatEnum) throws SQLQueryObjectException{
  1100.         if(field==null)
  1101.             throw new SQLQueryObjectException(FIELD_DEVE_ESSERE_DIVERSO_NULL);
  1102.         if(aliasTabella==null)
  1103.             throw new SQLQueryObjectException(NOME_TABELLA_DEVE_ESSERE_DIVERSO_NULL);
  1104.         if(!this.tableAlias.contains(aliasTabella)){
  1105.             throw new SQLQueryObjectException(ALIAS_TABELLA_INDICATO_NON_ESISTE);
  1106.         }
  1107.         engineAddSelectField(aliasTabella, field, alias, true,
  1108.                 getExtractDayFormatFromTimestampFieldPrefix(dayFormatEnum),
  1109.                 getExtractDayFormatFromTimestampFieldSuffix(dayFormatEnum),
  1110.                 true);
  1111.         return this;
  1112.     }
  1113.    
  1114.     /**
  1115.      * Aggiunge un field alla select che si occupa di estrarre il giorno, dal campo <var>field</var> (di tipo Timestamp), visualizzandolo nella forma 'full day name'
  1116.      * es: TO_CHAR(field, 'DAY') AS alias FROM ....
  1117.      *
  1118.      * @param field Nome del Field
  1119.      * @param alias Alias
  1120.      */
  1121.     @Override
  1122.     public ISQLQueryObject addSelectFullDayNameTimestampField(String field,String alias) throws SQLQueryObjectException{
  1123.         return addSelectTimestampFieldEngine(field, alias, DayFormatEnum.FULL_DAY_NAME);
  1124.     }
  1125.    
  1126.     /**
  1127.      * Aggiunge un field alla select che si occupa di estrarre il giorno, dal campo <var>field</var> (di tipo Timestamp), visualizzandolo nella forma 'full day name'
  1128.      * es: TO_CHAR(nomeTabella.field, 'DAY') AS alias FROM ....
  1129.      *
  1130.      * @param aliasTabella Alias della tabella su cui reperire il field
  1131.      * @param field Nome del Field
  1132.      * @param alias Alias
  1133.      */
  1134.     @Override
  1135.     public ISQLQueryObject addSelectFullDayNameTimestampField(String aliasTabella,String field,String alias) throws SQLQueryObjectException{
  1136.         return addSelectTimestampFieldEngine(aliasTabella, field, alias, DayFormatEnum.FULL_DAY_NAME);
  1137.     }
  1138.    
  1139.     /**
  1140.      * Aggiunge un field alla select che si occupa di estrarre il giorno, dal campo <var>field</var> (di tipo Timestamp), visualizzandolo nella forma 'short day name'
  1141.      * es: TO_CHAR(field, 'DY') AS alias FROM ....
  1142.      *
  1143.      * @param field Nome del Field
  1144.      * @param alias Alias
  1145.      */
  1146.     @Override
  1147.     public ISQLQueryObject addSelectShortDayNameTimestampField(String field,String alias) throws SQLQueryObjectException{
  1148.         return addSelectTimestampFieldEngine(field, alias, DayFormatEnum.SHORT_DAY_NAME);
  1149.     }
  1150.    
  1151.     /**
  1152.      * Aggiunge un field alla select che si occupa di estrarre il giorno, dal campo <var>field</var> (di tipo Timestamp), visualizzandolo nella forma 'short day name'
  1153.      * es: TO_CHAR(nomeTabella.field, 'DY') AS alias FROM ....
  1154.      *
  1155.      * @param aliasTabella Alias della tabella su cui reperire il field
  1156.      * @param field Nome del Field
  1157.      * @param alias Alias
  1158.      */
  1159.     @Override
  1160.     public ISQLQueryObject addSelectShortDayNameTimestampField(String aliasTabella,String field,String alias) throws SQLQueryObjectException{
  1161.         return addSelectTimestampFieldEngine(aliasTabella, field, alias, DayFormatEnum.SHORT_DAY_NAME);
  1162.     }
  1163.    
  1164.     /**
  1165.      * Aggiunge un field alla select che si occupa di estrarre il giorno, dal campo <var>field</var> (di tipo Timestamp), visualizzandolo nella forma 'day of year'
  1166.      * es: TO_CHAR(field, 'DDD') AS alias FROM ....
  1167.      *
  1168.      * @param field Nome del Field
  1169.      * @param alias Alias
  1170.      */
  1171.     @Override
  1172.     public ISQLQueryObject addSelectDayOfYearTimestampField(String field,String alias) throws SQLQueryObjectException{
  1173.         return addSelectTimestampFieldEngine(field, alias, DayFormatEnum.DAY_OF_YEAR);
  1174.     }
  1175.    
  1176.     /**
  1177.      * Aggiunge un field alla select che si occupa di estrarre il giorno, dal campo <var>field</var> (di tipo Timestamp), visualizzandolo nella forma 'day of year'
  1178.      * es: TO_CHAR(nomeTabella.field, 'DDD') AS alias FROM ....
  1179.      *
  1180.      * @param aliasTabella Alias della tabella su cui reperire il field
  1181.      * @param field Nome del Field
  1182.      * @param alias Alias
  1183.      */
  1184.     @Override
  1185.     public ISQLQueryObject addSelectDayOfYearTimestampField(String aliasTabella,String field,String alias) throws SQLQueryObjectException{
  1186.         return addSelectTimestampFieldEngine(aliasTabella, field, alias, DayFormatEnum.DAY_OF_YEAR);
  1187.     }
  1188.    
  1189.     /**
  1190.      * Aggiunge un field alla select che si occupa di estrarre il giorno, dal campo <var>field</var> (di tipo Timestamp), visualizzandolo nella forma 'day of week'
  1191.      * es: TO_CHAR(field, 'D') AS alias FROM ....
  1192.      *
  1193.      * @param field Nome del Field
  1194.      * @param alias Alias
  1195.      */
  1196.     @Override
  1197.     public ISQLQueryObject addSelectDayOfWeekTimestampField(String field,String alias) throws SQLQueryObjectException{
  1198.         return addSelectTimestampFieldEngine(field, alias, DayFormatEnum.DAY_OF_WEEK);
  1199.     }
  1200.    
  1201.     /**
  1202.      * Aggiunge un field alla select che si occupa di estrarre il giorno, dal campo <var>field</var> (di tipo Timestamp), visualizzandolo nella forma 'day of week'
  1203.      * es: TO_CHAR(nomeTabella.field, 'D') AS alias FROM ....
  1204.      *
  1205.      * @param aliasTabella Alias della tabella su cui reperire il field
  1206.      * @param field Nome del Field
  1207.      * @param alias Alias
  1208.      */
  1209.     @Override
  1210.     public ISQLQueryObject addSelectDayOfWeekTimestampField(String aliasTabella,String field,String alias) throws SQLQueryObjectException{
  1211.         return addSelectTimestampFieldEngine(aliasTabella, field, alias, DayFormatEnum.DAY_OF_WEEK);
  1212.     }


  1213.    
  1214.     /**
  1215.      * Aggiunge una costante alla select di tipo 'timestamp'
  1216.      * es: timestamp 'costante' AS alias FROM ....
  1217.      *
  1218.      * @param date Costante
  1219.      * @param alias Alias
  1220.      */
  1221.     @Override
  1222.     public ISQLQueryObject addSelectTimestampConstantField(Date date,String alias) throws SQLQueryObjectException{
  1223.         if(date==null)
  1224.             throw new SQLQueryObjectException("Date non puo' essere null");
  1225.        
  1226.         String constantValue = getSelectTimestampConstantField(date);
  1227.         return this.addSelectAliasField(constantValue, alias);          
  1228.     }
  1229.    
  1230.    






  1231.     // SELECT FORCE INDEX

  1232.     /**
  1233.      * Aggiunge l'istruzione SQL per forzare l'utilizzo dell'indice indicato nel parametro nella lettura della tabella indicata
  1234.      * es: SELECT '/*+ index(nomeTabella indexName) *'  FROM ....
  1235.      *
  1236.      * @param nomeTabella Nome della tabella su cui forzare l'indice
  1237.      * @param indexName Nome dell'indice
  1238.      */
  1239.     @Override
  1240.     public ISQLQueryObject addSelectForceIndex(String nomeTabella,String indexName) throws SQLQueryObjectException{
  1241.         // per adesso implementato solamente per oracle
  1242.         return this;
  1243.     }







  1244.     // SET DISTINCTS IN CIMA ALLA SELECT

  1245.     /**
  1246.      * Aggiunge un field alla select, se non sono presenti field, viene utilizzato '*'
  1247.      * es: SELECT DISTINCT nomeField,nomeFiled2.... FROM ....
  1248.      *
  1249.      * @param value Indicazione sul distinct
  1250.      */
  1251.     @Override
  1252.     public void setSelectDistinct(boolean value) throws SQLQueryObjectException{
  1253.         this.distinct = value;

  1254.     }
  1255.     public boolean isSelectDistinct() throws SQLQueryObjectException{
  1256.         if(this.distinct &&
  1257.             this.fields.isEmpty()){
  1258.             throw new SQLQueryObjectException("Per usare la select distinct devono essere indicati dei select field");
  1259.         }
  1260.         return this.distinct;
  1261.     }






  1262.     // FIELDS/TABLE NAME

  1263.     /**
  1264.      * Ritorna i nomi dei fields impostati (se e' stato utilizzato un alias ritorna il valore dell'alias)
  1265.      *
  1266.      * @return i nomi dei fields impostati (se e' stato utilizzato un alias ritorna il valore dell'alias)
  1267.      * @throws SQLQueryObjectException
  1268.      */
  1269.     @Override
  1270.     public List<String> getFieldsName() throws SQLQueryObjectException{
  1271.         if(this.fieldNames==null || this.fieldNames.isEmpty()){
  1272.             throw new SQLQueryObjectException(NESSUN_FIELD_IMPOSTATO);
  1273.         }

  1274.         return this.fieldNames;
  1275.     }
  1276.    
  1277.     /**
  1278.      * Indicazione se e' il nome rappresenta una funzione
  1279.      *
  1280.      * @return Indicazione se e' il nome rappresenta una funzione
  1281.      * @throws SQLQueryObjectException
  1282.      */
  1283.     @Override
  1284.     public Boolean isFieldNameForFunction(String fieldName) throws SQLQueryObjectException{
  1285.         if(this.fieldNames==null || this.fieldNames.isEmpty()){
  1286.             throw new SQLQueryObjectException(NESSUN_FIELD_IMPOSTATO);
  1287.         }
  1288.         if(!this.fieldNameIsFunction.containsKey(fieldName)){
  1289.             throw new SQLQueryObjectException("Field ["+fieldName+"] non presente (se durante la definizione del field e' stato usato un 'alias' utilizzarlo come parametro di questo metodo)");
  1290.         }
  1291.         return this.fieldNameIsFunction.get(fieldName);
  1292.     }

  1293.     /**
  1294.      * Ritorna i nomi dei fields impostati (se e' stato utilizzato un alias ritorna comunque il nome della colonna)
  1295.      *
  1296.      * @return nomi dei fields impostati (se e' stato utilizzato un alias ritorna comunque il nome della colonna)
  1297.      * @throws SQLQueryObjectException
  1298.      */
  1299.     //@Override
  1300.     public List<String> getFields() throws SQLQueryObjectException{
  1301.         if(this.fields==null || this.fields.isEmpty()){
  1302.             throw new SQLQueryObjectException(NESSUN_FIELD_IMPOSTATO);
  1303.         }

  1304.         return this.fields;
  1305.     }

  1306.     /**
  1307.      * Ritorna i nomi delle tabelle impostate (se e' stato utilizzato un alias ritorna il valore dell'alias)
  1308.      *
  1309.      * @return nomi delle tabelle impostate (se e' stato utilizzato un alias ritorna il valore dell'alias)
  1310.      * @throws SQLQueryObjectException
  1311.      */
  1312.     @Override
  1313.     public List<String> getTablesName() throws SQLQueryObjectException{
  1314.         if(this.tableNames==null || this.tableNames.isEmpty()){
  1315.             throw new SQLQueryObjectException("Nessuna tabella impostata");
  1316.         }

  1317.         return this.tableNames;
  1318.     }

  1319.     /**
  1320.      * Ritorna i nomi delle tabelle impostate (se e' stato utilizzato un alias ritorna comunque il nome della tabella)
  1321.      *
  1322.      * @return nomi delle tabelle impostate (se e' stato utilizzato un alias ritorna comunque il nome della tabella)
  1323.      * @throws SQLQueryObjectException
  1324.      */
  1325.     //@Override
  1326.     public List<String> getTables() throws SQLQueryObjectException{
  1327.         if(this.tables==null || this.tables.isEmpty()){
  1328.             throw new SQLQueryObjectException("Nessuna tabella impostata");
  1329.         }

  1330.         return this.tables;
  1331.     }



  1332.    
  1333.    
  1334.    
  1335.    
  1336.     /// FIELDS UNIX FUNCTIONS
  1337.    
  1338.     /**
  1339.      * Ritorna la conversione in UnixTimestamp della Colonna
  1340.      *
  1341.      * @param column colonna da convertire in UnixTimestamp
  1342.      * @return conversione in UnixTimestamp della Colonna
  1343.      */
  1344.     /**@Override
  1345.     public abstract String getUnixTimestampConversion(String column);*/
  1346.    
  1347.     /**
  1348.      * Ritorna l'intervallo in unixTimestamp tra le due colonne fornite
  1349.      *
  1350.      * @param columnMax colonna con intervallo temporale maggiore
  1351.      * @param columnMin colonna con intervallo temporale minore
  1352.      * @return ritorna l'intervallo in unixTimestamp tra le due colonne fornite
  1353.      */
  1354.     /**@Override
  1355.     public abstract String getDiffUnixTimestamp(String columnMax,String columnMin);*/

  1356.    
  1357.    
  1358.    
  1359.    
  1360.    
  1361.     // FIELDS/TABLE ALIAS
  1362.    
  1363.     // GESTIONE ALIAS 'as'
  1364.     // Non tutti i database supportano l'alias 'as', ad esempio Oracle genera un errore se viene usato l'alias con le tabelle.
  1365.     /**
  1366.      * Ritorna l'alias di default utilizzabile per un field
  1367.      *
  1368.      * @return Ritorna l'alias di default utilizzabile per un field
  1369.      */
  1370.     @Override
  1371.     public String getDefaultAliasFieldKeyword(){
  1372.         return this.getSupportedAliasesField().get(0);
  1373.     }

  1374.     /**
  1375.      * Ritorna l'alias di default utilizzabile per una tabella
  1376.      *
  1377.      * @return Ritorna l'alias di default utilizzabile per una tabella
  1378.      */
  1379.     @Override
  1380.     public String getDefaultAliasTableKeyword(){
  1381.         return this.getSupportedAliasesTable().get(0);
  1382.     }

  1383.     /**
  1384.      * Ritorna gli aliases utilizzabili per un field
  1385.      *
  1386.      * @return Ritorna gli aliases utilizzabili per un field
  1387.      */
  1388.     @Override
  1389.     public List<String> getSupportedAliasesField(){
  1390.         return getSupportedAliasesEngine();
  1391.     }
  1392.    
  1393.     /**
  1394.      * Ritorna gli aliases utilizzabili per una tabella
  1395.      *
  1396.      * @return Ritorna gli aliases utilizzabili per una tabella
  1397.      */
  1398.     @Override
  1399.     public List<String> getSupportedAliasesTable(){
  1400.         return getSupportedAliasesEngine();
  1401.     }
  1402.    
  1403.     private List<String> getSupportedAliasesEngine(){
  1404.         List<String> lista = new ArrayList<>();
  1405.         lista.add(" as ");
  1406.         lista.add(" ");
  1407.         return lista;
  1408.     }
  1409.    



  1410.    
  1411.    
  1412.    

  1413.     // Engine

  1414.     /**
  1415.      * Aggiunge un field alla select, se non sono presenti field, viene utilizzato '*'
  1416.      * es: SELECT nomeTabella.nomeField FROM ....
  1417.      *
  1418.      * @param nomeTabella Nome della tabella su cui reperire il field
  1419.      * @param nomeField Nome del Field
  1420.      */
  1421.     protected ISQLQueryObject engineAddSelectField(String nomeTabella,String nomeField,String alias,boolean addFieldName,boolean isFunction) throws SQLQueryObjectException{
  1422.         return engineAddSelectField(nomeTabella, nomeField, alias, addFieldName, null, null,isFunction);
  1423.     }
  1424.     protected ISQLQueryObject engineAddSelectField(String nomeTabella,String nomeField,String alias,boolean addFieldName,
  1425.             String functionPrefix,String functionSuffix,boolean isFunction) throws SQLQueryObjectException{
  1426.         if(nomeField==null || "".equals(nomeField))
  1427.             throw new SQLQueryObjectException("Field is null or empty string");
  1428.        
  1429.         checkEngineAddSelectField(nomeField, alias);
  1430.        
  1431.         if(nomeTabella!=null && (!"".equals(nomeTabella))){
  1432.             engineAddSelectField(nomeTabella, nomeField, alias,
  1433.                     functionPrefix, functionSuffix);
  1434.         }else{
  1435.             engineAddSelectField(nomeField, alias,
  1436.                     functionPrefix, functionSuffix);
  1437.         }
  1438.         if(addFieldName){
  1439.             if(alias!=null){
  1440.                 this.fieldNames.add(alias);
  1441.                 this.fieldNameIsFunction.put(alias, isFunction);
  1442.             }else{
  1443.                 this.fieldNames.add(nomeField);
  1444.                 this.fieldNameIsFunction.put(nomeField, isFunction);
  1445.             }
  1446.         }
  1447.         return this;
  1448.     }
  1449.     private void checkEngineAddSelectField(String nomeField,String alias) throws SQLQueryObjectException {
  1450.         if(alias!=null){
  1451.             if(this.fields.contains("*")){
  1452.                 throw new SQLQueryObjectException("Alias "+alias+" del field "+nomeField+" non utilizzabile tra i select fields. La presenza del select field '*' non permette di inserirne altri");
  1453.             }
  1454.             if(this.fieldNames.contains(alias))
  1455.                 throw new SQLQueryObjectAlreadyExistsException("Alias "+alias+" gia inserito tra i select fields");
  1456.         }else{
  1457.             if(!"*".equals(nomeField) &&
  1458.                 this.fields.contains("*")){
  1459.                 throw new SQLQueryObjectException("Field "+nomeField+" non utilizzabile tra i select fields. La presenza del select field '*' non permette di inserirne altri");
  1460.             }
  1461.             if(this.fields.contains(nomeField))
  1462.                 throw new SQLQueryObjectAlreadyExistsException("Field "+nomeField+" gia inserito tra i select fields");
  1463.         }
  1464.     }
  1465.     private void engineAddSelectField(String nomeTabella, String nomeField, String alias,
  1466.             String functionPrefix,String functionSuffix) throws SQLQueryObjectException {
  1467.         if(!this.tableNames.contains(nomeTabella))
  1468.             throw new SQLQueryObjectException(TABELLA_PREFIX+nomeTabella+" non esiste tra le tabelle su cui effettuare la ricerca (se nella addFromTable e' stato utilizzato l'alias per la tabella, utilizzarlo anche come parametro in questo metodo)");
  1469.         String nomeTabellaConField = nomeTabella+"."+nomeField;
  1470.         if(functionPrefix!=null){
  1471.             nomeTabellaConField = functionPrefix + nomeTabellaConField;
  1472.         }
  1473.         if(functionSuffix!=null){
  1474.             nomeTabellaConField = nomeTabellaConField  + functionSuffix ;
  1475.         }
  1476.         if(alias!=null){
  1477.             /**this.fields.add(nomeTabellaConField+" as "+alias);*/
  1478.             this.fields.add(nomeTabellaConField+this.getDefaultAliasFieldKeyword()+alias);
  1479.             this.alias.put(alias, nomeTabellaConField);
  1480.         }else{
  1481.             this.fields.add(nomeTabellaConField);
  1482.         }
  1483.     }
  1484.     private void engineAddSelectField(String nomeField, String alias,
  1485.             String functionPrefix,String functionSuffix) {
  1486.         String tmp = nomeField + "";
  1487.         if(functionPrefix!=null){
  1488.             tmp = functionPrefix + tmp;
  1489.         }
  1490.         if(functionSuffix!=null){
  1491.             tmp = tmp + functionSuffix ;
  1492.         }
  1493.         if(alias!=null){
  1494.             /**this.fields.add(tmp+" as "+alias);*/
  1495.             this.fields.add(tmp+this.getDefaultAliasFieldKeyword()+alias);
  1496.             this.alias.put(alias, tmp);
  1497.         }else{
  1498.             this.fields.add(tmp);
  1499.         }
  1500.     }






  1501.     // FROM

  1502.     /**
  1503.      * Aggiunge una tabella di ricerca del from
  1504.      * es: SELECT * from tabella as tabella
  1505.      *
  1506.      * @param tabella
  1507.      */
  1508.     @Override
  1509.     public ISQLQueryObject addFromTable(String tabella) throws SQLQueryObjectException{
  1510.         if(tabella==null || "".equals(tabella))
  1511.             throw new SQLQueryObjectException("Tabella is null or empty string");
  1512.         if(this.tableNames.contains(tabella))
  1513.             throw new SQLQueryObjectAlreadyExistsException(TABELLA_PREFIX+tabella+" gia' esistente tra le tabella su cui effettuare la ricerca");
  1514.         this.tableNames.add(tabella);
  1515.         this.tables.add(tabella);
  1516.         return this;
  1517.     }

  1518.     /**
  1519.      * Aggiunge una tabella di ricerca del from
  1520.      * es: SELECT * from tabella as alias
  1521.      *
  1522.      * @param tabella Tabella
  1523.      * @param alias Alias
  1524.      */
  1525.     @Override
  1526.     public ISQLQueryObject addFromTable(String tabella,String alias) throws SQLQueryObjectException{
  1527.         if(tabella==null || "".equals(tabella))
  1528.             throw new SQLQueryObjectException("Tabella is null or empty string");
  1529.         if(alias==null || "".equals(alias))
  1530.             throw new SQLQueryObjectException("Alias tabella is null or empty string");
  1531.         if(this.tableNames.contains(alias))
  1532.             throw new SQLQueryObjectAlreadyExistsException(TABELLA_PREFIX+tabella+" gia' esistente tra le tabella su cui effettuare la ricerca");
  1533.         this.tableNames.add(alias);
  1534.         /**this.tables.add(tabella+" as "+alias);*/
  1535.         this.tables.add(tabella+this.getDefaultAliasTableKeyword()+alias);
  1536.         this.tableAlias.add(alias);
  1537.         return this;
  1538.     }




  1539.     // WHERE

  1540.     /**
  1541.      * Aggiunge una condizione di ricerca (e associa un operatore logico, se le condizioni di ricerca sono piu' di una)
  1542.      * es: SELECT * from tabella WHERE (condition)
  1543.      *
  1544.      * @param condition
  1545.      */
  1546.     @Override
  1547.     public ISQLQueryObject addWhereCondition(String condition) throws SQLQueryObjectException{
  1548.         if(condition==null || "".equals(condition))
  1549.             throw new SQLQueryObjectException("Where Condition is null or empty string");
  1550.         String buildCondition = "( "+condition+" )";
  1551.         if( (buildCondition.indexOf("?")==-1) && this.conditions.contains(buildCondition))
  1552.             throw new SQLQueryObjectException(WHERE_CONDITION_PREFIX+condition+GIA_ESISTENTE_TRA_CONDIZIONI_WHERE);
  1553.         this.conditions.add(buildCondition);
  1554.         return this;
  1555.     }
  1556.     /**
  1557.      * Aggiunge una condizione di ricerca (e associa un operatore logico, se le condizioni di ricerca sono piu' di una)
  1558.      * Imposta come operatore logico di una successiva condizione (se esiste) l'AND se true, l'OR se false
  1559.      * es: SELECT * from tabella WHERE ((condition1) andLogicOperator (condition2) etc.....)
  1560.      *
  1561.      * @param andLogicOperator
  1562.      * @param conditions
  1563.      */
  1564.     @Override
  1565.     public ISQLQueryObject addWhereCondition(boolean andLogicOperator,String... conditions) throws SQLQueryObjectException{
  1566.         this.addWhereCondition(andLogicOperator, false, conditions);
  1567.         return this;
  1568.     }


  1569.     /**
  1570.      * Aggiunge una condizione di ricerca (e associa un operatore logico, se le condizioni di ricerca sono piu' di una)
  1571.      * Imposta come operatore logico di una successiva condizione (se esiste) l'AND se true, l'OR se false
  1572.      * es: SELECT * from tabella WHERE ( [NOT] ( (condition1) andLogicOperator (condition2) etc.....) )
  1573.      * Se il parametro not is true, aggiunge il not davanti alle condizioni
  1574.      *
  1575.      * @param andLogicOperator
  1576.      * @param not
  1577.      * @param conditions
  1578.      */
  1579.     @Override
  1580.     public ISQLQueryObject addWhereCondition(boolean andLogicOperator,boolean not,String... conditions) throws SQLQueryObjectException{
  1581.         if(conditions==null || conditions.length<=0)
  1582.             throw new SQLQueryObjectException("Where Conditions non esistenti");
  1583.         StringBuilder buildCondition = new StringBuilder();

  1584.         if(not){
  1585.             buildCondition.append("( NOT ");
  1586.         }

  1587.         buildCondition.append("( ");
  1588.         addWhereCondition(buildCondition, andLogicOperator, conditions);
  1589.         buildCondition.append(" )");

  1590.         if(not){
  1591.             buildCondition.append(")");
  1592.         }

  1593.         if((buildCondition.indexOf("?")==-1) && this.conditions.contains(buildCondition.toString()))
  1594.             throw new SQLQueryObjectException(WHERE_CONDITION_PREFIX+buildCondition.toString()+GIA_ESISTENTE_TRA_CONDIZIONI_WHERE);
  1595.         this.conditions.add(buildCondition.toString());
  1596.         return this;
  1597.     }
  1598.     private void addWhereCondition(StringBuilder buildCondition, boolean andLogicOperator,String... conditions) throws SQLQueryObjectException {
  1599.         for(int i=0; i<conditions.length; i++){
  1600.             if(i>0){
  1601.                 if(andLogicOperator){
  1602.                     buildCondition.append(AND_SEPARATOR);
  1603.                 }else{
  1604.                     buildCondition.append(OR_SEPARATOR);
  1605.                 }
  1606.             }
  1607.             if(conditions[i]==null || "".equals(conditions[i]))
  1608.                 throw new SQLQueryObjectException("Where Condition["+i+"] is null or empty string");
  1609.             buildCondition.append("(");
  1610.             buildCondition.append(conditions[i]);
  1611.             buildCondition.append(")");
  1612.         }
  1613.     }


  1614.     /**
  1615.      * Aggiunge una condizione di ricerca (e associa un operatore logico, se le condizioni di ricerca sono piu' di una)
  1616.      * es: SELECT * from tabella WHERE (field is null)
  1617.      *
  1618.      * @param field Field da verificare
  1619.      */
  1620.     @Override
  1621.     public ISQLQueryObject addWhereIsNullCondition(String field) throws SQLQueryObjectException{
  1622.         if(field==null || "".equals(field)){
  1623.             throw new SQLQueryObjectException(IS_NULL_CONDITION_DEVE_ESSERE_DIVERSO_NULL);
  1624.         }
  1625.         this.addWhereCondition(field+" is null");
  1626.         return this;
  1627.     }

  1628.     /**
  1629.      * Aggiunge una condizione di ricerca (e associa un operatore logico, se le condizioni di ricerca sono piu' di una)
  1630.      * es: SELECT * from tabella WHERE (field is not null)
  1631.      *
  1632.      * @param field Field da verificare
  1633.      */
  1634.     @Override
  1635.     public ISQLQueryObject addWhereIsNotNullCondition(String field) throws SQLQueryObjectException{
  1636.         if(field==null || "".equals(field)){
  1637.             throw new SQLQueryObjectException(IS_NULL_CONDITION_DEVE_ESSERE_DIVERSO_NULL);
  1638.         }
  1639.         this.addWhereCondition(field+" is not null");
  1640.         return this;
  1641.     }
  1642.    
  1643.     /**
  1644.      * Aggiunge una condizione di ricerca (e associa un operatore logico, se le condizioni di ricerca sono piu' di una)
  1645.      * es: SELECT * from tabella WHERE (field = '')
  1646.      *
  1647.      * @param field Field da verificare
  1648.      */
  1649.     @Override
  1650.     public ISQLQueryObject addWhereIsEmptyCondition(String field) throws SQLQueryObjectException{
  1651.         if(field==null || "".equals(field)){
  1652.             throw new SQLQueryObjectException(IS_NULL_CONDITION_DEVE_ESSERE_DIVERSO_NULL);
  1653.         }
  1654.         this.addWhereCondition(field+" = ''");
  1655.         return this;
  1656.     }
  1657.    
  1658.     /**
  1659.      * Aggiunge una condizione di ricerca (e associa un operatore logico, se le condizioni di ricerca sono piu' di una)
  1660.      * es: SELECT * from tabella WHERE (field &lt;&gt; '')
  1661.      *
  1662.      * @param field Field da verificare
  1663.      */
  1664.     @Override
  1665.     public ISQLQueryObject addWhereIsNotEmptyCondition(String field) throws SQLQueryObjectException{
  1666.         if(field==null || "".equals(field)){
  1667.             throw new SQLQueryObjectException(IS_NULL_CONDITION_DEVE_ESSERE_DIVERSO_NULL);
  1668.         }
  1669.         this.addWhereCondition(field+" <> ''");
  1670.         return this;
  1671.     }


  1672.     /**
  1673.      * Aggiunge una condizione di ricerca in un insieme di valori
  1674.      * esempio concreto:    SELECT * from tabella WHERE id IN (a,b,c,d);
  1675.      * Se viene indicato stringValueType a true, ogni valore viene trattoto come stringa e nella sql prodotto viene aggiunto il carattere ' all'inizio e alla fine.
  1676.      *
  1677.      * @param field Field su cui effettuare la select
  1678.      * @param valore insieme di valori su cui effettuare il controllo
  1679.      * @throws SQLQueryObjectException
  1680.      */
  1681.     @Override
  1682.     public ISQLQueryObject addWhereINCondition(String field,boolean stringValueType,String ... valore) throws SQLQueryObjectException{
  1683.         if(valore==null || valore.length<1){
  1684.             throw new SQLQueryObjectException("Deve essere fornito almeno un valore");
  1685.         }
  1686.         StringBuilder bf = new StringBuilder(field);
  1687.         bf.append(" IN ( ");
  1688.         for (int i = 0; i < valore.length; i++) {
  1689.             if(i>0){
  1690.                 bf.append(",");
  1691.             }
  1692.             if(stringValueType){
  1693.                 bf.append("'");
  1694.                 bf.append(escapeStringValue(valore[i]));
  1695.                 bf.append("'");
  1696.             }
  1697.             else{
  1698.                 bf.append(valore[i]);
  1699.             }
  1700.         }
  1701.         bf.append(")");
  1702.         this.addWhereCondition(bf.toString());
  1703.         return this;
  1704.     }

  1705.     /**
  1706.      * Aggiunge una condizione di ricerca tra due valori
  1707.      * esempio concreto:    SELECT * from tabella WHERE id BEETWEEN a AND b
  1708.      * Se viene indicato stringValueType a true, ogni valore viene trattato come stringa e nella sql prodotto viene aggiunto il carattere ' all'inizio e alla fine.
  1709.      *
  1710.      * @param field Field su cui effettuare la select
  1711.      * @param stringValueType indica se i valori devono essere trattati come stringhe o meno
  1712.      * @param leftValue Valore dell'intervallo sinistro
  1713.      * @param rightValue Valore dell'intervallo destro
  1714.      * @return SQLQueryObjectException
  1715.      * @throws SQLQueryObjectException
  1716.      */
  1717.     @Override
  1718.     public ISQLQueryObject addWhereBetweenCondition(String field,boolean stringValueType,String leftValue,String rightValue) throws SQLQueryObjectException{
  1719.         if(leftValue==null){
  1720.             throw new SQLQueryObjectException("Deve essere fornito un valore per l'intervallo sinistro");
  1721.         }
  1722.         if(rightValue==null){
  1723.             throw new SQLQueryObjectException("Deve essere fornito un valore per l'intervallo destro");
  1724.         }
  1725.         StringBuilder bf = new StringBuilder(field);
  1726.         bf.append(" BETWEEN ");
  1727.         if(stringValueType){
  1728.             bf.append("'");
  1729.             bf.append(escapeStringValue(leftValue));
  1730.             bf.append("'");
  1731.         }
  1732.         else{
  1733.             bf.append(leftValue);
  1734.         }
  1735.         bf.append(AND_SEPARATOR);
  1736.         if(stringValueType){
  1737.             bf.append("'");
  1738.             bf.append(escapeStringValue(rightValue));
  1739.             bf.append("'");
  1740.         }
  1741.         else{
  1742.             bf.append(rightValue);
  1743.         }
  1744.         this.addWhereCondition(bf.toString());
  1745.         return this;
  1746.     }

  1747.     private String createWhereLikeCondition(String columnName,String searchPattern,boolean escape) throws SQLQueryObjectException{
  1748.         if(columnName==null || "".equals(columnName))
  1749.             throw new SQLQueryObjectException("Where Condition column name is null or empty string");
  1750.         if(searchPattern==null || "".equals(searchPattern))
  1751.             throw new SQLQueryObjectException("Where Condition searchPattern is null or empty string");
  1752.         if(searchPattern.length()>1){
  1753.             if(searchPattern.startsWith("'"))
  1754.                 searchPattern = searchPattern.substring(1);
  1755.             if(searchPattern.endsWith("'"))
  1756.                 searchPattern = searchPattern.substring(0,searchPattern.length()-1);
  1757.         }
  1758.         String buildCondition = null;
  1759.         if(escape){
  1760.             EscapeSQLPattern escapePattern = escapePatternValue(searchPattern);
  1761.             String escapeClausole = "";
  1762.             if(escapePattern.isUseEscapeClausole()){
  1763.                 escapeClausole = ESCAPE_SEPARATOR+"'"+escapePattern.getEscapeClausole()+"'";
  1764.             }
  1765.             buildCondition = "( "+columnName+LIKE_SEPARATOR+"'"+escapePattern.getEscapeValue()+"'"+escapeClausole+" )";
  1766.         }
  1767.         else{
  1768.             buildCondition = "( "+columnName+LIKE_SEPARATOR+"'"+searchPattern+"' )";
  1769.         }
  1770.         return buildCondition;
  1771.     }

  1772.     /**
  1773.      * Aggiunge una condizione di ricerca
  1774.      * es: SELECT * from tabella WHERE (columnName LIKE 'searc"+LIKE_SEPARATOR+"rn')
  1775.      *
  1776.      * @param columnName
  1777.      * @param searchPattern
  1778.      */
  1779.     @Override
  1780.     public ISQLQueryObject addWhereLikeCondition(String columnName,String searchPattern) throws SQLQueryObjectException{
  1781.         return addWhereLikeCondition(columnName, searchPattern,true);
  1782.     }
  1783.     @Override
  1784.     public ISQLQueryObject addWhereLikeCondition(String columnName,String searchPattern,boolean escape) throws SQLQueryObjectException{

  1785.         String buildCondition = this.createWhereLikeCondition(columnName, searchPattern,escape);
  1786.         if((buildCondition.indexOf("?")==-1) && this.conditions.contains(buildCondition))
  1787.             throw new SQLQueryObjectException(WHERE_CONDITION_PREFIX+buildCondition+GIA_ESISTENTE_TRA_CONDIZIONI_WHERE);
  1788.         this.conditions.add(buildCondition);
  1789.         return this;
  1790.     }

  1791.     /**
  1792.      * Ritorna una condizione di ricerca
  1793.      * es: "columnName LIKE 'searchPattern'"
  1794.      *
  1795.      * @param columnName
  1796.      * @param searchPattern
  1797.      */
  1798.     @Override
  1799.     public String getWhereLikeCondition(String columnName,String searchPattern) throws SQLQueryObjectException{
  1800.         return this.createWhereLikeCondition(columnName, searchPattern,true);
  1801.     }
  1802.     @Override
  1803.     public String getWhereLikeCondition(String columnName,String searchPattern,boolean escape) throws SQLQueryObjectException{
  1804.         return this.createWhereLikeCondition(columnName, searchPattern,escape);
  1805.     }

  1806.     @Override
  1807.     public String getWhereLikeCondition(String columnName,String searchPattern, LikeConfig c) throws SQLQueryObjectException{
  1808.         return this.createWhereLikeCondition(columnName,searchPattern,
  1809.                 c.isEscape(),
  1810.                 c.isContains(), c.isStartsWith(), c.isEndsWith(),
  1811.                 c.isCaseInsensitive());
  1812.     }
  1813.    
  1814.     private String createWhereLikeCondition(String columnName,String searchPattern,
  1815.             boolean escape,
  1816.             boolean contains, boolean startsWith, boolean endsWith,  
  1817.             boolean caseInsensitive) throws SQLQueryObjectException{
  1818.         if(columnName==null || "".equals(columnName))
  1819.             throw new SQLQueryObjectException("Where Condition column name is null or empty string");
  1820.         if(searchPattern==null || "".equals(searchPattern))
  1821.             throw new SQLQueryObjectException("Where Condition searchPattern is null or empty string");
  1822.         if(searchPattern.length()>1){
  1823.             if(searchPattern.startsWith("'"))
  1824.                 searchPattern = searchPattern.substring(1);
  1825.             if(searchPattern.endsWith("'"))
  1826.                 searchPattern = searchPattern.substring(0,searchPattern.length()-1);
  1827.         }
  1828.         String buildCondition = null;
  1829.         if(escape){
  1830.             buildCondition = createWhereLikeConditionEscapeEngine(columnName, searchPattern,
  1831.                     contains, startsWith, endsWith,  
  1832.                     caseInsensitive);
  1833.         }
  1834.         else{
  1835.             buildCondition = createWhereLikeConditionNoEscapeEngine(columnName, searchPattern,
  1836.                     contains, startsWith, endsWith,  
  1837.                     caseInsensitive);
  1838.         }

  1839.         return buildCondition;
  1840.     }
  1841.     private String createWhereLikeConditionEscapeEngine(String columnName,String searchPattern,
  1842.             boolean contains, boolean startsWith, boolean endsWith,  
  1843.             boolean caseInsensitive) throws SQLQueryObjectException {
  1844.         String buildCondition = null;
  1845.         if(caseInsensitive) {
  1846.             buildCondition = createWhereLikeConditionEscapeEngineCaseInsensitive(columnName, searchPattern,
  1847.                     contains, startsWith, endsWith);
  1848.         }
  1849.         else {
  1850.             buildCondition = createWhereLikeConditionEscapeEngineCaseSensitive(columnName, searchPattern,
  1851.                     contains, startsWith, endsWith);
  1852.         }
  1853.         return buildCondition;
  1854.     }
  1855.     private String createWhereLikeConditionEscapeEngineCaseInsensitive(String columnName,String searchPattern,
  1856.             boolean contains, boolean startsWith, boolean endsWith) throws SQLQueryObjectException {
  1857.         String buildCondition = null;
  1858.         EscapeSQLPattern escapePattern = escapePatternValue(searchPattern);
  1859.         String escapeClausole = "";
  1860.         if(escapePattern.isUseEscapeClausole()){
  1861.             escapeClausole = ESCAPE_SEPARATOR+"'"+escapePattern.getEscapeClausole()+"'";
  1862.         }
  1863.         if(contains) {
  1864.             buildCondition =LOWER_PREFIX+columnName+")"+LIKE_SEPARATOR+"'%"+escapePattern.getEscapeValue().toLowerCase()+"%'"+escapeClausole+" )";
  1865.         }
  1866.         else if(startsWith) {
  1867.             buildCondition =LOWER_PREFIX+columnName+")"+LIKE_SEPARATOR+"'"+escapePattern.getEscapeValue().toLowerCase()+"%'"+escapeClausole+" )";
  1868.         }
  1869.         else if(endsWith) {
  1870.             buildCondition =LOWER_PREFIX+columnName+")"+LIKE_SEPARATOR+"'%"+escapePattern.getEscapeValue().toLowerCase()+"'"+escapeClausole+" )";
  1871.         }
  1872.         else {
  1873.             buildCondition =LOWER_PREFIX+columnName+")"+LIKE_SEPARATOR+"'"+escapePattern.getEscapeValue().toLowerCase()+"'"+escapeClausole+" )";
  1874.         }  
  1875.         return buildCondition;
  1876.     }
  1877.     private String createWhereLikeConditionEscapeEngineCaseSensitive(String columnName,String searchPattern,
  1878.             boolean contains, boolean startsWith, boolean endsWith) throws SQLQueryObjectException {
  1879.         String buildCondition = null;
  1880.         EscapeSQLPattern escapePattern = escapePatternValue(searchPattern);
  1881.         String escapeClausole = "";
  1882.         if(escapePattern.isUseEscapeClausole()){
  1883.             escapeClausole = ESCAPE_SEPARATOR+"'"+escapePattern.getEscapeClausole()+"'";
  1884.         }
  1885.         if(contains) {
  1886.             buildCondition ="( "+columnName+LIKE_SEPARATOR+"'%"+escapePattern.getEscapeValue()+"%'"+escapeClausole+" )";
  1887.         }
  1888.         else if(startsWith) {
  1889.             buildCondition ="( "+columnName+LIKE_SEPARATOR+"'"+escapePattern.getEscapeValue()+"%'"+escapeClausole+" )";
  1890.         }
  1891.         else if(endsWith) {
  1892.             buildCondition ="( "+columnName+LIKE_SEPARATOR+"'%"+escapePattern.getEscapeValue()+"'"+escapeClausole+" )";
  1893.         }
  1894.         else {
  1895.             buildCondition ="( "+columnName+LIKE_SEPARATOR+"'"+escapePattern.getEscapeValue()+"'"+escapeClausole+" )";
  1896.         }  
  1897.         return buildCondition;
  1898.     }
  1899.     private String createWhereLikeConditionNoEscapeEngine(String columnName,String searchPattern,
  1900.             boolean contains, boolean startsWith, boolean endsWith,  
  1901.             boolean caseInsensitive) {
  1902.         String buildCondition = null;
  1903.         if(caseInsensitive) {
  1904.             buildCondition = createWhereLikeConditionNoEscapeEngineCaseInsensitive(columnName, searchPattern,
  1905.                     contains, startsWith, endsWith);
  1906.         }
  1907.         else {
  1908.             buildCondition = createWhereLikeConditionNoEscapeEngineCaseSensitive(columnName, searchPattern,
  1909.                     contains, startsWith, endsWith);
  1910.         }              
  1911.         return buildCondition;
  1912.     }
  1913.     private String createWhereLikeConditionNoEscapeEngineCaseInsensitive(String columnName,String searchPattern,
  1914.             boolean contains, boolean startsWith, boolean endsWith) {
  1915.         String buildCondition = null;
  1916.         if(contains) {
  1917.             buildCondition =LOWER_PREFIX+columnName+")"+LIKE_SEPARATOR+"'%"+searchPattern.toLowerCase()+"%' )";
  1918.         }
  1919.         else if(startsWith) {
  1920.             buildCondition =LOWER_PREFIX+columnName+")"+LIKE_SEPARATOR+"'"+searchPattern.toLowerCase()+"%' )";
  1921.         }
  1922.         else if(endsWith) {
  1923.             buildCondition =LOWER_PREFIX+columnName+")"+LIKE_SEPARATOR+"'%"+searchPattern.toLowerCase()+"' )";
  1924.         }
  1925.         else {
  1926.             buildCondition =LOWER_PREFIX+columnName+")"+LIKE_SEPARATOR+"'"+searchPattern.toLowerCase()+"' )";
  1927.         }              
  1928.         return buildCondition;
  1929.     }
  1930.     private String createWhereLikeConditionNoEscapeEngineCaseSensitive(String columnName,String searchPattern,
  1931.             boolean contains, boolean startsWith, boolean endsWith) {
  1932.         String buildCondition = null;
  1933.         if(contains) {
  1934.             buildCondition ="( "+columnName+LIKE_SEPARATOR+"'%"+searchPattern+"%' )";
  1935.         }
  1936.         else if(startsWith) {
  1937.             buildCondition ="( "+columnName+LIKE_SEPARATOR+"'"+searchPattern+"%' )";
  1938.         }
  1939.         else if(endsWith) {
  1940.             buildCondition ="( "+columnName+LIKE_SEPARATOR+"'%"+searchPattern+"' )";
  1941.         }
  1942.         else {
  1943.             buildCondition ="( "+columnName+LIKE_SEPARATOR+"'"+searchPattern+"' )";
  1944.         }              
  1945.         return buildCondition;
  1946.     }
  1947.    
  1948.     /**
  1949.      * Aggiunge una condizione di ricerca
  1950.      * es: SELECT * from tabella WHERE (columnName LIKE 'searchPattern')
  1951.      *
  1952.      * @param columnName
  1953.      * @param searchPattern
  1954.      * @param contains true se la parola deve essere contenuta nella colonna, false se deve essere esattamente la colonna
  1955.      * @param caseInsensitive
  1956.      */
  1957.     @Override
  1958.     public ISQLQueryObject addWhereLikeCondition(String columnName,String searchPattern, boolean contains, boolean caseInsensitive) throws SQLQueryObjectException{
  1959.         return addWhereLikeCondition(columnName,searchPattern,true,contains,caseInsensitive);
  1960.     }
  1961.     @Override
  1962.     public ISQLQueryObject addWhereLikeCondition(String columnName,String searchPattern, boolean escape, boolean contains, boolean caseInsensitive) throws SQLQueryObjectException{

  1963.         String buildCondition = this.createWhereLikeCondition(columnName, searchPattern,
  1964.                 escape,
  1965.                 contains, false, false,
  1966.                 caseInsensitive);
  1967.         if((buildCondition.indexOf("?")==-1) && this.conditions.contains(buildCondition))
  1968.             throw new SQLQueryObjectException(WHERE_CONDITION_PREFIX+buildCondition+GIA_ESISTENTE_TRA_CONDIZIONI_WHERE);
  1969.         this.conditions.add(buildCondition);
  1970.         return this;
  1971.     }

  1972.     @Override
  1973.     public ISQLQueryObject addWhereLikeCondition(String columnName,String searchPattern, LikeConfig likeConfig) throws SQLQueryObjectException{
  1974.        
  1975.         String buildCondition = this.createWhereLikeCondition(columnName, searchPattern,
  1976.                 likeConfig.isEscape(),
  1977.                 likeConfig.isContains(), likeConfig.isStartsWith(), likeConfig.isEndsWith(),
  1978.                 likeConfig.isCaseInsensitive());
  1979.         if((buildCondition.indexOf("?")==-1) && this.conditions.contains(buildCondition))
  1980.             throw new SQLQueryObjectException(WHERE_CONDITION_PREFIX+buildCondition+GIA_ESISTENTE_TRA_CONDIZIONI_WHERE);
  1981.         this.conditions.add(buildCondition);
  1982.         return this;
  1983.        
  1984.     }
  1985.    
  1986.     /**
  1987.      * Ritorna una condizione di ricerca
  1988.      * es: "columnName LIKE 'searchPattern'"
  1989.      *
  1990.      * @param columnName
  1991.      * @param searchPattern
  1992.      * @param contains true se la parola deve essere contenuta nella colonna, false se deve essere esattamente la colonna
  1993.      * @param caseInsensitive
  1994.      */
  1995.     @Override
  1996.     public String getWhereLikeCondition(String columnName,String searchPattern, boolean contains, boolean caseInsensitive) throws SQLQueryObjectException{
  1997.         return this.createWhereLikeCondition(columnName, searchPattern,
  1998.                 true,
  1999.                 contains, false, false,
  2000.                 caseInsensitive);
  2001.     }
  2002.     @Override
  2003.     public String getWhereLikeCondition(String columnName,String searchPattern,boolean escape, boolean contains, boolean caseInsensitive) throws SQLQueryObjectException{
  2004.         return this.createWhereLikeCondition(columnName, searchPattern,
  2005.                 escape,
  2006.                 contains, false, false,
  2007.                 caseInsensitive);
  2008.     }

  2009.    
  2010.    
  2011.    
  2012.     private ISQLQueryObject addWhereCondition(String columnName,String searchPattern, DateTimePartEnum dateTimePart) throws SQLQueryObjectException{
  2013.         if(columnName==null || "".equals(columnName)){
  2014.             throw new SQLQueryObjectException(FIELD_DEVE_ESSERE_DIVERSO_NULL);
  2015.         }
  2016.         String field = this.getExtractDateTimePartFromTimestampFieldPrefix(dateTimePart)+columnName+this.getExtractDateTimePartFromTimestampFieldSuffix(dateTimePart);
  2017.         this.addWhereCondition(field+" = '"+searchPattern+"'");
  2018.         return this;
  2019.     }

  2020.     /**
  2021.      * Aggiunge una condizione di ricerca
  2022.      * es: SELECT * from tabella WHERE (EXTRACT(YEAR FROM columnName) = 'pattern')
  2023.      *
  2024.      * @param columnName
  2025.      * @param searchPattern
  2026.      */
  2027.     @Override
  2028.     public ISQLQueryObject addWhereYearCondition(String columnName,String searchPattern) throws SQLQueryObjectException{
  2029.         return addWhereCondition(columnName, searchPattern, DateTimePartEnum.YEAR);
  2030.     }
  2031.    
  2032.     /**
  2033.      * Aggiunge una condizione di ricerca
  2034.      * es: SELECT * from tabella WHERE (EXTRACT(MONTH FROM columnName) = 'pattern')
  2035.      *
  2036.      * @param columnName
  2037.      * @param searchPattern
  2038.      */
  2039.     @Override
  2040.     public ISQLQueryObject addWhereMonthCondition(String columnName,String searchPattern) throws SQLQueryObjectException{
  2041.         return addWhereCondition(columnName, searchPattern, DateTimePartEnum.MONTH);
  2042.     }
  2043.    
  2044.     /**
  2045.      * Aggiunge una condizione di ricerca
  2046.      * es: SELECT * from tabella WHERE (EXTRACT(DAY FROM columnName) = 'pattern')
  2047.      *
  2048.      * @param columnName
  2049.      * @param searchPattern
  2050.      */
  2051.     @Override
  2052.     public ISQLQueryObject addWhereDayCondition(String columnName,String searchPattern) throws SQLQueryObjectException{
  2053.         return addWhereCondition(columnName, searchPattern, DateTimePartEnum.DAY);
  2054.     }
  2055.    
  2056.     /**
  2057.      * Aggiunge una condizione di ricerca
  2058.      * es: SELECT * from tabella WHERE (EXTRACT(HOUR FROM columnName) = 'pattern')
  2059.      *
  2060.      * @param columnName
  2061.      * @param searchPattern
  2062.      */
  2063.     @Override
  2064.     public ISQLQueryObject addWhereHourCondition(String columnName,String searchPattern) throws SQLQueryObjectException{
  2065.         return addWhereCondition(columnName, searchPattern, DateTimePartEnum.HOUR);
  2066.     }
  2067.    
  2068.     /**
  2069.      * Aggiunge una condizione di ricerca
  2070.      * es: SELECT * from tabella WHERE (EXTRACT(MINUTE FROM columnName) = 'pattern')
  2071.      *
  2072.      * @param columnName
  2073.      * @param searchPattern
  2074.      */
  2075.     @Override
  2076.     public ISQLQueryObject addWhereMinuteCondition(String columnName,String searchPattern) throws SQLQueryObjectException{
  2077.         return addWhereCondition(columnName, searchPattern, DateTimePartEnum.MINUTE);
  2078.     }
  2079.    
  2080.     /**
  2081.      * Aggiunge una condizione di ricerca
  2082.      * es: SELECT * from tabella WHERE (EXTRACT(SECOND FROM columnName) = 'pattern')
  2083.      *
  2084.      * @param columnName
  2085.      * @param searchPattern
  2086.      */
  2087.     @Override
  2088.     public ISQLQueryObject addWhereSecondCondition(String columnName,String searchPattern) throws SQLQueryObjectException{
  2089.         return addWhereCondition(columnName, searchPattern, DateTimePartEnum.SECOND);
  2090.     }
  2091.    
  2092.    
  2093.    
  2094.     private ISQLQueryObject addWhereCondition(String columnName,String searchPattern, DayFormatEnum dayFormatEnum) throws SQLQueryObjectException{
  2095.         if(columnName==null || "".equals(columnName)){
  2096.             throw new SQLQueryObjectException(FIELD_DEVE_ESSERE_DIVERSO_NULL);
  2097.         }
  2098.         String field = this.getExtractDayFormatFromTimestampFieldPrefix(dayFormatEnum)+columnName+this.getExtractDayFormatFromTimestampFieldSuffix(dayFormatEnum);
  2099.         this.addWhereCondition(field+" = '"+searchPattern+"'");
  2100.         return this;
  2101.     }
  2102.    
  2103.     /**
  2104.      * Aggiunge una condizione di ricerca
  2105.      * es: SELECT * from tabella WHERE (TO_CHAR(field, 'DAY') = 'pattern')
  2106.      *
  2107.      * @param columnName
  2108.      * @param searchPattern
  2109.      */
  2110.     @Override
  2111.     public ISQLQueryObject addWhereFullDayNameCondition(String columnName,String searchPattern) throws SQLQueryObjectException{
  2112.         return addWhereCondition(columnName, searchPattern, DayFormatEnum.FULL_DAY_NAME);
  2113.     }
  2114.    
  2115.     /**
  2116.      * Aggiunge una condizione di ricerca
  2117.      * es: SELECT * from tabella WHERE (TO_CHAR(field, 'DY') = 'pattern')
  2118.      *
  2119.      * @param columnName
  2120.      * @param searchPattern
  2121.      */
  2122.     @Override
  2123.     public ISQLQueryObject addWhereShortDayNameCondition(String columnName,String searchPattern) throws SQLQueryObjectException{
  2124.         return addWhereCondition(columnName, searchPattern, DayFormatEnum.SHORT_DAY_NAME);
  2125.     }
  2126.    
  2127.     /**
  2128.      * Aggiunge una condizione di ricerca
  2129.      * es: SELECT * from tabella WHERE (TO_CHAR(field, 'DDD') = 'pattern')
  2130.      *
  2131.      * @param columnName
  2132.      * @param searchPattern
  2133.      */
  2134.     @Override
  2135.     public ISQLQueryObject addWhereDayOfYearCondition(String columnName,String searchPattern) throws SQLQueryObjectException{
  2136.         return addWhereCondition(columnName, searchPattern, DayFormatEnum.DAY_OF_YEAR);
  2137.     }
  2138.    
  2139.     /**
  2140.      * Aggiunge una condizione di ricerca
  2141.      * es: SELECT * from tabella WHERE (TO_CHAR(field, 'D') = 'pattern')
  2142.      *
  2143.      * @param columnName
  2144.      * @param searchPattern
  2145.      */
  2146.     @Override
  2147.     public ISQLQueryObject addWhereDayOfWeekCondition(String columnName,String searchPattern) throws SQLQueryObjectException{
  2148.         return addWhereCondition(columnName, searchPattern, DayFormatEnum.DAY_OF_WEEK);
  2149.     }
  2150.    
  2151.    
  2152.    
  2153.    
  2154.    
  2155.    
  2156.     private String createWhereExistsCondition(boolean notExists,ISQLQueryObject sqlQueryObject)throws SQLQueryObjectException{
  2157.         if(sqlQueryObject==null)
  2158.             throw new SQLQueryObjectException("ISQLQueryObject, su cui viene effettuato il controllo di exists, non fornito");

  2159.         if(sqlQueryObject instanceof SQLQueryObjectCore){
  2160.             // http://stackoverflow.com/questions/5119190/oracle-sql-order-by-in-subquery-problems
  2161.             SQLQueryObjectCore core = (SQLQueryObjectCore) sqlQueryObject;
  2162.             if(core.orderBy!=null && !core.orderBy.isEmpty()){
  2163.                 throw new SQLQueryObjectException("ISQLQueryObject, su cui viene effettuato il controllo di exists, non deve possedere condizioni di order by");
  2164.             }
  2165.             if(core.offset>=0){
  2166.                 throw new SQLQueryObjectException("ISQLQueryObject, su cui viene effettuato il controllo di exists, non deve possedere la condizione di OFFSET");
  2167.             }
  2168.         }

  2169.         StringBuilder bf = new StringBuilder();
  2170.         if(notExists)
  2171.             bf.append("NOT ");
  2172.         bf.append("EXISTS (");
  2173.         bf.append(sqlQueryObject.createSQLQuery());
  2174.         bf.append(" )");
  2175.         return bf.toString();
  2176.     }

  2177.     /**
  2178.      * Aggiunge una condizione di ricerca con EXISTS
  2179.      * La query su cui viene effettuato il controllo di exists e' definito dal parametro sqlQueryObject
  2180.      * es. SELECT * from tabella WHERE [NOT] EXISTS ( sqlQueryObject.createSQLQuery() )
  2181.      *
  2182.      * @param notExists Indicazione se applicare la negazione all'exists
  2183.      * @param sqlQueryObject query su cui viene effettuato il controllo di exists, la query viene prodotta attraverso il metodo createSQLQuery()
  2184.      * @throws SQLQueryObjectException
  2185.      */
  2186.     @Override
  2187.     public ISQLQueryObject addWhereExistsCondition(boolean notExists,ISQLQueryObject sqlQueryObject) throws SQLQueryObjectException{
  2188.         this.addWhereCondition(this.createWhereExistsCondition(notExists, sqlQueryObject));
  2189.         return this;
  2190.     }

  2191.     /**
  2192.      * Ritorna una condizione di ricerca con EXISTS
  2193.      * La query su cui viene effettuato il controllo di exists e' definito dal parametro sqlQueryObject
  2194.      * es. SELECT * from tabella WHERE [NOT] EXISTS ( sqlQueryObject.createSQLQuery() )
  2195.      *
  2196.      * @param notExists Indicazione se applicare la negazione all'exists
  2197.      * @param sqlQueryObject query su cui viene effettuato il controllo di exists, la query viene prodotta attraverso il metodo createSQLQuery()
  2198.      * @throws SQLQueryObjectException
  2199.      */
  2200.     @Override
  2201.     public String getWhereExistsCondition(boolean notExists,ISQLQueryObject sqlQueryObject) throws SQLQueryObjectException{
  2202.         return this.createWhereExistsCondition(notExists, sqlQueryObject);
  2203.     }


  2204.     /**
  2205.      * Aggiunge una condizione di ricerca con sotto-select
  2206.      * La query su cui viene effettuato la ricerca della sotto-select e' definita dal parametro sqlQueryObject
  2207.      * es. SELECT * from tabella WHERE [NOT] field=( sqlQueryObject.createSQLQuery() )
  2208.      * esempio concreto:    SELECT * from tabella WHERE id=(select rif from riferimenti);
  2209.      *
  2210.      * @param notExists Indicazione se applicare la negazione
  2211.      * @param field Field su cui effettuare la select
  2212.      * @param sqlQueryObject query su cui viene effettuato la ricerca, la query viene prodotta attraverso il metodo createSQLQuery()
  2213.      * @throws SQLQueryObjectException
  2214.      */
  2215.     @Override
  2216.     public ISQLQueryObject addWhereSelectSQLCondition(boolean notExists,String field,ISQLQueryObject sqlQueryObject) throws SQLQueryObjectException{
  2217.         this.addWhereCondition(this.createWhereSQLConditionCondition(notExists,false,field,sqlQueryObject));
  2218.         return this;
  2219.     }

  2220.     /**
  2221.      * Aggiunge una condizione di ricerca con sotto-select
  2222.      * La query su cui viene effettuato la ricerca della sotto-select e' definita dal parametro sqlQueryObject
  2223.      * es. SELECT * from tabella WHERE [NOT] field IN ( sqlQueryObject.createSQLQuery() )
  2224.      * esempio concreto:    SELECT * from tabella WHERE id IN (select rif from riferimenti);
  2225.      *
  2226.      * @param notExists Indicazione se applicare la negazione
  2227.      * @param field Field su cui effettuare la select
  2228.      * @param sqlQueryObject query su cui viene effettuato la ricerca, la query viene prodotta attraverso il metodo createSQLQuery()
  2229.      * @throws SQLQueryObjectException
  2230.      */
  2231.     @Override
  2232.     public ISQLQueryObject addWhereINSelectSQLCondition(boolean notExists,String field,ISQLQueryObject sqlQueryObject) throws SQLQueryObjectException{
  2233.         this.addWhereCondition(this.createWhereSQLConditionCondition(notExists,true,field,sqlQueryObject));
  2234.         return this;
  2235.     }

  2236.     private String createWhereSQLConditionCondition(boolean notExists, boolean in,String field,ISQLQueryObject sqlQueryObject)throws SQLQueryObjectException{

  2237.         if(sqlQueryObject==null)
  2238.             throw new SQLQueryObjectException("ISQLQueryObject, su cui viene costruita la ricerca, non fornito");
  2239.         if(field==null)
  2240.             throw new SQLQueryObjectException("Field non fornito");

  2241.         if(sqlQueryObject instanceof SQLQueryObjectCore){
  2242.             // http://stackoverflow.com/questions/5119190/oracle-sql-order-by-in-subquery-problems
  2243.             SQLQueryObjectCore core = (SQLQueryObjectCore) sqlQueryObject;
  2244.             checkWhereSqlConditionConditionLimitOffse(in, core);
  2245.         }

  2246.         StringBuilder bf = new StringBuilder();
  2247.         if(notExists)
  2248.             bf.append("NOT ");
  2249.         bf.append(field);
  2250.         if(in)
  2251.             bf.append(" IN ");
  2252.         else
  2253.             bf.append(" = ");
  2254.         bf.append(" (");
  2255.         bf.append(sqlQueryObject.createSQLQuery());
  2256.         bf.append(" )");
  2257.         return bf.toString();
  2258.     }
  2259.     private void checkWhereSqlConditionConditionLimitOffse(boolean in,SQLQueryObjectCore core) throws SQLQueryObjectException {
  2260.         // http://stackoverflow.com/questions/5119190/oracle-sql-order-by-in-subquery-problems
  2261.         if(core.orderBy!=null && !core.orderBy.isEmpty()){
  2262.             throw new SQLQueryObjectException("ISQLQueryObject, su cui viene effettuato il controllo di exists, non deve possedere condizioni di order by");
  2263.         }
  2264.         if(core.offset>=0){
  2265.             throw new SQLQueryObjectException("ISQLQueryObject, su cui viene effettuato il controllo di exists, non deve possedere la condizione di OFFSET");
  2266.         }
  2267.         if(!in &&
  2268.             core.limit>1){
  2269.             throw new SQLQueryObjectException("ISQLQueryObject, su cui viene effettuato il controllo di exists, non deve possedere la condizione di LIMIT o al massimo puo' essere definita con valore '1')");
  2270.         }
  2271.     }

  2272.     /**
  2273.      * Imposta come operatore logico tra due o piu' condizioni esistenti l'AND se true, l'OR se false
  2274.      *
  2275.      * @param andLogicOperator
  2276.      */
  2277.     @Override
  2278.     public void setANDLogicOperator(boolean andLogicOperator) throws SQLQueryObjectException{
  2279.         this.andLogicOperator = andLogicOperator;
  2280.     } // se false viene utilizzato OR tra le condizioni

  2281.     /**
  2282.      * Imposta il NOT prima delle condizioni NOT ( conditions )
  2283.      *
  2284.      * @param not
  2285.      */
  2286.     @Override
  2287.     public void setNOTBeforeConditions(boolean not) throws SQLQueryObjectException{
  2288.         this.notBeforeConditions = not;
  2289.     } // se true viene utilizzato il NOT davanti alle condizioni






  2290.     // ESCAPE
  2291.     /**
  2292.      * Effettua l'escape di un valore di tipo stringa
  2293.      *
  2294.      * @param value valore su cui effettuare l'escape
  2295.      * @return valore su cui e' stato effettuato l'escape
  2296.      * @throws SQLQueryObjectException
  2297.      */
  2298.     @Override
  2299.     public String escapeStringValue(String value) throws SQLQueryObjectException{

  2300.         return SQLQueryObjectCore.getEscapeStringValue(value);

  2301.     }
  2302.     public static String getEscapeStringValue(String value) throws SQLQueryObjectException{

  2303.         if(value==null){
  2304.             throw new SQLQueryObjectException("Valore non fornito per escape");
  2305.         }
  2306.         // converte ' in ''
  2307.         int index = value.indexOf('\'');
  2308.         if(index>=0){
  2309.             StringBuilder str =  new StringBuilder();
  2310.             char[] v = value.toCharArray();
  2311.             for(int i=0; i<v.length; i++){
  2312.                 if(v[i]=='\''){
  2313.                     str.append('\'');
  2314.                 }
  2315.                 str.append(v[i]);
  2316.             }
  2317.             return str.toString();
  2318.         }

  2319.         return value;
  2320.     }

  2321.     /**
  2322.      * Effettua l'escape di un pattern
  2323.      *
  2324.      * @param pattern pattern su cui effettuare l'escape
  2325.      * @return pattern su cui e' stato effettuato l'escape
  2326.      * @throws SQLQueryObjectException
  2327.      */
  2328.     @Override
  2329.     public EscapeSQLPattern escapePatternValue(String pattern)
  2330.             throws SQLQueryObjectException {

  2331.         EscapeSQLPattern escapeSqlPattern = new EscapeSQLPattern();

  2332.         if(pattern==null){
  2333.             throw new SQLQueryObjectException("Valore non fornito per escape");
  2334.         }

  2335.         EscapeSQLConfiguration escapeConfig = this.getEscapeSQLConfiguration();

  2336.         StringBuilder str =  new StringBuilder();
  2337.         char[] v = pattern.toCharArray();
  2338.         for(int i=0; i<v.length; i++){
  2339.            
  2340.             if(escapeConfig.isDefaultEscape(v[i])){
  2341.                 str.append(escapeConfig.getEscape());

  2342.                 if(escapeConfig.isUseEscapeClausole()){
  2343.                     escapeSqlPattern.setUseEscapeClausole(true);
  2344.                     escapeSqlPattern.setEscapeClausole(escapeConfig.getEscape());
  2345.                 }
  2346.             }
  2347.             else if(escapeConfig.isOtherEscape(v[i])){
  2348.                 str.append(escapeConfig.getOtherEscapeCharacter(v[i]));
  2349.             }
  2350.            
  2351.             str.append(v[i]);

  2352.         }

  2353.         String returnStr = str.toString();  
  2354.         escapeSqlPattern.setEscapeValue(returnStr);
  2355.         return escapeSqlPattern;

  2356.     }
  2357.     protected abstract EscapeSQLConfiguration getEscapeSQLConfiguration();





  2358.     // GROUP BY

  2359.     /**
  2360.      * Aggiunge una condizione di GroupBy per i field con il nome sottostante.
  2361.      * I field devono essere precedentemente stati inseriti come SelectField
  2362.      *
  2363.      * @param groupByNomeField Nome del field di raggruppamento
  2364.      */
  2365.     @Override
  2366.     public ISQLQueryObject addGroupBy(String groupByNomeField) throws SQLQueryObjectException{
  2367.         if(groupByNomeField==null || "".equals(groupByNomeField))
  2368.             throw new SQLQueryObjectException("GroupBy Condition is null or empty string");
  2369.         /**
  2370.          * Non e' sempre vero
  2371.          * if(this.fields.contains(groupByNomeField)==false){
  2372.          *  throw new SQLQueryObjectException("GroupBy Condition field non e' registrati tra i select field");
  2373.         }*/

  2374.         /**if(this.tableAlias.size()>0){
  2375.             throw new SQLQueryObjectException("Non e' possibile utilizzare alias nelle tabelle se poi si vuole usufruire della condizione GroupBy");
  2376.         } IL PROBLEMA DOVREBBE ESSERE STATO RISOLTO CON LA GESTIONE DEGLI ALIAS
  2377.          */
  2378.         if(this.alias.containsKey(groupByNomeField)){
  2379.             this.groupBy.add(this.alias.get(groupByNomeField));
  2380.         }
  2381.         else{
  2382.             this.groupBy.add(groupByNomeField);
  2383.         }
  2384.         return this;
  2385.     }

  2386.     public List<String> getGroupByConditions() throws SQLQueryObjectException{
  2387.         if(this.groupBy!=null && !this.groupBy.isEmpty() &&
  2388.             this.fields.isEmpty()){
  2389.             throw new SQLQueryObjectException("Non e' possibile utilizzare condizioni di group by se non sono stati indicati select field");
  2390.         }
  2391.         return this.groupBy;
  2392.     }


  2393.     // ORDER BY

  2394.     /**
  2395.      * Aggiunge una condizione di OrderBy per i field con il nome sottostante.
  2396.      * I field devono essere precedentemente stati inseriti come SelectField
  2397.      *
  2398.      * @param orderByNomeField Nome del field di ordinamento
  2399.      */
  2400.     @Override
  2401.     public ISQLQueryObject addOrderBy(String orderByNomeField) throws SQLQueryObjectException{
  2402.         if(orderByNomeField==null || "".equals(orderByNomeField))
  2403.             throw new SQLQueryObjectException("OrderBy Condition is null or empty string");
  2404.         /**
  2405.          * Non e' sempre vero
  2406.          * if(this.fields.contains(orderByNomeField)==false){
  2407.          *  throw new SQLQueryObjectException("OrderBy Condition field non e' registrati tra i select field");
  2408.         }*/
  2409.         this.orderBy.add(orderByNomeField);
  2410.         return this;
  2411.     }

  2412.     /**
  2413.      * Aggiunge una condizione di OrderBy per i field con il nome sottostante.
  2414.      * I field devono essere precedentemente stati inseriti come SelectField
  2415.      *
  2416.      * @param orderByNomeField Nome del field di ordinamento
  2417.      * @param asc Imposta la stringa di ordinamento (Crescente:true/Decrescente:false)
  2418.      */
  2419.     @Override
  2420.     public ISQLQueryObject addOrderBy(String orderByNomeField, boolean asc) throws SQLQueryObjectException{
  2421.         this.addOrderBy(orderByNomeField);
  2422.         this.orderBySortType.put(orderByNomeField, asc);
  2423.         return this;
  2424.     }

  2425.     /**
  2426.      * Imposta la stringa di ordinamento (Crescente:true/Decrescente:false)
  2427.      */
  2428.     @Override
  2429.     public void setSortType(boolean sort) throws SQLQueryObjectException{
  2430.         if(this.orderBy.isEmpty())
  2431.             throw new SQLQueryObjectException("OrderBy Conditions non definite");
  2432.         this.sortTypeAsc = sort;
  2433.     }




  2434.     // LIMIT E OFFSET

  2435.     /**
  2436.      * Aggiunge un limite ai risultati ritornati
  2437.      *
  2438.      * @param limit limite dei risultati ritornati
  2439.      */
  2440.     @Override
  2441.     public void setLimit(int limit) throws SQLQueryObjectException{
  2442.         this.limit = limit;
  2443.     }

  2444.     public int getLimit() {
  2445.         return this.limit;
  2446.     }

  2447.     /**
  2448.      * Aggiunge un offset per i risultati ritornati
  2449.      *
  2450.      * @param offset offset per i risultati ritornati
  2451.      */
  2452.     @Override
  2453.     public void setOffset(int offset) throws SQLQueryObjectException{
  2454.         this.offset = offset;
  2455.     }

  2456.     public int getOffset() {
  2457.         return this.offset;
  2458.     }

  2459.    
  2460.     // SELECT FOR UPDATE
  2461.    
  2462.     public boolean isSelectForUpdate() {
  2463.         return this.selectForUpdate;
  2464.     }
  2465.    
  2466.     @Override
  2467.     public void setSelectForUpdate(boolean selectForUpdate) throws SQLQueryObjectException {
  2468.         this.selectForUpdate = selectForUpdate;
  2469.     }
  2470.    
  2471.     protected void checkSelectForUpdate(boolean update,boolean delete, boolean union) throws SQLQueryObjectException{
  2472.         if(this.selectForUpdate){
  2473.             String tipo = null;
  2474.             if(update){
  2475.                 tipo = "UPDATE";
  2476.             }
  2477.             else if(delete){
  2478.                 tipo = "DELETE";
  2479.             }
  2480.             else if(union){
  2481.                 tipo = "UNION";
  2482.             }
  2483.             else if(!this.getGroupByConditions().isEmpty()){
  2484.                 tipo = "GROUP BY";
  2485.             }
  2486.             else if(this.isSelectDistinct()){
  2487.                 tipo = "DISTINCT";
  2488.             }
  2489.             else if(this.limit>=0){
  2490.                 tipo = "LIMIT";
  2491.             }
  2492.             else if(this.offset>=0){
  2493.                 tipo = "OFFSET";
  2494.             }
  2495.             if(tipo!=null)
  2496.                 throw new SQLQueryObjectException("Utilizzo dell'opzione 'FOR UPDATE' non permesso con il comando "+tipo);
  2497.         }
  2498.     }
  2499.    
  2500.    

  2501.     // GENERAZIONE SQL

  2502.     /**
  2503.      * Crea una SQL Query con i dati dell'oggetto
  2504.      *
  2505.      * @return SQL Query
  2506.      */
  2507.     /**@Override
  2508.     public abstract String createSQLQuery() throws SQLQueryObjectException;*/

  2509.     @Override
  2510.     public String toString(){
  2511.         try{
  2512.             return this.createSQLQuery();
  2513.         }catch(Exception e){
  2514.             return "Oggetto non corretto: "+e.getMessage();
  2515.         }
  2516.     }

  2517.     protected void checkUnionField(boolean count,ISQLQueryObject... sqlQueryObject)throws SQLQueryObjectException{

  2518.         if(count){
  2519.             checkUnionFieldCount();
  2520.         }

  2521.         if(this.offset>=0 &&
  2522.             this.fields.isEmpty()) {
  2523.             throw new SQLQueryObjectException("Non e' possibile usare offset se non e' stato indicato alcun field nella select piu' esterna della union");
  2524.         }
  2525.         if(this.limit>0 &&
  2526.             this.fields.isEmpty()) {
  2527.             throw new SQLQueryObjectException("Non e' possibile usare limit se non e' stato indicato alcun field nella select piu' esterna della union");
  2528.         }

  2529.         if(this.distinct){
  2530.             throw new SQLQueryObjectException("Non e' possibile usare distinct nella select piu' esterna della union (utilizza il parametro boolean unionAll)");
  2531.         }

  2532.         if(sqlQueryObject==null || sqlQueryObject.length<=0){
  2533.             throw new SQLQueryObjectException("Parametro is null");
  2534.         }
  2535.         if(sqlQueryObject.length==1){
  2536.             throw new SQLQueryObjectException("Parametro contiene un solo sqlQueryObject (minimo 2)");
  2537.         }

  2538.         // Check presenza fields
  2539.         checkUnionFieldExists(sqlQueryObject);

  2540.         // Check nomi fields            
  2541.         checkUnionFieldNames(sqlQueryObject);

  2542.         // Check presenza order by DEVE essere accompagnata da un offset in modo che venga generata la condizione di order by su Oracle/SLQServer per le condizioni
  2543.         checkUnionFieldOrderOffset(sqlQueryObject);
  2544.        
  2545.         // Check Select For Update
  2546.         if(this.selectForUpdate){
  2547.             throw new SQLQueryObjectException("Non è possibile abilitare il comando 'selectForUpdate' con la UNION");
  2548.         }
  2549.     }
  2550.     protected void checkUnionFieldCount() throws SQLQueryObjectException{
  2551.         if(this.orderBy!=null && !this.orderBy.isEmpty()){
  2552.             throw new SQLQueryObjectException("Non e' possibile usare order by in una count");
  2553.         }
  2554.         if(this.limit>0){
  2555.             throw new SQLQueryObjectException("Non e' possibile usare limit in una count");
  2556.         }
  2557.         if(this.offset>=0){
  2558.             throw new SQLQueryObjectException("Non e' possibile usare offset in una count");
  2559.         }
  2560.     }
  2561.     protected void checkUnionFieldExists(ISQLQueryObject... sqlQueryObject)throws SQLQueryObjectException{
  2562.         for(int i=0;i<sqlQueryObject.length;i++){
  2563.             ISQLQueryObject sqlQueryObjectDaVerificare = sqlQueryObject[i];
  2564.             List<String> nomiFieldSqlQueryObjectDaVerificare = sqlQueryObjectDaVerificare.getFieldsName();
  2565.             if(nomiFieldSqlQueryObjectDaVerificare==null || nomiFieldSqlQueryObjectDaVerificare.isEmpty()){
  2566.                 throw new SQLQueryObjectException("La select numero "+(i+1)+" non possiede fields?");
  2567.             }
  2568.         }
  2569.     }
  2570.     protected void checkUnionFieldNames(ISQLQueryObject... sqlQueryObject)throws SQLQueryObjectException{
  2571.         /**     for(int i=0;i<sqlQueryObject.length;i++){
  2572.         //          System.out.println("CHECK ["+i+"] ...");
  2573.         //          List<String> nomiFieldSqlQueryObjectDaVerificare = sqlQueryObject[i].getFieldsName();
  2574.         //          for (String string : nomiFieldSqlQueryObjectDaVerificare) {
  2575.         //              System.out.println("\t-"+string);
  2576.         //          }
  2577.         //      }*/
  2578.         for(int i=0;i<sqlQueryObject.length;i++){

  2579.             List<String> nomiFieldSqlQueryObjectDaVerificare = sqlQueryObject[i].getFieldsName();
  2580.             String [] nomi = nomiFieldSqlQueryObjectDaVerificare.toArray(new String[1]);

  2581.             for(int indiceField =0; indiceField<nomi.length;indiceField++){

  2582.                 String fieldDaVerificare = nomi[indiceField];

  2583.                 for(int altriSqlObject=0;altriSqlObject<sqlQueryObject.length;altriSqlObject++){

  2584.                     if(altriSqlObject==i){
  2585.                         // e' l'oggetto in questione
  2586.                         continue;
  2587.                     }

  2588.                     if( (!sqlQueryObject[altriSqlObject].getFieldsName().contains(fieldDaVerificare)) &&
  2589.                             (!sqlQueryObject[altriSqlObject].getFieldsName().contains("*")) ){
  2590.                         throw new SQLQueryObjectException("Field ["+fieldDaVerificare+"] trovato nella select numero "+(i+1) +" non presente nella select numero "+(altriSqlObject+1) +" (Se sono campi diversi usare lo stesso alias)");
  2591.                     }
  2592.                 }
  2593.             }
  2594.         }
  2595.     }
  2596.     protected void checkUnionFieldOrderOffset(ISQLQueryObject... sqlQueryObject)throws SQLQueryObjectException{
  2597.         for(int i=0;i<sqlQueryObject.length;i++){
  2598.             SQLQueryObjectCore sqlQueryObjectDaVerificare = (SQLQueryObjectCore) sqlQueryObject[i];
  2599.             if(sqlQueryObjectDaVerificare.orderBy!=null && !sqlQueryObjectDaVerificare.orderBy.isEmpty() &&
  2600.                 sqlQueryObjectDaVerificare.offset<0){
  2601.                 /**throw new SQLQueryObjectException("La select numero "+(i+1)+" per poter essere utilizzata nella UNION, siccome presenta condizioni di ordinamento, deve specificare anche l'offset");*/
  2602.                 sqlQueryObjectDaVerificare.setOffset(0); // Se viene messo il limit, l'offset cmq parte da 0
  2603.             }
  2604.         }
  2605.     }



  2606.     /* ---------------- UPDATE ------------------ */

  2607.     /**
  2608.      * Definisce la tabella su cui deve essere effettuato l'update
  2609.      * es: UPDATE table set ...
  2610.      *
  2611.      * @param nomeTabella Nome della tabella
  2612.      */
  2613.     @Override
  2614.     public ISQLQueryObject addUpdateTable(String nomeTabella) throws SQLQueryObjectException{
  2615.         if(nomeTabella==null || "".equals(nomeTabella))
  2616.             throw new SQLQueryObjectException("Nome tabella is null or empty string");
  2617.         this.updateTable = nomeTabella;
  2618.         return this;
  2619.     }

  2620.     /**
  2621.      * Aggiunge un field per l'update
  2622.      * es: UPDATE table set nomeField=valueField WHERE ...
  2623.      *
  2624.      * @param nomeField Nome del Field
  2625.      */
  2626.     @Override
  2627.     public ISQLQueryObject addUpdateField(String nomeField,String valueField) throws SQLQueryObjectException{
  2628.         if(nomeField==null || "".equals(nomeField))
  2629.             throw new SQLQueryObjectException(FIELD_NAME_IS_NULL_OR_EMPTY);
  2630.         if(valueField==null)
  2631.             throw new SQLQueryObjectException("Field value is null");
  2632.         if(this.updateFieldsName.contains(nomeField)){
  2633.             throw new SQLQueryObjectException(FIELD_NAME_PREFIX+nomeField+" gia inserito tra gli update fields");
  2634.         }else{
  2635.             this.updateFieldsName.add(nomeField);
  2636.             this.updateFieldsValue.add(valueField);
  2637.         }
  2638.         return this;
  2639.     }
  2640.    
  2641.     @Override
  2642.     public ISQLQueryObject addUpdateField(String nomeField,Case caseValue) throws SQLQueryObjectException{
  2643.         if(nomeField==null || "".equals(nomeField))
  2644.             throw new SQLQueryObjectException(FIELD_NAME_IS_NULL_OR_EMPTY);
  2645.        
  2646.         if(this.updateFieldsName.contains(nomeField)){
  2647.             throw new SQLQueryObjectException(FIELD_NAME_PREFIX+nomeField+" gia inserito tra gli update fields");
  2648.         }else{
  2649.             String caseCondition = getCaseCondition(caseValue);
  2650.                                    
  2651.             this.updateFieldsName.add(nomeField);
  2652.             this.updateFieldsValue.add(caseCondition);
  2653.         }
  2654.         return this;
  2655.     }
  2656.     protected String getPrefixCastValue(CastColumnType type, int length) {
  2657.         if(type!=null && length>0) {
  2658.             // nop
  2659.         }
  2660.         return "";
  2661.     }
  2662.     protected String getSuffixCastValue(CastColumnType type, int length) {
  2663.         if(type!=null || length>0) {
  2664.             // nop
  2665.         }
  2666.         return "";
  2667.     }
  2668.    
  2669.     @Override
  2670.     public String createSQLUpdate() throws SQLQueryObjectException{
  2671.        
  2672.         if(this.updateTable==null)
  2673.             throw new SQLQueryObjectException("Nome Tabella per l'aggiornamento non definito");
  2674.         if(this.updateFieldsName.isEmpty())
  2675.             throw new SQLQueryObjectException("Nessuna coppia nome/valore da aggiornare presente");
  2676.         if(this.updateFieldsName.size()!= this.updateFieldsValue.size()){
  2677.             throw new SQLQueryObjectException("FieldsName.size["+this.updateFieldsName.size()+"] <> FieldsValue.size["+this.updateFieldsValue.size()+"]");
  2678.         }
  2679.        
  2680.         if(this.forceSelectForUpdateDisabledForNotQueryMethod){
  2681.            
  2682.             // Per permettere di usare l'oggetto sqlQueryObject con più comandi
  2683.             boolean oldValueSelectForUpdate = this.selectForUpdate;
  2684.             try{
  2685.                 this.selectForUpdate = false;
  2686.                 return this.createSQLUpdateEngine();
  2687.             }finally{
  2688.                 this.selectForUpdate = oldValueSelectForUpdate;
  2689.             }
  2690.            
  2691.         }
  2692.         else{
  2693.             return this.createSQLUpdateEngine();
  2694.         }
  2695.     }
  2696.    
  2697.     protected abstract String createSQLUpdateEngine() throws SQLQueryObjectException;





  2698.     /* ---------------- INSERT ------------------ */

  2699.     /**
  2700.      * Definisce la tabella su cui deve essere effettuato l'insert
  2701.      * es: INSERT INTO table (XX) VALUES (VV)
  2702.      *
  2703.      * @param nomeTabella Nome della tabella
  2704.      */
  2705.     @Override
  2706.     public ISQLQueryObject addInsertTable(String nomeTabella) throws SQLQueryObjectException{
  2707.         if(nomeTabella==null || "".equals(nomeTabella))
  2708.             throw new SQLQueryObjectException("Nome tabella is null or empty string");
  2709.         this.insertTable = nomeTabella;
  2710.         return this;
  2711.     }

  2712.     /**
  2713.      * Aggiunge un field per la insert
  2714.      * es: INSERT INTO table (nomeField) VALUES (valueField)
  2715.      *
  2716.      * @param nomeField Nome del Field
  2717.      */
  2718.     @Override
  2719.     public ISQLQueryObject addInsertField(String nomeField,String valueField) throws SQLQueryObjectException{
  2720.         if(nomeField==null || "".equals(nomeField))
  2721.             throw new SQLQueryObjectException(FIELD_NAME_IS_NULL_OR_EMPTY);
  2722.         if(valueField==null)
  2723.             throw new SQLQueryObjectException("Field value is null");
  2724.         if(this.insertFieldsName.contains(nomeField)){
  2725.             throw new SQLQueryObjectException(FIELD_NAME_PREFIX+nomeField+" gia inserito tra gli insert fields");
  2726.         }else{
  2727.             this.insertFieldsName.add(nomeField);
  2728.             this.insertFieldsValue.add(valueField);
  2729.         }
  2730.         return this;
  2731.     }

  2732.     /**
  2733.      * Crea una SQL per una operazione di Insert con i dati dell'oggetto
  2734.      *
  2735.      * @return SQL per una operazione di Insert
  2736.      */
  2737.     @Override
  2738.     public String createSQLInsert() throws SQLQueryObjectException{
  2739.        
  2740.         if(this.insertTable==null)
  2741.             throw new SQLQueryObjectException("Nome Tabella per l'inserimento non definito");
  2742.         if(this.insertFieldsName.isEmpty())
  2743.             throw new SQLQueryObjectException("Nessuna coppia nome/valore da inserire presente");
  2744.         if(this.insertFieldsName.size()!= this.insertFieldsValue.size()){
  2745.             throw new SQLQueryObjectException("FieldsName.size <> FieldsValue.size");
  2746.         }

  2747.         if(this.forceSelectForUpdateDisabledForNotQueryMethod){
  2748.        
  2749.             // Per permettere di usare l'oggetto sqlQueryObject con più comandi
  2750.             boolean oldValueSelectForUpdate = this.selectForUpdate;
  2751.             try{
  2752.                 this.selectForUpdate = false;
  2753.                 return this.createSQLInsertEngine();
  2754.             }finally{
  2755.                 this.selectForUpdate = oldValueSelectForUpdate;
  2756.             }
  2757.            
  2758.         }
  2759.         else{
  2760.             return this.createSQLInsertEngine();
  2761.         }
  2762.        

  2763.     }
  2764.     private String createSQLInsertEngine() {
  2765.         StringBuilder bf = new StringBuilder();
  2766.         bf.append("INSERT INTO ");
  2767.         bf.append(this.insertTable);
  2768.         bf.append(" (");
  2769.         for(int i=0; i<this.insertFieldsName.size(); i++){
  2770.             if(i>0)
  2771.                 bf.append(",");
  2772.             bf.append(this.insertFieldsName.get(i));
  2773.         }
  2774.         bf.append(") VALUES (");
  2775.         for(int i=0; i<this.insertFieldsValue.size(); i++){
  2776.             if(i>0)
  2777.                 bf.append(",");
  2778.             bf.append(this.insertFieldsValue.get(i));
  2779.         }
  2780.         bf.append(")");
  2781.         return bf.toString();
  2782.     }





  2783.     /* ---------------- DELETE ------------------ */

  2784.     /**
  2785.      * Aggiunge una tabella di ricerca del from
  2786.      * es: DELETE from tabella
  2787.      *
  2788.      * @param tabella
  2789.      */
  2790.     @Override
  2791.     public ISQLQueryObject addDeleteTable(String tabella) throws SQLQueryObjectException{
  2792.         checkDeleteTable(tabella);
  2793.         this.addFromTable(tabella);
  2794.         return this;
  2795.     }
  2796.    
  2797.     @Override
  2798.     public String createSQLDelete() throws SQLQueryObjectException {

  2799.         // Table dove effettuare la ricerca 'FromTable'
  2800.         if(this.tables.isEmpty()){
  2801.             throw new SQLQueryObjectException("Non e' possibile creare un comando di delete senza aver definito le tabelle su cui apportare l'eliminazione dei dati");
  2802.         }else{
  2803.             Iterator<String> it = this.tables.iterator();
  2804.             while(it.hasNext()){
  2805.                 String table = it.next();
  2806.                 checkDeleteTable(table);
  2807.             }
  2808.         }

  2809.         if(this.forceSelectForUpdateDisabledForNotQueryMethod){
  2810.            
  2811.             // Per permettere di usare l'oggetto sqlQueryObject con più comandi
  2812.             boolean oldValueSelectForUpdate = this.selectForUpdate;
  2813.             try{
  2814.                 this.selectForUpdate = false;
  2815.                 return this.createSQLDeleteEngine();
  2816.             }finally{
  2817.                 this.selectForUpdate = oldValueSelectForUpdate;
  2818.             }
  2819.            
  2820.         }
  2821.         else{
  2822.             return this.createSQLDeleteEngine();
  2823.         }
  2824.     }
  2825.    
  2826.     protected abstract String createSQLDeleteEngine() throws SQLQueryObjectException;
  2827.    
  2828.     private void checkDeleteTable(String tabella) throws SQLQueryObjectException{
  2829.         // Controllo quelli standard (da fare per impostare il controllo in ogni classe)
  2830.         if(tabella.contains(" as ") || tabella.contains(" ")){
  2831.             throw new SQLQueryObjectException("Non e' possibile utilizzare tabelle definite tramite alias in caso di delete");
  2832.         }

  2833.         List<String> asModeSupportati = this.getSupportedAliasesTable();
  2834.         for (Iterator<?> iterator = asModeSupportati.iterator(); iterator.hasNext();) {
  2835.             String aliasMode = (String) iterator.next();
  2836.             if(tabella.contains(aliasMode)){
  2837.                 throw new SQLQueryObjectException("Non e' possibile utilizzare tabelle definite tramite alias in caso di delete");
  2838.             }
  2839.         }
  2840.     }
  2841.    
  2842.    
  2843.    
  2844.    
  2845.    
  2846.     /* ---------------- WHERE CONDITIONS ------------------ */
  2847.    
  2848.     @Override
  2849.     public String createSQLConditions() throws SQLQueryObjectException{
  2850.        
  2851.         if(this.conditions==null)
  2852.             throw new SQLQueryObjectException("Condizioni non definite");
  2853.         if(this.conditions.isEmpty())
  2854.             throw new SQLQueryObjectException("Nessuna condizione presente");
  2855.        
  2856.         if(this.forceSelectForUpdateDisabledForNotQueryMethod){
  2857.            
  2858.             // Per permettere di usare l'oggetto sqlQueryObject con più comandi
  2859.             boolean oldValueSelectForUpdate = this.selectForUpdate;
  2860.             try{
  2861.                 this.selectForUpdate = false;
  2862.                 return this.createSQLConditionsEngine();
  2863.             }finally{
  2864.                 this.selectForUpdate = oldValueSelectForUpdate;
  2865.             }
  2866.            
  2867.         }
  2868.         else{
  2869.             return this.createSQLConditionsEngine();
  2870.         }
  2871.     }

  2872.     protected abstract String createSQLConditionsEngine() throws SQLQueryObjectException;







  2873.     /* ---------------- NEW SQL QUERY OBJECT ------------------ */

  2874.     /**
  2875.      * Inizializza un nuovo SQLQueryObject
  2876.      *
  2877.      * @return SQLQueryObject
  2878.      *
  2879.      * @throws SQLQueryObjectException
  2880.      */
  2881.     @Override
  2882.     public ISQLQueryObject newSQLQueryObject() throws SQLQueryObjectException{
  2883.         return SQLObjectFactory.createSQLQueryObject(this.tipoDatabase);
  2884.     }

  2885.     /**
  2886.      * Indicazione sul tipo di database
  2887.      *
  2888.      * @return tipo di database
  2889.      *
  2890.      * @throws SQLQueryObjectException
  2891.      */
  2892.     @Override
  2893.     public String getTipoDatabase() throws SQLQueryObjectException{
  2894.         return this.tipoDatabase.toString();
  2895.     }

  2896.     /**
  2897.      * Indicazione sul tipo di database
  2898.      *
  2899.      * @return tipo di database
  2900.      *
  2901.      * @throws SQLQueryObjectException
  2902.      */
  2903.     @Override
  2904.     public TipiDatabase getTipoDatabaseOpenSPCoop2() throws SQLQueryObjectException{
  2905.         return this.tipoDatabase;
  2906.     }
  2907. }